summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJussi Laako <jussi.laako@linux.intel.com>2014-03-25 15:25:44 +0200
committerJussi Laako <jussi.laako@linux.intel.com>2014-03-25 15:26:50 +0200
commitbb0ada3bddfeeb4e98d3415c37266061c865005f (patch)
treef644444272c1a5f01b333977a94677bdc80f2184 /src
downloadecryptfs-utils-bb0ada3bddfeeb4e98d3415c37266061c865005f.tar.gz
ecryptfs-utils-bb0ada3bddfeeb4e98d3415c37266061c865005f.tar.bz2
ecryptfs-utils-bb0ada3bddfeeb4e98d3415c37266061c865005f.zip
Change-Id: I5f609bdfdf73bda344b01c41519f6cd65ea76f55
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am13
-rw-r--r--src/Makefile.in705
-rw-r--r--src/daemon/Makefile.am7
-rw-r--r--src/daemon/Makefile.in727
-rw-r--r--src/daemon/main.c404
-rw-r--r--src/desktop/Makefile.am17
-rw-r--r--src/desktop/Makefile.in626
-rwxr-xr-xsrc/desktop/ecryptfs-mount-private.desktop.in8
-rwxr-xr-xsrc/desktop/ecryptfs-record-passphrase18
-rwxr-xr-xsrc/desktop/ecryptfs-setup-private.desktop.in8
-rw-r--r--src/include/Makefile.am4
-rw-r--r--src/include/Makefile.in637
-rw-r--r--src/include/decision_graph.h141
-rw-r--r--src/include/ecryptfs.h581
-rw-r--r--src/key_mod/Makefile.am52
-rw-r--r--src/key_mod/Makefile.in867
-rw-r--r--src/key_mod/ecryptfs_key_mod_gpg.c411
-rw-r--r--src/key_mod/ecryptfs_key_mod_openssl.c1029
-rw-r--r--src/key_mod/ecryptfs_key_mod_passphrase.c330
-rw-r--r--src/key_mod/ecryptfs_key_mod_pkcs11_helper.c1684
-rw-r--r--src/key_mod/ecryptfs_key_mod_tspi.c751
-rw-r--r--src/libecryptfs-swig/Makefile.am16
-rw-r--r--src/libecryptfs-swig/Makefile.in804
-rw-r--r--src/libecryptfs-swig/libecryptfs.i17
-rw-r--r--src/libecryptfs-swig/libecryptfs.py55
-rw-r--r--src/libecryptfs-swig/libecryptfs_wrap.c3251
-rw-r--r--src/libecryptfs/Makefile.am28
-rw-r--r--src/libecryptfs/Makefile.in875
-rw-r--r--src/libecryptfs/cmd_ln_parser.c443
-rw-r--r--src/libecryptfs/decision_graph.c1213
-rw-r--r--src/libecryptfs/ecryptfs-stat.c188
-rw-r--r--src/libecryptfs/key_management.c860
-rw-r--r--src/libecryptfs/key_mod.c434
-rw-r--r--src/libecryptfs/libecryptfs.pc.in10
-rw-r--r--src/libecryptfs/main.c881
-rw-r--r--src/libecryptfs/messaging.c188
-rw-r--r--src/libecryptfs/miscdev.c277
-rw-r--r--src/libecryptfs/module_mgr.c998
-rw-r--r--src/libecryptfs/packets.c369
-rw-r--r--src/libecryptfs/sysfs.c167
-rw-r--r--src/pam_ecryptfs/Makefile.am17
-rw-r--r--src/pam_ecryptfs/Makefile.in747
-rw-r--r--src/pam_ecryptfs/pam_ecryptfs.c519
-rw-r--r--src/utils/Makefile.am72
-rw-r--r--src/utils/Makefile.in1517
-rwxr-xr-xsrc/utils/ecryptfs-find59
-rwxr-xr-xsrc/utils/ecryptfs-migrate-home206
-rwxr-xr-xsrc/utils/ecryptfs-mount-private81
-rwxr-xr-xsrc/utils/ecryptfs-recover-private123
-rwxr-xr-xsrc/utils/ecryptfs-rewrite-file75
-rwxr-xr-xsrc/utils/ecryptfs-setup-private464
-rwxr-xr-xsrc/utils/ecryptfs-setup-swap181
-rw-r--r--src/utils/ecryptfs-stat.c75
-rwxr-xr-xsrc/utils/ecryptfs-umount-private26
-rwxr-xr-xsrc/utils/ecryptfs-verify245
-rw-r--r--src/utils/ecryptfs_add_passphrase.c123
-rw-r--r--src/utils/ecryptfs_generate_tpm_key.c264
-rw-r--r--src/utils/ecryptfs_insert_wrapped_passphrase_into_keyring.c97
-rw-r--r--src/utils/ecryptfs_rewrap_passphrase.c115
-rw-r--r--src/utils/ecryptfs_unwrap_passphrase.c93
-rw-r--r--src/utils/ecryptfs_wrap_passphrase.c96
-rw-r--r--src/utils/ecryptfsrc2
-rw-r--r--src/utils/gen_key.c180
-rw-r--r--src/utils/io.c293
-rw-r--r--src/utils/io.h32
-rw-r--r--src/utils/manager.c146
-rw-r--r--src/utils/mount.ecryptfs.c646
-rw-r--r--src/utils/mount.ecryptfs_private.c724
-rw-r--r--src/utils/plaintext_decision_graph.c42
-rw-r--r--src/utils/test.c480
-rw-r--r--src/utils/umount.ecryptfs.c190
71 files changed, 28024 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..5877c09
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,13 @@
+# Copyright (C) 2006 Michael Halcrow <mhalcrow@us.ibm.com>
+#
+# This file is free software; as a special exception the author 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.
+
+MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+
+SUBDIRS = key_mod libecryptfs utils daemon desktop include pam_ecryptfs libecryptfs-swig
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 0000000..3bccbb7
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,705 @@
+# 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@
+
+# Copyright (C) 2006 Michael Halcrow <mhalcrow@us.ibm.com>
+#
+# This file is free software; as a special exception the author 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.
+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@
+subdir = src
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
+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 =
+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 =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ distdir
+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
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+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
+SUBDIRS = key_mod libecryptfs utils daemon desktop include pam_ecryptfs libecryptfs-swig
+all: all-recursive
+
+.SUFFIXES:
+$(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/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/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):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ $(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-recursive
+
+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-recursive
+
+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
+
+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
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+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:
+
+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-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+ check-am clean clean-generic clean-libtool cscopelist-am ctags \
+ ctags-am distclean distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am tags tags-am uninstall uninstall-am
+
+
+# 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/daemon/Makefile.am b/src/daemon/Makefile.am
new file mode 100644
index 0000000..92dd426
--- /dev/null
+++ b/src/daemon/Makefile.am
@@ -0,0 +1,7 @@
+MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+
+bin_PROGRAMS=ecryptfsd
+
+ecryptfsd_SOURCES = main.c
+ecryptfsd_CFLAGS = $(AM_CFLAGS) $(LIBGCRYPT_CFLAGS) $(KEYUTILS_CFLAGS)
+ecryptfsd_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la $(KEYUTILS_LIBS) $(LIBGCRYPT_LIBS)
diff --git a/src/daemon/Makefile.in b/src/daemon/Makefile.in
new file mode 100644
index 0000000..6c2e199
--- /dev/null
+++ b/src/daemon/Makefile.in
@@ -0,0 +1,727 @@
+# 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@
+bin_PROGRAMS = ecryptfsd$(EXEEXT)
+subdir = src/daemon
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/depcomp
+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 =
+am__installdirs = "$(DESTDIR)$(bindir)"
+PROGRAMS = $(bin_PROGRAMS)
+am_ecryptfsd_OBJECTS = ecryptfsd-main.$(OBJEXT)
+ecryptfsd_OBJECTS = $(am_ecryptfsd_OBJECTS)
+am__DEPENDENCIES_1 =
+ecryptfsd_DEPENDENCIES = \
+ $(top_builddir)/src/libecryptfs/libecryptfs.la \
+ $(am__DEPENDENCIES_1)
+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 =
+ecryptfsd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(ecryptfsd_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+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 = $(ecryptfsd_SOURCES)
+DIST_SOURCES = $(ecryptfsd_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
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+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
+ecryptfsd_SOURCES = main.c
+ecryptfsd_CFLAGS = $(AM_CFLAGS) $(LIBGCRYPT_CFLAGS) $(KEYUTILS_CFLAGS)
+ecryptfsd_LDADD = $(top_builddir)/src/libecryptfs/libecryptfs.la $(KEYUTILS_LIBS) $(LIBGCRYPT_LIBS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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/daemon/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/daemon/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
+
+ecryptfsd$(EXEEXT): $(ecryptfsd_OBJECTS) $(ecryptfsd_DEPENDENCIES) $(EXTRA_ecryptfsd_DEPENDENCIES)
+ @rm -f ecryptfsd$(EXEEXT)
+ $(AM_V_CCLD)$(ecryptfsd_LINK) $(ecryptfsd_OBJECTS) $(ecryptfsd_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecryptfsd-main.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 $@ $<
+
+ecryptfsd-main.o: main.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ecryptfsd_CFLAGS) $(CFLAGS) -MT ecryptfsd-main.o -MD -MP -MF $(DEPDIR)/ecryptfsd-main.Tpo -c -o ecryptfsd-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ecryptfsd-main.Tpo $(DEPDIR)/ecryptfsd-main.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main.c' object='ecryptfsd-main.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) $(ecryptfsd_CFLAGS) $(CFLAGS) -c -o ecryptfsd-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
+
+ecryptfsd-main.obj: main.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ecryptfsd_CFLAGS) $(CFLAGS) -MT ecryptfsd-main.obj -MD -MP -MF $(DEPDIR)/ecryptfsd-main.Tpo -c -o ecryptfsd-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ecryptfsd-main.Tpo $(DEPDIR)/ecryptfsd-main.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main.c' object='ecryptfsd-main.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) $(ecryptfsd_CFLAGS) $(CFLAGS) -c -o ecryptfsd-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.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
+
+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
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+ for dir in "$(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:
+
+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 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-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS
+
+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
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
+ clean-binPROGRAMS clean-generic clean-libtool 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-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS
+
+
+# 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/daemon/main.c b/src/daemon/main.c
new file mode 100644
index 0000000..d6ee220
--- /dev/null
+++ b/src/daemon/main.c
@@ -0,0 +1,404 @@
+/**
+ * Userspace daemon which responds to the eCryptfs kernel module's requests
+ *
+ * Copyright (C) 2004-2006 International Business Machines Corp.
+ * Author(s): Tyler Hicks <tyhicks@ou.edu>
+ *
+ * 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 <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <syslog.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <pthread.h>
+#include <libgen.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/resource.h>
+#include "../include/ecryptfs.h"
+
+static char *pidfile = NULL;
+static char *prompt_prog = NULL;
+
+static
+int
+prompt_callback(char *prompt_type, char *prompt, char *input, int input_size) {
+ int status;
+ pid_t pid = -1;
+ int fds[2] = {-1, -1};
+ int r = 0;
+ int rc;
+
+ /*
+ * Make sure we don't reuse input
+ */
+ if (input) {
+ memset (input, 0, input_size);
+ }
+
+ if (prompt_prog == NULL) {
+ rc = -EINVAL;
+ goto out;
+ }
+
+ if (pipe (fds) == -1) {
+ rc = -errno;
+ goto out;
+ }
+
+ if ((pid = fork ()) == -1) {
+ rc = -errno;
+ goto out;
+ }
+
+ if (pid == 0) {
+ close (fds[0]);
+ fds[0] = -1;
+
+ if (dup2 (fds[1], 1) == -1) {
+ exit (1);
+ }
+
+ close (fds[1]);
+ fds[1] = -1;
+
+ execl (
+ prompt_prog,
+ prompt_prog,
+ "-t",
+ prompt_type,
+ prompt,
+ NULL
+ );
+
+ exit (1);
+ }
+
+ close (fds[1]);
+ fds[1] = -1;
+
+ while (
+ (r=waitpid (pid, &status, 0)) == 0 ||
+ (r == -1 && errno == EINTR)
+ );
+
+ if (r == -1) {
+ rc = -errno;
+ goto out;
+ }
+
+ if (!WIFEXITED (status)) {
+ rc = -EFAULT;
+ goto out;
+ }
+
+ if (WEXITSTATUS (status) != 0) {
+ rc = -EIO;
+ goto out;
+ }
+
+ if (!strcmp (prompt_type, "password")) {
+ if ((r = read (fds[0], input, input_size)) == -1) {
+ rc = -errno;
+ goto out;
+ }
+
+ input[r] = '\0';
+
+ if (strlen (input) > 0 && input[strlen (input)-1] == '\n') {
+ input[strlen (input)-1] = '\0';
+ }
+ }
+
+ rc = 0;
+
+out:
+ if (rc != 0) {
+ if (input) {
+ memset (input, 0, input_size);
+ }
+ }
+
+ if (fds[0] != -1) {
+ close (fds[0]);
+ fds[0] = -1;
+ }
+
+ if (fds[1] != -1) {
+ close (fds[1]);
+ fds[1] = -1;
+ }
+
+ return rc;
+}
+
+struct ecryptfs_messaging_ctx mctx;
+pthread_mutex_t mctx_mux;
+
+static void ecryptfsd_exit(struct ecryptfs_messaging_ctx *mctx, int retval)
+{
+ int rc = 0;
+
+ if (pidfile != NULL) {
+ unlink(pidfile);
+ free(pidfile);
+ pidfile = NULL;
+ }
+ rc = ecryptfs_send_message(mctx, NULL, ECRYPTFS_MSG_QUIT, 0, 0);
+ if (rc)
+ syslog(LOG_ERR, "%s: Error attempting to send quit message to "
+ "kernel; rc = [%d]\n", __FUNCTION__, rc);
+ rc = ecryptfs_messaging_exit(mctx);
+ if (rc)
+ syslog(LOG_ERR, "%s: Error attempting to shut down messaging; "
+ "rc = [%d]\n", __FUNCTION__, rc);
+
+ ecryptfs_syslog(LOG_INFO, "Closing eCryptfs userspace daemon\n");
+ exit(retval);
+}
+
+void daemonize(void)
+{
+ pid_t pid;
+ int fd;
+ int null;
+
+ if(getppid() == 1)
+ return; /* Already a daemon */
+ if ((pid=fork()) == -1) {
+ fprintf(stderr, "Failed to create daemon process: %m\n");
+ exit(1);
+ }
+ if (pid != 0)
+ exit(0);
+ setsid();
+ umask(027);
+ if (chdir("/") == -1 ) {
+ syslog(LOG_ERR, "Failed to change directory: %m");
+ exit(1);
+ }
+ if ((pid=fork()) == -1) { /* Fork in new session */
+ syslog(LOG_ERR, "Failed to create daemon process: %m\n");
+ exit(1);
+ }
+ if (pid != 0)
+ exit(0);
+ /* Make std handles write to null; close all others. */
+ if ((null = open("/dev/null", O_RDWR)) == -1) {
+ syslog(LOG_ERR, "Cannot open /dev/null");
+ exit(1);
+ }
+ for (fd=0; fd < 3; fd++) {
+ if (dup2(null, fd) == -1) {
+ syslog(LOG_ERR, "Failed to dup null: %m\n");
+ exit(1);
+ }
+ }
+ for (fd = (getdtablesize() - 1); fd > 2; fd--)
+ close(fd);
+ /* Ignore major signals */
+ if (signal(SIGHUP, SIG_IGN) == SIG_ERR
+ || signal(SIGTERM, SIG_IGN) == SIG_ERR
+ || signal(SIGINT, SIG_IGN) == SIG_ERR) {
+ syslog(LOG_ERR, "Failed to setup initial signals");
+ exit(1);
+ }
+}
+
+void sigterm_handler(int sig)
+{
+ pthread_mutex_lock(&mctx_mux);
+ ecryptfsd_exit(&mctx, 0);
+ pthread_mutex_unlock(&mctx_mux);
+}
+
+void usage(const char *const me, const struct option *const options,
+ const char *const short_options)
+{
+ const struct option *opt;
+
+ printf("Usage: %s [options]", me);
+ for (opt = options; opt->name; opt++) {
+ const char *descr = opt->name + strlen(opt->name) + 1;
+
+ if (strchr(short_options, opt->val))
+ printf("\n -%c, --%s", opt->val, opt->name);
+ else
+ printf("\n --%s", opt->name);
+ if (opt->has_arg)
+ printf(" <%s>", opt->name);
+ if (strlen(descr))
+ printf("\t%s",descr);
+ }
+ printf("\n");
+}
+
+
+
+int main(int argc, char **argv)
+{
+ static struct option long_options[] = {
+ {"pidfile\0\tSet pid file name", required_argument, NULL, 'p'},
+ {"foreground\0\t\tDon't fork into background", no_argument,
+ NULL, 'f'},
+ {"chroot\0\t\tChroot to directory", required_argument, NULL,
+ 'C'},
+ {"prompt-prog\0Program to execute for user prompt",
+ required_argument, NULL, 'R'},
+ {"version\0\t\t\tShow version information", no_argument, NULL,
+ 'V'},
+ {"help\0\t\t\tShow usage information", no_argument, NULL, 'h'},
+ {NULL, 0, NULL, 0}
+ };
+ static char *short_options = "p:fC:R:Vh";
+ int long_options_ret;
+ struct rlimit core = {0, 0};
+ int foreground = 0;
+ char *chrootdir = NULL;
+ char *tty = NULL;
+ uint32_t version;
+ int rc = 0;
+
+ while ((long_options_ret = getopt_long(argc, argv, short_options,
+ long_options, NULL)) != -1) {
+ switch (long_options_ret) {
+ case 'p':
+ pidfile = strdup(optarg);
+ break;
+ case 'f':
+ foreground = 1;
+ break;
+ case 'C':
+ chrootdir = strdup(optarg);
+ break;
+ case 'R':
+ prompt_prog = strdup(optarg);
+ break;
+ case 'V':
+ printf(("%s (%s) %s\n"
+ "\n"
+ "This is free software. You may "
+ "redistribute copies of it under the "
+ "terms of\n"
+ "the GNU General Public License "
+ "<http://www.gnu.org/licenses/"
+ "gpl.html>.\n"
+ "There is NO WARRANTY, to the extent "
+ "permitted by law.\n"),
+ basename(argv[0]),
+ PACKAGE_NAME,
+ PACKAGE_VERSION);
+ exit(0);
+ break;
+ case 'h':
+ default:
+ usage(basename(argv[0]), long_options,
+ short_options);
+ exit(1);
+ break;
+ }
+ }
+ rc = ecryptfs_get_version(&version);
+ if (!rc && !(version & ECRYPTFS_VERSIONING_MISCDEV)) {
+ rc = -EPROTONOSUPPORT;
+ syslog(LOG_ERR, "%s: Current kernel does not have support for "
+ "/dev/ecryptfs; please use 2.6.26 or newer\n", __func__);
+ exit(rc);
+ }
+ openlog(argv[0], LOG_PID | (foreground ? LOG_PERROR : 0), 0);
+ if (rc) {
+ syslog(LOG_WARNING, "%s: Unable to retrieve versioning "
+ "info from kernel module; assuming /dev/ecryptfs is "
+ "available\n " , __FUNCTION__);
+ }
+ tty = ttyname(0); /* We may need the tty name later */
+ if (tty != NULL)
+ setenv ("TERM_DEVICE", tty, 0);
+ if (!foreground)
+ daemonize(); /* This will exit if cannot be completed */
+ /* Disallow core file; secret values may be in it */
+ if (setrlimit(RLIMIT_CORE, &core) == -1) {
+ rc = -errno;
+ syslog(LOG_ERR, "Cannot setrlimit: %m");
+ goto daemon_out;
+ }
+ if (chrootdir != NULL) {
+ if (chroot(chrootdir) == -1) {
+ rc = -errno;
+ syslog(LOG_ERR, "Failed to chroot to '%s': %m\n",
+ chrootdir);
+ goto daemon_out;
+ }
+ free(chrootdir);
+ chrootdir = NULL;
+ }
+ if (pidfile != NULL) {
+ FILE *fp = fopen(pidfile, "w");
+
+ if (fp == NULL) {
+ rc = -errno;
+ syslog(LOG_ERR, "Failed to open pid file '%s': %m\n",
+ pidfile);
+ goto daemon_out;
+ }
+ fprintf(fp, "%d", (int)getpid());
+ fclose(fp);
+ }
+ if (signal(SIGTERM, sigterm_handler) == SIG_ERR) {
+ rc = -ENOTSUP;
+ syslog(LOG_ERR, "Failed to attach handler to SIGTERM");
+ goto daemon_out;
+ }
+ if (signal(SIGINT, sigterm_handler) == SIG_ERR) {
+ rc = -ENOTSUP;
+ syslog(LOG_ERR, "Failed to attach handler to SIGINT");
+ goto daemon_out;
+ }
+ cryptfs_get_ctx_opts()->prompt = prompt_callback;
+ pthread_mutex_init(&mctx_mux, NULL);
+ pthread_mutex_lock(&mctx_mux);
+ rc = ecryptfs_init_messaging(&mctx, ECRYPTFS_MESSAGING_TYPE_MISCDEV);
+ if (rc) {
+ syslog(LOG_ERR, "%s: Failed to initialize messaging; rc = "
+ "[%d]\n", __FUNCTION__, rc);
+ pthread_mutex_unlock(&mctx_mux);
+ goto daemon_out;
+ }
+ rc = ecryptfs_send_message(&mctx, NULL, ECRYPTFS_MSG_HELO, 0, 0);
+ if (rc) {
+ syslog(LOG_ERR, "%s: Error attempting to send message to "
+ "eCryptfs kernel module via /dev/ecryptfs; rc = [%d]\n",
+ __func__, rc);
+ pthread_mutex_unlock(&mctx_mux);
+ goto daemon_out;
+ }
+ mctx.state |= ECRYPTFS_MESSAGING_STATE_LISTENING;
+ pthread_mutex_unlock(&mctx_mux);
+ rc = ecryptfs_run_daemon(&mctx);
+ pthread_mutex_lock(&mctx_mux);
+ mctx.state &= ~ECRYPTFS_MESSAGING_STATE_LISTENING;
+ pthread_mutex_unlock(&mctx_mux);
+daemon_out:
+ ecryptfsd_exit(&mctx, rc);
+ return rc;
+}
diff --git a/src/desktop/Makefile.am b/src/desktop/Makefile.am
new file mode 100644
index 0000000..2ffea77
--- /dev/null
+++ b/src/desktop/Makefile.am
@@ -0,0 +1,17 @@
+MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+
+eudatarootdir = $(datarootdir)/ecryptfs-utils
+dist_eudataroot_SCRIPTS = ecryptfs-record-passphrase
+
+desktopdir = $(datarootdir)/ecryptfs-utils
+
+desktop_in_files = \
+ ecryptfs-mount-private.desktop.in \
+ ecryptfs-setup-private.desktop.in
+
+desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
+
+@INTLTOOL_DESKTOP_RULE@
+
+
+
diff --git a/src/desktop/Makefile.in b/src/desktop/Makefile.in
new file mode 100644
index 0000000..aa4a668
--- /dev/null
+++ b/src/desktop/Makefile.in
@@ -0,0 +1,626 @@
+# 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@
+subdir = src/desktop
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(srcdir)/ecryptfs-mount-private.desktop.in \
+ $(srcdir)/ecryptfs-setup-private.desktop.in \
+ $(dist_eudataroot_SCRIPTS)
+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 = ecryptfs-mount-private.desktop \
+ ecryptfs-setup-private.desktop
+CONFIG_CLEAN_VPATH_FILES =
+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; }; \
+ }
+am__installdirs = "$(DESTDIR)$(eudatarootdir)" \
+ "$(DESTDIR)$(desktopdir)"
+SCRIPTS = $(dist_eudataroot_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 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+DATA = $(desktop_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+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
+eudatarootdir = $(datarootdir)/ecryptfs-utils
+dist_eudataroot_SCRIPTS = ecryptfs-record-passphrase
+desktopdir = $(datarootdir)/ecryptfs-utils
+desktop_in_files = \
+ ecryptfs-mount-private.desktop.in \
+ ecryptfs-setup-private.desktop.in
+
+desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
+all: all-am
+
+.SUFFIXES:
+$(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/desktop/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/desktop/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):
+ecryptfs-mount-private.desktop: $(top_builddir)/config.status $(srcdir)/ecryptfs-mount-private.desktop.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+ecryptfs-setup-private.desktop: $(top_builddir)/config.status $(srcdir)/ecryptfs-setup-private.desktop.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+install-dist_eudatarootSCRIPTS: $(dist_eudataroot_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ @list='$(dist_eudataroot_SCRIPTS)'; test -n "$(eudatarootdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(eudatarootdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(eudatarootdir)" || 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)$(eudatarootdir)$$dir'"; \
+ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(eudatarootdir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-dist_eudatarootSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_eudataroot_SCRIPTS)'; test -n "$(eudatarootdir)" || exit 0; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 's,.*/,,;$(transform)'`; \
+ dir='$(DESTDIR)$(eudatarootdir)'; $(am__uninstall_files_from_dir)
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-desktopDATA: $(desktop_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(desktop_DATA)'; test -n "$(desktopdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(desktopdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(desktopdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(desktopdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(desktopdir)" || exit $$?; \
+ done
+
+uninstall-desktopDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(desktop_DATA)'; test -n "$(desktopdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(desktopdir)'; $(am__uninstall_files_from_dir)
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+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
+check: check-am
+all-am: Makefile $(SCRIPTS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(eudatarootdir)" "$(DESTDIR)$(desktopdir)"; 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:
+
+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-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-desktopDATA install-dist_eudatarootSCRIPTS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+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 -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-desktopDATA uninstall-dist_eudatarootSCRIPTS
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ cscopelist-am ctags-am distclean distclean-generic \
+ distclean-libtool distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am \
+ install-desktopDATA install-dist_eudatarootSCRIPTS install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags-am uninstall uninstall-am uninstall-desktopDATA \
+ uninstall-dist_eudatarootSCRIPTS
+
+
+@INTLTOOL_DESKTOP_RULE@
+
+# 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/desktop/ecryptfs-mount-private.desktop.in b/src/desktop/ecryptfs-mount-private.desktop.in
new file mode 100755
index 0000000..6e51570
--- /dev/null
+++ b/src/desktop/ecryptfs-mount-private.desktop.in
@@ -0,0 +1,8 @@
+[Desktop Entry]
+_Name=Access Your Private Data
+_GenericName=Access Your Private Data
+Exec=/usr/bin/ecryptfs-mount-private
+Terminal=true
+Type=Application
+Categories=System;Security;
+X-Ubuntu-Gettext-Domain=ecryptfs-utils
diff --git a/src/desktop/ecryptfs-record-passphrase b/src/desktop/ecryptfs-record-passphrase
new file mode 100755
index 0000000..b63d228
--- /dev/null
+++ b/src/desktop/ecryptfs-record-passphrase
@@ -0,0 +1,18 @@
+_Name: Record your encryption passphrase
+Priority: High
+OnlyAdminUsers: False
+DisplayIf: test -e $HOME/.ecryptfs/wrapped-passphrase -a ! -e $HOME/.ecryptfs/.wrapped-passphrase.recorded
+Terminal: True
+GettextDomain: ecryptfs-utils
+Command: "sh -c 'ecryptfs-unwrap-passphrase $HOME/.ecryptfs/wrapped-passphrase 2>/dev/null && echo [Enter] && head -n1 && touch $HOME/.ecryptfs/.wrapped-passphrase.recorded '"
+_Description:
+ To encrypt your home directory or "Private" folder, a strong
+ passphrase has been automatically generated. Usually your directory is unlocked
+ with your user password, but if you ever need to manually recover this
+ directory, you will need this passphrase. Please print or write it down and
+ store it in a safe location.
+ If you click "Run this action now", enter your login password at the
+ "Passphrase" prompt and you can display your randomly generated passphrase.
+ Otherwise, you will need to run "ecryptfs-unwrap-passphrase" from the command
+ line to retrieve and record your generated passphrase.
+
diff --git a/src/desktop/ecryptfs-setup-private.desktop.in b/src/desktop/ecryptfs-setup-private.desktop.in
new file mode 100755
index 0000000..989882b
--- /dev/null
+++ b/src/desktop/ecryptfs-setup-private.desktop.in
@@ -0,0 +1,8 @@
+[Desktop Entry]
+_Name=Setup Your Encrypted Private Directory
+_GenericName=Setup Your Encrypted Private Directory
+Exec=/usr/bin/ecryptfs-setup-private
+Terminal=true
+Type=Application
+Categories=Settings;Security;
+X-Ubuntu-Gettext-Domain=ecryptfs-utils
diff --git a/src/include/Makefile.am b/src/include/Makefile.am
new file mode 100644
index 0000000..8d56e46
--- /dev/null
+++ b/src/include/Makefile.am
@@ -0,0 +1,4 @@
+MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+
+include_HEADERS = ecryptfs.h
+dist_noinst_HEADERS = decision_graph.h
diff --git a/src/include/Makefile.in b/src/include/Makefile.in
new file mode 100644
index 0000000..adc2345
--- /dev/null
+++ b/src/include/Makefile.in
@@ -0,0 +1,637 @@
+# 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@
+subdir = src/include
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(dist_noinst_HEADERS) $(include_HEADERS)
+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 =
+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 =
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+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; }; \
+ }
+am__installdirs = "$(DESTDIR)$(includedir)"
+HEADERS = $(dist_noinst_HEADERS) $(include_HEADERS)
+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
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+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
+include_HEADERS = ecryptfs.h
+dist_noinst_HEADERS = decision_graph.h
+all: all-am
+
+.SUFFIXES:
+$(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/include/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/include/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):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
+
+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
+
+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
+check: check-am
+all-am: Makefile $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(includedir)"; 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:
+
+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-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-includeHEADERS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+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 -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-includeHEADERS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libtool cscopelist-am ctags ctags-am distclean \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-includeHEADERS install-info install-info-am \
+ install-man install-pdf install-pdf-am install-ps \
+ install-ps-am install-strip installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am tags tags-am uninstall uninstall-am \
+ uninstall-includeHEADERS
+
+
+# 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/include/decision_graph.h b/src/include/decision_graph.h
new file mode 100644
index 0000000..f0f170f
--- /dev/null
+++ b/src/include/decision_graph.h
@@ -0,0 +1,141 @@
+/**
+ * Header file for eCryptfs decision graph
+ *
+ * Copyright (C) 2004-2006 International Business Machines Corp.
+ * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
+ * Trevor Highland <trevor.highland@gmail.com>
+ *
+ * The structs here are shared between kernel and userspace, so if you
+ * are running a 64-bit kernel, you need to compile your userspace
+ * applications as 64-bit binaries.
+ *
+ * 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.
+ */
+
+#ifndef DECISION_GRAPH_H
+#define DECISION_GRAPH_H
+
+#ifndef S_SPLINT_S
+#include <stdio.h>
+#endif
+
+struct param_node;
+
+struct val_node {
+ void *val;
+ struct val_node *next;
+};
+
+struct ecryptfs_ctx;
+
+/**
+ * transition_node
+ * @val: If this value and the value set for the parent param_node
+ * match, then this transition_node is followed. This value is
+ * part of the transition_node's definition. For internal use
+ * only.
+ * @pretty_val: The value displayed to the user.
+ * @next_token: The param_node that we transition to if this
+ * transition_node is followed.
+ * @trans_func: The function to execute when this transition node is
+ * followed.
+ *
+ * See src/libecryptfs/decision_graph.c::do_transition()
+ *
+ * If @val is set to NULL on definition, then this transition node
+ * will be followed by default, no matter what the parent param_node's
+ * val is set to.
+ *
+ * If @next_token is NULL, then @trans_func must be defined.
+ *
+ * If @trans_func is defined and returns NULL_TOK, then @next_token is
+ * used as the next param_node.
+ */
+struct transition_node {
+#define ECRYPTFS_TN_FLAG_REQ_FREE 0x00000001
+ uint32_t flags;
+ char *val;
+ char *pretty_val;
+ struct param_node *next_token;
+ int (*trans_func)(struct ecryptfs_ctx *, struct param_node *,
+ struct val_node **, void **);
+};
+
+struct param_node {
+#define NULL_TOK 1
+#define DEFAULT_TOK 2
+#define MOUNT_ERROR 3
+#define WRONG_VALUE 4
+ int num_mnt_opt_names;
+#define MAX_NUM_MNT_OPT_NAMES 8
+ char *mnt_opt_names[MAX_NUM_MNT_OPT_NAMES];
+ char *prompt;
+#define VAL_STR 0
+#define VAL_HEX 1
+ int val_type;
+ char *val;
+ char *default_val;
+ char *suggested_val;
+ void (*display_opts)(struct param_node *);
+#define ECRYPTFS_PARAM_FLAG_ECHO_INPUT 0x00000001
+#define ECRYPTFS_PARAM_FLAG_MASK_OUTPUT 0x00000002
+#define ECRYPTFS_ALLOW_IMPLICIT_TRANSITION 0x00000004
+#define ECRYPTFS_PARAM_FLAG_NO_VALUE 0x00000008
+#define DISPLAY_TRANSITION_NODE_VALS 0x00000010
+#define VERIFY_VALUE 0x00000020
+#define STDIN_REQUIRED 0x00000040
+#define PARAMETER_SET 0x00000080
+#define ECRYPTFS_PARAM_FLAG_LOCK_MEM 0x00000100
+#define ECRYPTFS_PARAM_FORCE_DISPLAY_NODES 0x00000200
+#define ECRYPTFS_DISPLAY_PRETTY_VALS 0x00000400
+#define ECRYPTFS_NO_AUTO_TRANSITION 0x00000800
+#define ECRYPTFS_IMPLICIT_OVERRIDE_DEFAULT 0x00001000
+#define ECRYPTFS_NONEMPTY_VALUE_REQUIRED 0x00002000
+ uint32_t flags;
+ int num_transitions;
+#define MAX_NUM_TRANSITIONS 64
+ struct transition_node tl[MAX_NUM_TRANSITIONS];
+};
+
+struct prompt_elem;
+
+struct prompt_elem {
+ char *str;
+ struct prompt_elem *next;
+};
+
+int add_transition_node_to_param_node(struct param_node *param_node,
+ struct transition_node *trans_node);
+void ecryptfs_dump_param_node(FILE *file_stream,
+ struct param_node *param_node, int depth,
+ int recursive);
+void ecryptfs_dump_transition_node(FILE *file_stream,
+ struct transition_node *trans_node,
+ int depth, int recursive);
+void ecryptfs_dump_decision_graph(FILE *file_stream,
+ struct param_node *param_node, int depth);
+int ecryptfs_set_exit_param_on_graph(struct param_node *param_node,
+ struct param_node *exit_param_node);
+
+struct ecryptfs_name_val_pair;
+
+int ecryptfs_insert_params_in_subgraph(struct ecryptfs_name_val_pair *nvp,
+ struct transition_node *trans_node);
+int eval_param_tree(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct ecryptfs_name_val_pair *nvp_head,
+ struct val_node **val_stack_head);
+
+#endif
diff --git a/src/include/ecryptfs.h b/src/include/ecryptfs.h
new file mode 100644
index 0000000..a644061
--- /dev/null
+++ b/src/include/ecryptfs.h
@@ -0,0 +1,581 @@
+/**
+ * Header file for eCryptfs userspace tools.
+ *
+ * Copyright (C) 2004-2008 International Business Machines Corp.
+ * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
+ *
+ * The structs here are shared between kernel and userspace, so if you
+ * are running a 64-bit kernel, you need to compile your userspace
+ * applications as 64-bit binaries.
+ *
+ * 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.
+ */
+
+#ifndef ECRYTPFS_H
+#define ECRYTPFS_H
+
+#include <stdint.h>
+#include <netdb.h>
+#include <limits.h>
+#include <termios.h>
+#ifndef S_SPLINT_S
+#include <stdio.h>
+#include <syslog.h>
+#endif
+#include <pthread.h>
+#include <unistd.h>
+#ifndef S_SPLINT_S
+#include <sys/types.h>
+#include <linux/types.h>
+#endif
+
+/* Version verification for shared data structures w/ userspace */
+#ifndef ECRYPTFS_VERSION_MAJOR
+#define ECRYPTFS_VERSION_MAJOR 0x00
+#endif
+#ifndef ECRYPTFS_VERSION_MINOR
+#define ECRYPTFS_VERSION_MINOR 0x04
+#endif
+
+#ifndef ECRYPTFS_SUPPORTED_FILE_VERSION
+#define ECRYPTFS_SUPPORTED_FILE_VERSION 0x03
+#endif
+
+/* These flags indicate which features are supported by the kernel
+ * module; userspace tools such as the mount helper read from a sysfs
+ * handle in order to determine how to behave. */
+#define ECRYPTFS_VERSIONING_PASSPHRASE 0x00000001
+#define ECRYPTFS_VERSIONING_PUBKEY 0x00000002
+#define ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH 0x00000004
+#define ECRYPTFS_VERSIONING_POLICY 0x00000008
+#define ECRYPTFS_VERSIONING_XATTR 0x00000010
+#define ECRYPTFS_VERSIONING_MULTKEY 0x00000020
+#define ECRYPTFS_VERSIONING_MISCDEV 0x00000040
+#define ECRYPTFS_VERSIONING_HMAC 0x00000080
+#define ECRYPTFS_VERSIONING_FILENAME_ENCRYPTION 0x00000100
+#define ECRYPTFS_VERSIONING_GCM 0x00000200
+
+#define ECRYPTFS_MAX_PASSWORD_LENGTH 64
+#define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH
+#define ECRYPTFS_SALT_SIZE 8
+#define ECRYPTFS_SALT_SIZE_HEX (ECRYPTFS_SALT_SIZE*2)
+#define ECRYPTFS_DEFAULT_SALT_HEX "0011223344556677"
+#define ECRYPTFS_DEFAULT_SALT_FNEK_HEX "9988776655443322"
+/* The original signature size is only for what is stored on disk; all
+ * in-memory representations are expanded hex, so it better adapted to
+ * be passed around on the command line */
+#define ECRYPTFS_SIG_SIZE 8
+#define ECRYPTFS_SIG_SIZE_HEX (ECRYPTFS_SIG_SIZE*2)
+#define ECRYPTFS_PASSWORD_SIG_SIZE ECRYPTFS_SIG_SIZE_HEX
+#define ECRYPTFS_MAX_KEY_BYTES 64
+#define ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES 512
+#define ECRYPTFS_DEFAULT_IV_BYTES 16
+#define ECRYPTFS_FILE_VERSION 0x03
+#define ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE 8192
+#define ECRYPTFS_DEFAULT_EXTENT_SIZE 4096
+#define ECRPYTFS_STRING_LENGTH 128
+#ifndef MAGIC_ECRYPTFS_MARKER_STR
+#define MAGIC_ECRYPTFS_MARKER_STR "3c81b7f5"
+#endif
+#ifndef MAGIC_ECRYPTFS_MARKER
+#define MAGIC_ECRYPTFS_MARKER 0x3c81b7f5
+#define MAGIC_ECRYPTFS_MARKER_SIZE_BYTES 8 /* 4*2 */
+#endif
+#define MAX_NAME_SIZE 128
+#define MAX_KEY_MOD_VALUE_SIZE 4096
+#define ECRYPTFS_TAG_1_PACKET_TYPE 0x01
+#define ECRYPTFS_TAG_3_PACKET_TYPE 0x8C
+#define ECRYPTFS_TAG_11_PACKET_TYPE 0xED
+#define ECRYPTFS_TAG_64_PACKET_TYPE 0x40
+#define ECRYPTFS_TAG_65_PACKET_TYPE 0x41
+#define ECRYPTFS_TAG_66_PACKET_TYPE 0x42
+#define ECRYPTFS_TAG_67_PACKET_TYPE 0x43
+#define ECRYPTFS_MSG_HELO 100
+#define ECRYPTFS_MSG_QUIT 101
+#define ECRYPTFS_MSG_REQUEST 102
+#define ECRYPTFS_MSG_RESPONSE 103
+#define ECRYPTFS_MSG_MAX_SIZE 1024
+#define ECRYPTFS_MSG_ERROR_COUNT_THRESHOLD 8
+#define ECRYPTFS_MAX_KEY_MOD_NAME_BYTES 16
+
+#ifndef SHA512_DIGEST_LENGTH
+#define SHA512_DIGEST_LENGTH 64
+#endif
+
+#ifndef SHA1_DIGEST_LENGTH
+#define SHA1_DIGEST_LENGTH 20
+#endif
+
+#define PGP_DIGEST_ALGO_SHA512 10
+
+/* TODO: Put this in configure.in, and make this ECRYPTFS_DEFAULT_KEY_MOD */
+#define ECRYPTFS_KEY_MOD_OPENSSL "openssl"
+
+#define ECRYPTFS_NOT_SALTLESS 0
+#define ECRYPTFS_SALTLESS 1
+/* Hash iterations are intended to make dictionary attacks more difficult */
+#define ECRYPTFS_DEFAULT_NUM_HASH_ITERATIONS 65536
+
+#define ECRYPTFS_FILE_SIZE_BYTES (sizeof(uint64_t))
+
+#define ECRYPTFS_TAG_64_PACKET 0x40
+#define ECRYPTFS_TAG_65_PACKET 0x41
+#define ECRYPTFS_TAG_66_PACKET 0x42
+#define ECRYPTFS_TAG_67_PACKET 0x43
+
+#define ecryptfs_syslog(type, fmt, arg...) \
+ syslog(type, "%s: " fmt, __FUNCTION__, ## arg);
+
+#define ECRYPTFS_MAX_NUM_CIPHERS 64
+#define ECRYPTFS_ECHO_ON 1
+#define ECRYPTFS_ECHO_OFF 0
+
+#define ECRYPTFS_AES_BLOCK_SIZE 16
+#define ECRYPTFS_AES_KEY_BYTES 16
+
+#define ECRYPTFS_DEFAULT_WRAPPED_PASSPHRASE_FILENAME "wrapped-passphrase"
+
+#define ECRYPTFS_ERROR_INSERT_KEY "Error: Inserting key into the user session keyring failed"
+#define ECRYPTFS_ERROR_UNWRAP "Error: Unwrapping passphrase failed"
+#define ECRYPTFS_ERROR_UNWRAP_AND_INSERT "Error: Unwrapping passphrase and inserting into the user session keyring failed"
+#define ECRYPTFS_ERROR_WRAP "Error: Wrapping passphrase failed"
+#define ECRYPTFS_ERROR_FNEK_SUPPORT "Error: Your kernel does not support filename encryption"
+#define ECRYPTFS_INFO_CHECK_LOG "Info: Check the system log for more information from libecryptfs"
+#define ECRYPTFS_WARN_DEFAULT_SALT "Warning: Using default salt value (undefined in ~/.ecryptfsrc)"
+
+extern int ecryptfs_verbosity;
+
+/**
+ * For convenience, we may need to pass around the encrypted session
+ * key between kernel and userspace because the authentication token
+ * may not be extractable. For example, the TPM may not release the
+ * private key, instead requiring the encrypted data and returning the
+ * decrypted data.
+ */
+struct ecryptfs_session_key {
+#define ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT 0x00000001
+#define ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT 0x00000002
+#define ECRYPTFS_CONTAINS_DECRYPTED_KEY 0x00000004
+#define ECRYPTFS_CONTAINS_ENCRYPTED_KEY 0x00000008
+ int32_t flags;
+ int32_t encrypted_key_size;
+ int32_t decrypted_key_size;
+ uint8_t encrypted_key[ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES];
+ uint8_t decrypted_key[ECRYPTFS_MAX_KEY_BYTES];
+};
+
+static const char common_salt[ECRYPTFS_SALT_SIZE] =
+ { (char)0x00, (char)0x11, (char)0x22, (char)0x33, (char)0x44,
+ (char)0x55, (char)0x66, (char)0x77 };
+
+struct ecryptfs_password {
+ int32_t password_bytes;
+ int32_t hash_algo;
+ int32_t hash_iterations;
+ int32_t session_key_encryption_key_bytes;
+#define ECRYPTFS_PERSISTENT_PASSWORD 0x01
+#define ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET 0x02
+ uint32_t flags;
+ /* Iterated-hash concatenation of salt and passphrase */
+ uint8_t session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES];
+ uint8_t signature[ECRYPTFS_PASSWORD_SIG_SIZE + 1];
+ /* Always in expanded hex */
+ uint8_t salt[ECRYPTFS_SALT_SIZE];
+};
+
+struct ecryptfs_private_key {
+ uint32_t key_size;
+ uint32_t data_len;
+ uint8_t signature[ECRYPTFS_PASSWORD_SIG_SIZE + 1];
+ char key_mod_alias[ECRYPTFS_MAX_KEY_MOD_NAME_BYTES + 1];
+ uint8_t data[];
+};
+
+enum ecryptfs_token_types {ECRYPTFS_PASSWORD, ECRYPTFS_PRIVATE_KEY};
+
+
+
+/* This struct must be identical to that as defined in the kernel. */
+struct ecryptfs_auth_tok {
+ uint16_t version; /* 8-bit major and 8-bit minor */
+ uint16_t token_type;
+#define ECRYPTFS_ENCRYPT_ONLY 0x00000001
+ uint32_t flags;
+ struct ecryptfs_session_key session_key;
+ uint8_t reserved[32];
+ union {
+ struct ecryptfs_password password;
+ struct ecryptfs_private_key private_key;
+ } token;
+} __attribute__ ((packed));
+
+struct ecryptfs_auth_tok_list {
+ struct ecryptfs_auth_tok *auth_tok;
+ struct ecryptfs_auth_tok_list *next;
+};
+
+struct ecryptfs_name_val_pair {
+#define ECRYPTFS_DEFAULT_VALUE_SET 0x00000004
+#define ECRYPTFS_PROCESSED 0x00000008
+#define ECRYPTFS_NO_ECHO 0x00000010
+ uint32_t flags;
+ char *name;
+ char *value;
+ struct ecryptfs_name_val_pair *parent;
+#define NV_MAX_CHILDREN 16
+ struct ecryptfs_name_val_pair *children[NV_MAX_CHILDREN];
+ struct ecryptfs_name_val_pair *next;
+};
+
+void dump_auth_tok( struct ecryptfs_auth_tok *auth_tok );
+extern void to_hex( char *dst, char *src, int src_size );
+extern void from_hex( char *dst, char *src, int dst_size );
+extern int generate_version_from_string(unsigned char *major,
+ unsigned char *minor,
+ char *version);
+
+struct ecryptfs_daemon_info {
+ char socket_file_full_path[PATH_MAX];
+};
+
+struct ecryptfs_message {
+ uint32_t index;
+ uint32_t data_len;
+ uint8_t data[];
+};
+
+struct transition_node;
+
+/**
+ * @id: Internal (to the key module) identifier for this module
+ * parameter. The key module will use the key_mod_param id to
+ * match the given value for this parameter
+ * @val: The value provided
+ */
+struct key_mod_param_val {
+ int id;
+ char *val;
+};
+
+/**
+ * @id: Internal (to the key module) identifier for this module
+ * parameter. The key module will use the key_mod_param_val id to
+ * match the given value for this parameter
+ * @option: The parameter option
+ * @description: A long text description of the parameter option
+ * @suggested_val: The value that will presented to the user as the
+ * one to select
+ * @default_val: The value that will be assigned by default if none is
+ * given
+ * @val: Pointer to the struct key_mod_param_val provided for this
+ * struct key_mod_param. This is matched based on @id
+ */
+struct key_mod_param {
+ int id;
+ uint32_t flags;
+ char *option;
+ char *description;
+ char *suggested_val;
+ char *default_val;
+ struct key_mod_param_val *val;
+};
+
+#define ECRYPTFS_BLOB_TYPE_BLOB 0
+#define ECRYPTFS_BLOB_TYPE_HINT 1
+
+#define ECRYPTFS_KEY_MOD_SUCCESS 0
+#define ECRYPTFS_KEY_MOD_BADPARAM 1
+#define ECRYPTFS_KEY_MOD_BUFTOOSMALL 2
+#define ECRYPTFS_KEY_MOD_INSUFFICIENT_PARAMS 3
+#define ECRYPTFS_KEY_MOD_DATA_TOO_LARGE 4
+#define ECRYPTFS_KEY_MOD_ENCRYPT_FAILED 5
+#define ECRYPTFS_KEY_MOD_DECRYPT_FAILED 6
+#define ECRYPTFS_KEY_MOD_NO_SUCH_KEY 7
+#define ECRYPTFS_KEY_MOD_HINT_INSUFFICIENT 8
+
+struct ecryptfs_ctx_ops {
+ int (*prompt)(char *prompt_type, char *prompt, char *input,
+ int input_size);
+};
+
+/**
+ * @init: Allocates memory on the heap and sets the alias into that
+ * memory; callee will free
+ * @get_params:
+ * @get_key_data: The first uint32_t (big-endian) bytes indicate the
+ * key type. If key_data_len is 0, then libecryptfs
+ * will call get_key_sig() so that the key module can
+ * generate its own sig.
+ * @get_key_sig: Optional. Allows the key module to generate its own
+ * key signature. Used in cases where libecryptfs does
+ * not know about the key type, so @get_key_data is of
+ * no use. @get_key_sig is not called if @get_key_data
+ * returns valid key data.
+ * @encrypt: If to is NULL, only fill in to_size with the amount
+ * that the callee needs to allocate.
+ * @decrypt: If to is NULL, only fill in to_size with the amount
+ * that the callee needs to allocate.
+ * @finalize: Call when the entire key module is shutting down
+ */
+struct ecryptfs_key_mod_ops {
+ int (*init)(char **alias);
+ int (*get_gen_key_params)(struct key_mod_param **params,
+ uint32_t *num_params);
+ int (*get_gen_key_subgraph_trans_node)(struct transition_node **trans,
+ uint32_t version);
+ int (*get_params)(struct key_mod_param **params, uint32_t *num_params);
+ int (*get_param_subgraph_trans_node)(struct transition_node **trans,
+ uint32_t version);
+ int (*get_blob)(unsigned char *blob, size_t *blob_size,
+ struct key_mod_param_val *param_vals,
+ uint32_t num_param_vals);
+ int (*get_key_data)(unsigned char *key_data, size_t *key_data_len,
+ unsigned char *blob);
+ int (*get_key_sig)(unsigned char *sig, unsigned char *blob);
+ int (*get_key_hint)(unsigned char *hint, size_t *hint_len,
+ unsigned char *blob);
+ int (*encrypt)(char *to, size_t *to_size, char *from, size_t from_size,
+ unsigned char *blob, int blob_type);
+ int (*decrypt)(char *to, size_t *to_size, char *from, size_t from_size,
+ unsigned char *blob, int blob_type);
+ int (*destroy)(unsigned char *blob);
+ int (*finalize)(void);
+};
+
+/**
+ * @lib_handle:
+ * @alias:
+ * @lib_path:
+ * @trans_into_mod_subgraph:
+ * @ops:
+ * @param_vals:
+ * @num_param_vals:
+ * @nvp_head:
+ * @next:
+ */
+struct ecryptfs_key_mod {
+ void *lib_handle;
+ char *alias;
+ char *lib_path;
+ struct transition_node *trans_into_mod_subgraph;
+ struct transition_node *trans_into_mod_key_gen_subgraph;
+ struct ecryptfs_key_mod_ops *ops;
+ struct key_mod_param_val *param_vals;
+ uint32_t num_param_vals;
+ char *blob;
+ size_t blob_size;
+ struct ecryptfs_key_mod *next;
+};
+
+struct ecryptfs_ctx {
+ void *ctx_mutex;
+ struct ecryptfs_key_mod key_mod_list_head;
+ int verbosity;
+ int (*get_string)(char **val, char *prompt, int echo);
+ FILE *file_in;
+ FILE *file_out;
+ struct ecryptfs_name_val_pair *nvp_head;
+};
+
+enum main_menu_enum {
+ MME_NULL,
+ MME_MOUNT_PASSPHRASE,
+ MME_MOUNT_PUBKEY,
+ MME_GEN_PUBKEY,
+ MME_ABORT
+};
+
+struct val_node;
+struct param_node;
+
+struct ecryptfs_nl_ctx {
+ int socket_fd;
+};
+
+#define ECRYPTFS_DEFAULT_MISCDEV_FULLPATH_0 "/dev/ecryptfs"
+#define ECRYPTFS_DEFAULT_MISCDEV_FULLPATH_1 "/dev/misc/ecryptfs"
+
+struct ecryptfs_miscdev_ctx {
+ char *miscdev_filename;
+ int miscdev_fd;
+};
+
+struct ecryptfs_messaging_ctx {
+#define ECRYPTFS_MESSAGING_TYPE_NETLINK 0x00000001 /* No longer supported */
+#define ECRYPTFS_MESSAGING_TYPE_MISCDEV 0x00000002
+ uint32_t type;
+#define ECRYPTFS_MESSAGING_STATE_LISTENING 0x00000001
+ uint32_t state;
+ union {
+ struct ecryptfs_miscdev_ctx miscdev_ctx;
+ struct ecryptfs_nl_ctx nl_ctx;
+ } ctx;
+};
+
+struct ecryptfs_crypt_stat_user {
+#define ECRYPTFS_STRUCT_INITIALIZED 0x00000001
+#define ECRYPTFS_POLICY_APPLIED 0x00000002
+#define ECRYPTFS_NEW_FILE 0x00000004
+#define ECRYPTFS_ENCRYPTED 0x00000008
+#define ECRYPTFS_SECURITY_WARNING 0x00000010
+#define ECRYPTFS_ENABLE_HMAC 0x00000020
+#define ECRYPTFS_ENCRYPT_IV_PAGES 0x00000040
+#define ECRYPTFS_KEY_VALID 0x00000080
+#define ECRYPTFS_METADATA_IN_XATTR 0x00000100
+#define ECRYPTFS_VIEW_AS_ENCRYPTED 0x00000200
+#define ECRYPTFS_KEY_SET 0x00000400
+ uint32_t flags;
+ unsigned int file_version;
+ uint64_t file_size;
+ size_t iv_bytes;
+ size_t num_header_bytes_at_front;
+ size_t extent_size;
+ size_t key_size;
+ struct ecryptfs_auth_tok_list *ptr_to_auth_tok_list_head;
+};
+
+typedef struct binary_data {
+ int size;
+ unsigned char *data;
+} binary_data;
+
+int ecryptfs_get_version(uint32_t *version);
+int ecryptfs_supports_passphrase(uint32_t version);
+int ecryptfs_supports_pubkey(uint32_t version);
+int ecryptfs_supports_plaintext_passthrough(uint32_t version);
+int ecryptfs_supports_hmac(uint32_t version);
+int ecryptfs_supports_filename_encryption(uint32_t version);
+int ecryptfs_supports_policy(uint32_t version);
+int ecryptfs_supports_xattr(uint32_t version);
+#define ECRYPTFS_ASK_FOR_ALL_MOUNT_OPTIONS 0
+#define ECRYPTFS_KEY_MODULE_ONLY 1
+int ecryptfs_process_decision_graph(struct ecryptfs_ctx *ctx,
+ struct val_node **head, uint32_t version,
+ char *opts_str, int key_module_only);
+int ecryptfs_process_key_gen_decision_graph(struct ecryptfs_ctx *ctx,
+ uint32_t version);
+int get_string(char *val, int len, int echo);
+int get_string_stdin(char **val, char *prompt, int echo);
+int stack_pop(struct val_node **head);
+int stack_pop_val(struct val_node **head, void **val);
+int stack_push(struct val_node **head, void *val);
+int ecryptfs_get_key_mod_list(struct ecryptfs_ctx* ctx);
+int ecryptfs_parse_rc_file(struct ecryptfs_name_val_pair *nvp_list_head);
+int ecryptfs_parse_options(char *opts, struct ecryptfs_name_val_pair *head);
+int ecryptfs_eval_decision_graph(struct ecryptfs_ctx *ctx,
+ struct val_node **head,
+ struct param_node *root_node,
+ struct ecryptfs_name_val_pair *nvp_head);
+int ecryptfs_add_passphrase_key_to_keyring(char *auth_tok_sig, char *passphrase,
+ char *salt);
+int ecryptfs_add_key_module_key_to_keyring(char *auth_tok_sig,
+ struct ecryptfs_key_mod *key_mod);
+int ecryptfs_read_salt_hex_from_rc(char *salt_hex);
+int ecryptfs_generate_key(void);
+int ecryptfs_free_key_mod_list(struct ecryptfs_ctx *ctx);
+int create_default_dir(char *home, struct ecryptfs_key_mod *key_mod);
+int
+create_subdirectory(char *file, char *home, struct ecryptfs_key_mod *key_mod);
+int parse_packet(struct ecryptfs_ctx *ctx,
+ struct ecryptfs_message *emsg,
+ struct ecryptfs_message **reply);
+int ecryptfs_find_key_mod(struct ecryptfs_key_mod **key_mod,
+ struct ecryptfs_ctx *ctx, char *key_mod_alias);
+int generate_passphrase_sig(char *passphrase_sig, char *fekek, char *salt,
+ char *passphrase);
+int
+generate_payload(struct ecryptfs_auth_tok *auth_tok, char *passphrase_sig,
+ char *salt, char *session_key_encryption_key);
+int
+ecryptfs_generate_key_payload(struct ecryptfs_auth_tok *auth_tok,
+ struct ecryptfs_key_mod *key_mod, char *sig,
+ size_t blob_size);
+int parse_options_file(int fd, struct ecryptfs_name_val_pair *head);
+int free_name_val_pairs(struct ecryptfs_name_val_pair *pair);
+int ecryptfs_init_messaging(struct ecryptfs_messaging_ctx *mctx, uint32_t type);
+int ecryptfs_messaging_exit(struct ecryptfs_messaging_ctx *mctx);
+int ecryptfs_nvp_list_union(struct ecryptfs_name_val_pair *dst,
+ struct ecryptfs_name_val_pair *src,
+ struct ecryptfs_name_val_pair *allowed_duplicates);
+int ecryptfs_read_salt_hex_from_rc(char *salt_hex);
+#define ECRYPTFS_SIG_FLAG_NOENT 0x00000001
+int ecryptfs_check_sig(char *auth_tok_sig, char *sig_cache_filename,
+ int *flags);
+int ecryptfs_append_sig(char *auth_tok_sig, char *sig_cache_filename);
+int ecryptfs_wrap_passphrase_file(char *dest, char *wrapping_passphrase,
+ char *wrapping_salt, char *src);
+int ecryptfs_wrap_passphrase(char *filename, char *wrapping_passphrase,
+ char *wrapping_salt, char *decrypted_passphrase);
+int ecryptfs_unwrap_passphrase(char *decrypted_passphrase, char *filename,
+ char *wrapping_passphrase, char *wrapping_salt);
+int ecryptfs_insert_wrapped_passphrase_into_keyring(
+ char *auth_tok_sig, char *filename, char *wrapping_passphrase,
+ char *salt);
+char *ecryptfs_get_wrapped_passphrase_filename();
+struct ecryptfs_key_mod_ops *passphrase_get_key_mod_ops(void);
+int ecryptfs_validate_keyring(void);
+#define ECRYPTFS_SHM_KEY 0x3c81b7f5
+#define ECRYPTFS_SEM_KEY 0x3c81b7f6
+#define ECRYPTFS_SHM_SIZE 4096
+#define ECRYPTFS_ZOMBIE_SLEEP_SECONDS 300
+int ecryptfs_set_zombie_session_placeholder(void);
+int ecryptfs_kill_and_clear_zombie_session_placeholder(void);
+int ecryptfs_list_zombie_session_placeholders(void);
+int ecryptfs_build_linear_subgraph_from_nvp(struct transition_node **trans_node,
+ struct ecryptfs_key_mod *key_mod);
+int ecryptfs_build_linear_subgraph(struct transition_node **trans_node,
+ struct ecryptfs_key_mod *key_mod);
+int ecryptfs_generate_sig_from_key_data(unsigned char *sig,
+ unsigned char *key_data,
+ size_t key_data_len);
+int ecryptfs_fill_in_dummy_ops(struct ecryptfs_key_mod_ops *key_mod_ops);
+int ecryptfs_register_key_modules(struct ecryptfs_ctx* ctx);
+int ecryptfs_write_packet_length(char *dest, size_t size,
+ size_t *packet_size_length);
+int ecryptfs_parse_packet_length(unsigned char *data, size_t *size,
+ size_t *length_size);
+int ecryptfs_get_proc_mount_point(char **proc_mount_point);
+int ecryptfs_send_message(struct ecryptfs_messaging_ctx *mctx,
+ struct ecryptfs_message *msg,
+ unsigned char msg_type, uint16_t msg_flags,
+ uint32_t msg_seq);
+int ecryptfs_init_miscdev(struct ecryptfs_miscdev_ctx *miscdev_ctx);
+int ecryptfs_send_miscdev(struct ecryptfs_miscdev_ctx *miscdev_ctx,
+ struct ecryptfs_message *msg, uint8_t msg_type,
+ uint16_t msg_flags, uint32_t msg_seq);
+void ecryptfs_release_miscdev(struct ecryptfs_miscdev_ctx *miscdev_ctx);
+int ecryptfs_run_miscdev_daemon(struct ecryptfs_miscdev_ctx *miscdev_ctx);
+struct ecryptfs_ctx_ops *cryptfs_get_ctx_opts(void);
+int ecryptfs_parse_stat(struct ecryptfs_crypt_stat_user *crypt_stat, char *buf,
+ size_t buf_size);
+binary_data ecryptfs_passphrase_blob(char *salt, char *passphrase);
+binary_data ecryptfs_passphrase_sig_from_blob(char *blob);
+int ecryptfs_add_passphrase_blob_to_keyring(char *blob, char *sig);
+int ecryptfs_remove_auth_tok_from_keyring(char *auth_tok_sig);
+int ecryptfs_add_auth_tok_to_keyring(struct ecryptfs_auth_tok *auth_tok,
+ char *auth_tok_sig);
+int ecryptfs_add_blob_to_keyring(char *blob, char *sig);
+
+int ecryptfs_disable_echo(struct termios *saved_settings);
+int ecryptfs_enable_echo(struct termios *saved_settings);
+char *ecryptfs_get_passphrase(char *prompt);
+int ecryptfs_run_daemon(struct ecryptfs_messaging_ctx *mctx);
+
+#define ECRYPTFS_PRIVATE_DIR "Private"
+char *ecryptfs_fetch_private_mnt(char *pw_dir);
+int ecryptfs_private_is_mounted(char *dev, char *mnt, char *sig, int mounting);
+
+#endif
diff --git a/src/key_mod/Makefile.am b/src/key_mod/Makefile.am
new file mode 100644
index 0000000..1af0812
--- /dev/null
+++ b/src/key_mod/Makefile.am
@@ -0,0 +1,52 @@
+MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+
+ecryptfskeymod_LTLIBRARIES=libecryptfs_key_mod_passphrase.la
+
+if BUILD_OPENSSL
+ecryptfskeymod_LTLIBRARIES+=libecryptfs_key_mod_openssl.la
+endif
+if BUILD_PKCS11_HELPER
+ecryptfskeymod_LTLIBRARIES+=libecryptfs_key_mod_pkcs11_helper.la
+endif
+if BUILD_TSPI
+ecryptfskeymod_LTLIBRARIES+=libecryptfs_key_mod_tspi.la
+endif
+if BUILD_GPG
+ecryptfskeymod_LTLIBRARIES+=libecryptfs_key_mod_gpg.la
+endif
+
+libecryptfs_key_mod_openssl_la_SOURCES = ecryptfs_key_mod_openssl.c
+libecryptfs_key_mod_openssl_la_CFLAGS = $(AM_CFLAGS) $(OPENSSL_CFLAGS)
+libecryptfs_key_mod_openssl_la_LIBADD = $(OPENSSL_LIBS)
+libecryptfs_key_mod_openssl_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version -shared
+
+libecryptfs_key_mod_pkcs11_helper_la_SOURCES = ecryptfs_key_mod_pkcs11_helper.c
+libecryptfs_key_mod_pkcs11_helper_la_CFLAGS = $(AM_CFLAGS) $(PKCS11_HELPER_CFLAGS) $(OPENSSL_CFLAGS)
+libecryptfs_key_mod_pkcs11_helper_la_LIBADD = $(PKCS11_HELPER_LIBS) $(OPENSSL_LIBS)
+libecryptfs_key_mod_pkcs11_helper_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version -shared
+
+libecryptfs_key_mod_tspi_la_SOURCES = ecryptfs_key_mod_tspi.c
+libecryptfs_key_mod_tspi_la_CFLAGS = $(AM_CFLAGS) $(TSPI_CFLAGS)
+libecryptfs_key_mod_tspi_la_LIBADD = $(TSPI_LIBS)
+libecryptfs_key_mod_tspi_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version -shared
+
+libecryptfs_key_mod_gpg_la_SOURCES = ecryptfs_key_mod_gpg.c
+libecryptfs_key_mod_gpg_la_CFLAGS = $(AM_CFLAGS) $(GPGME_CFLAGS)
+libecryptfs_key_mod_gpg_la_LIBADD = $(GPGME_LIBS)
+libecryptfs_key_mod_gpg_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version -shared
+
+libecryptfs_key_mod_passphrase_la_SOURCES = ecryptfs_key_mod_passphrase.c
+libecryptfs_key_mod_passphrase_la_CFLAGS = $(AM_CFLAGS) $(LIBGCRYPT_CFLAGS)
+libecryptfs_key_mod_passphrase_la_LIBADD = $(LIBGCRYPT_LIBS)
+libecryptfs_key_mod_passphrase_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version -shared
+
+# Needed until libtool-2
+install-data-hook: install-ecryptfskeymodLTLIBRARIES
+ for f in `echo "$(ecryptfskeymod_LTLIBRARIES)" | $(SED) 's/\.la//g'`; do \
+ rm -f "$(DESTDIR)$(ecryptfskeymoddir)/$$f.la"; \
+ rm -f "$(DESTDIR)$(ecryptfskeymoddir)/$$f.a"; \
+ done
+uninstall-local:
+ for f in `echo "$(ecryptfskeymod_LTLIBRARIES)" | $(SED) 's/\.la//g'`; do \
+ rm -f "$(DESTDIR)$(ecryptfskeymoddir)/$$f.so"; \
+ done
diff --git a/src/key_mod/Makefile.in b/src/key_mod/Makefile.in
new file mode 100644
index 0000000..53d0d1e
--- /dev/null
+++ b/src/key_mod/Makefile.in
@@ -0,0 +1,867 @@
+# 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@
+@BUILD_OPENSSL_TRUE@am__append_1 = libecryptfs_key_mod_openssl.la
+@BUILD_PKCS11_HELPER_TRUE@am__append_2 = libecryptfs_key_mod_pkcs11_helper.la
+@BUILD_TSPI_TRUE@am__append_3 = libecryptfs_key_mod_tspi.la
+@BUILD_GPG_TRUE@am__append_4 = libecryptfs_key_mod_gpg.la
+subdir = src/key_mod
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/depcomp
+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 =
+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; }; \
+ }
+am__installdirs = "$(DESTDIR)$(ecryptfskeymoddir)"
+LTLIBRARIES = $(ecryptfskeymod_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libecryptfs_key_mod_gpg_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_libecryptfs_key_mod_gpg_la_OBJECTS = \
+ libecryptfs_key_mod_gpg_la-ecryptfs_key_mod_gpg.lo
+libecryptfs_key_mod_gpg_la_OBJECTS = \
+ $(am_libecryptfs_key_mod_gpg_la_OBJECTS)
+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 =
+libecryptfs_key_mod_gpg_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(libecryptfs_key_mod_gpg_la_CFLAGS) $(CFLAGS) \
+ $(libecryptfs_key_mod_gpg_la_LDFLAGS) $(LDFLAGS) -o $@
+@BUILD_GPG_TRUE@am_libecryptfs_key_mod_gpg_la_rpath = -rpath \
+@BUILD_GPG_TRUE@ $(ecryptfskeymoddir)
+libecryptfs_key_mod_openssl_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_libecryptfs_key_mod_openssl_la_OBJECTS = \
+ libecryptfs_key_mod_openssl_la-ecryptfs_key_mod_openssl.lo
+libecryptfs_key_mod_openssl_la_OBJECTS = \
+ $(am_libecryptfs_key_mod_openssl_la_OBJECTS)
+libecryptfs_key_mod_openssl_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(libecryptfs_key_mod_openssl_la_CFLAGS) $(CFLAGS) \
+ $(libecryptfs_key_mod_openssl_la_LDFLAGS) $(LDFLAGS) -o $@
+@BUILD_OPENSSL_TRUE@am_libecryptfs_key_mod_openssl_la_rpath = -rpath \
+@BUILD_OPENSSL_TRUE@ $(ecryptfskeymoddir)
+libecryptfs_key_mod_passphrase_la_DEPENDENCIES =
+am_libecryptfs_key_mod_passphrase_la_OBJECTS = libecryptfs_key_mod_passphrase_la-ecryptfs_key_mod_passphrase.lo
+libecryptfs_key_mod_passphrase_la_OBJECTS = \
+ $(am_libecryptfs_key_mod_passphrase_la_OBJECTS)
+libecryptfs_key_mod_passphrase_la_LINK = $(LIBTOOL) $(AM_V_lt) \
+ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \
+ $(CCLD) $(libecryptfs_key_mod_passphrase_la_CFLAGS) $(CFLAGS) \
+ $(libecryptfs_key_mod_passphrase_la_LDFLAGS) $(LDFLAGS) -o $@
+libecryptfs_key_mod_pkcs11_helper_la_DEPENDENCIES = \
+ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+am_libecryptfs_key_mod_pkcs11_helper_la_OBJECTS = libecryptfs_key_mod_pkcs11_helper_la-ecryptfs_key_mod_pkcs11_helper.lo
+libecryptfs_key_mod_pkcs11_helper_la_OBJECTS = \
+ $(am_libecryptfs_key_mod_pkcs11_helper_la_OBJECTS)
+libecryptfs_key_mod_pkcs11_helper_la_LINK = $(LIBTOOL) $(AM_V_lt) \
+ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \
+ $(CCLD) $(libecryptfs_key_mod_pkcs11_helper_la_CFLAGS) \
+ $(CFLAGS) $(libecryptfs_key_mod_pkcs11_helper_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@BUILD_PKCS11_HELPER_TRUE@am_libecryptfs_key_mod_pkcs11_helper_la_rpath = \
+@BUILD_PKCS11_HELPER_TRUE@ -rpath $(ecryptfskeymoddir)
+libecryptfs_key_mod_tspi_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_libecryptfs_key_mod_tspi_la_OBJECTS = \
+ libecryptfs_key_mod_tspi_la-ecryptfs_key_mod_tspi.lo
+libecryptfs_key_mod_tspi_la_OBJECTS = \
+ $(am_libecryptfs_key_mod_tspi_la_OBJECTS)
+libecryptfs_key_mod_tspi_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(libecryptfs_key_mod_tspi_la_CFLAGS) $(CFLAGS) \
+ $(libecryptfs_key_mod_tspi_la_LDFLAGS) $(LDFLAGS) -o $@
+@BUILD_TSPI_TRUE@am_libecryptfs_key_mod_tspi_la_rpath = -rpath \
+@BUILD_TSPI_TRUE@ $(ecryptfskeymoddir)
+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 = $(libecryptfs_key_mod_gpg_la_SOURCES) \
+ $(libecryptfs_key_mod_openssl_la_SOURCES) \
+ $(libecryptfs_key_mod_passphrase_la_SOURCES) \
+ $(libecryptfs_key_mod_pkcs11_helper_la_SOURCES) \
+ $(libecryptfs_key_mod_tspi_la_SOURCES)
+DIST_SOURCES = $(libecryptfs_key_mod_gpg_la_SOURCES) \
+ $(libecryptfs_key_mod_openssl_la_SOURCES) \
+ $(libecryptfs_key_mod_passphrase_la_SOURCES) \
+ $(libecryptfs_key_mod_pkcs11_helper_la_SOURCES) \
+ $(libecryptfs_key_mod_tspi_la_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
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+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
+ecryptfskeymod_LTLIBRARIES = libecryptfs_key_mod_passphrase.la \
+ $(am__append_1) $(am__append_2) $(am__append_3) \
+ $(am__append_4)
+libecryptfs_key_mod_openssl_la_SOURCES = ecryptfs_key_mod_openssl.c
+libecryptfs_key_mod_openssl_la_CFLAGS = $(AM_CFLAGS) $(OPENSSL_CFLAGS)
+libecryptfs_key_mod_openssl_la_LIBADD = $(OPENSSL_LIBS)
+libecryptfs_key_mod_openssl_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version -shared
+libecryptfs_key_mod_pkcs11_helper_la_SOURCES = ecryptfs_key_mod_pkcs11_helper.c
+libecryptfs_key_mod_pkcs11_helper_la_CFLAGS = $(AM_CFLAGS) $(PKCS11_HELPER_CFLAGS) $(OPENSSL_CFLAGS)
+libecryptfs_key_mod_pkcs11_helper_la_LIBADD = $(PKCS11_HELPER_LIBS) $(OPENSSL_LIBS)
+libecryptfs_key_mod_pkcs11_helper_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version -shared
+libecryptfs_key_mod_tspi_la_SOURCES = ecryptfs_key_mod_tspi.c
+libecryptfs_key_mod_tspi_la_CFLAGS = $(AM_CFLAGS) $(TSPI_CFLAGS)
+libecryptfs_key_mod_tspi_la_LIBADD = $(TSPI_LIBS)
+libecryptfs_key_mod_tspi_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version -shared
+libecryptfs_key_mod_gpg_la_SOURCES = ecryptfs_key_mod_gpg.c
+libecryptfs_key_mod_gpg_la_CFLAGS = $(AM_CFLAGS) $(GPGME_CFLAGS)
+libecryptfs_key_mod_gpg_la_LIBADD = $(GPGME_LIBS)
+libecryptfs_key_mod_gpg_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version -shared
+libecryptfs_key_mod_passphrase_la_SOURCES = ecryptfs_key_mod_passphrase.c
+libecryptfs_key_mod_passphrase_la_CFLAGS = $(AM_CFLAGS) $(LIBGCRYPT_CFLAGS)
+libecryptfs_key_mod_passphrase_la_LIBADD = $(LIBGCRYPT_LIBS)
+libecryptfs_key_mod_passphrase_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version -shared
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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/key_mod/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/key_mod/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-ecryptfskeymodLTLIBRARIES: $(ecryptfskeymod_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(ecryptfskeymod_LTLIBRARIES)'; test -n "$(ecryptfskeymoddir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(ecryptfskeymoddir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(ecryptfskeymoddir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(ecryptfskeymoddir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(ecryptfskeymoddir)"; \
+ }
+
+uninstall-ecryptfskeymodLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(ecryptfskeymod_LTLIBRARIES)'; test -n "$(ecryptfskeymoddir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(ecryptfskeymoddir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(ecryptfskeymoddir)/$$f"; \
+ done
+
+clean-ecryptfskeymodLTLIBRARIES:
+ -test -z "$(ecryptfskeymod_LTLIBRARIES)" || rm -f $(ecryptfskeymod_LTLIBRARIES)
+ @list='$(ecryptfskeymod_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+libecryptfs_key_mod_gpg.la: $(libecryptfs_key_mod_gpg_la_OBJECTS) $(libecryptfs_key_mod_gpg_la_DEPENDENCIES) $(EXTRA_libecryptfs_key_mod_gpg_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libecryptfs_key_mod_gpg_la_LINK) $(am_libecryptfs_key_mod_gpg_la_rpath) $(libecryptfs_key_mod_gpg_la_OBJECTS) $(libecryptfs_key_mod_gpg_la_LIBADD) $(LIBS)
+
+libecryptfs_key_mod_openssl.la: $(libecryptfs_key_mod_openssl_la_OBJECTS) $(libecryptfs_key_mod_openssl_la_DEPENDENCIES) $(EXTRA_libecryptfs_key_mod_openssl_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libecryptfs_key_mod_openssl_la_LINK) $(am_libecryptfs_key_mod_openssl_la_rpath) $(libecryptfs_key_mod_openssl_la_OBJECTS) $(libecryptfs_key_mod_openssl_la_LIBADD) $(LIBS)
+
+libecryptfs_key_mod_passphrase.la: $(libecryptfs_key_mod_passphrase_la_OBJECTS) $(libecryptfs_key_mod_passphrase_la_DEPENDENCIES) $(EXTRA_libecryptfs_key_mod_passphrase_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libecryptfs_key_mod_passphrase_la_LINK) -rpath $(ecryptfskeymoddir) $(libecryptfs_key_mod_passphrase_la_OBJECTS) $(libecryptfs_key_mod_passphrase_la_LIBADD) $(LIBS)
+
+libecryptfs_key_mod_pkcs11_helper.la: $(libecryptfs_key_mod_pkcs11_helper_la_OBJECTS) $(libecryptfs_key_mod_pkcs11_helper_la_DEPENDENCIES) $(EXTRA_libecryptfs_key_mod_pkcs11_helper_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libecryptfs_key_mod_pkcs11_helper_la_LINK) $(am_libecryptfs_key_mod_pkcs11_helper_la_rpath) $(libecryptfs_key_mod_pkcs11_helper_la_OBJECTS) $(libecryptfs_key_mod_pkcs11_helper_la_LIBADD) $(LIBS)
+
+libecryptfs_key_mod_tspi.la: $(libecryptfs_key_mod_tspi_la_OBJECTS) $(libecryptfs_key_mod_tspi_la_DEPENDENCIES) $(EXTRA_libecryptfs_key_mod_tspi_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libecryptfs_key_mod_tspi_la_LINK) $(am_libecryptfs_key_mod_tspi_la_rpath) $(libecryptfs_key_mod_tspi_la_OBJECTS) $(libecryptfs_key_mod_tspi_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecryptfs_key_mod_gpg_la-ecryptfs_key_mod_gpg.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecryptfs_key_mod_openssl_la-ecryptfs_key_mod_openssl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecryptfs_key_mod_passphrase_la-ecryptfs_key_mod_passphrase.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecryptfs_key_mod_pkcs11_helper_la-ecryptfs_key_mod_pkcs11_helper.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecryptfs_key_mod_tspi_la-ecryptfs_key_mod_tspi.Plo@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 $@ $<
+
+libecryptfs_key_mod_gpg_la-ecryptfs_key_mod_gpg.lo: ecryptfs_key_mod_gpg.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_key_mod_gpg_la_CFLAGS) $(CFLAGS) -MT libecryptfs_key_mod_gpg_la-ecryptfs_key_mod_gpg.lo -MD -MP -MF $(DEPDIR)/libecryptfs_key_mod_gpg_la-ecryptfs_key_mod_gpg.Tpo -c -o libecryptfs_key_mod_gpg_la-ecryptfs_key_mod_gpg.lo `test -f 'ecryptfs_key_mod_gpg.c' || echo '$(srcdir)/'`ecryptfs_key_mod_gpg.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecryptfs_key_mod_gpg_la-ecryptfs_key_mod_gpg.Tpo $(DEPDIR)/libecryptfs_key_mod_gpg_la-ecryptfs_key_mod_gpg.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ecryptfs_key_mod_gpg.c' object='libecryptfs_key_mod_gpg_la-ecryptfs_key_mod_gpg.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_key_mod_gpg_la_CFLAGS) $(CFLAGS) -c -o libecryptfs_key_mod_gpg_la-ecryptfs_key_mod_gpg.lo `test -f 'ecryptfs_key_mod_gpg.c' || echo '$(srcdir)/'`ecryptfs_key_mod_gpg.c
+
+libecryptfs_key_mod_openssl_la-ecryptfs_key_mod_openssl.lo: ecryptfs_key_mod_openssl.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_key_mod_openssl_la_CFLAGS) $(CFLAGS) -MT libecryptfs_key_mod_openssl_la-ecryptfs_key_mod_openssl.lo -MD -MP -MF $(DEPDIR)/libecryptfs_key_mod_openssl_la-ecryptfs_key_mod_openssl.Tpo -c -o libecryptfs_key_mod_openssl_la-ecryptfs_key_mod_openssl.lo `test -f 'ecryptfs_key_mod_openssl.c' || echo '$(srcdir)/'`ecryptfs_key_mod_openssl.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecryptfs_key_mod_openssl_la-ecryptfs_key_mod_openssl.Tpo $(DEPDIR)/libecryptfs_key_mod_openssl_la-ecryptfs_key_mod_openssl.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ecryptfs_key_mod_openssl.c' object='libecryptfs_key_mod_openssl_la-ecryptfs_key_mod_openssl.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_key_mod_openssl_la_CFLAGS) $(CFLAGS) -c -o libecryptfs_key_mod_openssl_la-ecryptfs_key_mod_openssl.lo `test -f 'ecryptfs_key_mod_openssl.c' || echo '$(srcdir)/'`ecryptfs_key_mod_openssl.c
+
+libecryptfs_key_mod_passphrase_la-ecryptfs_key_mod_passphrase.lo: ecryptfs_key_mod_passphrase.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_key_mod_passphrase_la_CFLAGS) $(CFLAGS) -MT libecryptfs_key_mod_passphrase_la-ecryptfs_key_mod_passphrase.lo -MD -MP -MF $(DEPDIR)/libecryptfs_key_mod_passphrase_la-ecryptfs_key_mod_passphrase.Tpo -c -o libecryptfs_key_mod_passphrase_la-ecryptfs_key_mod_passphrase.lo `test -f 'ecryptfs_key_mod_passphrase.c' || echo '$(srcdir)/'`ecryptfs_key_mod_passphrase.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecryptfs_key_mod_passphrase_la-ecryptfs_key_mod_passphrase.Tpo $(DEPDIR)/libecryptfs_key_mod_passphrase_la-ecryptfs_key_mod_passphrase.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ecryptfs_key_mod_passphrase.c' object='libecryptfs_key_mod_passphrase_la-ecryptfs_key_mod_passphrase.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_key_mod_passphrase_la_CFLAGS) $(CFLAGS) -c -o libecryptfs_key_mod_passphrase_la-ecryptfs_key_mod_passphrase.lo `test -f 'ecryptfs_key_mod_passphrase.c' || echo '$(srcdir)/'`ecryptfs_key_mod_passphrase.c
+
+libecryptfs_key_mod_pkcs11_helper_la-ecryptfs_key_mod_pkcs11_helper.lo: ecryptfs_key_mod_pkcs11_helper.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_key_mod_pkcs11_helper_la_CFLAGS) $(CFLAGS) -MT libecryptfs_key_mod_pkcs11_helper_la-ecryptfs_key_mod_pkcs11_helper.lo -MD -MP -MF $(DEPDIR)/libecryptfs_key_mod_pkcs11_helper_la-ecryptfs_key_mod_pkcs11_helper.Tpo -c -o libecryptfs_key_mod_pkcs11_helper_la-ecryptfs_key_mod_pkcs11_helper.lo `test -f 'ecryptfs_key_mod_pkcs11_helper.c' || echo '$(srcdir)/'`ecryptfs_key_mod_pkcs11_helper.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecryptfs_key_mod_pkcs11_helper_la-ecryptfs_key_mod_pkcs11_helper.Tpo $(DEPDIR)/libecryptfs_key_mod_pkcs11_helper_la-ecryptfs_key_mod_pkcs11_helper.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ecryptfs_key_mod_pkcs11_helper.c' object='libecryptfs_key_mod_pkcs11_helper_la-ecryptfs_key_mod_pkcs11_helper.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_key_mod_pkcs11_helper_la_CFLAGS) $(CFLAGS) -c -o libecryptfs_key_mod_pkcs11_helper_la-ecryptfs_key_mod_pkcs11_helper.lo `test -f 'ecryptfs_key_mod_pkcs11_helper.c' || echo '$(srcdir)/'`ecryptfs_key_mod_pkcs11_helper.c
+
+libecryptfs_key_mod_tspi_la-ecryptfs_key_mod_tspi.lo: ecryptfs_key_mod_tspi.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_key_mod_tspi_la_CFLAGS) $(CFLAGS) -MT libecryptfs_key_mod_tspi_la-ecryptfs_key_mod_tspi.lo -MD -MP -MF $(DEPDIR)/libecryptfs_key_mod_tspi_la-ecryptfs_key_mod_tspi.Tpo -c -o libecryptfs_key_mod_tspi_la-ecryptfs_key_mod_tspi.lo `test -f 'ecryptfs_key_mod_tspi.c' || echo '$(srcdir)/'`ecryptfs_key_mod_tspi.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecryptfs_key_mod_tspi_la-ecryptfs_key_mod_tspi.Tpo $(DEPDIR)/libecryptfs_key_mod_tspi_la-ecryptfs_key_mod_tspi.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ecryptfs_key_mod_tspi.c' object='libecryptfs_key_mod_tspi_la-ecryptfs_key_mod_tspi.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_key_mod_tspi_la_CFLAGS) $(CFLAGS) -c -o libecryptfs_key_mod_tspi_la-ecryptfs_key_mod_tspi.lo `test -f 'ecryptfs_key_mod_tspi.c' || echo '$(srcdir)/'`ecryptfs_key_mod_tspi.c
+
+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
+
+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
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(ecryptfskeymoddir)"; 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:
+
+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-ecryptfskeymodLTLIBRARIES clean-generic clean-libtool \
+ 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-ecryptfskeymodLTLIBRARIES
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+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-ecryptfskeymodLTLIBRARIES uninstall-local
+
+.MAKE: install-am install-data-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
+ clean-ecryptfskeymodLTLIBRARIES clean-generic clean-libtool \
+ 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-data install-data-am install-data-hook install-dvi \
+ install-dvi-am install-ecryptfskeymodLTLIBRARIES install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am \
+ uninstall-ecryptfskeymodLTLIBRARIES uninstall-local
+
+
+# Needed until libtool-2
+install-data-hook: install-ecryptfskeymodLTLIBRARIES
+ for f in `echo "$(ecryptfskeymod_LTLIBRARIES)" | $(SED) 's/\.la//g'`; do \
+ rm -f "$(DESTDIR)$(ecryptfskeymoddir)/$$f.la"; \
+ rm -f "$(DESTDIR)$(ecryptfskeymoddir)/$$f.a"; \
+ done
+uninstall-local:
+ for f in `echo "$(ecryptfskeymod_LTLIBRARIES)" | $(SED) 's/\.la//g'`; do \
+ rm -f "$(DESTDIR)$(ecryptfskeymoddir)/$$f.so"; \
+ done
+
+# 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/key_mod/ecryptfs_key_mod_gpg.c b/src/key_mod/ecryptfs_key_mod_gpg.c
new file mode 100644
index 0000000..c973477
--- /dev/null
+++ b/src/key_mod/ecryptfs_key_mod_gpg.c
@@ -0,0 +1,411 @@
+/**
+ * Copyright (C) 2007 International Business Machines Corp.
+ * Author(s): Mike 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 <fcntl.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <gpgme.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "../include/ecryptfs.h"
+#include "../include/decision_graph.h"
+
+struct key_mod_gpg {
+#define KEY_MOD_DATA_SET 0x00000001
+ uint32_t flags;
+ gpgme_ctx_t ctx;
+ unsigned int keylist_idx;
+ char *gpgsig;
+ char *sig;
+};
+
+void destroy_key_mod_gpg(struct key_mod_gpg *key_mod_gpg)
+{
+ if (key_mod_gpg->sig)
+ free(key_mod_gpg->sig);
+ memset(key_mod_gpg, 0, sizeof(struct key_mod_gpg));
+}
+
+static int serialize_key_module_data(unsigned char *blob,
+ struct key_mod_gpg *key_mod_data)
+{
+ int rc = 0;
+
+out:
+ return rc;
+}
+
+static int deserialize_key_module_data(struct key_mod_gpg *key_mod_data,
+ unsigned char *blob)
+{
+ int rc = 0;
+
+out:
+ return rc;
+}
+
+static int
+ecryptfs_gpg_initialize_key_module_state(unsigned char *blob,
+ struct ecryptfs_name_val_pair *pair)
+
+{
+ struct key_mod_gpg key_mod_gpg;
+ char *gpgsig = NULL;
+ unsigned int gpgsig_len;
+ int i = 0;
+ int rc = 0;
+
+ while (pair) {
+ if (!pair->name)
+ ;
+ else if (!strcmp(pair->name, "gpgsig"))
+ gpgsig = pair->value;
+ pair = pair->next;
+ }
+ if (gpgsig) {
+ gpgsig_len = strlen(gpgsig) + 1;
+ blob[i++] = gpgsig_len % 256;
+ blob[i++] = gpgsig_len >> 8;
+ memcpy(&blob[i], gpgsig, gpgsig_len);
+ i += gpgsig_len;
+ } else {
+ rc = -EINVAL;
+ goto out;
+ }
+ /* TODO: Get the gpg key */
+ key_mod_gpg.flags = KEY_MOD_DATA_SET;
+ serialize_key_module_data(blob, &key_mod_gpg);
+out:
+ return rc;
+}
+
+static int
+ecryptfs_gpg_get_key_metadata(char *sig, int *length, unsigned char *blob)
+{
+ struct key_mod_gpg key_mod_gpg;
+ int rc = 0;
+
+ sig[0] = '\0';
+ (*length) = 0;
+ memset(&key_mod_gpg, 0, sizeof(struct key_mod_gpg));
+ if ((rc = deserialize_key_module_data(&key_mod_gpg, blob))) {
+ goto out;
+ }
+ memcpy(sig, key_mod_gpg.sig, ECRYPTFS_SIG_SIZE_HEX + 1);
+ (*length) = 0; /* TODO */
+out:
+ destroy_key_mod_gpg(&key_mod_gpg);
+ return rc;
+}
+
+int ecryptfs_gpg_generate_key(char *filename)
+{
+ int rc = 0;
+
+out:
+ return rc;
+}
+
+int ecryptfs_gpg_encrypt(char *to, int size, char *from, unsigned char *blob)
+{
+ int rc = 0;
+
+/* gpg_op_encrypt(...); */
+out:
+ return rc;
+}
+
+int ecryptfs_gpg_decrypt(char *to, size_t *decrypted_key_size, char *from,
+ unsigned char *blob)
+{
+/* gpgme_key_t key;
+ int rc;
+
+. gpgme_get_key(ctx, &key);
+ if (rc) {
+ rc = -(int)ERR_get_error();
+ syslog(LOG_ERR, "Error attempting to read RSA key from file;"
+ " rc = [%d]\n", rc);
+ goto out;
+ }
+ gpgme_decrypt(...);
+ if (rc == -1) {
+ rc = -(int)ERR_get_error();
+ syslog(LOG_ERR, "Error attempting to perform RSA public key "
+ "decryption; rc = [%d]\n", rc);
+ } else {
+ *decrypted_key_size = rc;
+ rc = 0;
+ }
+out:
+. free? */
+ return 0;
+}
+
+struct pki_nvp_map_elem {
+ char *name;
+ uint32_t flags;
+};
+
+static struct pki_nvp_map_elem pki_nvp_map[] = {
+ {"gpgsig", (ECRYPTFS_PARAM_FLAG_ECHO_INPUT
+ | ECRYPTFS_DEFAULT_VALUE_SET)},
+ {NULL, 0}
+};
+
+/*
+
+static int ssl_sig(struct ecryptfs_pki_elem *pki, struct val_node **head)
+{
+ struct ecryptfs_name_val_pair *openssl_nvp;
+ char *sig;
+ char *param;
+ int rc;
+
+ sig = malloc(ECRYPTFS_SIG_SIZE_HEX + 1);
+ if (!sig) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = ecryptfs_add_key_module_key_to_keyring(sig, pki);
+ if (rc < 0)
+ goto out;
+ else
+ rc = 0;
+ asprintf(&param, "ecryptfs_sig=%s", sig);
+ free(sig);
+ stack_push(head, param);
+out:
+ if (rc)
+ return MOUNT_ERROR;
+ return DEFAULT_TOK;
+}
+
+static int tf_ssl_file(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **head, void **foo)
+{
+ stack_push(head, node->val);
+ node->val = NULL;
+ return DEFAULT_TOK;
+}
+
+*/
+
+static int tf_gpg_keysig(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **head, void **foo);
+
+/* TODO: Create a param node for each block of keysigs in the gpg
+ * keyring. Make one option point to the previous node and another to
+ * the next node. */
+
+#define GPG_TOK 0
+static struct param_node gpg_param_nodes[] = {
+ {.num_mnt_opt_names = 1,
+ .mnt_opt_names = {"keysig"},
+ .prompt = "Key signature",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .flags = ECRYPTFS_PARAM_FLAG_NO_VALUE,
+ .num_transitions = 1,
+ .tl = {{.flags = 0,
+ .val = NULL,
+ .pretty_val = NULL,
+ .next_token = NULL,
+ .trans_func = tf_gpg_keysig}}},
+};
+
+/**
+ * tf_gpg_keysig
+ * @ctx:
+ * @node:
+ * @head: The value node list for this key module
+ * @foo:
+ *
+ */
+static int tf_gpg_keysig(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **head, void **foo)
+{
+ struct key_mod_gpg *key_mod_gpg = (struct key_mod_gpg *)(*foo);
+ int i = 0;
+ gpgme_error_t err;
+ int rc = 0;
+ gpgme_key_t key;
+
+ while ((err = gpgme_op_keylist_next(key_mod_gpg->ctx, &key)) == 0) {
+ gpgme_subkey_t subkey = key->subkeys;
+
+ while (subkey) {
+ if ((rc = asprintf(&gpg_param_nodes[0].tl[i].val,
+ "%s", subkey->keyid)) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ subkey = subkey->next;
+ }
+ }
+ rc = 0;
+out:
+ return rc;
+}
+
+int validate_keysig(char *keysig)
+{
+ int rc = 0;
+
+out:
+ return rc;
+}
+
+static int generate_name_val_list(struct ecryptfs_name_val_pair *head)
+{
+ uid_t id = getuid();
+ int rc = 0;
+
+ head->next = NULL;
+out:
+ return rc;
+}
+
+static int tf_gpg_exit(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **head, void **foo)
+{
+ struct key_mod_gpg *key_mod_gpg;
+
+ key_mod_gpg = (struct key_mod_gpg *)(*foo);
+ if (key_mod_gpg) {
+ destroy_key_mod_gpg(key_mod_gpg);
+ free(key_mod_gpg);
+ }
+ return 0;
+}
+
+
+static int tf_gpg_enter(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **head, void **foo)
+{
+ struct key_mod_gpg *key_mod_gpg;
+ gpgme_error_t err;
+ int rc = 0;
+
+ (*foo) = NULL;
+ if ((key_mod_gpg = malloc(sizeof(struct key_mod_gpg))) == NULL) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ if ((err = gpgme_new(&key_mod_gpg->ctx))) {
+ printf("Error attempting to initialize new GPGME ctx\n");
+ rc = -EINVAL;
+ free(key_mod_gpg);
+ goto out;
+ }
+ if ((err = gpgme_op_keylist_start(key_mod_gpg->ctx, "", 0))) {
+ printf("Error attempting to start keylist\n");
+ rc = -EINVAL;
+ gpgme_release(key_mod_gpg->ctx);
+ free(key_mod_gpg);
+ goto out;
+ }
+ key_mod_gpg->keylist_idx = 0;
+ (*foo) = (void *)key_mod_gpg;
+out:
+ return rc;
+}
+
+struct transition_node gpg_transition = {
+ .val = "gpg",
+ .pretty_val = "GnuPG Module",
+ .next_token = &(gpg_param_nodes[0]),
+ .trans_func = tf_gpg_enter
+};
+
+static int
+ecryptfs_gpg_get_param_subgraph_trans_node(struct transition_node **trans,
+ uint32_t version)
+{
+ if ((version & ECRYPTFS_VERSIONING_PUBKEY) == 0)
+ return -1;
+ *trans = &gpg_transition;
+ return 0;
+}
+
+int destruct_pki(void)
+{
+ return 0;
+}
+
+int fill_in_sig_transitions(void)
+{
+ int rc = 0;
+
+/* gpg_param_nodes[0].tl */
+out:
+ return rc;
+}
+
+static int ecryptfs_gpg_init(char **alias)
+{
+ uid_t id;
+ struct passwd *pw;
+ int rc = 0;
+
+ if (asprintf(alias, "gpgme") == -1) {
+ rc = -ENOMEM;
+ syslog(LOG_ERR, "Out of memory\n");
+ goto out;
+ }
+ id = getuid();
+ pw = getpwuid(id);
+ rc = -EINVAL; /* Disable for now */
+out:
+ return rc;
+}
+
+int ecryptfs_gpg_finalize(void)
+{
+ return 0;
+}
+
+static struct ecryptfs_key_mod_ops ecryptfs_gpg_ops = {
+ &ecryptfs_gpg_init,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &ecryptfs_gpg_finalize
+};
+
+struct ecryptfs_key_mod_ops *get_key_mod_ops(void)
+{
+ return &ecryptfs_gpg_ops;
+}
diff --git a/src/key_mod/ecryptfs_key_mod_openssl.c b/src/key_mod/ecryptfs_key_mod_openssl.c
new file mode 100644
index 0000000..56ebe2d
--- /dev/null
+++ b/src/key_mod/ecryptfs_key_mod_openssl.c
@@ -0,0 +1,1029 @@
+/**
+ * Copyright (C) 2006-2007 International Business Machines Corp.
+ * Author(s): Trevor S. Highland <trevor.highland@gmail.com>
+ * Mike 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.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#include <fcntl.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <libgen.h>
+#include <openssl/pem.h>
+#include <openssl/rsa.h>
+#include <openssl/err.h>
+#include <openssl/engine.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "../include/ecryptfs.h"
+#include "../include/decision_graph.h"
+
+struct openssl_data {
+ char *path;
+ char *passphrase;
+};
+
+static void
+ecryptfs_openssl_destroy_openssl_data(struct openssl_data *openssl_data)
+{
+ free(openssl_data->path);
+ free(openssl_data->passphrase);
+ memset(openssl_data, 0, sizeof(struct openssl_data));
+}
+
+/**
+ * ecryptfs_openssl_deserialize
+ * @openssl_data: The deserialized version of the key module data;
+ * internal components pointed to blob memory
+ * @blob: The key module-specific state blob
+ *
+ */
+static int ecryptfs_openssl_deserialize(struct openssl_data *openssl_data,
+ unsigned char *blob)
+{
+ size_t path_length;
+ size_t passphrase_length;
+ size_t i = 0;
+
+ path_length = blob[i++] % 256;
+ path_length += blob[i++] << 8;
+ i += path_length;
+ passphrase_length = blob[i++] % 256;
+ passphrase_length += blob[i++] << 8;
+ openssl_data->path = (char *) blob + 2;
+ openssl_data->passphrase = (openssl_data->path + path_length + 2);
+ return 0;
+}
+
+/**
+ * @blob: Callee allocates this memory
+ */
+static int ecryptfs_openssl_serialize(unsigned char *blob, size_t *blob_size,
+ struct openssl_data *openssl_data)
+{
+ size_t path_length;
+ size_t passphrase_length;
+ size_t i = 0;
+ int rc = 0;
+
+ (*blob_size) = 0;
+ if (!openssl_data->path || !openssl_data->passphrase) {
+ rc = -EINVAL;
+ syslog(LOG_ERR, "openssl_data internal structure not "
+ "properly filled in\n");
+ goto out;
+ }
+ path_length = strlen(openssl_data->path) + 1; /* + '\0' */
+ passphrase_length = strlen(openssl_data->passphrase) + 1;
+ (*blob_size) = (2 + path_length + 2 + passphrase_length);
+ if (!blob)
+ goto out;
+ blob[i++] = path_length % 256;
+ blob[i++] = path_length >> 8;
+ memcpy(&blob[i], openssl_data->path, path_length);
+ i += path_length;
+ blob[i++] = passphrase_length % 256;
+ blob[i++] = passphrase_length >> 8;
+ memcpy(&blob[i], openssl_data->passphrase, passphrase_length);
+out:
+ return rc;
+}
+
+struct ecryptfs_subgraph_ctx {
+ struct ecryptfs_key_mod *key_mod;
+ struct openssl_data openssl_data;
+};
+
+static void
+ecryptfs_openssl_destroy_subgraph_ctx(struct ecryptfs_subgraph_ctx *ctx)
+{
+ ecryptfs_openssl_destroy_openssl_data(&ctx->openssl_data);
+ memset(ctx, 0, sizeof(struct ecryptfs_subgraph_ctx));
+}
+
+/**
+ * ecryptfs_openssl_generate_signature
+ * @sig: Generated sig (ECRYPTFS_SIG_SIZE_HEX + 1 bytes of allocated memory)
+ * @key: RSA key from which to generate sig
+ */
+static int ecryptfs_openssl_generate_signature(char *sig, RSA *key)
+{
+ int len, nbits, ebits, i;
+ int nbytes, ebytes;
+ unsigned char *hash;
+ unsigned char *data = NULL;
+ int rc = 0;
+
+ hash = malloc(SHA_DIGEST_LENGTH);
+ if (!hash) {
+ syslog(LOG_ERR, "Out of memory\n");
+ rc = -ENOMEM;
+ goto out;
+ }
+ nbits = BN_num_bits(key->n);
+ nbytes = nbits / 8;
+ if (nbits % 8)
+ nbytes++;
+ ebits = BN_num_bits(key->e);
+ ebytes = ebits / 8;
+ if (ebits % 8)
+ ebytes++;
+ len = 10 + nbytes + ebytes;
+ data = malloc(3 + len);
+ if (!data) {
+ syslog(LOG_ERR, "Out of memory\n");
+ rc = -ENOMEM;
+ goto out;
+ }
+ i = 0;
+ data[i++] = '\x99';
+ data[i++] = (len >> 8);
+ data[i++] = len;
+ data[i++] = '\x04';
+ data[i++] = '\00';
+ data[i++] = '\00';
+ data[i++] = '\00';
+ data[i++] = '\00';
+ data[i++] = '\02';
+ data[i++] = (nbits >> 8);
+ data[i++] = nbits;
+ BN_bn2bin(key->n, &(data[i]));
+ i += nbytes;
+ data[i++] = (ebits >> 8);
+ data[i++] = ebits;
+ BN_bn2bin(key->e, &(data[i]));
+ i += ebytes;
+ SHA1(data, len + 3, hash);
+ to_hex(sig, (char *)hash, ECRYPTFS_SIG_SIZE);
+ sig[ECRYPTFS_SIG_SIZE_HEX] = '\0';
+out:
+ free(data);
+ free(hash);
+ return rc;
+}
+
+static int
+ecryptfs_openssl_mkdir_recursive(char *dir, mode_t mode)
+{
+ char *temp = NULL;
+ char *parent = NULL;
+ int rc = 0;
+
+ if (!strcmp(dir, ".") || !strcmp(dir, "/"))
+ goto out;
+ temp = strdup(dir);
+ if (temp == NULL) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ parent = dirname(temp);
+ rc = ecryptfs_openssl_mkdir_recursive(parent, mode);
+ if (rc)
+ goto out;
+ if (mkdir(dir, mode) == -1) {
+ if (errno != EEXIST) {
+ rc = -errno;
+ goto out;
+ }
+ }
+ rc = 0;
+out:
+ free(temp);
+ return rc;
+}
+
+static int
+ecryptfs_openssl_write_key_to_file(RSA *rsa, char *filename, char *passphrase)
+{
+ char *tmp_filename;
+ char *openssl_dir;
+ BIO *out;
+ const EVP_CIPHER *enc = EVP_aes_256_cbc();
+ int rc = 0;
+
+ tmp_filename = strdup(filename);
+ if (tmp_filename == NULL) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ openssl_dir = dirname(tmp_filename);
+ rc = ecryptfs_openssl_mkdir_recursive(openssl_dir, 0700);
+ if (rc) {
+ syslog(LOG_WARNING, "%s: Error attempting to mkdir [%s]; "
+ "rc = [%d]\n", __FUNCTION__, openssl_dir, rc);
+ }
+ if ((out = BIO_new(BIO_s_file())) == NULL) {
+ syslog(LOG_ERR, "Unable to create BIO for output\n");
+ rc= -EIO;
+ goto out;
+ }
+ if (BIO_write_filename(out, filename) <= 0) {
+ syslog(LOG_ERR, "Failed to open file for reading\n");
+ rc = -EIO;
+ goto out_free_bio;
+ }
+ if (!PEM_write_bio_RSAPrivateKey(out, rsa, enc, NULL, 0, NULL,
+ (void *)passphrase)) {
+ syslog(LOG_ERR, "Failed to write key to file\n");
+ rc = -EIO;
+ goto out_free_bio;
+ }
+out_free_bio:
+ BIO_free_all(out);
+out:
+ free(tmp_filename);
+ return rc;
+}
+
+/**
+ * ecryptfs_openssl_read_key
+ * @rsa: RSA key to allocate
+ * @blob: Key module data to use in finding the key
+ */
+static int ecryptfs_openssl_read_key(RSA **rsa, unsigned char *blob)
+{
+ struct openssl_data *openssl_data = NULL;
+ BIO *in = NULL;
+ int rc;
+
+ CRYPTO_malloc_init();
+ ERR_load_crypto_strings();
+ OpenSSL_add_all_algorithms();
+ ENGINE_load_builtin_engines();
+ openssl_data = malloc(sizeof(struct openssl_data));
+ if (!openssl_data) {
+ syslog(LOG_ERR, "Out of memory\n");
+ rc = -ENOMEM;
+ goto out;
+ }
+ ecryptfs_openssl_deserialize(openssl_data, blob);
+ if ((in = BIO_new(BIO_s_file())) == NULL) {
+ syslog(LOG_ERR, "Unable to create BIO for output\n");
+ rc = -EIO;
+ goto out;
+ }
+ if (BIO_read_filename(in, openssl_data->path) <= 0) {
+ syslog(LOG_ERR, "Unable to read filename [%s]\n",
+ openssl_data->path);
+ rc = -EIO;
+ goto out;
+ }
+ if ((*rsa = PEM_read_bio_RSAPrivateKey(in, NULL, NULL,
+ openssl_data->passphrase))
+ == NULL) {
+ syslog(LOG_ERR,
+ "%s: Unable to read private key from file [%s]\n",
+ __FUNCTION__, openssl_data->path);
+ rc = -ENOKEY;
+ goto out;
+ }
+ rc = 0;
+out:
+ free(openssl_data);
+ BIO_free_all(in);
+ EVP_cleanup();
+ CRYPTO_cleanup_all_ex_data();
+ ERR_remove_state(0);
+ ERR_free_strings();
+ return rc;
+}
+
+int ecryptfs_openssl_get_key_sig(unsigned char *sig, unsigned char *blob)
+{
+ RSA *rsa = NULL;
+ int rc;
+
+ if ((rc = ecryptfs_openssl_read_key(&rsa, blob))) {
+ syslog(LOG_ERR, "Error attempting to read RSA key from file;"
+ " rc = [%d]\n", rc);
+ goto out;
+ }
+ if ((rc = ecryptfs_openssl_generate_signature((char *)sig, rsa))) {
+ syslog(LOG_ERR, "%s: Error attempting to generate key "
+ "signature; rc = [%d]\n", __FUNCTION__, rc);
+ goto out_free_rsa;
+ }
+out_free_rsa:
+ RSA_free(rsa);
+out:
+ return rc;
+}
+
+/**
+ * ecryptfs_openssl_generate_key
+ * @filename: File into which to write the newly generated key
+ *
+ * Generate a new key and write it out to a file.
+ */
+static int ecryptfs_openssl_generate_key(struct openssl_data *openssl_data)
+{
+ RSA *rsa;
+ int rc = 0;
+
+ if ((rsa = RSA_generate_key(1024, 65537, NULL, NULL)) == NULL) {
+ syslog(LOG_ERR, "Error generating new RSA key\n");
+ rc = -ENOMEM;
+ goto out;
+ }
+ if ((rc = ecryptfs_openssl_write_key_to_file(
+ rsa, openssl_data->path, openssl_data->passphrase))) {
+ syslog(LOG_ERR, "Error writing key to file; rc = [%d]\n", rc);
+ rc = -EIO;
+ goto out_free_rsa;
+ }
+out_free_rsa:
+ RSA_free(rsa);
+out:
+ return rc;
+}
+
+/**
+ * ecryptfs_openssl_encrypt
+ * @to: Where to write encrypted data
+ * @size: Number of bytes to encrypt
+ * @from: Data to encrypt
+ * @blob: Arbitrary blob specific to this key module
+ *
+ * Encrypt @size bytes of data in @from, writing the encrypted data
+ * into @to, using @blob as the parameters for the
+ * encryption.
+ */
+static int ecryptfs_openssl_encrypt(char *to, size_t *to_size, char *from,
+ size_t from_size, unsigned char *blob,
+ int blob_type)
+{
+ RSA *rsa = NULL;
+ int rc;
+
+ (*to_size) = 0;
+ if ((rc = ecryptfs_openssl_read_key(&rsa, blob))) {
+ rc = -(int)ERR_get_error();
+ syslog(LOG_ERR, "Error attempting to read RSA key from file;"
+ " rc = [%d]\n", rc);
+ goto out;
+ }
+ (*to_size) = RSA_size(rsa);
+ if (to) {
+ if ((rc = RSA_public_encrypt(from_size, (unsigned char *)from,
+ (unsigned char *)to, rsa,
+ RSA_PKCS1_OAEP_PADDING)) == -1) {
+ rc = -(int)ERR_get_error();
+ syslog(LOG_ERR, "Error attempting to perform RSA "
+ "public key encryption; rc = [%d]\n", rc);
+ goto out_free_rsa;
+ } else {
+ (*to_size) = rc;
+ rc = 0;
+ }
+ }
+out_free_rsa:
+ RSA_free(rsa);
+out:
+
+ return rc;
+}
+
+/**
+ * ecryptfs_openssl_dencrypt
+ * @from: Data to decrypt
+ * @to: Where to write decrypted data
+ * @decrypted_key_size: Number of bytes decrypted
+ * @blob: Arbitrary blob specific to this key module
+ *
+ * Decrypt data in @from, writing the decrypted data into @to, using
+ * @blob as the parameters for the encryption.
+ */
+static int ecryptfs_openssl_decrypt(char *to, size_t *to_size, char *from,
+ size_t from_size, unsigned char *blob,
+ int blob_type)
+{
+ RSA *rsa = NULL;
+ int rc;
+
+ (*to_size) = 0;
+ if ((rc = ecryptfs_openssl_read_key(&rsa, blob))) {
+ rc = -(int)ERR_get_error();
+ syslog(LOG_ERR, "Error attempting to read RSA key from file;"
+ " rc = [%d]\n", rc);
+ goto out;
+ }
+ (*to_size) = RSA_size(rsa);
+ if (to) {
+ if ((rc = RSA_private_decrypt(from_size, (unsigned char *)from,
+ (unsigned char *)to, rsa,
+ RSA_PKCS1_OAEP_PADDING)) == -1) {
+ rc = -(int)ERR_get_error();
+ syslog(LOG_ERR, "Error attempting to perform RSA "
+ "public key decryption; rc = [%d]\n", rc);
+ goto out_free_rsa;
+ } else {
+ (*to_size) = rc;
+ rc = 0;
+ }
+ }
+out_free_rsa:
+ RSA_free(rsa);
+out:
+ return rc;
+}
+int ecryptfs_openssl_init_from_param_vals(struct openssl_data *, struct key_mod_param_val *, uint32_t);
+static int ecryptfs_openssl_get_blob(unsigned char *blob, size_t *blob_size,
+ struct key_mod_param_val *param_vals,
+ uint32_t num_param_vals)
+{
+ struct openssl_data openssl_data;
+ int rc = 0;
+
+ if ((rc = ecryptfs_openssl_init_from_param_vals(&openssl_data,
+ param_vals,
+ num_param_vals))) {
+ syslog(LOG_ERR, "Error parsing parameter values; rc = [%d]\n",
+ rc);
+ goto out;
+ }
+ if (blob == NULL) {
+ if ((rc = ecryptfs_openssl_serialize(NULL, blob_size,
+ &openssl_data))) {
+ syslog(LOG_ERR,
+ "Error serializing openssl; rc = [%d]\n", rc);
+ goto out;
+ }
+ goto out;
+ }
+ if ((rc = ecryptfs_openssl_serialize(blob, blob_size, &openssl_data))) {
+ syslog(LOG_ERR, "Error serializing openssl; rc = [%d]\n", rc);
+ goto out;
+ }
+out:
+ return rc;
+}
+
+static int tf_ssl_keyfile(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **mnt_params, void **foo)
+{
+ struct ecryptfs_subgraph_ctx *subgraph_ctx;
+ int rc;
+
+ subgraph_ctx = (struct ecryptfs_subgraph_ctx *)(*foo);
+ if ((rc = asprintf(&subgraph_ctx->openssl_data.path, "%s", node->val))
+ == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = DEFAULT_TOK;
+ free(node->val);
+ node->val = NULL;
+out:
+ return rc;
+}
+
+static int
+ecryptfs_openssl_process_key(struct ecryptfs_subgraph_ctx *subgraph_ctx,
+ struct val_node **mnt_params)
+{
+ size_t blob_size;
+ char *sig_mnt_opt;
+ char sig[ECRYPTFS_SIG_SIZE_HEX + 1];
+ int rc;
+
+ if ((rc = ecryptfs_openssl_serialize(NULL, &blob_size,
+ &subgraph_ctx->openssl_data))) {
+ syslog(LOG_ERR, "Error serializing openssl; rc = [%d]\n", rc);
+ rc = MOUNT_ERROR;
+ goto out;
+ }
+ if (blob_size == 0) {
+ syslog(LOG_ERR, "Error serializing openssl\n");
+ rc = MOUNT_ERROR;
+ goto out;
+ }
+ if ((subgraph_ctx->key_mod->blob = malloc(blob_size)) == NULL) {
+ syslog(LOG_ERR, "Out of memory\n");
+ rc = -ENOMEM;
+ goto out;
+ }
+ if ((rc = ecryptfs_openssl_serialize((unsigned char *)
+ subgraph_ctx->key_mod->blob,
+ &subgraph_ctx->key_mod->blob_size,
+ &subgraph_ctx->openssl_data))) {
+ syslog(LOG_ERR, "Error serializing openssl; rc = [%d]\n", rc);
+ rc = MOUNT_ERROR;
+ goto out;
+ }
+ if (subgraph_ctx->key_mod->blob_size != blob_size) {
+ syslog(LOG_ERR, "%s: Internal error\n", __FUNCTION__);
+ exit(1);
+ }
+ if ((rc = ecryptfs_add_key_module_key_to_keyring(
+ sig, subgraph_ctx->key_mod)) < 0) {
+ syslog(LOG_ERR, "Error attempting to add key to keyring for "
+ "key module [%s]; rc = [%d]\n",
+ subgraph_ctx->key_mod->alias, rc);
+ goto out;
+ }
+ if ((rc = asprintf(&sig_mnt_opt, "ecryptfs_sig=%s", sig)) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = stack_push(mnt_params, sig_mnt_opt);
+out:
+ return rc;
+}
+
+static int limit_key_size(struct val_node **params,
+ struct ecryptfs_subgraph_ctx *subgraph_ctx)
+{
+ char *buf;
+ int rc;
+ RSA *rsa = NULL;
+
+ if ((rc=ecryptfs_openssl_read_key(&rsa,
+ (unsigned char *)subgraph_ctx->key_mod->blob)))
+ return rc;
+ /* 41 is for padding and 3 are for additional data send from
+ * kernel (1 for cipher type and 2 for checksum */
+ if ((rc = asprintf(&buf, "max_key_bytes=%d",
+ RSA_size(rsa)-41-3)) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ rc = stack_push(params, buf);
+out:
+ RSA_free(rsa);
+ return rc;
+}
+
+/**
+ *
+ *
+ */
+static int tf_ssl_passwd(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **mnt_params, void **foo)
+{
+ struct ecryptfs_subgraph_ctx *subgraph_ctx;
+ int rc;
+
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO, "%s: Called w/ node->val = [%s]\n",
+ __FUNCTION__, node->val);
+ subgraph_ctx = (struct ecryptfs_subgraph_ctx *)(*foo);
+ if ((rc = asprintf(&subgraph_ctx->openssl_data.passphrase, "%s",
+ node->val)) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ free(node->val);
+ node->val = NULL;
+ if ((rc = ecryptfs_openssl_process_key(subgraph_ctx, mnt_params))) {
+ syslog(LOG_ERR, "Error processing OpenSSL key; rc = [%d]", rc);
+ goto out;
+ }
+ limit_key_size(mnt_params, subgraph_ctx);
+ ecryptfs_openssl_destroy_subgraph_ctx(subgraph_ctx);
+ free(subgraph_ctx);
+ (*foo) = NULL;
+ rc = DEFAULT_TOK;
+out:
+ return rc;
+}
+
+static int tf_ssl_passwd_file(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **mnt_params, void **foo)
+{
+ int rc = 0;
+ int fd;
+ struct ecryptfs_subgraph_ctx *subgraph_ctx;
+ struct ecryptfs_name_val_pair file_head = { 0, };
+ struct ecryptfs_name_val_pair *walker = NULL;
+
+ syslog(LOG_INFO, "%s: Called\n", __FUNCTION__);
+ subgraph_ctx = (struct ecryptfs_subgraph_ctx *)(*foo);
+ if (strcmp(node->mnt_opt_names[0], "openssl_passwd_file") == 0)
+ fd = open(node->val, O_RDONLY);
+ else if (strcmp(node->mnt_opt_names[0], "openssl_passwd_fd") == 0)
+ fd = strtol(node->val, NULL, 0);
+ else {
+ rc = MOUNT_ERROR;
+ goto out;
+ }
+ if (fd == -1) {
+ syslog(LOG_ERR, "%s: Error attempting to open file\n",
+ __FUNCTION__);
+ rc = MOUNT_ERROR;
+ goto out;
+ }
+ rc = parse_options_file(fd, &file_head);
+ close(fd);
+ if (rc) {
+ syslog(LOG_ERR, "%s: Error attempting to parse options out "
+ "of file\n", __FUNCTION__);
+ goto out;
+ }
+ walker = file_head.next;
+ while (walker) {
+ if (strcmp(walker->name, "openssl_passwd") == 0) {
+ if ((rc =
+ asprintf(&subgraph_ctx->openssl_data.passphrase,
+ "%s", walker->value)) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ break;
+ }
+ walker = walker->next;
+ }
+ if (!walker) {
+ syslog(LOG_ERR, "%s: No openssl_passwd option found in file\n",
+ __FUNCTION__);
+ rc = MOUNT_ERROR;
+ goto out;
+ }
+ walker = NULL;
+ if ((rc = ecryptfs_openssl_process_key(subgraph_ctx, mnt_params))) {
+ syslog(LOG_ERR, "Error processing OpenSSL key; rc = [%d]", rc);
+ goto out;
+ }
+ limit_key_size(mnt_params, subgraph_ctx);
+ ecryptfs_openssl_destroy_subgraph_ctx(subgraph_ctx);
+ free(subgraph_ctx);
+ (*foo) = NULL;
+ rc = DEFAULT_TOK;
+out:
+ free_name_val_pairs(file_head.next);
+ free(file_head.name);
+ free(file_head.value);
+ free(node->val);
+ node->val = NULL;
+ syslog(LOG_INFO, "%s: Exiting\n", __FUNCTION__);
+ return rc;
+}
+
+static int tf_ssl_passwd_fd(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **mnt_params, void **foo)
+{
+ return ENOSYS;
+}
+
+static int tf_ecryptfs_openssl_gen_key_param_node_keyfile(
+ struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **mnt_params, void **foo)
+{
+ struct ecryptfs_subgraph_ctx *subgraph_ctx;
+ int rc = DEFAULT_TOK;
+
+ subgraph_ctx = (struct ecryptfs_subgraph_ctx *)(*foo);
+ if ((rc = asprintf(&subgraph_ctx->openssl_data.path, "%s",
+ node->val)) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = DEFAULT_TOK;
+out:
+ return rc;
+}
+
+static int tf_ecryptfs_openssl_gen_key_param_node_passphrase(
+ struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **mnt_params, void **foo)
+{
+ struct ecryptfs_subgraph_ctx *subgraph_ctx;
+ int rc = DEFAULT_TOK;
+
+ subgraph_ctx = (struct ecryptfs_subgraph_ctx *)(*foo);
+ if ((rc = asprintf(&subgraph_ctx->openssl_data.passphrase, "%s",
+ node->val)) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ if ((rc = ecryptfs_openssl_generate_key(&subgraph_ctx->openssl_data))) {
+ syslog(LOG_ERR, "%s: Error generating key to file [%s]; "
+ "rc = [%d]\n", __FUNCTION__,
+ subgraph_ctx->openssl_data.path, rc);
+ rc = MOUNT_ERROR;
+ goto out;
+ }
+out:
+ return rc;
+}
+
+#define ECRYPTFS_OPENSSL_GEN_KEY_PARAM_NODE_KEYFILE 0
+#define ECRYPTFS_OPENSSL_GEN_KEY_PARAM_NODE_PASSPHRASE 1
+static struct param_node ecryptfs_openssl_gen_key_param_nodes[] = {
+ {.num_mnt_opt_names = 1,
+ .mnt_opt_names = {"keyfile"},
+ .prompt = "SSL key file path",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .suggested_val = NULL,
+ .flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
+ .num_transitions = 1,
+ .tl = {{.val = "default",
+ .pretty_val = "",
+ .next_token = &ecryptfs_openssl_gen_key_param_nodes[
+ ECRYPTFS_OPENSSL_GEN_KEY_PARAM_NODE_PASSPHRASE],
+ .trans_func = &tf_ecryptfs_openssl_gen_key_param_node_keyfile}}},
+ {.num_mnt_opt_names = 1,
+ .mnt_opt_names = {"passphrase"},
+ .prompt = "Passphrase",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .suggested_val = NULL,
+ .flags = ECRYPTFS_PARAM_FLAG_MASK_OUTPUT | VERIFY_VALUE,
+ .num_transitions = 1,
+ .tl = {{.val = NULL,
+ .pretty_val = NULL,
+ .next_token = NULL,
+ .trans_func =
+ &tf_ecryptfs_openssl_gen_key_param_node_passphrase}}}
+};
+
+#define SSL_KEY_SOURCE_TOK 0
+#define SSL_KEY_FILE_TOK 1
+#define SSL_PASSPHRASE_METHOD_TOK 2
+#define SSL_USER_PROVIDED_PASSWD_TOK 3
+#define SSL_FILE_PASSWD_TOK 4
+#define SSL_FD_PASSWD_TOK 5
+static struct param_node ssl_param_nodes[] = {
+ {.num_mnt_opt_names = 2,
+ .mnt_opt_names = {"openssl_keysource", "keysource"},
+ .prompt = "Key source",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = "keyfile",
+ .flags = ECRYPTFS_PARAM_FLAG_NO_VALUE,
+ .num_transitions = 1,
+ .tl = {{.val = "default",
+ .pretty_val = "OpenSSL Key File",
+ .next_token = &ssl_param_nodes[SSL_KEY_FILE_TOK],
+ .trans_func = NULL}}}, /* Add more options here later */
+
+ {.num_mnt_opt_names = 2,
+ .mnt_opt_names = {"openssl_keyfile", "keyfile"},
+ .prompt = "PEM key file",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
+ .num_transitions = 1,
+ .tl = {{.val = "default", /* The decision graph code will
+ * just follow a "default"
+ * transition node */
+ .pretty_val = "Passphrase Method",
+ .next_token = &ssl_param_nodes[SSL_PASSPHRASE_METHOD_TOK],
+ .trans_func = tf_ssl_keyfile}}},
+
+ {.num_mnt_opt_names = 2,
+ .mnt_opt_names = {"openssl_passwd_specification_method",
+ "passwd_specification_method"},
+ .prompt = "Method of providing the passphrase",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .suggested_val = "openssl_passwd",
+ /* An implicit transition takes place if one of the key
+ * module parameters that are the target of one of the
+ * transition nodes already exists in the provided parameter
+ * list. */
+ .flags = (DISPLAY_TRANSITION_NODE_VALS | ECRYPTFS_DISPLAY_PRETTY_VALS
+ | ECRYPTFS_PARAM_FLAG_ECHO_INPUT
+ | ECRYPTFS_ALLOW_IMPLICIT_TRANSITION),
+ .num_transitions = 3,
+ .tl = {{.val = "openssl_passwd",
+ .pretty_val = "openssl_passwd: Enter on Console",
+ .next_token = &ssl_param_nodes[SSL_USER_PROVIDED_PASSWD_TOK],
+ .trans_func = NULL},
+ {.val = "openssl_passwd_file",
+ .pretty_val = "openssl_passwd_file: File Containing Passphrase",
+ .next_token = &ssl_param_nodes[SSL_FILE_PASSWD_TOK],
+ .trans_func = NULL},
+ {.val = "openssl_passwd_fd",
+ .pretty_val = ("openssl_passwd_fd: File Descriptor for File "
+ "Containing Passphrase"),
+ .next_token = &ssl_param_nodes[SSL_FD_PASSWD_TOK],
+ .trans_func = NULL}}},
+
+ {.num_mnt_opt_names = 2,
+ .mnt_opt_names = {"openssl_passwd", "passwd"},
+ .prompt = "Passphrase",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .flags = STDIN_REQUIRED | ECRYPTFS_PARAM_FLAG_MASK_OUTPUT,
+ .num_transitions = 1,
+ .tl = {{.val = NULL,
+ .pretty_val = NULL,
+ .next_token = NULL,
+ .trans_func = tf_ssl_passwd}}},
+
+ {.num_mnt_opt_names = 2,
+ .mnt_opt_names = {"openssl_passwd_file", "passwd_file"},
+ .prompt = "Passphrase File",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .flags = STDIN_REQUIRED | ECRYPTFS_PARAM_FLAG_ECHO_INPUT
+ | ECRYPTFS_NONEMPTY_VALUE_REQUIRED,
+ .num_transitions = 1,
+ .tl = {{.val = NULL,
+ .pretty_val = NULL,
+ .next_token = NULL,
+ .trans_func = tf_ssl_passwd_file}}},
+
+ {.num_mnt_opt_names = 2,
+ .mnt_opt_names = {"openssl_passwd_fd", "passwd_fd"},
+ .prompt = "Passphrase File Descriptor",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .flags = STDIN_REQUIRED | ECRYPTFS_PARAM_FLAG_ECHO_INPUT
+ | ECRYPTFS_NONEMPTY_VALUE_REQUIRED,
+ .num_transitions = 1,
+ .tl = {{.val = NULL,
+ .pretty_val = NULL,
+ .next_token = NULL,
+ .trans_func = tf_ssl_passwd_fd}}}
+
+};
+
+/**
+ * tf_openssl_enter
+ * @ctx: The current applicable libecryptfs context struct
+ * @node: The param_node from which we are transitioning
+ * @head: The head of the name/value pair list that is being
+ * constructed as the decision graph is being traversed
+ * @foo: Arbitrary state information for the current subgraph
+ *
+ * Each transition from one node in the decision graph to another node
+ * can have a function executed on the transition event. A transition
+ * into any given subgraph may require certain housekeeping and
+ * initialization functions to occur.
+ *
+ * The decision graph engine forwards along an arbitrary data
+ * structure among the nodes of any subgraph. The logic in the
+ * subgraph can use that data structure to access and maintain
+ * arbitrary status information that is unique to the function of that
+ * subgraph.
+ */
+static int tf_openssl_enter(struct ecryptfs_ctx *ctx,
+ struct param_node *param_node,
+ struct val_node **mnt_params, void **foo)
+{
+ struct ecryptfs_subgraph_ctx *subgraph_ctx;
+ int rc;
+
+ if ((subgraph_ctx = malloc(sizeof(struct ecryptfs_subgraph_ctx)))
+ == NULL) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ memset(subgraph_ctx, 0, sizeof(struct ecryptfs_subgraph_ctx));
+ if ((rc = ecryptfs_find_key_mod(&subgraph_ctx->key_mod, ctx,
+ param_node->val))) {
+ syslog(LOG_ERR, "%s: Cannot find key_mod for param_node with "
+ "val = [%s]\n", __FUNCTION__, param_node->val);
+ free(subgraph_ctx);
+ goto out;
+ }
+ (*foo) = (void *)subgraph_ctx;
+out:
+ return rc;
+}
+
+struct transition_node openssl_transition = {
+ .val = "openssl",
+ .pretty_val = "OpenSSL module",
+ .next_token = &(ssl_param_nodes[SSL_KEY_SOURCE_TOK]),
+ .trans_func = tf_openssl_enter
+};
+
+static int ecryptfs_openssl_get_param_subgraph_trans_node(
+ struct transition_node **trans, uint32_t version)
+{
+ if ((version & ECRYPTFS_VERSIONING_PUBKEY) == 0)
+ return -1;
+ (*trans) = &openssl_transition;
+ return 0;
+}
+
+struct transition_node openssl_gen_key_transition = {
+ .val = "openssl",
+ .pretty_val = "OpenSSL module",
+ .next_token = &(ecryptfs_openssl_gen_key_param_nodes[
+ ECRYPTFS_OPENSSL_GEN_KEY_PARAM_NODE_KEYFILE]),
+ .trans_func = tf_openssl_enter
+};
+
+static int ecryptfs_openssl_get_gen_key_param_subgraph_trans_node(
+ struct transition_node **trans, uint32_t version)
+{
+ if ((version & ECRYPTFS_VERSIONING_PUBKEY) == 0)
+ return -1;
+ (*trans) = &openssl_gen_key_transition;
+ return 0;
+}
+
+int ecryptfs_openssl_finalize(void)
+{
+ return 0;
+}
+
+static int ecryptfs_openssl_init(char **alias)
+{
+ uid_t id;
+ struct passwd *pw;
+ struct param_node *gen_key_keyfile_param_node =
+ &ecryptfs_openssl_gen_key_param_nodes[
+ ECRYPTFS_OPENSSL_GEN_KEY_PARAM_NODE_KEYFILE];
+ int rc = 0;
+
+ if (asprintf(alias, "openssl") == -1) {
+ rc = -ENOMEM;
+ syslog(LOG_ERR, "Out of memory\n");
+ goto out;
+ }
+ id = getuid();
+ pw = getpwuid(id);
+ if (!pw) {
+ rc = -EIO;
+ goto out;
+ }
+ if ((rc = asprintf(&ssl_param_nodes[SSL_KEY_FILE_TOK].suggested_val,
+ "%s/.ecryptfs/pki/openssl/key.pem",
+ pw->pw_dir)) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ if ((rc = asprintf(&gen_key_keyfile_param_node->suggested_val,
+ "%s/.ecryptfs/pki/openssl/key.pem",
+ pw->pw_dir)) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+out:
+ return rc;
+}
+
+static struct ecryptfs_key_mod_ops ecryptfs_openssl_ops = {
+ &ecryptfs_openssl_init,
+ NULL,
+ &ecryptfs_openssl_get_gen_key_param_subgraph_trans_node,
+ NULL,
+ &ecryptfs_openssl_get_param_subgraph_trans_node,
+ &ecryptfs_openssl_get_blob,
+ NULL,
+ &ecryptfs_openssl_get_key_sig,
+ NULL,
+ &ecryptfs_openssl_encrypt,
+ &ecryptfs_openssl_decrypt,
+ NULL,
+ &ecryptfs_openssl_finalize
+};
+
+struct ecryptfs_key_mod_ops *get_key_mod_ops(void)
+{
+ return &ecryptfs_openssl_ops;
+}
diff --git a/src/key_mod/ecryptfs_key_mod_passphrase.c b/src/key_mod/ecryptfs_key_mod_passphrase.c
new file mode 100644
index 0000000..d318ddd
--- /dev/null
+++ b/src/key_mod/ecryptfs_key_mod_passphrase.c
@@ -0,0 +1,330 @@
+/**
+ * Copyright (C) 2006-2007 International Business Machines Corp.
+ * Author(s): Mike 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 <sys/types.h>
+#include <sys/stat.h>
+#include <syslog.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "../include/ecryptfs.h"
+#include "../include/decision_graph.h"
+
+static int tf_passwd(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **head, void **foo)
+{
+ int rc;
+ if (!node->val)
+ return -EINVAL;
+ if ((rc = stack_push(head, node->val)))
+ return rc;
+ node->val = NULL;
+ return DEFAULT_TOK;
+}
+
+static int tf_pass_file(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **head, void **foo)
+{
+ char *tmp_val = NULL;
+ int fd;
+ struct ecryptfs_name_val_pair *file_head;
+ struct ecryptfs_name_val_pair *walker;
+ int rc = 0;
+
+ if (strcmp(node->mnt_opt_names[0], "passphrase_passwd_file") == 0) {
+ fd = open(node->val, O_RDONLY);
+ if (fd == -1) {
+ rc = -errno;
+ syslog(LOG_ERR, "%s: Error whilst attempting to open "
+ "[%s]; errno = [%m]\n", __FUNCTION__, node->val);
+ goto out;
+ }
+ } else if (strcmp(node->mnt_opt_names[0], "passphrase_passwd_fd") == 0) {
+ fd = strtol(node->val, NULL, 0);
+ } else {
+ syslog(LOG_ERR, "%s: Invalid file descriptor qualifier\n",
+ __FUNCTION__);
+ rc = MOUNT_ERROR;
+ goto out;
+ }
+ file_head = malloc(sizeof(struct ecryptfs_name_val_pair));
+ if (!file_head) {
+ close(fd);
+ rc = -ENOMEM;
+ goto out;
+ }
+ memset(file_head, 0, sizeof(struct ecryptfs_name_val_pair));
+ rc = parse_options_file(fd, file_head);
+ close(fd);
+ if (rc) {
+ syslog(LOG_ERR, "%s: Error parsing file for passwd; "
+ "rc = [%d]\n", __FUNCTION__, rc);
+ goto out;
+ }
+ walker = file_head->next;
+ while (walker) {
+ if (strcmp(walker->name, "passphrase_passwd") == 0
+ || strcmp(walker->name, "passwd") == 0) {
+ if (asprintf(&tmp_val, "%s", walker->value) < 0) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ stack_push(head, tmp_val);
+ break;
+ }
+ walker = walker->next;
+ }
+ if (!walker) {
+ syslog(LOG_ERR, "%s: Cannot find [passwd] directive\n",
+ __FUNCTION__);
+ rc = MOUNT_ERROR;
+ goto out;
+ }
+ free_name_val_pairs(file_head);
+ file_head = NULL;
+ walker = NULL;
+out:
+ free(node->val);
+ node->val = NULL;
+ return rc;
+}
+
+static int tf_salt(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **head, void **foo)
+{
+ char *passwd;
+ char salt[ECRYPTFS_SALT_SIZE];
+ char *salt_hex;
+ char *auth_tok_sig;
+ char *param;
+ int rc = 0;
+
+ if (!node->val)
+ rc = asprintf(&node->val, "%s", node->default_val);
+ if (rc == -1)
+ return -ENOMEM;
+ stack_push(head, node->val);
+ node->val = NULL;
+ stack_pop_val(head, (void *)&salt_hex);
+ stack_pop_val(head, (void *)&passwd);
+ auth_tok_sig = malloc(ECRYPTFS_SIG_SIZE_HEX + 1);
+ if (!auth_tok_sig) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ from_hex(salt, salt_hex, ECRYPTFS_SIG_SIZE);
+ rc = ecryptfs_add_passphrase_key_to_keyring(auth_tok_sig, passwd, salt);
+ if (rc < 0) {
+ free(auth_tok_sig);
+ goto out;
+ }
+ rc = asprintf(&param, "ecryptfs_sig=%s", auth_tok_sig);
+ if (rc == -1) {
+ free(auth_tok_sig);
+ rc = -ENOMEM;
+ goto out;
+ }
+ free(auth_tok_sig);
+ rc = stack_push(head, param);
+out:
+ free(salt_hex);
+ free(passwd);
+ if (rc)
+ return rc;
+ return DEFAULT_TOK;
+}
+
+#define ECRYPTFS_PASSPHRASE_TOK 0
+#define ECRYPTFS_PASSWD_TOK 1
+#define ECRYPTFS_PASS_FILE_TOK 2
+#define ECRYPTFS_PASS_FD_TOK 3
+#define ECRYPTFS_SALT_TOK 4
+struct param_node passphrase_param_nodes[] = {
+ /* ECRYPTFS_PASSPHRASE_TOK = 0 */
+ {.num_mnt_opt_names = 1,
+ .mnt_opt_names = {"passphrase_type"},
+ .prompt = "Method for providing the passphrase",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = "passphrase_passwd",
+ .flags = (ECRYPTFS_PARAM_FLAG_NO_VALUE
+ | ECRYPTFS_ALLOW_IMPLICIT_TRANSITION
+ | ECRYPTFS_IMPLICIT_OVERRIDE_DEFAULT),
+ .num_transitions = 3,
+ .tl = {{.val = "passphrase_passwd",
+ .pretty_val = "Provide passphrase directly",
+ .next_token = &passphrase_param_nodes[ECRYPTFS_PASSWD_TOK],
+ .trans_func = NULL},
+ {.val = "passphrase_passwd_file",
+ .pretty_val = "File containing passphrase (only use secure "
+ "media)",
+ .next_token = &passphrase_param_nodes[ECRYPTFS_PASS_FILE_TOK],
+ .trans_func = NULL},
+ {.val = "passphrase_passwd_fd",
+ .pretty_val = "File descriptor for file containing passphrase",
+ .next_token = &passphrase_param_nodes[ECRYPTFS_PASS_FD_TOK],
+ .trans_func = NULL}}},
+
+ /* ECRYPTFS_PASSWD_TOK = 1 */
+ {.num_mnt_opt_names = 2,
+ .mnt_opt_names = {"passphrase_passwd", "passwd"},
+ .prompt = "Passphrase",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .flags = (ECRYPTFS_PARAM_FLAG_MASK_OUTPUT
+ | ECRYPTFS_NONEMPTY_VALUE_REQUIRED),
+ .num_transitions = 2,
+ .tl = {{.val = "passphrase_salt",
+ .pretty_val = "salt",
+ .next_token = &passphrase_param_nodes[ECRYPTFS_SALT_TOK],
+ .trans_func = tf_passwd},
+ {.val = "default",
+ .pretty_val = "default",
+ .next_token = &passphrase_param_nodes[ECRYPTFS_SALT_TOK],
+ .trans_func = tf_passwd}}},
+
+ /* ECRYPTFS_PASS_FILE_TOK = 2 */
+ {.num_mnt_opt_names = 2,
+ .mnt_opt_names = {"passphrase_passwd_file", "passfile"},
+ .prompt = "Passphrase File",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT
+ | ECRYPTFS_NONEMPTY_VALUE_REQUIRED,
+ .num_transitions = 2,
+ .tl = {{.val = "passphrase_salt",
+ .pretty_val = "salt",
+ .next_token = &passphrase_param_nodes[ECRYPTFS_SALT_TOK],
+ .trans_func = tf_pass_file},
+ {.val = "default",
+ .pretty_val = "default",
+ .next_token = &passphrase_param_nodes[ECRYPTFS_SALT_TOK],
+ .trans_func = tf_pass_file}}},
+
+ /* ECRYPTFS_PASS_FD_TOK = 3 */
+ {.num_mnt_opt_names = 2,
+ .mnt_opt_names = {"passphrase_passwd_fd", "passfd"},
+ .prompt = "Passphrase File Discriptor",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT
+ | ECRYPTFS_NONEMPTY_VALUE_REQUIRED,
+ .num_transitions = 2,
+ .tl = {{.val = "salt",
+ .pretty_val = "salt",
+ .next_token = &passphrase_param_nodes[ECRYPTFS_SALT_TOK],
+ .trans_func = tf_pass_file},
+ {.val = "default",
+ .pretty_val = "default",
+ .next_token = &passphrase_param_nodes[ECRYPTFS_SALT_TOK],
+ .trans_func = tf_pass_file}}},
+
+ /* ECRYPTFS_SALT_TOK = 4 */
+ {.num_mnt_opt_names = 2,
+ .mnt_opt_names = {"passphrase_salt", "salt"},
+ .prompt = "Salt (hexadecimal representation)",
+ .val_type = VAL_HEX,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = ECRYPTFS_DEFAULT_SALT_HEX,
+ .flags = 0,
+ .num_transitions = 1,
+ .tl = {{.val = NULL,
+ .pretty_val = NULL,
+ .next_token = NULL,
+ .trans_func = tf_salt}}},
+};
+
+struct transition_node passphrase_transition = {
+ .val = "passphrase",
+ .pretty_val = "Passphrase",
+ .next_token = &(passphrase_param_nodes[0]),
+ .trans_func = NULL
+};
+
+static int ecryptfs_passphrase_get_param_subgraph_trans_node(
+ struct transition_node **trans, uint32_t version)
+{
+ if ((version & ECRYPTFS_VERSIONING_PASSPHRASE) == 0)
+ return -1;
+ *trans = &passphrase_transition;
+ return 0;
+}
+
+static int ecryptfs_passphrase_init(char **alias)
+{
+ int rc = 0;
+
+ if (asprintf(alias, "passphrase") == -1) {
+ syslog(LOG_ERR, "Out of memory\n");
+ rc = -ENOMEM;
+ goto out;
+ }
+out:
+ return rc;
+}
+
+static int ecryptfs_passphrase_destroy(unsigned char *blob)
+{
+ return 0;
+}
+
+static int ecryptfs_passphrase_finalize(void)
+{
+ return 0;
+}
+
+struct ecryptfs_key_mod_ops ecryptfs_passphrase_ops = {
+ &ecryptfs_passphrase_init,
+ NULL,
+ NULL,
+ NULL,
+ &ecryptfs_passphrase_get_param_subgraph_trans_node,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &ecryptfs_passphrase_destroy,
+ &ecryptfs_passphrase_finalize
+};
+
+struct ecryptfs_key_mod_ops *get_key_mod_ops(void)
+{
+ return &ecryptfs_passphrase_ops;
+}
+
+/**
+ * Builtin handle
+ */
+struct ecryptfs_key_mod_ops *passphrase_get_key_mod_ops(void)
+{
+ return get_key_mod_ops();
+}
diff --git a/src/key_mod/ecryptfs_key_mod_pkcs11_helper.c b/src/key_mod/ecryptfs_key_mod_pkcs11_helper.c
new file mode 100644
index 0000000..39cae0d
--- /dev/null
+++ b/src/key_mod/ecryptfs_key_mod_pkcs11_helper.c
@@ -0,0 +1,1684 @@
+/**
+ * Copyright (C) 2006-2007 International Business Machines Corp.
+ * Author(s): Alon Bar-Lev <alon.barlev@gmail.com>, based on:
+ * Trevor S. Highland <trevor.highland@gmail.com>
+ * Mike 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.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#include <fcntl.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/x509.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <pkcs11-helper-1.0/pkcs11h-certificate.h>
+#include "../include/ecryptfs.h"
+#include "../include/decision_graph.h"
+
+struct pkcs11h_data {
+ char *serialized_id;
+ unsigned char *certificate_blob;
+ size_t certificate_blob_size;
+ char *passphrase;
+};
+
+struct pkcs11h_subgraph_key_ctx {
+ struct ecryptfs_key_mod *key_mod;
+ struct pkcs11h_data pkcs11h_data;
+};
+
+struct pkcs11h_subgraph_provider_ctx {
+ struct ecryptfs_key_mod *key_mod;
+ char *name;
+ char *library;
+ int allow_protected_authentication;
+ int certificate_is_private;
+ unsigned private_mask;
+};
+
+#if OPENSSL_VERSION_NUMBER < 0x00908000L
+typedef unsigned char *__pkcs11_openssl_d2i_t;
+#else
+typedef const unsigned char *__pkcs11_openssl_d2i_t;
+#endif
+
+/**
+ * ecryptfs_pkcs11h_deserialize
+ * @pkcs11h_data: The deserialized version of the key module data;
+ * internal components pointed to blob memory
+ * @blob: The key module-specific state blob
+ *
+ */
+static int ecryptfs_pkcs11h_deserialize(struct pkcs11h_data *pkcs11h_data,
+ unsigned char *blob)
+{
+ size_t serialized_id_length;
+ size_t passphrase_length;
+ size_t i = 0;
+ int rc;
+
+ serialized_id_length = blob[i++] % 256;
+ serialized_id_length += blob[i++] << 8;
+ if (serialized_id_length == 0) {
+ pkcs11h_data->serialized_id = NULL;
+ }
+ else {
+ pkcs11h_data->serialized_id = blob + i;
+ i += serialized_id_length;
+ }
+ pkcs11h_data->certificate_blob_size = blob[i++] % 256;
+ pkcs11h_data->certificate_blob_size += blob[i++] << 8;
+ if (pkcs11h_data->certificate_blob_size == 0) {
+ pkcs11h_data->certificate_blob = NULL;
+ }
+ else {
+ pkcs11h_data->certificate_blob = blob + i;
+ i += pkcs11h_data->certificate_blob_size;
+ }
+ passphrase_length = blob[i++] % 256;
+ passphrase_length += blob[i++] << 8;
+ if (passphrase_length == 0) {
+ pkcs11h_data->passphrase = NULL;
+ }
+ else {
+ pkcs11h_data->passphrase = blob + i;
+ i += passphrase_length;
+ }
+
+ rc = 0;
+out:
+ return rc;
+}
+
+/**
+ * @blob: Callee allocates this memory
+ */
+static int ecryptfs_pkcs11h_serialize(unsigned char *blob, size_t *blob_size,
+ struct pkcs11h_data *pkcs11h_data)
+{
+#define PUSHSER1(x) do { if (blob) { blob[i] = x; } i++; } while (0)
+#define PUSHSERN(x,s) do { if (blob) { memcpy(&blob[i], x, s); } i+=s; } while (0)
+ size_t serialized_id_length;
+ size_t passphrase_length;
+ size_t i = 0;
+ int rc = 0;
+
+ (*blob_size) = 0;
+ if (!pkcs11h_data->serialized_id) {
+ rc = -EINVAL;
+ syslog(LOG_ERR, "PKCS#11: pkcs11h_data internal structure not properly filled in\n");
+ goto out;
+ }
+ serialized_id_length = strlen(pkcs11h_data->serialized_id) + 1; /* + '\0' */
+ PUSHSER1(serialized_id_length % 256);
+ PUSHSER1(serialized_id_length >> 8);
+ PUSHSERN(pkcs11h_data->serialized_id, serialized_id_length);
+ PUSHSER1(pkcs11h_data->certificate_blob_size % 256);
+ PUSHSER1(pkcs11h_data->certificate_blob_size >> 8);
+ PUSHSERN(pkcs11h_data->certificate_blob, pkcs11h_data->certificate_blob_size);
+ passphrase_length = strlen(pkcs11h_data->passphrase) + 1; /* + '\0' */
+ PUSHSER1(passphrase_length % 256);
+ PUSHSER1(passphrase_length >> 8);
+ PUSHSERN(pkcs11h_data->passphrase, passphrase_length);
+ (*blob_size) = i;
+out:
+ return rc;
+#undef PUSHSER1
+#undef PUSHSERN
+}
+
+static
+void
+pkcs11h_log (
+ void * const global_data,
+ unsigned flags,
+ const char * const format,
+ va_list args
+) {
+ vsyslog(LOG_INFO, format, args);
+}
+
+static
+PKCS11H_BOOL
+pkcs11h_token_prompt (
+ void * const global_data,
+ void * const user_data,
+ const pkcs11h_token_id_t token,
+ const unsigned retry
+) {
+ (void)global_data;
+ (void)user_data;
+ (void)retry;
+
+ return FALSE;
+}
+
+static
+PKCS11H_BOOL
+pkcs11h_pin_prompt (
+ void * const global_data,
+ void * const user_data,
+ const pkcs11h_token_id_t token,
+ const unsigned retry,
+ char * const pin,
+ const size_t pin_max
+) {
+ char *prompt = NULL;
+ int use_static_password = 0;
+ int rc;
+
+ (void)global_data;
+
+ if (asprintf (&prompt, "Please enter PIN for token '%s'", token->display) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ /* TEMP TEMP TEMP - BEGIN
+ * Until we can affect ecryptfs context via daemon */
+ if (cryptfs_get_ctx_opts ()->prompt) {
+ rc = cryptfs_get_ctx_opts ()->prompt ("password", prompt, pin, pin_max);
+ if (rc == -EINVAL) {
+ use_static_password = 1;
+ }
+ else {
+ goto out;
+ }
+ }
+ else {
+ use_static_password = 1;
+ }
+
+ if (use_static_password) {
+ if (retry != 0 || user_data == NULL) {
+ rc = -EIO;
+ goto out;
+ }
+ strncpy (pin, (char *)user_data, pin_max-1);
+ pin[pin_max-1] = '\x0';
+ }
+
+ rc = 0;
+
+ /* TEMP TEMP TEMP - END */
+out:
+
+ if (prompt != NULL) {
+ free (prompt);
+ }
+
+ return rc == 0;
+}
+
+/**
+ * ecryptfs_pkcs11h_get_public_key
+ * @rsa: RSA key to allocate
+ * @blob: Key module data to use in finding the key
+ */
+static int ecryptfs_pkcs11h_get_public_key(RSA **rsa, unsigned char *blob)
+{
+ struct pkcs11h_data _pkcs11h_data;
+ struct pkcs11h_data *pkcs11h_data = &_pkcs11h_data;
+ X509 *x509 = NULL;
+ EVP_PKEY *pubkey = NULL;
+ __pkcs11_openssl_d2i_t d2i1 = NULL;
+ int rc;
+
+ if ((rc = ecryptfs_pkcs11h_deserialize(pkcs11h_data, blob)) != 0) {
+ goto out;
+ }
+
+ if ((x509 = X509_new ()) == NULL) {
+ syslog(LOG_ERR, "PKCS#11: Unable to allocate certificate object");
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ d2i1 = (__pkcs11_openssl_d2i_t)pkcs11h_data->certificate_blob;
+ if (!d2i_X509 (&x509, &d2i1, pkcs11h_data->certificate_blob_size)) {
+ syslog(LOG_ERR, "PKCS#11: Unable to parse X.509 certificate");
+ rc = -EIO;
+ goto out;
+ }
+
+ if ((pubkey = X509_get_pubkey(x509)) == NULL) {
+ syslog(LOG_ERR, "PKCS#11: Cannot get public key");
+ rc = -EIO;
+ goto out;
+ }
+
+ if (pubkey->type != EVP_PKEY_RSA) {
+ syslog(LOG_ERR, "PKCS#11: Invalid public key algorithm");
+ rc = -EIO;
+ goto out;
+ }
+
+ if (
+ (*rsa = EVP_PKEY_get1_RSA(pubkey)) == NULL
+ ) {
+ syslog(LOG_ERR, "PKCS#11: Cannot get RSA key");
+ rc = -EIO;
+ goto out;
+ }
+
+ rc = 0;
+out:
+ if (pubkey != NULL) {
+ EVP_PKEY_free(pubkey);
+ pubkey = NULL;
+ }
+
+ if (x509 != NULL) {
+ X509_free(x509);
+ x509 = NULL;
+ }
+
+ return rc;
+}
+
+static int ecryptfs_pkcs11h_get_key_sig(unsigned char *sig, unsigned char *blob)
+{
+ RSA *rsa = NULL;
+ int len, nbits, ebits, i;
+ int nbytes, ebytes;
+ char *hash = NULL;
+ char *data = NULL;
+ int rc;
+
+ if ((rc = ecryptfs_pkcs11h_get_public_key(&rsa, blob))) {
+ syslog(LOG_ERR, "PKCS#11: Error attempting to read RSA key from token; rc=[%d]\n", rc);
+ goto out;
+ }
+
+ hash = malloc(SHA_DIGEST_LENGTH);
+ if (!hash) {
+ syslog(LOG_ERR, "PKCS#11: Out of memory\n");
+ rc = -ENOMEM;
+ goto out;
+ }
+ nbits = BN_num_bits(rsa->n);
+ nbytes = nbits / 8;
+ if (nbits % 8)
+ nbytes++;
+ ebits = BN_num_bits(rsa->e);
+ ebytes = ebits / 8;
+ if (ebits % 8)
+ ebytes++;
+ len = 10 + nbytes + ebytes;
+ data = malloc(3 + len);
+ if (!data) {
+ syslog(LOG_ERR, "PKCS#11: Out of memory\n");
+ rc = -ENOMEM;
+ goto out;
+ }
+ i = 0;
+ data[i++] = '\x99';
+ data[i++] = (char)(len >> 8);
+ data[i++] = (char)len;
+ data[i++] = '\x04';
+ data[i++] = '\00';
+ data[i++] = '\00';
+ data[i++] = '\00';
+ data[i++] = '\00';
+ data[i++] = '\02';
+ data[i++] = (char)(nbits >> 8);
+ data[i++] = (char)nbits;
+ BN_bn2bin(rsa->n, &(data[i]));
+ i += nbytes;
+ data[i++] = (char)(ebits >> 8);
+ data[i++] = (char)ebits;
+ BN_bn2bin(rsa->e, &(data[i]));
+ i += ebytes;
+ SHA1(data, len + 3, hash);
+ to_hex(sig, hash, ECRYPTFS_SIG_SIZE);
+ sig[ECRYPTFS_SIG_SIZE_HEX] = '\0';
+
+ rc = 0;
+out:
+ if (rc != 0) {
+ syslog(LOG_ERR, "PKCS#11: Error attempting to generate key signature; rc=[%d]\n", rc);
+ }
+
+ if (data != NULL) {
+ free(data);
+ data = NULL;
+ }
+ if (hash != NULL) {
+ free(hash);
+ hash = NULL;
+ }
+
+ if (rsa != NULL) {
+ RSA_free(rsa);
+ rsa = NULL;
+ }
+
+ return rc;
+}
+
+/**
+ * ecryptfs_pkcs11h_encrypt
+ * @to: Where to write encrypted data
+ * @size: Number of bytes to encrypt
+ * @from: Data to encrypt
+ * @blob: Arbitrary blob specific to this key module
+ *
+ * Encrypt @size bytes of data in @from, writing the encrypted data
+ * into @to, using @blob as the parameters for the
+ * encryption.
+ */
+static int ecryptfs_pkcs11h_encrypt(char *to, size_t *to_size, char *from,
+ size_t from_size, unsigned char *blob,
+ int blob_type)
+{
+ RSA *rsa = NULL;
+ int rc;
+
+ if (to == NULL) {
+ *to_size = 0;
+ }
+
+ if ((rc = ecryptfs_pkcs11h_get_public_key(&rsa, blob))) {
+ syslog(LOG_ERR, "PKCS#11: Error attempting to read RSA key from token; rc=[%d]\n", rc);
+ goto out;
+ }
+
+ (*to_size) = RSA_size(rsa);
+ if (to) {
+ if (
+ (rc = RSA_public_encrypt(
+ from_size,
+ from,
+ to,
+ rsa,
+ RSA_PKCS1_PADDING
+ )) == -1
+ ) {
+ rc = -(int)ERR_get_error();
+ syslog(LOG_ERR, "PKCS#11: Error attempting to perform RSA public key encryption; rc=[%d]\n", rc);
+ goto out;
+ }
+
+ (*to_size) = rc;
+ }
+
+ rc = 0;
+out:
+ if (rsa != NULL) {
+ RSA_free(rsa);
+ rsa = NULL;
+ }
+
+ return rc;
+}
+
+/**
+ * ecryptfs_pkcs11h_dencrypt
+ * @from: Data to decrypt
+ * @to: Where to write decrypted data
+ * @decrypted_key_size: Number of bytes decrypted
+ * @blob: Arbitrary blob specific to this key module
+ *
+ * Decrypt data in @from, writing the decrypted data into @to, using
+ * @blob as the parameters for the encryption.
+ */
+static int ecryptfs_pkcs11h_decrypt(char *to, size_t *to_size, char *from,
+ size_t from_size, unsigned char *blob,
+ int blob_type)
+{
+ struct pkcs11h_data _pkcs11h_data;
+ struct pkcs11h_data *pkcs11h_data = &_pkcs11h_data;
+ pkcs11h_certificate_id_t certificate_id = NULL;
+ pkcs11h_certificate_t certificate = NULL;
+ CK_RV rv = CKR_OK;
+ int rc;
+
+ if (to == NULL) {
+ *to_size = 0;
+ }
+
+ if ((rc = ecryptfs_pkcs11h_deserialize(pkcs11h_data, blob)) != 0) {
+ goto out;
+ }
+
+ if (
+ (rv = pkcs11h_certificate_deserializeCertificateId (
+ &certificate_id,
+ pkcs11h_data->serialized_id
+ )) != CKR_OK
+ ) {
+ syslog(LOG_ERR, "PKCS#11: Cannot deserialize id rv=[%ld-'%s']", rv, pkcs11h_getMessage (rv));
+ rc = -EIO;
+ goto out;
+ }
+
+ if (
+ pkcs11h_data->certificate_blob != NULL &&
+ (rv = pkcs11h_certificate_setCertificateIdCertificateBlob (
+ certificate_id,
+ pkcs11h_data->certificate_blob,
+ pkcs11h_data->certificate_blob_size
+ )) != CKR_OK
+ ) {
+ syslog(LOG_ERR, "PKCS#11: Cannot set certificate blob rv=[%ld-'%s']", rv, pkcs11h_getMessage (rv));
+ rc = -EIO;
+ goto out;
+ }
+
+ if (
+ (rv = pkcs11h_certificate_create (
+ certificate_id,
+ pkcs11h_data->passphrase,
+ PKCS11H_PROMPT_MASK_ALLOW_ALL,
+ PKCS11H_PIN_CACHE_INFINITE,
+ &certificate
+ )) != CKR_OK
+ ) {
+ syslog(LOG_ERR, "PKCS#11: Cannot create certificate handle rv=[%ld-'%s']", rv, pkcs11h_getMessage (rv));
+ rc = -EIO;
+ goto out;
+ }
+
+ if (
+ (rv = pkcs11h_certificate_decryptAny (
+ certificate,
+ CKM_RSA_PKCS,
+ from,
+ from_size,
+ to,
+ to_size
+ )) != CKR_OK
+ ) {
+ syslog(LOG_ERR, "PKCS#11: Cannot decrypt rv=[%ld-'%s']", rv, pkcs11h_getMessage (rv));
+ rc = -EIO;
+ goto out;
+ }
+
+
+ /*
+ * As we cannot store context between
+ * calls, we must end PKCS#11 operation
+ * or token will fail with operation
+ * in progress.
+ */
+ if (to == NULL) {
+ char *tmp = (char *)malloc(*to_size);
+ if (tmp == NULL) {
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ pkcs11h_certificate_decryptAny (
+ certificate,
+ CKM_RSA_PKCS,
+ from,
+ from_size,
+ tmp,
+ to_size
+ );
+
+ free(tmp);
+ tmp = NULL;
+ }
+
+ rc = 0;
+out:
+ if (certificate != NULL) {
+ pkcs11h_certificate_freeCertificate (certificate);
+ certificate = NULL;
+ }
+
+ if (certificate_id != NULL) {
+ pkcs11h_certificate_freeCertificateId (certificate_id);
+ certificate_id = NULL;
+ }
+
+ return rc;
+}
+
+static int pkcs11h_get_id_list (char **list) {
+ pkcs11h_certificate_id_list_t user_certificates = NULL;
+ pkcs11h_certificate_id_list_t current = NULL;
+ CK_RV rv = CKR_FUNCTION_FAILED;
+ char *s = NULL;
+ int rc;
+
+ *list = NULL;
+
+ if (
+ (rv = pkcs11h_certificate_enumCertificateIds (
+ PKCS11H_ENUM_METHOD_CACHE_EXIST,
+ NULL,
+ PKCS11H_PROMPT_MASK_ALLOW_ALL,
+ NULL,
+ &user_certificates
+ )) != CKR_OK
+ ) {
+ syslog(LOG_ERR, "PKCS#11: Cannot enumerate certificates rv=[%ld-'%s']", rv, pkcs11h_getMessage (rv));
+ rc = -EIO;
+ goto cleanup;
+ }
+
+ for (current = user_certificates; current != NULL; current = current->next) {
+ pkcs11h_certificate_t certificate = NULL;
+ X509 *x509 = NULL;
+ BIO *bio = NULL;
+ __pkcs11_openssl_d2i_t d2i1 = NULL;
+ unsigned char *certificate_blob = NULL;
+ size_t certificate_blob_size;
+ char dn[1024] = {0};
+ char serial[1024] = {0};
+ char *ser = NULL;
+ size_t ser_len = 0;
+ int n;
+
+ if (
+ (rv = pkcs11h_certificate_serializeCertificateId (
+ NULL,
+ &ser_len,
+ current->certificate_id
+ )) != CKR_OK
+ ) {
+ syslog(LOG_ERR, "PKCS#11: Cannot serialize certificate id certificates rv=[%ld-'%s']", rv, pkcs11h_getMessage (rv));
+ rc = -EIO;
+ goto cleanup1;
+ }
+
+ if (
+ (ser = (char *)malloc (ser_len)) == NULL
+ ) {
+ syslog(LOG_ERR, "PKCS#11: Cannot allocate memory");
+ rc = -ENOMEM;
+ goto cleanup1;
+ }
+
+ if (
+ (rv = pkcs11h_certificate_serializeCertificateId (
+ ser,
+ &ser_len,
+ current->certificate_id
+ )) != CKR_OK
+ ) {
+ syslog(LOG_ERR, "PKCS#11: Cannot serialize certificate id certificates rv=[%ld-'%s']", rv, pkcs11h_getMessage (rv));
+ rc = -EIO;
+ goto cleanup1;
+ }
+
+ if (
+ (rv = pkcs11h_certificate_create (
+ current->certificate_id,
+ NULL,
+ PKCS11H_PROMPT_MASK_ALLOW_ALL,
+ PKCS11H_PIN_CACHE_INFINITE,
+ &certificate
+ )) != CKR_OK
+ ) {
+ syslog(LOG_ERR, "PKCS#11: Cannot create certificate rv=[%ld-'%s']", rv, pkcs11h_getMessage (rv));
+ rc = -EIO;
+ goto cleanup1;
+ }
+
+ if (
+ (rv = pkcs11h_certificate_getCertificateBlob (
+ certificate,
+ NULL,
+ &certificate_blob_size
+ )) != CKR_OK
+ ) {
+ syslog(LOG_ERR, "PKCS#11: Cannot load certificate rv=[%ld-'%s']", rv, pkcs11h_getMessage (rv));
+ rc = -EIO;
+ goto cleanup1;
+ }
+
+ certificate_blob = malloc(certificate_blob_size);
+ if (!certificate_blob) {
+ syslog(LOG_ERR, "Out of memory\n");
+ rc = -ENOMEM;
+ goto cleanup1;
+ }
+
+ if (
+ (rv = pkcs11h_certificate_getCertificateBlob (
+ certificate,
+ certificate_blob,
+ &certificate_blob_size
+ )) != CKR_OK
+ ) {
+ syslog(LOG_ERR, "PKCS#11: Cannot load certificate rv=[%ld-'%s']", rv, pkcs11h_getMessage (rv));
+ rc = -EIO;
+ goto cleanup1;
+ }
+
+ if ((x509 = X509_new ()) == NULL) {
+ syslog(LOG_ERR, "PKCS#11: Unable to allocate certificate object");
+ rc = -ENOMEM;
+ goto cleanup1;
+ }
+
+ d2i1 = (__pkcs11_openssl_d2i_t)certificate_blob;
+ if (!d2i_X509 (&x509, &d2i1, certificate_blob_size)) {
+ syslog(LOG_ERR, "PKCS#11: Unable to parse X.509 certificate");
+ rc = -EIO;
+ goto cleanup1;
+ }
+
+ X509_NAME_oneline (
+ X509_get_subject_name (x509),
+ dn,
+ sizeof(dn)
+ );
+
+ if ((bio = BIO_new (BIO_s_mem ())) == NULL) {
+ syslog(LOG_ERR, "PKCS#11: Cannot create BIO");
+ rc = -EIO;
+ goto cleanup1;
+ }
+
+ i2a_ASN1_INTEGER(bio, X509_get_serialNumber (x509));
+ n = BIO_read (bio, serial, sizeof(serial)-1);
+ if (n<0) {
+ serial[0] = '\x0';
+ }
+ else {
+ serial[n] = 0;
+ }
+
+ {
+ char *t = NULL;
+
+ if (asprintf (&t, "%s%s (%s) [%s]\n", s!=NULL?s:"", dn, serial, ser) == -1) {
+ rc = -ENOMEM;
+ goto cleanup1;
+ }
+ if (s != NULL) {
+ free(s);
+ }
+ s = t;
+ }
+
+ cleanup1:
+ if (certificate_blob != NULL) {
+ free(certificate_blob);
+ certificate_blob = NULL;
+ }
+
+ if (x509 != NULL) {
+ X509_free(x509);
+ x509 = NULL;
+ }
+
+ if (bio != NULL) {
+ BIO_free_all (bio);
+ bio = NULL;
+ }
+
+ if (certificate != NULL) {
+ pkcs11h_certificate_freeCertificate (certificate);
+ certificate = NULL;
+ }
+
+ if (ser != NULL) {
+ free(ser);
+ ser = NULL;
+ }
+ }
+
+ *list = s;
+ s = NULL;
+ rc = 0;
+
+cleanup:
+
+ if (user_certificates != NULL) {
+ pkcs11h_certificate_freeCertificateIdList (user_certificates);
+ user_certificates = NULL;
+ }
+
+ if (s != NULL) {
+ free(s);
+ s = NULL;
+ }
+
+ return rc;
+}
+
+static int ecryptfs_pkcs11h_process_key(struct pkcs11h_subgraph_key_ctx *subgraph_key_ctx,
+ struct val_node **mnt_params)
+{
+ struct pkcs11h_data *pkcs11h_data = &subgraph_key_ctx->pkcs11h_data;
+ pkcs11h_certificate_id_t certificate_id = NULL;
+ pkcs11h_certificate_t certificate = NULL;
+ size_t blob_size;
+ char *sig_mnt_opt;
+ char sig[ECRYPTFS_SIG_SIZE_HEX + 1];
+ CK_RV rv;
+ int rc;
+
+ if (
+ (rv = pkcs11h_certificate_deserializeCertificateId (
+ &certificate_id,
+ pkcs11h_data->serialized_id
+ )) != CKR_OK
+ ) {
+ syslog(LOG_ERR, "PKCS#11: Cannot deserialize id rv=[%ld-'%s']", rv, pkcs11h_getMessage (rv));
+ rc = -EIO;
+ goto out;
+ }
+
+ if (
+ (rv = pkcs11h_certificate_create (
+ certificate_id,
+ pkcs11h_data->passphrase,
+ PKCS11H_PROMPT_MASK_ALLOW_ALL,
+ PKCS11H_PIN_CACHE_INFINITE,
+ &certificate
+ )) != CKR_OK
+ ) {
+ syslog(LOG_ERR, "PKCS#11: Cannot get certificate rv=[%ld-'%s']", rv, pkcs11h_getMessage (rv));
+ rc = -EIO;
+ goto out;
+ }
+
+ if (pkcs11h_data->certificate_blob == NULL) {
+ if (
+ (rv = pkcs11h_certificate_getCertificateBlob (
+ certificate,
+ NULL,
+ &pkcs11h_data->certificate_blob_size
+ )) != CKR_OK
+ ) {
+ syslog(LOG_ERR, "PKCS#11: Cannot load certificate rv=[%ld-'%s']", rv, pkcs11h_getMessage (rv));
+ rc = -EIO;
+ goto out;
+ }
+
+ pkcs11h_data->certificate_blob = malloc(pkcs11h_data->certificate_blob_size);
+ if (!pkcs11h_data->certificate_blob) {
+ syslog(LOG_ERR, "PKCS#11: Out of memory\n");
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ if (
+ (rv = pkcs11h_certificate_getCertificateBlob (
+ certificate,
+ pkcs11h_data->certificate_blob,
+ &pkcs11h_data->certificate_blob_size
+ )) != CKR_OK
+ ) {
+ syslog(LOG_ERR, "PKCS#11: Cannot load certificate rv=[%ld-'%s']", rv, pkcs11h_getMessage (rv));
+ rc = -EIO;
+ goto out;
+ }
+ }
+
+ if ((rc = ecryptfs_pkcs11h_serialize(NULL, &blob_size,
+ pkcs11h_data))) {
+ syslog(LOG_ERR, "PKCS#11: Error serializing pkcs11; rc=[%d]\n", rc);
+ rc = MOUNT_ERROR;
+ goto out;
+ }
+ if (blob_size == 0) {
+ syslog(LOG_ERR, "PKCS#11: Error serializing pkcs11\n");
+ rc = MOUNT_ERROR;
+ goto out;
+ }
+ if ((subgraph_key_ctx->key_mod->blob = malloc(blob_size)) == NULL) {
+ syslog(LOG_ERR, "PKCS#11: Out of memory\n");
+ rc = MOUNT_ERROR;
+ goto out;
+ }
+ if ((rc = ecryptfs_pkcs11h_serialize(subgraph_key_ctx->key_mod->blob,
+ &subgraph_key_ctx->key_mod->blob_size,
+ pkcs11h_data))) {
+ syslog(LOG_ERR, "PKCS#11: Error serializing pkcs11; rc=[%d]\n", rc);
+ rc = MOUNT_ERROR;
+ goto out;
+ }
+ if (subgraph_key_ctx->key_mod->blob_size != blob_size) {
+ syslog(LOG_ERR, "PKCS#11: %s: Internal error\n", __FUNCTION__);
+ exit(1);
+ }
+ if ((rc = ecryptfs_add_key_module_key_to_keyring(sig, subgraph_key_ctx->key_mod)) < 0) {
+ syslog(
+ LOG_ERR,
+ "PKCS#11: Error attempting to add key to keyring for key module [%s]; rc=[%d]\n",
+ subgraph_key_ctx->key_mod->alias,
+ rc
+ );
+ rc = MOUNT_ERROR;
+ goto out;
+ }
+ if ((rc = asprintf(&sig_mnt_opt, "ecryptfs_sig=%s", sig)) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+ stack_push(mnt_params, sig_mnt_opt);
+out:
+ if (certificate != NULL) {
+ pkcs11h_certificate_freeCertificate (certificate);
+ certificate = NULL;
+ }
+
+ if (certificate_id != NULL) {
+ pkcs11h_certificate_freeCertificateId (certificate_id);
+ certificate_id = NULL;
+ }
+
+ return rc;
+}
+
+static void
+tf_ecryptfs_pkcs11h_destroy_subgraph_key_ctx(struct pkcs11h_subgraph_key_ctx *ctx)
+{
+ if (ctx->pkcs11h_data.serialized_id != NULL) {
+ free(ctx->pkcs11h_data.serialized_id);
+ }
+ if (ctx->pkcs11h_data.passphrase != NULL) {
+ memset(ctx->pkcs11h_data.passphrase, 0, strlen(ctx->pkcs11h_data.passphrase));
+ free(ctx->pkcs11h_data.passphrase);
+ }
+ if (ctx->pkcs11h_data.certificate_blob != NULL) {
+ free(ctx->pkcs11h_data.certificate_blob);
+ }
+ memset(&ctx->pkcs11h_data, 0, sizeof(ctx->pkcs11h_data));
+ memset(ctx, 0, sizeof(*ctx));
+}
+
+static void
+tf_ecryptfs_pkcs11h_destroy_subgraph_provider_ctx(struct pkcs11h_subgraph_provider_ctx *ctx)
+{
+ if (ctx->name != NULL) {
+ free(ctx->name);
+ }
+ if (ctx->library != NULL) {
+ free(ctx->library);
+ }
+ memset(ctx, 0, sizeof(*ctx));
+}
+
+static int tf_pkcs11h_global_loglevel(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **mnt_params, void **foo)
+{
+ int rc;
+
+ pkcs11h_setLogLevel (atoi (node->val));
+
+ rc = DEFAULT_TOK;
+ node->val = NULL;
+out:
+ return rc;
+}
+
+static int tf_pkcs11h_global_pincache(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **mnt_params, void **foo)
+{
+ int rc;
+
+ pkcs11h_setPINCachePeriod (atoi (node->val));
+
+ rc = DEFAULT_TOK;
+ node->val = NULL;
+out:
+ return rc;
+}
+
+static int tf_pkcs11h_provider(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **mnt_params, void **foo)
+{
+ struct pkcs11h_subgraph_provider_ctx *subgraph_provider_ctx;
+ int rc;
+
+ if ((subgraph_provider_ctx = malloc(sizeof(*ctx)))
+ == NULL) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ memset(subgraph_provider_ctx, 0, sizeof(*ctx));
+
+ (*foo) = (void *)subgraph_provider_ctx;
+ rc = DEFAULT_TOK;
+ node->val = NULL;
+out:
+ return rc;
+}
+
+static int tf_pkcs11h_provider_name(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **mnt_params, void **foo)
+{
+ struct pkcs11h_subgraph_provider_ctx *subgraph_provider_ctx;
+ int rc;
+
+ subgraph_provider_ctx = (struct pkcs11h_subgraph_provider_ctx *)(*foo);
+ if ((rc = asprintf(&subgraph_provider_ctx->name, "%s", node->val))
+ == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = DEFAULT_TOK;
+ node->val = NULL;
+out:
+ return rc;
+}
+
+static int tf_pkcs11h_provider_library(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **mnt_params, void **foo)
+{
+ struct pkcs11h_subgraph_provider_ctx *subgraph_provider_ctx;
+ int rc;
+
+ subgraph_provider_ctx = (struct pkcs11h_subgraph_provider_ctx *)(*foo);
+ if ((rc = asprintf(&subgraph_provider_ctx->library, "%s", node->val))
+ == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = DEFAULT_TOK;
+ node->val = NULL;
+out:
+ return rc;
+}
+
+static int tf_pkcs11h_provider_prot_auth(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **mnt_params, void **foo)
+{
+ struct pkcs11h_subgraph_provider_ctx *subgraph_provider_ctx;
+ int rc;
+
+ subgraph_provider_ctx = (struct pkcs11h_subgraph_provider_ctx *)(*foo);
+ sscanf (node->val, "%x", &subgraph_provider_ctx->allow_protected_authentication);
+ rc = DEFAULT_TOK;
+ node->val = NULL;
+out:
+ return rc;
+}
+
+static int tf_pkcs11h_provider_cert_private(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **mnt_params, void **foo)
+{
+ struct pkcs11h_subgraph_provider_ctx *subgraph_provider_ctx;
+ int rc;
+
+ subgraph_provider_ctx = (struct pkcs11h_subgraph_provider_ctx *)(*foo);
+ sscanf (node->val, "%x", &subgraph_provider_ctx->certificate_is_private);
+ rc = DEFAULT_TOK;
+ node->val = NULL;
+out:
+ return rc;
+}
+
+static int tf_pkcs11h_provider_private_mask(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **mnt_params, void **foo)
+{
+ struct pkcs11h_subgraph_provider_ctx *subgraph_provider_ctx;
+ int rc;
+
+ subgraph_provider_ctx = (struct pkcs11h_subgraph_provider_ctx *)(*foo);
+ sscanf (node->val, "%x", &subgraph_provider_ctx->private_mask);
+
+ rc = DEFAULT_TOK;
+ node->val = NULL;
+out:
+ return rc;
+}
+
+static int tf_pkcs11h_provider_end(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **mnt_params, void **foo)
+{
+ struct pkcs11h_subgraph_provider_ctx *subgraph_provider_ctx;
+ CK_RV rv = CKR_FUNCTION_FAILED;
+ int rc;
+
+ subgraph_provider_ctx = (struct pkcs11h_subgraph_provider_ctx *)(*foo);
+
+ if (
+ (rv = pkcs11h_addProvider (
+ subgraph_provider_ctx->name,
+ subgraph_provider_ctx->library,
+ subgraph_provider_ctx->allow_protected_authentication != 0,
+ subgraph_provider_ctx->private_mask,
+ PKCS11H_SLOTEVENT_METHOD_AUTO,
+ 0,
+ subgraph_provider_ctx->certificate_is_private != 0
+ )) != CKR_OK
+ ) {
+ syslog(LOG_ERR, "PKCS#11: Cannot initialize provider '%s' rv=[%ld-'%s']", subgraph_provider_ctx->name, rv, pkcs11h_getMessage (rv));
+ }
+
+ tf_ecryptfs_pkcs11h_destroy_subgraph_provider_ctx(subgraph_provider_ctx);
+ free(subgraph_provider_ctx);
+ *foo = NULL;
+ rc = DEFAULT_TOK;
+out:
+ return rc;
+}
+
+static int tf_pkcs11h_key_id(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **mnt_params, void **foo)
+{
+ struct pkcs11h_subgraph_key_ctx *subgraph_key_ctx;
+ int rc;
+
+ subgraph_key_ctx = (struct pkcs11h_subgraph_key_ctx *)(*foo);
+ if ((rc = asprintf(&subgraph_key_ctx->pkcs11h_data.serialized_id, "%s", node->val))
+ == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = DEFAULT_TOK;
+ node->val = NULL;
+out:
+ return rc;
+}
+
+static int tf_pkcs11h_key_passwd(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **mnt_params, void **foo)
+{
+ struct pkcs11h_subgraph_key_ctx *subgraph_key_ctx;
+ int rc;
+
+ subgraph_key_ctx = (struct pkcs11h_subgraph_key_ctx *)(*foo);
+ if ((rc = asprintf(&subgraph_key_ctx->pkcs11h_data.passphrase, "%s",
+ node->val)) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ node->val = NULL;
+ rc = DEFAULT_TOK;
+out:
+ return rc;
+}
+
+static int tf_pkcs11h_key_x509file(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **mnt_params, void **foo)
+{
+ struct pkcs11h_subgraph_key_ctx *subgraph_key_ctx;
+ X509 *x509 = NULL;
+ unsigned char *p = NULL;
+ FILE *fp = NULL;
+ int rc;
+
+ subgraph_key_ctx = (struct pkcs11h_subgraph_key_ctx *)(*foo);
+
+ if (node->val != NULL && strlen(node->val) > 0) {
+ if ((fp = fopen (node->val, "r")) == NULL) {
+ syslog(LOG_ERR, "PKCS#11: Cannot open file '%s'", node->val);
+ rc = -errno;
+ goto out;
+ }
+
+ if (
+ !PEM_read_X509 (
+ fp,
+ &x509,
+ NULL,
+ 0
+ )
+ ) {
+ x509 = NULL;
+ syslog(LOG_ERR, "PKCS#11: Cannot read PEM from file '%s'", node->val);
+ rc = -EIO;
+ goto out;
+ }
+
+ if ((subgraph_key_ctx->pkcs11h_data.certificate_blob_size = i2d_X509 (x509, NULL)) < 0 ) {
+ syslog(LOG_ERR, "PKCS#11: Cannot read decode certificate");
+ rc = -EIO;
+ goto out;
+ }
+
+ if (
+ (subgraph_key_ctx->pkcs11h_data.certificate_blob = (unsigned char *)malloc (
+ subgraph_key_ctx->pkcs11h_data.certificate_blob_size
+ )) == NULL
+ ) {
+ syslog(LOG_ERR, "PKCS#11: Cannot allocate memory");
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ /*
+ * i2d_X509 increments p!!!
+ */
+ p = subgraph_key_ctx->pkcs11h_data.certificate_blob;
+
+ if ((subgraph_key_ctx->pkcs11h_data.certificate_blob_size = i2d_X509 (x509, &p)) < 0) {
+ syslog(LOG_ERR, "PKCS#11: Cannot read decode certificate");
+ goto out;
+ }
+ }
+
+ node->val = NULL;
+ if ((rc = ecryptfs_pkcs11h_process_key(subgraph_key_ctx, mnt_params))) {
+ syslog(LOG_ERR, "PKCS#11: Error processing PKCS#11 key; rc=[%d]", rc);
+ goto out;
+ }
+ tf_ecryptfs_pkcs11h_destroy_subgraph_key_ctx(subgraph_key_ctx);
+ free(subgraph_key_ctx);
+ (*foo) = NULL;
+ rc = DEFAULT_TOK;
+
+out:
+
+ if (x509 != NULL) {
+ X509_free(x509);
+ x509 = NULL;
+ }
+
+ if (fp != NULL) {
+ fclose (fp);
+ fp = NULL;
+ }
+
+ return rc;
+}
+
+#define PKCS11H_GLOBAL_TOK_LOGLEVEL 0
+#define PKCS11H_GLOBAL_TOK_PINCACHE 1
+static struct param_node pkcs11h_global_param_nodes[] = {
+
+ {.num_mnt_opt_names = 1,
+ .mnt_opt_names = {"pkcs11-log-level"},
+ .prompt = "PKCS#11 Log Level",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = "0",
+ .suggested_val = NULL,
+ .flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
+ .num_transitions = 1,
+ .tl = {{.val = NULL,
+ .pretty_val = NULL,
+ .next_token = NULL,
+ .trans_func = tf_pkcs11h_global_loglevel}}},
+
+ {.num_mnt_opt_names = 1,
+ .mnt_opt_names = {"pkcs11-pin-cache-timeout"},
+ .prompt = "PKCS#11 Log Level",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = "-1",
+ .suggested_val = NULL,
+ .flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
+ .num_transitions = 1,
+ .tl = {{.val = NULL,
+ .pretty_val = NULL,
+ .next_token = NULL,
+ .trans_func = tf_pkcs11h_global_pincache}}},
+};
+
+#define PKCS11H_PROVIER_TOK_PROVIDER 0
+#define PKCS11H_PROVIER_TOK_NAME 1
+#define PKCS11H_PROVIER_TOK_LIBRARY 2
+#define PKCS11H_PROVIER_TOK_PROT_AUTH 3
+#define PKCS11H_PROVIER_TOK_CERT_PRIVATE 4
+#define PKCS11H_PROVIER_TOK_PRIVATE_MASK 5
+#define PKCS11H_PROVIER_TOK_END 6
+static struct param_node pkcs11h_provider_param_nodes[] = {
+
+ {.num_mnt_opt_names = 1,
+ .mnt_opt_names = {"pkcs11-provider"},
+ .prompt = "PKCS#11 Provider",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = "",
+ .suggested_val = NULL,
+ .flags = DISPLAY_TRANSITION_NODE_VALS | ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
+ .num_transitions = 1,
+ .tl = {{.val = "name",
+ .pretty_val = NULL,
+ .next_token = &pkcs11h_provider_param_nodes[PKCS11H_PROVIER_TOK_NAME],
+ .trans_func = tf_pkcs11h_provider}}},
+
+ {.num_mnt_opt_names = 1,
+ .mnt_opt_names = {"name"},
+ .prompt = "PKCS#11 Provider Alias",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
+ .num_transitions = 1,
+ .tl = {{.val = "library",
+ .pretty_val = NULL,
+ .next_token = &pkcs11h_provider_param_nodes[PKCS11H_PROVIER_TOK_LIBRARY],
+ .trans_func = tf_pkcs11h_provider_name}}},
+
+ {.num_mnt_opt_names = 1,
+ .mnt_opt_names = {"library"},
+ .prompt = "PKCS#11 Library",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
+ .num_transitions = 1,
+ .tl = {{.val = "default",
+ .pretty_val = NULL,
+ .next_token = &pkcs11h_provider_param_nodes[PKCS11H_PROVIER_TOK_PROT_AUTH],
+ .trans_func = tf_pkcs11h_provider_library}}},
+
+ {.num_mnt_opt_names = 1,
+ .mnt_opt_names = {"allow-protected-auth"},
+ .prompt = "Allow Protected Authentication",
+ .val_type = VAL_HEX,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = "1",
+ .flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT | ECRYPTFS_ALLOW_IMPLICIT_TRANSITION,
+ .num_transitions = 1,
+ .tl = {{.val = "default",
+ .pretty_val = NULL,
+ .next_token = &pkcs11h_provider_param_nodes[PKCS11H_PROVIER_TOK_CERT_PRIVATE],
+ .trans_func = tf_pkcs11h_provider_prot_auth}}},
+
+ {.num_mnt_opt_names = 1,
+ .mnt_opt_names = {"cert-private"},
+ .prompt = "Certificate is private object",
+ .val_type = VAL_HEX,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = "0",
+ .flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
+ .num_transitions = 1,
+ .tl = {{.val = "default",
+ .pretty_val = NULL,
+ .next_token = &pkcs11h_provider_param_nodes[PKCS11H_PROVIER_TOK_PRIVATE_MASK],
+ .trans_func = tf_pkcs11h_provider_cert_private}}},
+
+ {.num_mnt_opt_names = 1,
+ .mnt_opt_names = {"private-mask"},
+ .prompt = "Private Key Mask",
+ .val_type = VAL_HEX,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = "0",
+ .flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
+ .num_transitions = 1,
+ .tl = {{.val = "default",
+ .pretty_val = NULL,
+ .next_token = &pkcs11h_provider_param_nodes[PKCS11H_PROVIER_TOK_END],
+ .trans_func = tf_pkcs11h_provider_private_mask}}},
+
+ {.num_mnt_opt_names = 1,
+ .mnt_opt_names = {"dummy"},
+ .prompt = "",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = "",
+ .flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
+ .num_transitions = 1,
+ .tl = {{.val = "default",
+ .pretty_val = NULL,
+ .next_token = &pkcs11h_provider_param_nodes[PKCS11H_PROVIER_TOK_PROVIDER],
+ .trans_func = tf_pkcs11h_provider_end}}},
+};
+
+#define PKCS11H_KEY_TOK_TOK 0
+#define PKCS11H_KEY_TOK_ID 1
+#define PKCS11H_KEY_TOK_PASSWD 2
+#define PKCS11H_KEY_TOK_PASS_ENV 3
+#define PKCS11H_KEY_TOK_PASS_STDIN 4
+#define PKCS11H_KEY_TOK_DEFAULT_PASS 5
+#define PKCS11H_KEY_TOK_DEFAULT_X509_FILE 6
+static struct param_node pkcs11h_key_param_nodes[] = {
+ {.num_mnt_opt_names = 1,
+ .mnt_opt_names = {"keyformat"},
+ .prompt = "Key format",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = "id",
+ .flags = ECRYPTFS_PARAM_FLAG_NO_VALUE,
+ .num_transitions = 1,
+ .tl = {{.val = "default",
+ .pretty_val = "PKCS#11 ID",
+ .next_token = &pkcs11h_key_param_nodes[PKCS11H_KEY_TOK_ID],
+ .trans_func = NULL}}},
+
+ {.num_mnt_opt_names = 1,
+ .mnt_opt_names = {"id"},
+ .prompt = "PKCS#11 Serialized ID",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .suggested_val = NULL,
+ .flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
+ .num_transitions = 4,
+ .tl = {{.val = "passwd",
+ .pretty_val = "",
+ .next_token = &pkcs11h_key_param_nodes[PKCS11H_KEY_TOK_PASSWD],
+ .trans_func = tf_pkcs11h_key_id},
+ {.val = "passenv",
+ .pretty_val = "Passphrase ENV",
+ .next_token = &pkcs11h_key_param_nodes[PKCS11H_KEY_TOK_PASS_ENV],
+ .trans_func = tf_pkcs11h_key_id},
+ {.val = "passstdin",
+ .pretty_val = "Passphrase STDIN",
+ .next_token = &pkcs11h_key_param_nodes[PKCS11H_KEY_TOK_PASS_STDIN],
+ .trans_func = tf_pkcs11h_key_id},
+ {.val = "default",
+ .pretty_val = "Passphrase (empty for interactive)",
+ .next_token = &pkcs11h_key_param_nodes[PKCS11H_KEY_TOK_DEFAULT_PASS],
+ .trans_func = tf_pkcs11h_key_id}}},
+
+ {.num_mnt_opt_names = 1,
+ .mnt_opt_names = {"passwd"},
+ .prompt = "Passphrase (empty for interactive)",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .flags = ECRYPTFS_PARAM_FLAG_MASK_OUTPUT,
+ .num_transitions = 1,
+ .tl = {{.val = NULL,
+ .pretty_val = NULL,
+ .next_token = NULL,
+ .trans_func = tf_pkcs11h_key_passwd}}},
+
+ {.num_mnt_opt_names = 1,
+ .mnt_opt_names = {"passenv"},
+ .prompt = "Passphrase (empty for interactive)",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .flags = ECRYPTFS_PARAM_FLAG_MASK_OUTPUT,
+ .num_transitions = 1,
+ .tl = {{.val = NULL,
+ .pretty_val = NULL,
+ .next_token = NULL,
+ .trans_func = tf_pkcs11h_key_passwd}}},
+
+ {.num_mnt_opt_names = 1,
+ .mnt_opt_names = {"passstdin"},
+ .prompt = "Passphrase (empty for interactive)",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .flags = VERIFY_VALUE | STDIN_REQUIRED,
+ .num_transitions = 1,
+ .tl = {{.val = NULL,
+ .pretty_val = NULL,
+ .next_token = NULL,
+ .trans_func = tf_pkcs11h_key_passwd}}},
+
+ {.num_mnt_opt_names = 1,
+ .mnt_opt_names = {"defaultpass"},
+ .prompt = "Passphrase (empty for interactive)",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .flags = STDIN_REQUIRED,
+ .num_transitions = 1,
+ .tl = {{.val = "default",
+ .pretty_val = "Optional X.509 Certificate PEM file",
+ .next_token = &pkcs11h_key_param_nodes[PKCS11H_KEY_TOK_DEFAULT_X509_FILE],
+ .trans_func = tf_pkcs11h_key_passwd}}},
+
+ {.num_mnt_opt_names = 1,
+ .mnt_opt_names = {"x509file"},
+ .prompt = "Optional X.509 Certificate PEM file",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
+ .num_transitions = 1,
+ .tl = {{.val = NULL,
+ .pretty_val = NULL,
+ .next_token = NULL,
+ .trans_func = tf_pkcs11h_key_x509file}}},
+};
+
+/**
+ * tf_pkcs11h_key_enter
+ * @ctx: The current applicable libecryptfs context struct
+ * @node: The param_node from which we are transitioning
+ * @head: The head of the name/value pair list that is being
+ * constructed as the decision graph is being traversed
+ * @foo: Arbitrary state information for the current subgraph
+ *
+ * Each transition from one node in the decision graph to another node
+ * can have a function executed on the transition event. A transition
+ * into any given subgraph may require certain housekeeping and
+ * initialization functions to occur.
+ *
+ * The decision graph engine forwards along an arbitrary data
+ * structure among the nodes of any subgraph. The logic in the
+ * subgraph can use that data structure to access and maintain
+ * arbitrary status information that is unique to the function of that
+ * subgraph.
+ */
+static int tf_pkcs11h_key_enter(struct ecryptfs_ctx *ctx,
+ struct param_node *param_node,
+ struct val_node **mnt_params, void **foo)
+{
+ struct pkcs11h_subgraph_key_ctx *subgraph_key_ctx;
+ int rc;
+
+ if ((subgraph_key_ctx = malloc(sizeof(*ctx)))
+ == NULL) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ memset(subgraph_key_ctx, 0, sizeof(*ctx));
+ if ((rc = ecryptfs_find_key_mod(&subgraph_key_ctx->key_mod, ctx,
+ param_node->val))) {
+ syslog(LOG_ERR, "PKCS#11: Cannot find key_mod for param_node with val = [%s]\n", param_node->val);
+ goto out;
+ }
+
+ if (pkcs11h_key_param_nodes[PKCS11H_KEY_TOK_ID].suggested_val) {
+ free (pkcs11h_key_param_nodes[PKCS11H_KEY_TOK_ID].suggested_val);
+ pkcs11h_key_param_nodes[PKCS11H_KEY_TOK_ID].suggested_val = NULL;
+ }
+
+ if (!strcmp (param_node->mnt_opt_names[0], "key")) {
+ if ((rc = pkcs11h_get_id_list(&pkcs11h_key_param_nodes[PKCS11H_KEY_TOK_ID].suggested_val)) != 0) {
+ goto out;
+ }
+ }
+
+ (*foo) = (void *)subgraph_key_ctx;
+out:
+ return rc;
+}
+
+struct transition_node pkcs11h_key_transition = {
+ .val = "pkcs11-helper",
+ .pretty_val = "PKCS#11 module using pkcs11-helper",
+ .next_token = &(pkcs11h_key_param_nodes[0]),
+ .trans_func = tf_pkcs11h_key_enter
+};
+
+static int ecryptfs_pkcs11h_get_param_subgraph_trans_node(
+ struct transition_node **trans, uint32_t version)
+{
+ if ((version & ECRYPTFS_VERSIONING_PUBKEY) == 0)
+ return -1;
+ (*trans) = &pkcs11h_key_transition;
+ return 0;
+}
+
+static int ecryptfs_pkcs11h_parse_file(struct param_node *param_nodes)
+{
+ struct ecryptfs_ctx _ctx;
+ struct ecryptfs_ctx *ctx = &_ctx;
+ struct ecryptfs_name_val_pair nvp_head;
+ struct val_node *dummy_mnt_params;
+ struct passwd *pw;
+ char *rcfile_fullpath = NULL;
+ int fd;
+ int rc;
+
+ if ((pw = getpwuid(getuid())) == NULL) {
+ rc = -EIO;
+ goto out;
+ }
+
+ if (asprintf(&rcfile_fullpath, "%s/.ecryptfsrc.pkcs11", pw->pw_dir) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ if ((fd = open(rcfile_fullpath, O_RDONLY)) == -1) {
+ rc = -errno;
+ goto out;
+ }
+
+ memset(ctx, 0, sizeof(*ctx));
+ memset(&nvp_head, 0, sizeof(nvp_head));
+
+ if ((dummy_mnt_params = malloc(sizeof(*dummy_mnt_params))) == NULL) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = parse_options_file(fd, &nvp_head);
+ close(fd);
+
+ if (ecryptfs_verbosity) {
+ struct ecryptfs_name_val_pair *nvp_item = &nvp_head;
+
+ while (nvp_item) {
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO, "PKCS#11: name = [%s]; value = [%s]\n",
+ nvp_item->name, nvp_item->value);
+ nvp_item = nvp_item->next;
+ }
+ }
+ ctx->nvp_head = &nvp_head;
+ ecryptfs_eval_decision_graph(ctx, &dummy_mnt_params, param_nodes,
+ &nvp_head);
+
+ rc = 0;
+out:
+ if (rcfile_fullpath != NULL) {
+ free(rcfile_fullpath);
+ }
+
+ return rc;
+}
+
+static int ecryptfs_pkcs11h_init(char **alias)
+{
+ CK_RV rv = CKR_FUNCTION_FAILED;
+ int rc = 0;
+
+ if (asprintf(alias, "pkcs11-helper") == -1) {
+ syslog(LOG_ERR, "PKCS#11: Out of memory\n");
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ if ((rv = pkcs11h_initialize ()) != CKR_OK) {
+ syslog(LOG_ERR, "PKCS#11: Cannot initialize rv=[%ld-'%s']", rv, pkcs11h_getMessage (rv));
+ rc = -EIO;
+ goto out;
+ }
+
+ if ((rv = pkcs11h_setLogHook (pkcs11h_log, NULL)) != CKR_OK) {
+ syslog(LOG_ERR, "PKCS#11: Cannot set hooks rv=[%ld-'%s']", rv, pkcs11h_getMessage (rv));
+ rc = -EIO;
+ goto out;
+ }
+
+ pkcs11h_setLogLevel (PKCS11H_LOG_QUIET);
+
+ ecryptfs_pkcs11h_parse_file(pkcs11h_global_param_nodes);
+
+ if ((rv = pkcs11h_setTokenPromptHook (pkcs11h_token_prompt, NULL)) != CKR_OK) {
+ syslog(LOG_ERR, "PKCS#11: Cannot set hooks rv=[%ld-'%s']", rv, pkcs11h_getMessage (rv));
+ rc = -EIO;
+ goto out;
+ }
+
+ if ((rv = pkcs11h_setPINPromptHook (pkcs11h_pin_prompt, NULL)) != CKR_OK) {
+ syslog(LOG_ERR, "PKCS#11: Cannot set hooks rv=[%ld-'%s']", rv, pkcs11h_getMessage (rv));
+ rc = -EIO;
+ goto out;
+ }
+
+ if ((rv = pkcs11h_setProtectedAuthentication (1)) != CKR_OK) {
+ syslog(LOG_ERR, "PKCS#11: Cannot set protected authentication mode rv=[%ld-'%s']", rv, pkcs11h_getMessage (rv));
+ rc = -EIO;
+ goto out;
+ }
+
+ ecryptfs_pkcs11h_parse_file(pkcs11h_provider_param_nodes);
+
+ rc = 0;
+out:
+ return rc;
+}
+
+static int ecryptfs_pkcs11h_finalize(void)
+{
+ if (pkcs11h_key_param_nodes[PKCS11H_KEY_TOK_ID].suggested_val)
+ free(pkcs11h_key_param_nodes[PKCS11H_KEY_TOK_ID].suggested_val);
+ pkcs11h_terminate ();
+ return 0;
+}
+
+static struct ecryptfs_key_mod_ops ecryptfs_pkcs11h_ops = {
+ .init = &ecryptfs_pkcs11h_init,
+ .get_gen_key_params = NULL,
+ .get_gen_key_subgraph_trans_node = NULL,
+ .get_params = NULL,
+ .get_param_subgraph_trans_node = &ecryptfs_pkcs11h_get_param_subgraph_trans_node,
+ .get_blob = NULL,
+ .get_key_data = NULL,
+ .get_key_sig = &ecryptfs_pkcs11h_get_key_sig,
+ .get_key_hint = NULL,
+ .encrypt = &ecryptfs_pkcs11h_encrypt,
+ .decrypt = &ecryptfs_pkcs11h_decrypt,
+ .destroy = NULL,
+ .finalize = &ecryptfs_pkcs11h_finalize
+};
+
+struct ecryptfs_key_mod_ops *get_key_mod_ops(void)
+{
+ return &ecryptfs_pkcs11h_ops;
+}
diff --git a/src/key_mod/ecryptfs_key_mod_tspi.c b/src/key_mod/ecryptfs_key_mod_tspi.c
new file mode 100644
index 0000000..b652c93
--- /dev/null
+++ b/src/key_mod/ecryptfs_key_mod_tspi.c
@@ -0,0 +1,751 @@
+/**
+ * Copyright (C) 2006-2007 International Business Machines Corp.
+ * Author(s): Mike Halcrow <mhalcrow@us.ibm.com>
+ * Kent Yoder <kyoder@users.sf.net>
+ *
+ * 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.
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <time.h>
+#include <unistd.h>
+#include <errno.h>
+#include <trousers/tss.h>
+#include <trousers/trousers.h>
+#include <openssl/sha.h>
+#include "../include/ecryptfs.h"
+#include "../include/decision_graph.h"
+
+#define ECRYPTFS_TSPI_DEFAULT_MAX_NUM_CONNECTIONS 10
+
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBGSYSLOG(x, ...) syslog(LOG_DEBUG, x, ##__VA_ARGS__)
+#define DBG_print_hex(a,b) print_hex(a,b)
+
+static void
+print_hex(BYTE *buf, uint32_t len)
+{
+ uint32_t i = 0, j;
+
+ while (i < len) {
+ for (j=0; (j < 15) && (i < len); j++, i++)
+ syslog(LOG_INFO, "%02x\n", buf[i] & 0xff);
+ }
+}
+
+#else
+#define LOG()
+#define DBGSYSLOG(x, ...)
+#define DBG_print_hex(a,b)
+#endif
+
+static TSS_UUID ecryptfs_tspi_srk_uuid = TSS_UUID_SRK;
+
+static struct key_mapper {
+ TSS_UUID uuid;
+ TSS_HKEY hKey;
+ struct key_mapper *next;
+} *mapper = NULL;
+
+struct tspi_data {
+ TSS_UUID uuid;
+};
+
+static void ecryptfs_tspi_to_hex(char *dst, char *src, int src_size)
+{
+ int x;
+
+ for (x = 0; x < src_size; x++)
+ sprintf(&dst[x * 2], "%.2x", (unsigned char)src[x]);
+}
+
+static int ecryptfs_tspi_generate_signature(char *sig, BYTE *n, uint32_t nbytes)
+{
+ int len, i;
+ unsigned char hash[SHA1_DIGEST_LENGTH];
+ unsigned char *data = NULL;
+ BYTE e[] = { 1, 0, 1 }; /* The e for all TPM RSA keys */
+ int rc = 0;
+
+ len = 10 + nbytes + sizeof(e);
+ if ((data = malloc(3 + len)) == NULL) {
+ syslog(LOG_ERR, "Out of memory\n");
+ rc = -ENOMEM;
+ goto out;
+ }
+ i = 0;
+ data[i++] = '\x99';
+ data[i++] = (len >> 8);
+ data[i++] = len;
+ data[i++] = '\x04';
+ data[i++] = '\00';
+ data[i++] = '\00';
+ data[i++] = '\00';
+ data[i++] = '\00';
+ data[i++] = '\02';
+ data[i++] = ((nbytes * 8) >> 8);
+ data[i++] = (nbytes * 8);
+ memcpy(&data[i], n, nbytes);
+ i += nbytes;
+ data[i++] = ((sizeof(e) * 8) >> 8);
+ data[i++] = (sizeof(e) * 8);
+ memcpy(&data[i], e, sizeof(e));
+ i += sizeof(e);
+ SHA1(data, len + 3, hash);
+ ecryptfs_tspi_to_hex(sig, (char *)hash, ECRYPTFS_SIG_SIZE);
+ sig[ECRYPTFS_SIG_SIZE_HEX] = '\0';
+out:
+ free(data);
+ return rc;
+}
+
+static int
+ecryptfs_tspi_deserialize(struct tspi_data *tspi_data, unsigned char *blob)
+{
+ int rc = 0;
+
+ memcpy(&tspi_data->uuid, blob, sizeof(TSS_UUID));
+
+ return rc;
+}
+
+static int ecryptfs_tspi_get_key_sig(unsigned char *sig, unsigned char *blob)
+{
+ struct tspi_data tspi_data;
+ BYTE *n;
+ uint32_t size_n;
+ TSS_RESULT result;
+ TSS_HCONTEXT h_ctx;
+ TSS_HKEY hKey;
+ int rc = 0;
+
+ ecryptfs_tspi_deserialize(&tspi_data, blob);
+ if ((result = Tspi_Context_Create(&h_ctx)) != TSS_SUCCESS) {
+ syslog(LOG_ERR, "Tspi_Context_Create failed: [%s]\n",
+ Trspi_Error_String(result));
+ rc = -EIO;
+ goto out;
+ }
+ DBG_print_hex((BYTE *)&tspi_data.uuid, sizeof(TSS_UUID));
+ if ((result = Tspi_Context_GetKeyByUUID(h_ctx, TSS_PS_TYPE_USER,
+ tspi_data.uuid, &hKey))
+ != TSS_SUCCESS) {
+ syslog(LOG_ERR, "Tspi_Context_GetKeyByUUID failed: [%s]\n",
+ Trspi_Error_String(result));
+ rc = -EIO;
+ goto out;
+ }
+ if ((result = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_RSAKEY_INFO,
+ TSS_TSPATTRIB_KEYINFO_RSA_MODULUS,
+ &size_n, &n))
+ != TSS_SUCCESS) {
+ syslog(LOG_ERR, "Tspi_GetAttribUint32 failed: [%s]\n",
+ Trspi_Error_String(result));
+ rc = -EIO;
+ goto out;
+ }
+ rc = ecryptfs_tspi_generate_signature((char *)sig, n, size_n);
+out:
+ return rc;
+}
+
+static pthread_mutex_t encrypt_lock = PTHREAD_MUTEX_INITIALIZER;
+
+struct ecryptfs_tspi_connect_ticket;
+
+struct ecryptfs_tspi_connect_ticket {
+ struct ecryptfs_tspi_connect_ticket *next;
+#define ECRYPTFS_TSPI_TICKET_CTX_INITIALIZED 0x00000001
+ uint32_t flags;
+ pthread_mutex_t lock;
+ pthread_mutex_t wait;
+ TSS_HCONTEXT tspi_ctx;
+ uint32_t num_pending;
+};
+
+static pthread_mutex_t ecryptfs_ticket_list_lock = PTHREAD_MUTEX_INITIALIZER;
+
+static uint32_t ecryptfs_tspi_num_tickets_free;
+static uint32_t ecryptfs_tspi_num_tickets_used;
+static uint32_t ecryptfs_tspi_num_tickets_connected;
+
+static struct ecryptfs_tspi_connect_ticket *ptr_to_free_ticket_list_head = NULL;
+static struct ecryptfs_tspi_connect_ticket *ptr_to_used_ticket_list_head = NULL;
+
+static int
+ecryptfs_tspi_grab_ticket(struct ecryptfs_tspi_connect_ticket **ret_ticket)
+{
+ struct ecryptfs_tspi_connect_ticket *ticket;
+ int rc = 0;
+
+ (*ret_ticket) = NULL;
+ pthread_mutex_lock(&ecryptfs_ticket_list_lock);
+ ticket = ptr_to_free_ticket_list_head;
+ if (!ticket) {
+ struct ecryptfs_tspi_connect_ticket *tmp;
+
+ ticket = ptr_to_used_ticket_list_head;
+ pthread_mutex_lock(&ticket->lock);
+ tmp = ticket->next;
+ while (tmp) {
+ struct ecryptfs_tspi_connect_ticket *next;
+
+ pthread_mutex_lock(&tmp->lock);
+ next = tmp->next;
+ if (tmp->num_pending < ticket->num_pending) {
+ pthread_mutex_unlock(&ticket->lock);
+ ticket = tmp;
+ } else
+ pthread_mutex_unlock(&tmp->lock);
+ tmp = next;
+ }
+ ticket->num_pending++;
+ pthread_mutex_unlock(&ticket->lock);
+ } else {
+ while (ticket) {
+ struct ecryptfs_tspi_connect_ticket *next;
+
+ pthread_mutex_lock(&ticket->lock);
+ next = ticket->next;
+ if (ticket->flags
+ & ECRYPTFS_TSPI_TICKET_CTX_INITIALIZED) {
+ pthread_mutex_unlock(&ticket->lock);
+ break;
+ }
+ pthread_mutex_unlock(&ticket->lock);
+ ticket = next;
+ }
+ if (!ticket) {
+ TSS_RESULT result;
+
+ ticket = ptr_to_free_ticket_list_head;
+ pthread_mutex_lock(&ticket->lock);
+ if ((result = Tspi_Context_Create(&ticket->tspi_ctx))
+ != TSS_SUCCESS) {
+ syslog(LOG_ERR, "Tspi_Context_Create failed: "
+ "[%s]\n", Trspi_Error_String(result));
+ rc = -EIO;
+ pthread_mutex_unlock(&ticket->lock);
+ pthread_mutex_unlock(
+ &ecryptfs_ticket_list_lock);
+ goto out;
+ }
+ if ((result = Tspi_Context_Connect(ticket->tspi_ctx,
+ NULL))
+ != TSS_SUCCESS) {
+ syslog(LOG_ERR, "Tspi_Context_Connect "
+ "failed: [%s]\n",
+ Trspi_Error_String(result));
+ rc = -EIO;
+ pthread_mutex_unlock(&ticket->lock);
+ pthread_mutex_unlock(
+ &ecryptfs_ticket_list_lock);
+ goto out;
+ }
+ ticket->flags |= ECRYPTFS_TSPI_TICKET_CTX_INITIALIZED;
+ ecryptfs_tspi_num_tickets_connected++;
+ pthread_mutex_unlock(&ticket->lock);
+ }
+ pthread_mutex_lock(&ticket->lock);
+ ptr_to_free_ticket_list_head = ticket->next;
+ ticket->next = ptr_to_used_ticket_list_head;
+ ptr_to_used_ticket_list_head = ticket;
+ ecryptfs_tspi_num_tickets_free--;
+ ecryptfs_tspi_num_tickets_used++;
+ ticket->num_pending++;
+ pthread_mutex_unlock(&ticket->lock);
+ }
+ pthread_mutex_unlock(&ecryptfs_ticket_list_lock);
+ pthread_mutex_lock(&ticket->wait);
+ pthread_mutex_lock(&ticket->lock);
+ ticket->num_pending--;
+ pthread_mutex_unlock(&ticket->lock);
+ (*ret_ticket) = ticket;
+out:
+ return rc;
+}
+
+static int
+ecryptfs_tspi_release_ticket(struct ecryptfs_tspi_connect_ticket *ticket)
+{
+ int rc = 0;
+
+ pthread_mutex_lock(&ecryptfs_ticket_list_lock);
+ pthread_mutex_unlock(&ticket->wait);
+ ptr_to_used_ticket_list_head = ticket->next;
+ ticket->next = ptr_to_free_ticket_list_head;
+ ptr_to_free_ticket_list_head = ticket;
+ ecryptfs_tspi_num_tickets_free++;
+ ecryptfs_tspi_num_tickets_used--;
+ pthread_mutex_unlock(&ecryptfs_ticket_list_lock);
+ return rc;
+}
+
+static int
+ecryptfs_tspi_encrypt(char *to, size_t *to_size, char *from, size_t from_size,
+ unsigned char *blob, int blob_type)
+{
+ static TSS_HPOLICY h_srk_policy = 0;
+ static TSS_HKEY h_srk = 0;
+ TSS_RESULT result;
+ TSS_HKEY hKey;
+ TSS_HENCDATA h_encdata;
+ uint32_t encdata_size;
+ BYTE *encdata;
+ struct tspi_data tspi_data;
+ struct ecryptfs_tspi_connect_ticket *ticket;
+ int rc = 0;
+ BYTE wellknown[] = TSS_WELL_KNOWN_SECRET;
+
+ pthread_mutex_lock(&encrypt_lock);
+ (*to_size) = 0;
+ ecryptfs_tspi_deserialize(&tspi_data, blob);
+ DBG_print_hex((BYTE *)&tspi_data.uuid, sizeof(TSS_UUID));
+ rc = ecryptfs_tspi_grab_ticket(&ticket);
+ if (rc) {
+ syslog(LOG_ERR, "%s: Error attempting to get TSPI connection "
+ "ticket; rc = [%d]\n", __FUNCTION__, rc);
+ goto out;
+ }
+ if ((result = Tspi_Context_LoadKeyByUUID(ticket->tspi_ctx,
+ TSS_PS_TYPE_SYSTEM,
+ ecryptfs_tspi_srk_uuid,
+ &h_srk)) != TSS_SUCCESS) {
+ syslog(LOG_ERR, "Tspi_Context_LoadKeyByUUID failed: [%s]\n",
+ Trspi_Error_String(result));
+ rc = -EIO;
+ goto out;
+ }
+ if ((result = Tspi_GetPolicyObject(h_srk, TSS_POLICY_USAGE,
+ &h_srk_policy))
+ != TSS_SUCCESS) {
+ syslog(LOG_ERR, "Tspi_GetPolicyObject failed: [%s]\n",
+ Trspi_Error_String(result));
+ rc = -EIO;
+ goto out;
+ }
+ if ((result = Tspi_Policy_SetSecret(h_srk_policy,
+ TSS_SECRET_MODE_SHA1,
+ sizeof(wellknown), wellknown))
+ != TSS_SUCCESS) {
+ syslog(LOG_ERR, "Tspi_Policy_SetSecret failed: [%s]\n",
+ Trspi_Error_String(result));
+ rc = -EIO;
+ goto out;
+ }
+ if ((result = Tspi_Context_CreateObject(ticket->tspi_ctx,
+ TSS_OBJECT_TYPE_ENCDATA,
+ TSS_ENCDATA_SEAL, &h_encdata))
+ != TSS_SUCCESS) {
+ syslog(LOG_ERR, "Tspi_Context_CreateObject failed: [%s]\n",
+ Trspi_Error_String(result));
+ rc = -EIO;
+ goto out;
+ }
+ if ((result = Tspi_Context_LoadKeyByUUID(ticket->tspi_ctx,
+ TSS_PS_TYPE_USER,
+ tspi_data.uuid, &hKey))
+ != TSS_SUCCESS) {
+ syslog(LOG_ERR, "Tspi_Context_LoadKeyByUUID failed: [%s]\n",
+ Trspi_Error_String(result));
+ rc = -EIO;
+ goto out;
+ }
+ if ((result = Tspi_Data_Seal(h_encdata, hKey, from_size,
+ (unsigned char *)from, 0))
+ != TSS_SUCCESS) {
+ syslog(LOG_ERR, "Tspi_Data_Seal failed: [%s]\n",
+ Trspi_Error_String(result));
+ rc = -EIO;
+ goto out;
+ }
+ if ((result = Tspi_GetAttribData(h_encdata, TSS_TSPATTRIB_ENCDATA_BLOB,
+ TSS_TSPATTRIB_ENCDATABLOB_BLOB,
+ &encdata_size, &encdata))
+ != TSS_SUCCESS) {
+ syslog(LOG_ERR, "Tspi_GetAttribData failed: [%s]\n",
+ Trspi_Error_String(result));
+ rc = -EIO;
+ goto out;
+ }
+ (*to_size) = encdata_size;
+ if (to)
+ memcpy(to, encdata, (*to_size));
+ Tspi_Context_FreeMemory(ticket->tspi_ctx, encdata);
+out:
+ pthread_mutex_unlock(&encrypt_lock);
+ if (ticket)
+ ecryptfs_tspi_release_ticket(ticket);
+ return rc;
+}
+
+static pthread_mutex_t decrypt_lock = PTHREAD_MUTEX_INITIALIZER;
+
+static int
+ecryptfs_tspi_decrypt(char *to, size_t *to_size, char *from, size_t from_size,
+ unsigned char *blob, int blob_type)
+{
+ static TSS_HPOLICY h_srk_policy = 0;
+ static TSS_HKEY h_srk = 0;
+ static TSS_HENCDATA h_encdata;
+ uint32_t encdata_bytes;
+ BYTE *encdata;
+ struct tspi_data tspi_data;
+ struct key_mapper *walker, *new_mapper;
+ struct ecryptfs_tspi_connect_ticket *ticket;
+ TSS_RESULT result;
+ int rc = 0;
+ BYTE wellknown[] = TSS_WELL_KNOWN_SECRET;
+
+ pthread_mutex_lock(&decrypt_lock);
+ ecryptfs_tspi_deserialize(&tspi_data, blob);
+ rc = ecryptfs_tspi_grab_ticket(&ticket);
+ if (rc) {
+ syslog(LOG_ERR, "%s: Error attempting to get TSPI connection "
+ "ticket; rc = [%d]\n", __FUNCTION__, rc);
+ goto out;
+ }
+ if ((result = Tspi_Context_LoadKeyByUUID(ticket->tspi_ctx,
+ TSS_PS_TYPE_SYSTEM,
+ ecryptfs_tspi_srk_uuid,
+ &h_srk)) != TSS_SUCCESS) {
+ syslog(LOG_ERR, "Tspi_Context_LoadKeyByUUID failed: [%s]\n",
+ Trspi_Error_String(result));
+ rc = -EIO;
+ goto out;
+ }
+ if ((result = Tspi_GetPolicyObject(h_srk, TSS_POLICY_USAGE,
+ &h_srk_policy))
+ != TSS_SUCCESS) {
+ syslog(LOG_ERR, "Tspi_GetPolicyObject failed: [%s]\n",
+ Trspi_Error_String(result));
+ rc = -EIO;
+ goto out;
+ }
+ if ((result = Tspi_Policy_SetSecret(h_srk_policy,
+ TSS_SECRET_MODE_SHA1,
+ sizeof(wellknown), wellknown))
+ != TSS_SUCCESS) {
+ syslog(LOG_ERR, "Tspi_Policy_SetSecret failed: [%s]\n",
+ Trspi_Error_String(result));
+ rc = -EIO;
+ goto out;
+ }
+ if ((result = Tspi_Context_CreateObject(ticket->tspi_ctx,
+ TSS_OBJECT_TYPE_ENCDATA,
+ TSS_ENCDATA_SEAL, &h_encdata))
+ != TSS_SUCCESS) {
+ syslog(LOG_ERR, "Tspi_Context_CreateObject failed: [%s]\n",
+ Trspi_Error_String(result));
+ rc = -EIO;
+ goto out;
+ }
+ for (walker = mapper; walker; walker = walker->next)
+ if (!memcmp(&walker->uuid, &tspi_data.uuid, sizeof(TSS_UUID)))
+ break;
+ if (!walker) {
+ if ((new_mapper = calloc(1, sizeof(struct key_mapper)))
+ == NULL) {
+ syslog(LOG_ERR, "calloc failed: [%m]\n");
+ rc = -EIO;
+ goto out;
+ }
+ if ((result = Tspi_Context_LoadKeyByUUID(ticket->tspi_ctx,
+ TSS_PS_TYPE_USER,
+ tspi_data.uuid,
+ &new_mapper->hKey))
+ != TSS_SUCCESS) {
+ syslog(LOG_ERR,
+ "Tspi_Context_LoadKeyByUUID failed: [%s]\n",
+ Trspi_Error_String(result));
+ rc = -EIO;
+ goto out;
+ }
+ DBGSYSLOG("New key object: [0x%x]\n", new_mapper->hKey);
+ memcpy(&new_mapper->uuid, &tspi_data.uuid, sizeof(TSS_UUID));
+ new_mapper->next = mapper;
+ walker = mapper = new_mapper;
+ }
+ if ((result = Tspi_SetAttribData(h_encdata, TSS_TSPATTRIB_ENCDATA_BLOB,
+ TSS_TSPATTRIB_ENCDATABLOB_BLOB,
+ from_size, (BYTE *)from))
+ != TSS_SUCCESS) {
+ syslog(LOG_ERR, "Tspi_SetAttribData failed: [%s]\n",
+ Trspi_Error_String(result));
+ rc = -EIO;
+ goto out;
+ }
+ if ((result = Tspi_Data_Unseal(h_encdata, walker->hKey,
+ &encdata_bytes, &encdata))
+ != TSS_SUCCESS) {
+ syslog(LOG_ERR, "Tspi_Data_Unseal failed: [%s]\n",
+ Trspi_Error_String(result));
+ rc = -EIO;
+ goto out;
+ }
+ (*to_size) = encdata_bytes;
+ if (to)
+ memcpy(to, encdata, encdata_bytes);
+ Tspi_Context_FreeMemory(ticket->tspi_ctx, encdata);
+ rc = 0;
+out:
+ pthread_mutex_unlock(&decrypt_lock);
+ if (ticket)
+ ecryptfs_tspi_release_ticket(ticket);
+ return rc;
+}
+
+#define ECRYPTFS_KEY_MOD_PARAM_TSPI_UUID 1
+static struct key_mod_param tspi_params[] = {
+ {.id = ECRYPTFS_KEY_MOD_PARAM_TSPI_UUID,
+ .flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
+ .option = "tspi_uuid",
+ .description = "tspi_uuid",
+ .suggested_val = NULL,
+ .default_val = NULL,
+ .val = NULL},
+ {.id = 0,
+ .flags = 0,
+ .option = NULL,
+ .description = NULL,
+ .suggested_val = NULL,
+ .default_val = NULL,
+ .val = NULL}
+};
+
+static uint32_t tspi_num_params = 1;
+
+/**
+ * Convert user input string into TSS_UUID data type
+ */
+static void string_to_uuid(TSS_UUID *uuid, char *str)
+{
+ BYTE tmp[(sizeof(uint32_t) * 2 + 1)];
+ uint32_t i, l;
+
+ tmp[sizeof(uint32_t) * 2] = '\0';
+ for (i = 0; i < (sizeof(TSS_UUID) * 2);
+ i += (sizeof(uint32_t) * 2)) {
+ memcpy(tmp, &str[i], sizeof(uint32_t) * 2);
+ l = strtoul((char *)tmp, NULL, 16);
+ l = htonl(l);
+ memcpy(&((BYTE *)uuid)[i/2], &l, sizeof(uint32_t));
+ }
+}
+
+static int ecryptfs_tspi_init(char **alias)
+{
+ int i;
+
+ int rc = 0;
+
+ if (asprintf(alias, "tspi") == -1) {
+ syslog(LOG_ERR, "Out of memory\n");
+ rc = -ENOMEM;
+ goto out;
+ }
+ ecryptfs_tspi_num_tickets_free = 0;
+ ecryptfs_tspi_num_tickets_used = 0;
+ ecryptfs_tspi_num_tickets_connected = 0;
+ for (i = 0; i < ECRYPTFS_TSPI_DEFAULT_MAX_NUM_CONNECTIONS; i++) {
+ struct ecryptfs_tspi_connect_ticket *ticket;
+
+ ticket = malloc(sizeof(struct ecryptfs_tspi_connect_ticket));
+ if (!ticket) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ pthread_mutex_init(&ticket->lock, NULL);
+ ticket->flags = 0;
+ ticket->tspi_ctx = 0;
+ ticket->num_pending = 0;
+ pthread_mutex_lock(&ecryptfs_ticket_list_lock);
+ ticket->next = ptr_to_free_ticket_list_head;
+ ptr_to_free_ticket_list_head = ticket;
+ ecryptfs_tspi_num_tickets_free++;
+ pthread_mutex_unlock(&ecryptfs_ticket_list_lock);
+ }
+out:
+ return rc;
+}
+
+static int
+ecryptfs_tspi_get_params(struct key_mod_param **params, uint32_t *num_params)
+{
+ (*params) = tspi_params;
+ (*num_params) = tspi_num_params;
+ return 0;
+}
+
+static int ecryptfs_tspi_serialize(unsigned char *blob, size_t *blob_size,
+ struct tspi_data *tspi_data)
+{
+ int rc = 0;
+
+ (*blob_size) = sizeof(TSS_UUID);
+ if (blob == NULL)
+ goto out;
+ memcpy(blob, &tspi_data->uuid, sizeof(TSS_UUID));
+out:
+ return rc;
+}
+
+static int
+ecryptfs_tspi_init_from_param_vals(struct tspi_data *tspi_data,
+ struct key_mod_param_val *param_vals,
+ uint32_t num_param_vals)
+{
+ int uuid_set = 0;
+ int i;
+ int rc = 0;
+
+ if (num_param_vals != tspi_num_params) {
+ rc = -EINVAL;
+ syslog(LOG_ERR, "Require [%d] param vals; got [%d]\n",
+ tspi_num_params, num_param_vals);
+ goto out;
+ }
+ for (i = 0; i < num_param_vals; i++)
+ tspi_params[i].val = &param_vals[i];
+ memset(tspi_data, 0, sizeof(struct tspi_data));
+ for (i = 0; i < num_param_vals; i++)
+ if (strcmp(tspi_params[i].option, "tspi_uuid") == 0) {
+ string_to_uuid(&tspi_data->uuid,
+ tspi_params[i].val->val);
+ uuid_set = 1;
+ }
+ if (!uuid_set) {
+ rc = -EINVAL;
+ syslog(LOG_ERR, "uuid parameter must be set\n");
+ goto out;
+ }
+out:
+ return rc;
+}
+
+static int ecryptfs_tspi_get_blob(unsigned char *blob, size_t *blob_size,
+ struct key_mod_param_val *param_vals,
+ uint32_t num_param_vals)
+{
+ struct tspi_data tspi_data;
+ int rc = 0;
+
+ if ((rc = ecryptfs_tspi_init_from_param_vals(&tspi_data, param_vals,
+ num_param_vals))) {
+ syslog(LOG_ERR, "Error parsing parameter values; rc = [%d]\n",
+ rc);
+ goto out;
+ }
+ if (blob == NULL) {
+ if ((rc = ecryptfs_tspi_serialize(NULL, blob_size,
+ &tspi_data))) {
+ syslog(LOG_ERR, "Error serializing tspi; rc = [%d]\n",
+ rc);
+ goto out;
+ }
+ goto out;
+ }
+ if ((rc = ecryptfs_tspi_serialize(blob, blob_size, &tspi_data))) {
+ syslog(LOG_ERR, "Error serializing tspi; rc = [%d]\n", rc);
+ goto out;
+ }
+out:
+ return rc;
+}
+
+static int ecryptfs_tspi_destroy(unsigned char *blob)
+{
+ return 0;
+}
+
+#define ECRYPTFS_TSPI_MAX_WAIT_FOR_END 5
+
+static int ecryptfs_tspi_finalize(void)
+{
+ uint32_t retries = 0;
+ struct ecryptfs_tspi_connect_ticket *ticket;
+ int rc = 0;
+
+ while (ptr_to_used_ticket_list_head
+ && (retries < ECRYPTFS_TSPI_MAX_WAIT_FOR_END)) {
+ sleep(1);
+ retries++;
+ }
+ if (retries == ECRYPTFS_TSPI_MAX_WAIT_FOR_END) {
+ syslog(LOG_ERR, "%s: Stale TSPI tickets in used list; cannot "
+ "shut down cleanly\n", __FUNCTION__);
+ rc = -EBUSY;
+ goto out;
+ }
+ ticket = ptr_to_free_ticket_list_head;
+ while (ticket) {
+ struct ecryptfs_tspi_connect_ticket *next;
+
+ pthread_mutex_lock(&ticket->lock);
+ next = ticket->next;
+ if (ticket->flags
+ & ECRYPTFS_TSPI_TICKET_CTX_INITIALIZED) {
+ Tspi_Context_Close(ticket->tspi_ctx);
+ ticket->flags &= ~ECRYPTFS_TSPI_TICKET_CTX_INITIALIZED;
+ }
+ pthread_mutex_unlock(&ticket->lock);
+ ticket = next;
+ }
+out:
+ return rc;
+}
+
+static struct ecryptfs_key_mod_ops ecryptfs_tspi_ops = {
+ &ecryptfs_tspi_init,
+ NULL,
+ NULL,
+ &ecryptfs_tspi_get_params,
+ NULL,
+ &ecryptfs_tspi_get_blob,
+ NULL,
+ &ecryptfs_tspi_get_key_sig,
+ NULL,
+ &ecryptfs_tspi_encrypt,
+ &ecryptfs_tspi_decrypt,
+ &ecryptfs_tspi_destroy,
+ &ecryptfs_tspi_finalize
+};
+
+struct ecryptfs_key_mod_ops *get_key_mod_ops(void)
+{
+ return &ecryptfs_tspi_ops;
+}
diff --git a/src/libecryptfs-swig/Makefile.am b/src/libecryptfs-swig/Makefile.am
new file mode 100644
index 0000000..5f41eb3
--- /dev/null
+++ b/src/libecryptfs-swig/Makefile.am
@@ -0,0 +1,16 @@
+if BUILD_PYWRAP
+
+BUILT_SOURCES = $(srcdir)/libecryptfs_wrap.c
+SWIG_SOURCES = libecryptfs.i
+
+pkgpython_PYTHON = libecryptfs.py
+pkgpyexec_LTLIBRARIES = _libecryptfs.la
+_libecryptfs_la_SOURCES = $(srcdir)/libecryptfs_wrap.c $(SWIG_SOURCES)
+_libecryptfs_la_CFLAGS = $(SWIG_PYTHON_CPPFLAGS) -I$(top_srcdir)/src/include
+_libecryptfs_la_LDFLAGS = -module
+_libecryptfs_la_LIBADD = ../libecryptfs/.libs/libecryptfs.la
+
+$(srcdir)/libecryptfs_wrap.c : $(SWIG_SOURCES)
+ $(SWIG) $(SWIG_PYTHON_OPT) -I$(top_srcdir)/src/include -o $@ $<
+
+endif
diff --git a/src/libecryptfs-swig/Makefile.in b/src/libecryptfs-swig/Makefile.in
new file mode 100644
index 0000000..4996b86
--- /dev/null
+++ b/src/libecryptfs-swig/Makefile.in
@@ -0,0 +1,804 @@
+# 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@
+subdir = src/libecryptfs-swig
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/depcomp $(am__pkgpython_PYTHON_DIST) \
+ $(top_srcdir)/py-compile
+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 =
+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; }; \
+ }
+am__installdirs = "$(DESTDIR)$(pkgpyexecdir)" \
+ "$(DESTDIR)$(pkgpythondir)"
+LTLIBRARIES = $(pkgpyexec_LTLIBRARIES)
+@BUILD_PYWRAP_TRUE@_libecryptfs_la_DEPENDENCIES = \
+@BUILD_PYWRAP_TRUE@ ../libecryptfs/.libs/libecryptfs.la
+am___libecryptfs_la_SOURCES_DIST = $(srcdir)/libecryptfs_wrap.c \
+ libecryptfs.i
+am__objects_1 =
+@BUILD_PYWRAP_TRUE@am__libecryptfs_la_OBJECTS = \
+@BUILD_PYWRAP_TRUE@ _libecryptfs_la-libecryptfs_wrap.lo \
+@BUILD_PYWRAP_TRUE@ $(am__objects_1)
+_libecryptfs_la_OBJECTS = $(am__libecryptfs_la_OBJECTS)
+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 =
+_libecryptfs_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(_libecryptfs_la_CFLAGS) $(CFLAGS) $(_libecryptfs_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@BUILD_PYWRAP_TRUE@am__libecryptfs_la_rpath = -rpath $(pkgpyexecdir)
+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 = $(_libecryptfs_la_SOURCES)
+DIST_SOURCES = $(am___libecryptfs_la_SOURCES_DIST)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__pkgpython_PYTHON_DIST = libecryptfs.py
+am__py_compile = PYTHON=$(PYTHON) $(SHELL) $(py_compile)
+am__pep3147_tweak = \
+ sed -e 's|\.py$$||' -e 's|[^/]*$$|__pycache__/&.*.py|'
+py_compile = $(top_srcdir)/py-compile
+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
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+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@
+@BUILD_PYWRAP_TRUE@BUILT_SOURCES = $(srcdir)/libecryptfs_wrap.c
+@BUILD_PYWRAP_TRUE@SWIG_SOURCES = libecryptfs.i
+@BUILD_PYWRAP_TRUE@pkgpython_PYTHON = libecryptfs.py
+@BUILD_PYWRAP_TRUE@pkgpyexec_LTLIBRARIES = _libecryptfs.la
+@BUILD_PYWRAP_TRUE@_libecryptfs_la_SOURCES = $(srcdir)/libecryptfs_wrap.c $(SWIG_SOURCES)
+@BUILD_PYWRAP_TRUE@_libecryptfs_la_CFLAGS = $(SWIG_PYTHON_CPPFLAGS) -I$(top_srcdir)/src/include
+@BUILD_PYWRAP_TRUE@_libecryptfs_la_LDFLAGS = -module
+@BUILD_PYWRAP_TRUE@_libecryptfs_la_LIBADD = ../libecryptfs/.libs/libecryptfs.la
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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/libecryptfs-swig/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/libecryptfs-swig/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-pkgpyexecLTLIBRARIES: $(pkgpyexec_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(pkgpyexec_LTLIBRARIES)'; test -n "$(pkgpyexecdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgpyexecdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgpyexecdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pkgpyexecdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pkgpyexecdir)"; \
+ }
+
+uninstall-pkgpyexecLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgpyexec_LTLIBRARIES)'; test -n "$(pkgpyexecdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pkgpyexecdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pkgpyexecdir)/$$f"; \
+ done
+
+clean-pkgpyexecLTLIBRARIES:
+ -test -z "$(pkgpyexec_LTLIBRARIES)" || rm -f $(pkgpyexec_LTLIBRARIES)
+ @list='$(pkgpyexec_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+_libecryptfs.la: $(_libecryptfs_la_OBJECTS) $(_libecryptfs_la_DEPENDENCIES) $(EXTRA__libecryptfs_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(_libecryptfs_la_LINK) $(am__libecryptfs_la_rpath) $(_libecryptfs_la_OBJECTS) $(_libecryptfs_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_libecryptfs_la-libecryptfs_wrap.Plo@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 $@ $<
+
+_libecryptfs_la-libecryptfs_wrap.lo: $(srcdir)/libecryptfs_wrap.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_libecryptfs_la_CFLAGS) $(CFLAGS) -MT _libecryptfs_la-libecryptfs_wrap.lo -MD -MP -MF $(DEPDIR)/_libecryptfs_la-libecryptfs_wrap.Tpo -c -o _libecryptfs_la-libecryptfs_wrap.lo `test -f '$(srcdir)/libecryptfs_wrap.c' || echo '$(srcdir)/'`$(srcdir)/libecryptfs_wrap.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/_libecryptfs_la-libecryptfs_wrap.Tpo $(DEPDIR)/_libecryptfs_la-libecryptfs_wrap.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(srcdir)/libecryptfs_wrap.c' object='_libecryptfs_la-libecryptfs_wrap.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(_libecryptfs_la_CFLAGS) $(CFLAGS) -c -o _libecryptfs_la-libecryptfs_wrap.lo `test -f '$(srcdir)/libecryptfs_wrap.c' || echo '$(srcdir)/'`$(srcdir)/libecryptfs_wrap.c
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-pkgpythonPYTHON: $(pkgpython_PYTHON)
+ @$(NORMAL_INSTALL)
+ @list='$(pkgpython_PYTHON)'; dlist=; list2=; test -n "$(pkgpythondir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgpythondir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgpythondir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \
+ if test -f $$b$$p; then \
+ $(am__strip_dir) \
+ dlist="$$dlist $$f"; \
+ list2="$$list2 $$b$$p"; \
+ else :; fi; \
+ done; \
+ for file in $$list2; do echo $$file; done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgpythondir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgpythondir)" || exit $$?; \
+ done || exit $$?; \
+ if test -n "$$dlist"; then \
+ $(am__py_compile) --destdir "$(DESTDIR)" \
+ --basedir "$(pkgpythondir)" $$dlist; \
+ else :; fi
+
+uninstall-pkgpythonPYTHON:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgpython_PYTHON)'; test -n "$(pkgpythondir)" || list=; \
+ py_files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$py_files" || exit 0; \
+ dir='$(DESTDIR)$(pkgpythondir)'; \
+ pyc_files=`echo "$$py_files" | sed 's|$$|c|'`; \
+ pyo_files=`echo "$$py_files" | sed 's|$$|o|'`; \
+ py_files_pep3147=`echo "$$py_files" | $(am__pep3147_tweak)`; \
+ echo "$$py_files_pep3147";\
+ pyc_files_pep3147=`echo "$$py_files_pep3147" | sed 's|$$|c|'`; \
+ pyo_files_pep3147=`echo "$$py_files_pep3147" | sed 's|$$|o|'`; \
+ st=0; \
+ for files in \
+ "$$py_files" \
+ "$$pyc_files" \
+ "$$pyo_files" \
+ "$$pyc_files_pep3147" \
+ "$$pyo_files_pep3147" \
+ ; do \
+ $(am__uninstall_files_from_dir) || st=$$?; \
+ done; \
+ exit $$st
+
+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
+
+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
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(pkgpyexecdir)" "$(DESTDIR)$(pkgpythondir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) 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:
+
+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 "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pkgpyexecLTLIBRARIES \
+ 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-pkgpythonPYTHON
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-pkgpyexecLTLIBRARIES
+
+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-pkgpyexecLTLIBRARIES uninstall-pkgpythonPYTHON
+
+.MAKE: all check install install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pkgpyexecLTLIBRARIES 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-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-pkgpyexecLTLIBRARIES install-pkgpythonPYTHON \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am \
+ uninstall-pkgpyexecLTLIBRARIES uninstall-pkgpythonPYTHON
+
+
+@BUILD_PYWRAP_TRUE@$(srcdir)/libecryptfs_wrap.c : $(SWIG_SOURCES)
+@BUILD_PYWRAP_TRUE@ $(SWIG) $(SWIG_PYTHON_OPT) -I$(top_srcdir)/src/include -o $@ $<
+
+# 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/libecryptfs-swig/libecryptfs.i b/src/libecryptfs-swig/libecryptfs.i
new file mode 100644
index 0000000..e7fd3d3
--- /dev/null
+++ b/src/libecryptfs-swig/libecryptfs.i
@@ -0,0 +1,17 @@
+%module libecryptfs
+%{
+#include "../include/ecryptfs.h"
+extern binary_data ecryptfs_passphrase_blob(char *salt, char *passphrase);
+extern binary_data ecryptfs_passphrase_sig_from_blob(char *blob);
+extern int ecryptfs_add_blob_to_keyring(char *blob, char *sig);
+%}
+
+#include "../include/ecryptfs.h"
+
+%typemap(out) binary_data {
+ $result = PyString_FromStringAndSize((char *)($1.data),$1.size);
+}
+
+extern binary_data ecryptfs_passphrase_blob(char *salt, char *passphrase);
+extern binary_data ecryptfs_passphrase_sig_from_blob(char *blob);
+extern int ecryptfs_add_blob_to_keyring(char *blob, char *sig);
diff --git a/src/libecryptfs-swig/libecryptfs.py b/src/libecryptfs-swig/libecryptfs.py
new file mode 100644
index 0000000..d21858e
--- /dev/null
+++ b/src/libecryptfs-swig/libecryptfs.py
@@ -0,0 +1,55 @@
+# This file was automatically generated by SWIG (http://www.swig.org).
+# Version 1.3.36
+#
+# Don't modify this file, modify the SWIG interface instead.
+# This file is compatible with both classic and new-style classes.
+
+import _libecryptfs
+import new
+new_instancemethod = new.instancemethod
+try:
+ _swig_property = property
+except NameError:
+ pass # Python < 2.2 doesn't have 'property'.
+def _swig_setattr_nondynamic(self,class_type,name,value,static=1):
+ if (name == "thisown"): return self.this.own(value)
+ if (name == "this"):
+ if type(value).__name__ == 'PySwigObject':
+ self.__dict__[name] = value
+ return
+ method = class_type.__swig_setmethods__.get(name,None)
+ if method: return method(self,value)
+ if (not static) or hasattr(self,name):
+ self.__dict__[name] = value
+ else:
+ raise AttributeError("You cannot add attributes to %s" % self)
+
+def _swig_setattr(self,class_type,name,value):
+ return _swig_setattr_nondynamic(self,class_type,name,value,0)
+
+def _swig_getattr(self,class_type,name):
+ if (name == "thisown"): return self.this.own()
+ method = class_type.__swig_getmethods__.get(name,None)
+ if method: return method(self)
+ raise AttributeError,name
+
+def _swig_repr(self):
+ try: strthis = "proxy of " + self.this.__repr__()
+ except: strthis = ""
+ return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
+
+import types
+try:
+ _object = types.ObjectType
+ _newclass = 1
+except AttributeError:
+ class _object : pass
+ _newclass = 0
+del types
+
+
+ecryptfs_passphrase_blob = _libecryptfs.ecryptfs_passphrase_blob
+ecryptfs_passphrase_sig_from_blob = _libecryptfs.ecryptfs_passphrase_sig_from_blob
+ecryptfs_add_blob_to_keyring = _libecryptfs.ecryptfs_add_blob_to_keyring
+
+
diff --git a/src/libecryptfs-swig/libecryptfs_wrap.c b/src/libecryptfs-swig/libecryptfs_wrap.c
new file mode 100644
index 0000000..7a25a9e
--- /dev/null
+++ b/src/libecryptfs-swig/libecryptfs_wrap.c
@@ -0,0 +1,3251 @@
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 1.3.36
+ *
+ * This file is not intended to be easily readable and contains a number of
+ * coding conventions designed to improve portability and efficiency. Do not make
+ * changes to this file unless you know what you are doing--modify the SWIG
+ * interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+#define SWIGPYTHON
+#define SWIG_PYTHON_DIRECTOR_NO_VTABLE
+/* -----------------------------------------------------------------------------
+ * This section contains generic SWIG labels for method/variable
+ * declarations/attributes, and other compiler dependent labels.
+ * ----------------------------------------------------------------------------- */
+
+/* template workaround for compilers that cannot correctly implement the C++ standard */
+#ifndef SWIGTEMPLATEDISAMBIGUATOR
+# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560)
+# define SWIGTEMPLATEDISAMBIGUATOR template
+# elif defined(__HP_aCC)
+/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */
+/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */
+# define SWIGTEMPLATEDISAMBIGUATOR template
+# else
+# define SWIGTEMPLATEDISAMBIGUATOR
+# endif
+#endif
+
+/* inline attribute */
+#ifndef SWIGINLINE
+# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__))
+# define SWIGINLINE inline
+# else
+# define SWIGINLINE
+# endif
+#endif
+
+/* attribute recognised by some compilers to avoid 'unused' warnings */
+#ifndef SWIGUNUSED
+# if defined(__GNUC__)
+# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+# define SWIGUNUSED __attribute__ ((__unused__))
+# else
+# define SWIGUNUSED
+# endif
+# elif defined(__ICC)
+# define SWIGUNUSED __attribute__ ((__unused__))
+# else
+# define SWIGUNUSED
+# endif
+#endif
+
+#ifndef SWIG_MSC_UNSUPPRESS_4505
+# if defined(_MSC_VER)
+# pragma warning(disable : 4505) /* unreferenced local function has been removed */
+# endif
+#endif
+
+#ifndef SWIGUNUSEDPARM
+# ifdef __cplusplus
+# define SWIGUNUSEDPARM(p)
+# else
+# define SWIGUNUSEDPARM(p) p SWIGUNUSED
+# endif
+#endif
+
+/* internal SWIG method */
+#ifndef SWIGINTERN
+# define SWIGINTERN static SWIGUNUSED
+#endif
+
+/* internal inline SWIG method */
+#ifndef SWIGINTERNINLINE
+# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE
+#endif
+
+/* exporting methods */
+#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+# ifndef GCC_HASCLASSVISIBILITY
+# define GCC_HASCLASSVISIBILITY
+# endif
+#endif
+
+#ifndef SWIGEXPORT
+# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+# if defined(STATIC_LINKED)
+# define SWIGEXPORT
+# else
+# define SWIGEXPORT __declspec(dllexport)
+# endif
+# else
+# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY)
+# define SWIGEXPORT __attribute__ ((visibility("default")))
+# else
+# define SWIGEXPORT
+# endif
+# endif
+#endif
+
+/* calling conventions for Windows */
+#ifndef SWIGSTDCALL
+# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+# define SWIGSTDCALL __stdcall
+# else
+# define SWIGSTDCALL
+# endif
+#endif
+
+/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
+#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
+# define _CRT_SECURE_NO_DEPRECATE
+#endif
+
+/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */
+#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE)
+# define _SCL_SECURE_NO_DEPRECATE
+#endif
+
+
+
+/* Python.h has to appear first */
+#include <Python.h>
+
+/* -----------------------------------------------------------------------------
+ * swigrun.swg
+ *
+ * This file contains generic CAPI SWIG runtime support for pointer
+ * type checking.
+ * ----------------------------------------------------------------------------- */
+
+/* This should only be incremented when either the layout of swig_type_info changes,
+ or for whatever reason, the runtime changes incompatibly */
+#define SWIG_RUNTIME_VERSION "4"
+
+/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */
+#ifdef SWIG_TYPE_TABLE
+# define SWIG_QUOTE_STRING(x) #x
+# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x)
+# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE)
+#else
+# define SWIG_TYPE_TABLE_NAME
+#endif
+
+/*
+ You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for
+ creating a static or dynamic library from the swig runtime code.
+ In 99.9% of the cases, swig just needs to declare them as 'static'.
+
+ But only do this if is strictly necessary, ie, if you have problems
+ with your compiler or so.
+*/
+
+#ifndef SWIGRUNTIME
+# define SWIGRUNTIME SWIGINTERN
+#endif
+
+#ifndef SWIGRUNTIMEINLINE
+# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE
+#endif
+
+/* Generic buffer size */
+#ifndef SWIG_BUFFER_SIZE
+# define SWIG_BUFFER_SIZE 1024
+#endif
+
+/* Flags for pointer conversions */
+#define SWIG_POINTER_DISOWN 0x1
+#define SWIG_CAST_NEW_MEMORY 0x2
+
+/* Flags for new pointer objects */
+#define SWIG_POINTER_OWN 0x1
+
+
+/*
+ Flags/methods for returning states.
+
+ The swig conversion methods, as ConvertPtr, return and integer
+ that tells if the conversion was successful or not. And if not,
+ an error code can be returned (see swigerrors.swg for the codes).
+
+ Use the following macros/flags to set or process the returning
+ states.
+
+ In old swig versions, you usually write code as:
+
+ if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) {
+ // success code
+ } else {
+ //fail code
+ }
+
+ Now you can be more explicit as:
+
+ int res = SWIG_ConvertPtr(obj,vptr,ty.flags);
+ if (SWIG_IsOK(res)) {
+ // success code
+ } else {
+ // fail code
+ }
+
+ that seems to be the same, but now you can also do
+
+ Type *ptr;
+ int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags);
+ if (SWIG_IsOK(res)) {
+ // success code
+ if (SWIG_IsNewObj(res) {
+ ...
+ delete *ptr;
+ } else {
+ ...
+ }
+ } else {
+ // fail code
+ }
+
+ I.e., now SWIG_ConvertPtr can return new objects and you can
+ identify the case and take care of the deallocation. Of course that
+ requires also to SWIG_ConvertPtr to return new result values, as
+
+ int SWIG_ConvertPtr(obj, ptr,...) {
+ if (<obj is ok>) {
+ if (<need new object>) {
+ *ptr = <ptr to new allocated object>;
+ return SWIG_NEWOBJ;
+ } else {
+ *ptr = <ptr to old object>;
+ return SWIG_OLDOBJ;
+ }
+ } else {
+ return SWIG_BADOBJ;
+ }
+ }
+
+ Of course, returning the plain '0(success)/-1(fail)' still works, but you can be
+ more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the
+ swig errors code.
+
+ Finally, if the SWIG_CASTRANK_MODE is enabled, the result code
+ allows to return the 'cast rank', for example, if you have this
+
+ int food(double)
+ int fooi(int);
+
+ and you call
+
+ food(1) // cast rank '1' (1 -> 1.0)
+ fooi(1) // cast rank '0'
+
+ just use the SWIG_AddCast()/SWIG_CheckState()
+
+
+ */
+#define SWIG_OK (0)
+#define SWIG_ERROR (-1)
+#define SWIG_IsOK(r) (r >= 0)
+#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError)
+
+/* The CastRankLimit says how many bits are used for the cast rank */
+#define SWIG_CASTRANKLIMIT (1 << 8)
+/* The NewMask denotes the object was created (using new/malloc) */
+#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1)
+/* The TmpMask is for in/out typemaps that use temporal objects */
+#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1)
+/* Simple returning values */
+#define SWIG_BADOBJ (SWIG_ERROR)
+#define SWIG_OLDOBJ (SWIG_OK)
+#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK)
+#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK)
+/* Check, add and del mask methods */
+#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r)
+#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r)
+#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK))
+#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r)
+#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r)
+#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK))
+
+
+/* Cast-Rank Mode */
+#if defined(SWIG_CASTRANK_MODE)
+# ifndef SWIG_TypeRank
+# define SWIG_TypeRank unsigned long
+# endif
+# ifndef SWIG_MAXCASTRANK /* Default cast allowed */
+# define SWIG_MAXCASTRANK (2)
+# endif
+# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1)
+# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK)
+SWIGINTERNINLINE int SWIG_AddCast(int r) {
+ return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r;
+}
+SWIGINTERNINLINE int SWIG_CheckState(int r) {
+ return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0;
+}
+#else /* no cast-rank mode */
+# define SWIG_AddCast
+# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0)
+#endif
+
+
+
+
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void *(*swig_converter_func)(void *, int *);
+typedef struct swig_type_info *(*swig_dycast_func)(void **);
+
+/* Structure to store information on one type */
+typedef struct swig_type_info {
+ const char *name; /* mangled name of this type */
+ const char *str; /* human readable name of this type */
+ swig_dycast_func dcast; /* dynamic cast function down a hierarchy */
+ struct swig_cast_info *cast; /* linked list of types that can cast into this type */
+ void *clientdata; /* language specific type data */
+ int owndata; /* flag if the structure owns the clientdata */
+} swig_type_info;
+
+/* Structure to store a type and conversion function used for casting */
+typedef struct swig_cast_info {
+ swig_type_info *type; /* pointer to type that is equivalent to this type */
+ swig_converter_func converter; /* function to cast the void pointers */
+ struct swig_cast_info *next; /* pointer to next cast in linked list */
+ struct swig_cast_info *prev; /* pointer to the previous cast */
+} swig_cast_info;
+
+/* Structure used to store module information
+ * Each module generates one structure like this, and the runtime collects
+ * all of these structures and stores them in a circularly linked list.*/
+typedef struct swig_module_info {
+ swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */
+ size_t size; /* Number of types in this module */
+ struct swig_module_info *next; /* Pointer to next element in circularly linked list */
+ swig_type_info **type_initial; /* Array of initially generated type structures */
+ swig_cast_info **cast_initial; /* Array of initially generated casting structures */
+ void *clientdata; /* Language specific module data */
+} swig_module_info;
+
+/*
+ Compare two type names skipping the space characters, therefore
+ "char*" == "char *" and "Class<int>" == "Class<int >", etc.
+
+ Return 0 when the two name types are equivalent, as in
+ strncmp, but skipping ' '.
+*/
+SWIGRUNTIME int
+SWIG_TypeNameComp(const char *f1, const char *l1,
+ const char *f2, const char *l2) {
+ for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) {
+ while ((*f1 == ' ') && (f1 != l1)) ++f1;
+ while ((*f2 == ' ') && (f2 != l2)) ++f2;
+ if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1;
+ }
+ return (int)((l1 - f1) - (l2 - f2));
+}
+
+/*
+ Check type equivalence in a name list like <name1>|<name2>|...
+ Return 0 if not equal, 1 if equal
+*/
+SWIGRUNTIME int
+SWIG_TypeEquiv(const char *nb, const char *tb) {
+ int equiv = 0;
+ const char* te = tb + strlen(tb);
+ const char* ne = nb;
+ while (!equiv && *ne) {
+ for (nb = ne; *ne; ++ne) {
+ if (*ne == '|') break;
+ }
+ equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0;
+ if (*ne) ++ne;
+ }
+ return equiv;
+}
+
+/*
+ Check type equivalence in a name list like <name1>|<name2>|...
+ Return 0 if equal, -1 if nb < tb, 1 if nb > tb
+*/
+SWIGRUNTIME int
+SWIG_TypeCompare(const char *nb, const char *tb) {
+ int equiv = 0;
+ const char* te = tb + strlen(tb);
+ const char* ne = nb;
+ while (!equiv && *ne) {
+ for (nb = ne; *ne; ++ne) {
+ if (*ne == '|') break;
+ }
+ equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0;
+ if (*ne) ++ne;
+ }
+ return equiv;
+}
+
+
+/* think of this as a c++ template<> or a scheme macro */
+#define SWIG_TypeCheck_Template(comparison, ty) \
+ if (ty) { \
+ swig_cast_info *iter = ty->cast; \
+ while (iter) { \
+ if (comparison) { \
+ if (iter == ty->cast) return iter; \
+ /* Move iter to the top of the linked list */ \
+ iter->prev->next = iter->next; \
+ if (iter->next) \
+ iter->next->prev = iter->prev; \
+ iter->next = ty->cast; \
+ iter->prev = 0; \
+ if (ty->cast) ty->cast->prev = iter; \
+ ty->cast = iter; \
+ return iter; \
+ } \
+ iter = iter->next; \
+ } \
+ } \
+ return 0
+
+/*
+ Check the typename
+*/
+SWIGRUNTIME swig_cast_info *
+SWIG_TypeCheck(const char *c, swig_type_info *ty) {
+ SWIG_TypeCheck_Template(strcmp(iter->type->name, c) == 0, ty);
+}
+
+/* Same as previous function, except strcmp is replaced with a pointer comparison */
+SWIGRUNTIME swig_cast_info *
+SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) {
+ SWIG_TypeCheck_Template(iter->type == from, into);
+}
+
+/*
+ Cast a pointer up an inheritance hierarchy
+*/
+SWIGRUNTIMEINLINE void *
+SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) {
+ return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory);
+}
+
+/*
+ Dynamic pointer casting. Down an inheritance hierarchy
+*/
+SWIGRUNTIME swig_type_info *
+SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) {
+ swig_type_info *lastty = ty;
+ if (!ty || !ty->dcast) return ty;
+ while (ty && (ty->dcast)) {
+ ty = (*ty->dcast)(ptr);
+ if (ty) lastty = ty;
+ }
+ return lastty;
+}
+
+/*
+ Return the name associated with this type
+*/
+SWIGRUNTIMEINLINE const char *
+SWIG_TypeName(const swig_type_info *ty) {
+ return ty->name;
+}
+
+/*
+ Return the pretty name associated with this type,
+ that is an unmangled type name in a form presentable to the user.
+*/
+SWIGRUNTIME const char *
+SWIG_TypePrettyName(const swig_type_info *type) {
+ /* The "str" field contains the equivalent pretty names of the
+ type, separated by vertical-bar characters. We choose
+ to print the last name, as it is often (?) the most
+ specific. */
+ if (!type) return NULL;
+ if (type->str != NULL) {
+ const char *last_name = type->str;
+ const char *s;
+ for (s = type->str; *s; s++)
+ if (*s == '|') last_name = s+1;
+ return last_name;
+ }
+ else
+ return type->name;
+}
+
+/*
+ Set the clientdata field for a type
+*/
+SWIGRUNTIME void
+SWIG_TypeClientData(swig_type_info *ti, void *clientdata) {
+ swig_cast_info *cast = ti->cast;
+ /* if (ti->clientdata == clientdata) return; */
+ ti->clientdata = clientdata;
+
+ while (cast) {
+ if (!cast->converter) {
+ swig_type_info *tc = cast->type;
+ if (!tc->clientdata) {
+ SWIG_TypeClientData(tc, clientdata);
+ }
+ }
+ cast = cast->next;
+ }
+}
+SWIGRUNTIME void
+SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) {
+ SWIG_TypeClientData(ti, clientdata);
+ ti->owndata = 1;
+}
+
+/*
+ Search for a swig_type_info structure only by mangled name
+ Search is a O(log #types)
+
+ We start searching at module start, and finish searching when start == end.
+ Note: if start == end at the beginning of the function, we go all the way around
+ the circular list.
+*/
+SWIGRUNTIME swig_type_info *
+SWIG_MangledTypeQueryModule(swig_module_info *start,
+ swig_module_info *end,
+ const char *name) {
+ swig_module_info *iter = start;
+ do {
+ if (iter->size) {
+ register size_t l = 0;
+ register size_t r = iter->size - 1;
+ do {
+ /* since l+r >= 0, we can (>> 1) instead (/ 2) */
+ register size_t i = (l + r) >> 1;
+ const char *iname = iter->types[i]->name;
+ if (iname) {
+ register int compare = strcmp(name, iname);
+ if (compare == 0) {
+ return iter->types[i];
+ } else if (compare < 0) {
+ if (i) {
+ r = i - 1;
+ } else {
+ break;
+ }
+ } else if (compare > 0) {
+ l = i + 1;
+ }
+ } else {
+ break; /* should never happen */
+ }
+ } while (l <= r);
+ }
+ iter = iter->next;
+ } while (iter != end);
+ return 0;
+}
+
+/*
+ Search for a swig_type_info structure for either a mangled name or a human readable name.
+ It first searches the mangled names of the types, which is a O(log #types)
+ If a type is not found it then searches the human readable names, which is O(#types).
+
+ We start searching at module start, and finish searching when start == end.
+ Note: if start == end at the beginning of the function, we go all the way around
+ the circular list.
+*/
+SWIGRUNTIME swig_type_info *
+SWIG_TypeQueryModule(swig_module_info *start,
+ swig_module_info *end,
+ const char *name) {
+ /* STEP 1: Search the name field using binary search */
+ swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name);
+ if (ret) {
+ return ret;
+ } else {
+ /* STEP 2: If the type hasn't been found, do a complete search
+ of the str field (the human readable name) */
+ swig_module_info *iter = start;
+ do {
+ register size_t i = 0;
+ for (; i < iter->size; ++i) {
+ if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name)))
+ return iter->types[i];
+ }
+ iter = iter->next;
+ } while (iter != end);
+ }
+
+ /* neither found a match */
+ return 0;
+}
+
+/*
+ Pack binary data into a string
+*/
+SWIGRUNTIME char *
+SWIG_PackData(char *c, void *ptr, size_t sz) {
+ static const char hex[17] = "0123456789abcdef";
+ register const unsigned char *u = (unsigned char *) ptr;
+ register const unsigned char *eu = u + sz;
+ for (; u != eu; ++u) {
+ register unsigned char uu = *u;
+ *(c++) = hex[(uu & 0xf0) >> 4];
+ *(c++) = hex[uu & 0xf];
+ }
+ return c;
+}
+
+/*
+ Unpack binary data from a string
+*/
+SWIGRUNTIME const char *
+SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
+ register unsigned char *u = (unsigned char *) ptr;
+ register const unsigned char *eu = u + sz;
+ for (; u != eu; ++u) {
+ register char d = *(c++);
+ register unsigned char uu;
+ if ((d >= '0') && (d <= '9'))
+ uu = ((d - '0') << 4);
+ else if ((d >= 'a') && (d <= 'f'))
+ uu = ((d - ('a'-10)) << 4);
+ else
+ return (char *) 0;
+ d = *(c++);
+ if ((d >= '0') && (d <= '9'))
+ uu |= (d - '0');
+ else if ((d >= 'a') && (d <= 'f'))
+ uu |= (d - ('a'-10));
+ else
+ return (char *) 0;
+ *u = uu;
+ }
+ return c;
+}
+
+/*
+ Pack 'void *' into a string buffer.
+*/
+SWIGRUNTIME char *
+SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) {
+ char *r = buff;
+ if ((2*sizeof(void *) + 2) > bsz) return 0;
+ *(r++) = '_';
+ r = SWIG_PackData(r,&ptr,sizeof(void *));
+ if (strlen(name) + 1 > (bsz - (r - buff))) return 0;
+ strcpy(r,name);
+ return buff;
+}
+
+SWIGRUNTIME const char *
+SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) {
+ if (*c != '_') {
+ if (strcmp(c,"NULL") == 0) {
+ *ptr = (void *) 0;
+ return name;
+ } else {
+ return 0;
+ }
+ }
+ return SWIG_UnpackData(++c,ptr,sizeof(void *));
+}
+
+SWIGRUNTIME char *
+SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) {
+ char *r = buff;
+ size_t lname = (name ? strlen(name) : 0);
+ if ((2*sz + 2 + lname) > bsz) return 0;
+ *(r++) = '_';
+ r = SWIG_PackData(r,ptr,sz);
+ if (lname) {
+ strncpy(r,name,lname+1);
+ } else {
+ *r = 0;
+ }
+ return buff;
+}
+
+SWIGRUNTIME const char *
+SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) {
+ if (*c != '_') {
+ if (strcmp(c,"NULL") == 0) {
+ memset(ptr,0,sz);
+ return name;
+ } else {
+ return 0;
+ }
+ }
+ return SWIG_UnpackData(++c,ptr,sz);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Errors in SWIG */
+#define SWIG_UnknownError -1
+#define SWIG_IOError -2
+#define SWIG_RuntimeError -3
+#define SWIG_IndexError -4
+#define SWIG_TypeError -5
+#define SWIG_DivisionByZero -6
+#define SWIG_OverflowError -7
+#define SWIG_SyntaxError -8
+#define SWIG_ValueError -9
+#define SWIG_SystemError -10
+#define SWIG_AttributeError -11
+#define SWIG_MemoryError -12
+#define SWIG_NullReferenceError -13
+
+
+
+
+/* Add PyOS_snprintf for old Pythons */
+#if PY_VERSION_HEX < 0x02020000
+# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM)
+# define PyOS_snprintf _snprintf
+# else
+# define PyOS_snprintf snprintf
+# endif
+#endif
+
+/* A crude PyString_FromFormat implementation for old Pythons */
+#if PY_VERSION_HEX < 0x02020000
+
+#ifndef SWIG_PYBUFFER_SIZE
+# define SWIG_PYBUFFER_SIZE 1024
+#endif
+
+static PyObject *
+PyString_FromFormat(const char *fmt, ...) {
+ va_list ap;
+ char buf[SWIG_PYBUFFER_SIZE * 2];
+ int res;
+ va_start(ap, fmt);
+ res = vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+ return (res < 0 || res >= (int)sizeof(buf)) ? 0 : PyString_FromString(buf);
+}
+#endif
+
+/* Add PyObject_Del for old Pythons */
+#if PY_VERSION_HEX < 0x01060000
+# define PyObject_Del(op) PyMem_DEL((op))
+#endif
+#ifndef PyObject_DEL
+# define PyObject_DEL PyObject_Del
+#endif
+
+/* A crude PyExc_StopIteration exception for old Pythons */
+#if PY_VERSION_HEX < 0x02020000
+# ifndef PyExc_StopIteration
+# define PyExc_StopIteration PyExc_RuntimeError
+# endif
+# ifndef PyObject_GenericGetAttr
+# define PyObject_GenericGetAttr 0
+# endif
+#endif
+/* Py_NotImplemented is defined in 2.1 and up. */
+#if PY_VERSION_HEX < 0x02010000
+# ifndef Py_NotImplemented
+# define Py_NotImplemented PyExc_RuntimeError
+# endif
+#endif
+
+
+/* A crude PyString_AsStringAndSize implementation for old Pythons */
+#if PY_VERSION_HEX < 0x02010000
+# ifndef PyString_AsStringAndSize
+# define PyString_AsStringAndSize(obj, s, len) {*s = PyString_AsString(obj); *len = *s ? strlen(*s) : 0;}
+# endif
+#endif
+
+/* PySequence_Size for old Pythons */
+#if PY_VERSION_HEX < 0x02000000
+# ifndef PySequence_Size
+# define PySequence_Size PySequence_Length
+# endif
+#endif
+
+
+/* PyBool_FromLong for old Pythons */
+#if PY_VERSION_HEX < 0x02030000
+static
+PyObject *PyBool_FromLong(long ok)
+{
+ PyObject *result = ok ? Py_True : Py_False;
+ Py_INCREF(result);
+ return result;
+}
+#endif
+
+/* Py_ssize_t for old Pythons */
+/* This code is as recommended by: */
+/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */
+#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
+typedef int Py_ssize_t;
+# define PY_SSIZE_T_MAX INT_MAX
+# define PY_SSIZE_T_MIN INT_MIN
+#endif
+
+/* -----------------------------------------------------------------------------
+ * error manipulation
+ * ----------------------------------------------------------------------------- */
+
+SWIGRUNTIME PyObject*
+SWIG_Python_ErrorType(int code) {
+ PyObject* type = 0;
+ switch(code) {
+ case SWIG_MemoryError:
+ type = PyExc_MemoryError;
+ break;
+ case SWIG_IOError:
+ type = PyExc_IOError;
+ break;
+ case SWIG_RuntimeError:
+ type = PyExc_RuntimeError;
+ break;
+ case SWIG_IndexError:
+ type = PyExc_IndexError;
+ break;
+ case SWIG_TypeError:
+ type = PyExc_TypeError;
+ break;
+ case SWIG_DivisionByZero:
+ type = PyExc_ZeroDivisionError;
+ break;
+ case SWIG_OverflowError:
+ type = PyExc_OverflowError;
+ break;
+ case SWIG_SyntaxError:
+ type = PyExc_SyntaxError;
+ break;
+ case SWIG_ValueError:
+ type = PyExc_ValueError;
+ break;
+ case SWIG_SystemError:
+ type = PyExc_SystemError;
+ break;
+ case SWIG_AttributeError:
+ type = PyExc_AttributeError;
+ break;
+ default:
+ type = PyExc_RuntimeError;
+ }
+ return type;
+}
+
+
+SWIGRUNTIME void
+SWIG_Python_AddErrorMsg(const char* mesg)
+{
+ PyObject *type = 0;
+ PyObject *value = 0;
+ PyObject *traceback = 0;
+
+ if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback);
+ if (value) {
+ PyObject *old_str = PyObject_Str(value);
+ PyErr_Clear();
+ Py_XINCREF(type);
+ PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg);
+ Py_DECREF(old_str);
+ Py_DECREF(value);
+ } else {
+ PyErr_SetString(PyExc_RuntimeError, mesg);
+ }
+}
+
+
+
+#if defined(SWIG_PYTHON_NO_THREADS)
+# if defined(SWIG_PYTHON_THREADS)
+# undef SWIG_PYTHON_THREADS
+# endif
+#endif
+#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */
+# if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL)
+# if (PY_VERSION_HEX >= 0x02030000) /* For 2.3 or later, use the PyGILState calls */
+# define SWIG_PYTHON_USE_GIL
+# endif
+# endif
+# if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */
+# ifndef SWIG_PYTHON_INITIALIZE_THREADS
+# define SWIG_PYTHON_INITIALIZE_THREADS PyEval_InitThreads()
+# endif
+# ifdef __cplusplus /* C++ code */
+ class SWIG_Python_Thread_Block {
+ bool status;
+ PyGILState_STATE state;
+ public:
+ void end() { if (status) { PyGILState_Release(state); status = false;} }
+ SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {}
+ ~SWIG_Python_Thread_Block() { end(); }
+ };
+ class SWIG_Python_Thread_Allow {
+ bool status;
+ PyThreadState *save;
+ public:
+ void end() { if (status) { PyEval_RestoreThread(save); status = false; }}
+ SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {}
+ ~SWIG_Python_Thread_Allow() { end(); }
+ };
+# define SWIG_PYTHON_THREAD_BEGIN_BLOCK SWIG_Python_Thread_Block _swig_thread_block
+# define SWIG_PYTHON_THREAD_END_BLOCK _swig_thread_block.end()
+# define SWIG_PYTHON_THREAD_BEGIN_ALLOW SWIG_Python_Thread_Allow _swig_thread_allow
+# define SWIG_PYTHON_THREAD_END_ALLOW _swig_thread_allow.end()
+# else /* C code */
+# define SWIG_PYTHON_THREAD_BEGIN_BLOCK PyGILState_STATE _swig_thread_block = PyGILState_Ensure()
+# define SWIG_PYTHON_THREAD_END_BLOCK PyGILState_Release(_swig_thread_block)
+# define SWIG_PYTHON_THREAD_BEGIN_ALLOW PyThreadState *_swig_thread_allow = PyEval_SaveThread()
+# define SWIG_PYTHON_THREAD_END_ALLOW PyEval_RestoreThread(_swig_thread_allow)
+# endif
+# else /* Old thread way, not implemented, user must provide it */
+# if !defined(SWIG_PYTHON_INITIALIZE_THREADS)
+# define SWIG_PYTHON_INITIALIZE_THREADS
+# endif
+# if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK)
+# define SWIG_PYTHON_THREAD_BEGIN_BLOCK
+# endif
+# if !defined(SWIG_PYTHON_THREAD_END_BLOCK)
+# define SWIG_PYTHON_THREAD_END_BLOCK
+# endif
+# if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW)
+# define SWIG_PYTHON_THREAD_BEGIN_ALLOW
+# endif
+# if !defined(SWIG_PYTHON_THREAD_END_ALLOW)
+# define SWIG_PYTHON_THREAD_END_ALLOW
+# endif
+# endif
+#else /* No thread support */
+# define SWIG_PYTHON_INITIALIZE_THREADS
+# define SWIG_PYTHON_THREAD_BEGIN_BLOCK
+# define SWIG_PYTHON_THREAD_END_BLOCK
+# define SWIG_PYTHON_THREAD_BEGIN_ALLOW
+# define SWIG_PYTHON_THREAD_END_ALLOW
+#endif
+
+/* -----------------------------------------------------------------------------
+ * Python API portion that goes into the runtime
+ * ----------------------------------------------------------------------------- */
+
+#ifdef __cplusplus
+extern "C" {
+#if 0
+} /* cc-mode */
+#endif
+#endif
+
+/* -----------------------------------------------------------------------------
+ * Constant declarations
+ * ----------------------------------------------------------------------------- */
+
+/* Constant Types */
+#define SWIG_PY_POINTER 4
+#define SWIG_PY_BINARY 5
+
+/* Constant information structure */
+typedef struct swig_const_info {
+ int type;
+ char *name;
+ long lvalue;
+ double dvalue;
+ void *pvalue;
+ swig_type_info **ptype;
+} swig_const_info;
+
+#ifdef __cplusplus
+#if 0
+{ /* cc-mode */
+#endif
+}
+#endif
+
+
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * pyrun.swg
+ *
+ * This file contains the runtime support for Python modules
+ * and includes code for managing global variables and pointer
+ * type checking.
+ *
+ * ----------------------------------------------------------------------------- */
+
+/* Common SWIG API */
+
+/* for raw pointers */
+#define SWIG_Python_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0)
+#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags)
+#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own)
+#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(ptr, type, flags)
+#define SWIG_CheckImplicit(ty) SWIG_Python_CheckImplicit(ty)
+#define SWIG_AcquirePtr(ptr, src) SWIG_Python_AcquirePtr(ptr, src)
+#define swig_owntype int
+
+/* for raw packed data */
+#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty)
+#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type)
+
+/* for class or struct pointers */
+#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags)
+#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags)
+
+/* for C or C++ function pointers */
+#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_Python_ConvertFunctionPtr(obj, pptr, type)
+#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_Python_NewPointerObj(ptr, type, 0)
+
+/* for C++ member pointers, ie, member methods */
+#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty)
+#define SWIG_NewMemberObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type)
+
+
+/* Runtime API */
+
+#define SWIG_GetModule(clientdata) SWIG_Python_GetModule()
+#define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer)
+#define SWIG_NewClientData(obj) PySwigClientData_New(obj)
+
+#define SWIG_SetErrorObj SWIG_Python_SetErrorObj
+#define SWIG_SetErrorMsg SWIG_Python_SetErrorMsg
+#define SWIG_ErrorType(code) SWIG_Python_ErrorType(code)
+#define SWIG_Error(code, msg) SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg)
+#define SWIG_fail goto fail
+
+
+/* Runtime API implementation */
+
+/* Error manipulation */
+
+SWIGINTERN void
+SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) {
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+ PyErr_SetObject(errtype, obj);
+ Py_DECREF(obj);
+ SWIG_PYTHON_THREAD_END_BLOCK;
+}
+
+SWIGINTERN void
+SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) {
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+ PyErr_SetString(errtype, (char *) msg);
+ SWIG_PYTHON_THREAD_END_BLOCK;
+}
+
+#define SWIG_Python_Raise(obj, type, desc) SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj)
+
+/* Set a constant value */
+
+SWIGINTERN void
+SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) {
+ PyDict_SetItemString(d, (char*) name, obj);
+ Py_DECREF(obj);
+}
+
+/* Append a value to the result obj */
+
+SWIGINTERN PyObject*
+SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) {
+#if !defined(SWIG_PYTHON_OUTPUT_TUPLE)
+ if (!result) {
+ result = obj;
+ } else if (result == Py_None) {
+ Py_DECREF(result);
+ result = obj;
+ } else {
+ if (!PyList_Check(result)) {
+ PyObject *o2 = result;
+ result = PyList_New(1);
+ PyList_SetItem(result, 0, o2);
+ }
+ PyList_Append(result,obj);
+ Py_DECREF(obj);
+ }
+ return result;
+#else
+ PyObject* o2;
+ PyObject* o3;
+ if (!result) {
+ result = obj;
+ } else if (result == Py_None) {
+ Py_DECREF(result);
+ result = obj;
+ } else {
+ if (!PyTuple_Check(result)) {
+ o2 = result;
+ result = PyTuple_New(1);
+ PyTuple_SET_ITEM(result, 0, o2);
+ }
+ o3 = PyTuple_New(1);
+ PyTuple_SET_ITEM(o3, 0, obj);
+ o2 = result;
+ result = PySequence_Concat(o2, o3);
+ Py_DECREF(o2);
+ Py_DECREF(o3);
+ }
+ return result;
+#endif
+}
+
+/* Unpack the argument tuple */
+
+SWIGINTERN int
+SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs)
+{
+ if (!args) {
+ if (!min && !max) {
+ return 1;
+ } else {
+ PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none",
+ name, (min == max ? "" : "at least "), (int)min);
+ return 0;
+ }
+ }
+ if (!PyTuple_Check(args)) {
+ PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple");
+ return 0;
+ } else {
+ register Py_ssize_t l = PyTuple_GET_SIZE(args);
+ if (l < min) {
+ PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d",
+ name, (min == max ? "" : "at least "), (int)min, (int)l);
+ return 0;
+ } else if (l > max) {
+ PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d",
+ name, (min == max ? "" : "at most "), (int)max, (int)l);
+ return 0;
+ } else {
+ register int i;
+ for (i = 0; i < l; ++i) {
+ objs[i] = PyTuple_GET_ITEM(args, i);
+ }
+ for (; l < max; ++l) {
+ objs[l] = 0;
+ }
+ return i + 1;
+ }
+ }
+}
+
+/* A functor is a function object with one single object argument */
+#if PY_VERSION_HEX >= 0x02020000
+#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunctionObjArgs(functor, obj, NULL);
+#else
+#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunction(functor, "O", obj);
+#endif
+
+/*
+ Helper for static pointer initialization for both C and C++ code, for example
+ static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...);
+*/
+#ifdef __cplusplus
+#define SWIG_STATIC_POINTER(var) var
+#else
+#define SWIG_STATIC_POINTER(var) var = 0; if (!var) var
+#endif
+
+/* -----------------------------------------------------------------------------
+ * Pointer declarations
+ * ----------------------------------------------------------------------------- */
+
+/* Flags for new pointer objects */
+#define SWIG_POINTER_NOSHADOW (SWIG_POINTER_OWN << 1)
+#define SWIG_POINTER_NEW (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN)
+
+#define SWIG_POINTER_IMPLICIT_CONV (SWIG_POINTER_DISOWN << 1)
+
+#ifdef __cplusplus
+extern "C" {
+#if 0
+} /* cc-mode */
+#endif
+#endif
+
+/* How to access Py_None */
+#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+# ifndef SWIG_PYTHON_NO_BUILD_NONE
+# ifndef SWIG_PYTHON_BUILD_NONE
+# define SWIG_PYTHON_BUILD_NONE
+# endif
+# endif
+#endif
+
+#ifdef SWIG_PYTHON_BUILD_NONE
+# ifdef Py_None
+# undef Py_None
+# define Py_None SWIG_Py_None()
+# endif
+SWIGRUNTIMEINLINE PyObject *
+_SWIG_Py_None(void)
+{
+ PyObject *none = Py_BuildValue((char*)"");
+ Py_DECREF(none);
+ return none;
+}
+SWIGRUNTIME PyObject *
+SWIG_Py_None(void)
+{
+ static PyObject *SWIG_STATIC_POINTER(none) = _SWIG_Py_None();
+ return none;
+}
+#endif
+
+/* The python void return value */
+
+SWIGRUNTIMEINLINE PyObject *
+SWIG_Py_Void(void)
+{
+ PyObject *none = Py_None;
+ Py_INCREF(none);
+ return none;
+}
+
+/* PySwigClientData */
+
+typedef struct {
+ PyObject *klass;
+ PyObject *newraw;
+ PyObject *newargs;
+ PyObject *destroy;
+ int delargs;
+ int implicitconv;
+} PySwigClientData;
+
+SWIGRUNTIMEINLINE int
+SWIG_Python_CheckImplicit(swig_type_info *ty)
+{
+ PySwigClientData *data = (PySwigClientData *)ty->clientdata;
+ return data ? data->implicitconv : 0;
+}
+
+SWIGRUNTIMEINLINE PyObject *
+SWIG_Python_ExceptionType(swig_type_info *desc) {
+ PySwigClientData *data = desc ? (PySwigClientData *) desc->clientdata : 0;
+ PyObject *klass = data ? data->klass : 0;
+ return (klass ? klass : PyExc_RuntimeError);
+}
+
+
+SWIGRUNTIME PySwigClientData *
+PySwigClientData_New(PyObject* obj)
+{
+ if (!obj) {
+ return 0;
+ } else {
+ PySwigClientData *data = (PySwigClientData *)malloc(sizeof(PySwigClientData));
+ /* the klass element */
+ data->klass = obj;
+ Py_INCREF(data->klass);
+ /* the newraw method and newargs arguments used to create a new raw instance */
+ if (PyClass_Check(obj)) {
+ data->newraw = 0;
+ data->newargs = obj;
+ Py_INCREF(obj);
+ } else {
+#if (PY_VERSION_HEX < 0x02020000)
+ data->newraw = 0;
+#else
+ data->newraw = PyObject_GetAttrString(data->klass, (char *)"__new__");
+#endif
+ if (data->newraw) {
+ Py_INCREF(data->newraw);
+ data->newargs = PyTuple_New(1);
+ PyTuple_SetItem(data->newargs, 0, obj);
+ } else {
+ data->newargs = obj;
+ }
+ Py_INCREF(data->newargs);
+ }
+ /* the destroy method, aka as the C++ delete method */
+ data->destroy = PyObject_GetAttrString(data->klass, (char *)"__swig_destroy__");
+ if (PyErr_Occurred()) {
+ PyErr_Clear();
+ data->destroy = 0;
+ }
+ if (data->destroy) {
+ int flags;
+ Py_INCREF(data->destroy);
+ flags = PyCFunction_GET_FLAGS(data->destroy);
+#ifdef METH_O
+ data->delargs = !(flags & (METH_O));
+#else
+ data->delargs = 0;
+#endif
+ } else {
+ data->delargs = 0;
+ }
+ data->implicitconv = 0;
+ return data;
+ }
+}
+
+SWIGRUNTIME void
+PySwigClientData_Del(PySwigClientData* data)
+{
+ Py_XDECREF(data->newraw);
+ Py_XDECREF(data->newargs);
+ Py_XDECREF(data->destroy);
+}
+
+/* =============== PySwigObject =====================*/
+
+typedef struct {
+ PyObject_HEAD
+ void *ptr;
+ swig_type_info *ty;
+ int own;
+ PyObject *next;
+} PySwigObject;
+
+SWIGRUNTIME PyObject *
+PySwigObject_long(PySwigObject *v)
+{
+ return PyLong_FromVoidPtr(v->ptr);
+}
+
+SWIGRUNTIME PyObject *
+PySwigObject_format(const char* fmt, PySwigObject *v)
+{
+ PyObject *res = NULL;
+ PyObject *args = PyTuple_New(1);
+ if (args) {
+ if (PyTuple_SetItem(args, 0, PySwigObject_long(v)) == 0) {
+ PyObject *ofmt = PyString_FromString(fmt);
+ if (ofmt) {
+ res = PyString_Format(ofmt,args);
+ Py_DECREF(ofmt);
+ }
+ Py_DECREF(args);
+ }
+ }
+ return res;
+}
+
+SWIGRUNTIME PyObject *
+PySwigObject_oct(PySwigObject *v)
+{
+ return PySwigObject_format("%o",v);
+}
+
+SWIGRUNTIME PyObject *
+PySwigObject_hex(PySwigObject *v)
+{
+ return PySwigObject_format("%x",v);
+}
+
+SWIGRUNTIME PyObject *
+#ifdef METH_NOARGS
+PySwigObject_repr(PySwigObject *v)
+#else
+PySwigObject_repr(PySwigObject *v, PyObject *args)
+#endif
+{
+ const char *name = SWIG_TypePrettyName(v->ty);
+ PyObject *hex = PySwigObject_hex(v);
+ PyObject *repr = PyString_FromFormat("<Swig Object of type '%s' at 0x%s>", name, PyString_AsString(hex));
+ Py_DECREF(hex);
+ if (v->next) {
+#ifdef METH_NOARGS
+ PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next);
+#else
+ PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next, args);
+#endif
+ PyString_ConcatAndDel(&repr,nrep);
+ }
+ return repr;
+}
+
+SWIGRUNTIME int
+PySwigObject_print(PySwigObject *v, FILE *fp, int SWIGUNUSEDPARM(flags))
+{
+#ifdef METH_NOARGS
+ PyObject *repr = PySwigObject_repr(v);
+#else
+ PyObject *repr = PySwigObject_repr(v, NULL);
+#endif
+ if (repr) {
+ fputs(PyString_AsString(repr), fp);
+ Py_DECREF(repr);
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+SWIGRUNTIME PyObject *
+PySwigObject_str(PySwigObject *v)
+{
+ char result[SWIG_BUFFER_SIZE];
+ return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ?
+ PyString_FromString(result) : 0;
+}
+
+SWIGRUNTIME int
+PySwigObject_compare(PySwigObject *v, PySwigObject *w)
+{
+ void *i = v->ptr;
+ void *j = w->ptr;
+ return (i < j) ? -1 : ((i > j) ? 1 : 0);
+}
+
+SWIGRUNTIME PyTypeObject* _PySwigObject_type(void);
+
+SWIGRUNTIME PyTypeObject*
+PySwigObject_type(void) {
+ static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigObject_type();
+ return type;
+}
+
+SWIGRUNTIMEINLINE int
+PySwigObject_Check(PyObject *op) {
+ return ((op)->ob_type == PySwigObject_type())
+ || (strcmp((op)->ob_type->tp_name,"PySwigObject") == 0);
+}
+
+SWIGRUNTIME PyObject *
+PySwigObject_New(void *ptr, swig_type_info *ty, int own);
+
+SWIGRUNTIME void
+PySwigObject_dealloc(PyObject *v)
+{
+ PySwigObject *sobj = (PySwigObject *) v;
+ PyObject *next = sobj->next;
+ if (sobj->own == SWIG_POINTER_OWN) {
+ swig_type_info *ty = sobj->ty;
+ PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0;
+ PyObject *destroy = data ? data->destroy : 0;
+ if (destroy) {
+ /* destroy is always a VARARGS method */
+ PyObject *res;
+ if (data->delargs) {
+ /* we need to create a temporal object to carry the destroy operation */
+ PyObject *tmp = PySwigObject_New(sobj->ptr, ty, 0);
+ res = SWIG_Python_CallFunctor(destroy, tmp);
+ Py_DECREF(tmp);
+ } else {
+ PyCFunction meth = PyCFunction_GET_FUNCTION(destroy);
+ PyObject *mself = PyCFunction_GET_SELF(destroy);
+ res = ((*meth)(mself, v));
+ }
+ Py_XDECREF(res);
+ }
+#if !defined(SWIG_PYTHON_SILENT_MEMLEAK)
+ else {
+ const char *name = SWIG_TypePrettyName(ty);
+ printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown"));
+ }
+#endif
+ }
+ Py_XDECREF(next);
+ PyObject_DEL(v);
+}
+
+SWIGRUNTIME PyObject*
+PySwigObject_append(PyObject* v, PyObject* next)
+{
+ PySwigObject *sobj = (PySwigObject *) v;
+#ifndef METH_O
+ PyObject *tmp = 0;
+ if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL;
+ next = tmp;
+#endif
+ if (!PySwigObject_Check(next)) {
+ return NULL;
+ }
+ sobj->next = next;
+ Py_INCREF(next);
+ return SWIG_Py_Void();
+}
+
+SWIGRUNTIME PyObject*
+#ifdef METH_NOARGS
+PySwigObject_next(PyObject* v)
+#else
+PySwigObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
+#endif
+{
+ PySwigObject *sobj = (PySwigObject *) v;
+ if (sobj->next) {
+ Py_INCREF(sobj->next);
+ return sobj->next;
+ } else {
+ return SWIG_Py_Void();
+ }
+}
+
+SWIGINTERN PyObject*
+#ifdef METH_NOARGS
+PySwigObject_disown(PyObject *v)
+#else
+PySwigObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
+#endif
+{
+ PySwigObject *sobj = (PySwigObject *)v;
+ sobj->own = 0;
+ return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject*
+#ifdef METH_NOARGS
+PySwigObject_acquire(PyObject *v)
+#else
+PySwigObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
+#endif
+{
+ PySwigObject *sobj = (PySwigObject *)v;
+ sobj->own = SWIG_POINTER_OWN;
+ return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject*
+PySwigObject_own(PyObject *v, PyObject *args)
+{
+ PyObject *val = 0;
+#if (PY_VERSION_HEX < 0x02020000)
+ if (!PyArg_ParseTuple(args,(char *)"|O:own",&val))
+#else
+ if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val))
+#endif
+ {
+ return NULL;
+ }
+ else
+ {
+ PySwigObject *sobj = (PySwigObject *)v;
+ PyObject *obj = PyBool_FromLong(sobj->own);
+ if (val) {
+#ifdef METH_NOARGS
+ if (PyObject_IsTrue(val)) {
+ PySwigObject_acquire(v);
+ } else {
+ PySwigObject_disown(v);
+ }
+#else
+ if (PyObject_IsTrue(val)) {
+ PySwigObject_acquire(v,args);
+ } else {
+ PySwigObject_disown(v,args);
+ }
+#endif
+ }
+ return obj;
+ }
+}
+
+#ifdef METH_O
+static PyMethodDef
+swigobject_methods[] = {
+ {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_NOARGS, (char *)"releases ownership of the pointer"},
+ {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_NOARGS, (char *)"aquires ownership of the pointer"},
+ {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"},
+ {(char *)"append", (PyCFunction)PySwigObject_append, METH_O, (char *)"appends another 'this' object"},
+ {(char *)"next", (PyCFunction)PySwigObject_next, METH_NOARGS, (char *)"returns the next 'this' object"},
+ {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_NOARGS, (char *)"returns object representation"},
+ {0, 0, 0, 0}
+};
+#else
+static PyMethodDef
+swigobject_methods[] = {
+ {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_VARARGS, (char *)"releases ownership of the pointer"},
+ {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_VARARGS, (char *)"aquires ownership of the pointer"},
+ {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"},
+ {(char *)"append", (PyCFunction)PySwigObject_append, METH_VARARGS, (char *)"appends another 'this' object"},
+ {(char *)"next", (PyCFunction)PySwigObject_next, METH_VARARGS, (char *)"returns the next 'this' object"},
+ {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_VARARGS, (char *)"returns object representation"},
+ {0, 0, 0, 0}
+};
+#endif
+
+#if PY_VERSION_HEX < 0x02020000
+SWIGINTERN PyObject *
+PySwigObject_getattr(PySwigObject *sobj,char *name)
+{
+ return Py_FindMethod(swigobject_methods, (PyObject *)sobj, name);
+}
+#endif
+
+SWIGRUNTIME PyTypeObject*
+_PySwigObject_type(void) {
+ static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer";
+
+ static PyNumberMethods PySwigObject_as_number = {
+ (binaryfunc)0, /*nb_add*/
+ (binaryfunc)0, /*nb_subtract*/
+ (binaryfunc)0, /*nb_multiply*/
+ (binaryfunc)0, /*nb_divide*/
+ (binaryfunc)0, /*nb_remainder*/
+ (binaryfunc)0, /*nb_divmod*/
+ (ternaryfunc)0,/*nb_power*/
+ (unaryfunc)0, /*nb_negative*/
+ (unaryfunc)0, /*nb_positive*/
+ (unaryfunc)0, /*nb_absolute*/
+ (inquiry)0, /*nb_nonzero*/
+ 0, /*nb_invert*/
+ 0, /*nb_lshift*/
+ 0, /*nb_rshift*/
+ 0, /*nb_and*/
+ 0, /*nb_xor*/
+ 0, /*nb_or*/
+ (coercion)0, /*nb_coerce*/
+ (unaryfunc)PySwigObject_long, /*nb_int*/
+ (unaryfunc)PySwigObject_long, /*nb_long*/
+ (unaryfunc)0, /*nb_float*/
+ (unaryfunc)PySwigObject_oct, /*nb_oct*/
+ (unaryfunc)PySwigObject_hex, /*nb_hex*/
+#if PY_VERSION_HEX >= 0x02050000 /* 2.5.0 */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */
+#elif PY_VERSION_HEX >= 0x02020000 /* 2.2.0 */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */
+#elif PY_VERSION_HEX >= 0x02000000 /* 2.0.0 */
+ 0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */
+#endif
+ };
+
+ static PyTypeObject pyswigobject_type;
+ static int type_init = 0;
+ if (!type_init) {
+ const PyTypeObject tmp
+ = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ (char *)"PySwigObject", /* tp_name */
+ sizeof(PySwigObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)PySwigObject_dealloc, /* tp_dealloc */
+ (printfunc)PySwigObject_print, /* tp_print */
+#if PY_VERSION_HEX < 0x02020000
+ (getattrfunc)PySwigObject_getattr, /* tp_getattr */
+#else
+ (getattrfunc)0, /* tp_getattr */
+#endif
+ (setattrfunc)0, /* tp_setattr */
+ (cmpfunc)PySwigObject_compare, /* tp_compare */
+ (reprfunc)PySwigObject_repr, /* tp_repr */
+ &PySwigObject_as_number, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)0, /* tp_hash */
+ (ternaryfunc)0, /* tp_call */
+ (reprfunc)PySwigObject_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ swigobject_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+#if PY_VERSION_HEX >= 0x02020000
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ swigobject_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+ 0, /* tp_free */
+ 0, /* tp_is_gc */
+ 0, /* tp_bases */
+ 0, /* tp_mro */
+ 0, /* tp_cache */
+ 0, /* tp_subclasses */
+ 0, /* tp_weaklist */
+#endif
+#if PY_VERSION_HEX >= 0x02030000
+ 0, /* tp_del */
+#endif
+#ifdef COUNT_ALLOCS
+ 0,0,0,0 /* tp_alloc -> tp_next */
+#endif
+ };
+ pyswigobject_type = tmp;
+ pyswigobject_type.ob_type = &PyType_Type;
+ type_init = 1;
+ }
+ return &pyswigobject_type;
+}
+
+SWIGRUNTIME PyObject *
+PySwigObject_New(void *ptr, swig_type_info *ty, int own)
+{
+ PySwigObject *sobj = PyObject_NEW(PySwigObject, PySwigObject_type());
+ if (sobj) {
+ sobj->ptr = ptr;
+ sobj->ty = ty;
+ sobj->own = own;
+ sobj->next = 0;
+ }
+ return (PyObject *)sobj;
+}
+
+/* -----------------------------------------------------------------------------
+ * Implements a simple Swig Packed type, and use it instead of string
+ * ----------------------------------------------------------------------------- */
+
+typedef struct {
+ PyObject_HEAD
+ void *pack;
+ swig_type_info *ty;
+ size_t size;
+} PySwigPacked;
+
+SWIGRUNTIME int
+PySwigPacked_print(PySwigPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags))
+{
+ char result[SWIG_BUFFER_SIZE];
+ fputs("<Swig Packed ", fp);
+ if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
+ fputs("at ", fp);
+ fputs(result, fp);
+ }
+ fputs(v->ty->name,fp);
+ fputs(">", fp);
+ return 0;
+}
+
+SWIGRUNTIME PyObject *
+PySwigPacked_repr(PySwigPacked *v)
+{
+ char result[SWIG_BUFFER_SIZE];
+ if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
+ return PyString_FromFormat("<Swig Packed at %s%s>", result, v->ty->name);
+ } else {
+ return PyString_FromFormat("<Swig Packed %s>", v->ty->name);
+ }
+}
+
+SWIGRUNTIME PyObject *
+PySwigPacked_str(PySwigPacked *v)
+{
+ char result[SWIG_BUFFER_SIZE];
+ if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){
+ return PyString_FromFormat("%s%s", result, v->ty->name);
+ } else {
+ return PyString_FromString(v->ty->name);
+ }
+}
+
+SWIGRUNTIME int
+PySwigPacked_compare(PySwigPacked *v, PySwigPacked *w)
+{
+ size_t i = v->size;
+ size_t j = w->size;
+ int s = (i < j) ? -1 : ((i > j) ? 1 : 0);
+ return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size);
+}
+
+SWIGRUNTIME PyTypeObject* _PySwigPacked_type(void);
+
+SWIGRUNTIME PyTypeObject*
+PySwigPacked_type(void) {
+ static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigPacked_type();
+ return type;
+}
+
+SWIGRUNTIMEINLINE int
+PySwigPacked_Check(PyObject *op) {
+ return ((op)->ob_type == _PySwigPacked_type())
+ || (strcmp((op)->ob_type->tp_name,"PySwigPacked") == 0);
+}
+
+SWIGRUNTIME void
+PySwigPacked_dealloc(PyObject *v)
+{
+ if (PySwigPacked_Check(v)) {
+ PySwigPacked *sobj = (PySwigPacked *) v;
+ free(sobj->pack);
+ }
+ PyObject_DEL(v);
+}
+
+SWIGRUNTIME PyTypeObject*
+_PySwigPacked_type(void) {
+ static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer";
+ static PyTypeObject pyswigpacked_type;
+ static int type_init = 0;
+ if (!type_init) {
+ const PyTypeObject tmp
+ = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+ (char *)"PySwigPacked", /* tp_name */
+ sizeof(PySwigPacked), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)PySwigPacked_dealloc, /* tp_dealloc */
+ (printfunc)PySwigPacked_print, /* tp_print */
+ (getattrfunc)0, /* tp_getattr */
+ (setattrfunc)0, /* tp_setattr */
+ (cmpfunc)PySwigPacked_compare, /* tp_compare */
+ (reprfunc)PySwigPacked_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)0, /* tp_hash */
+ (ternaryfunc)0, /* tp_call */
+ (reprfunc)PySwigPacked_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ swigpacked_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+#if PY_VERSION_HEX >= 0x02020000
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+ 0, /* tp_free */
+ 0, /* tp_is_gc */
+ 0, /* tp_bases */
+ 0, /* tp_mro */
+ 0, /* tp_cache */
+ 0, /* tp_subclasses */
+ 0, /* tp_weaklist */
+#endif
+#if PY_VERSION_HEX >= 0x02030000
+ 0, /* tp_del */
+#endif
+#ifdef COUNT_ALLOCS
+ 0,0,0,0 /* tp_alloc -> tp_next */
+#endif
+ };
+ pyswigpacked_type = tmp;
+ pyswigpacked_type.ob_type = &PyType_Type;
+ type_init = 1;
+ }
+ return &pyswigpacked_type;
+}
+
+SWIGRUNTIME PyObject *
+PySwigPacked_New(void *ptr, size_t size, swig_type_info *ty)
+{
+ PySwigPacked *sobj = PyObject_NEW(PySwigPacked, PySwigPacked_type());
+ if (sobj) {
+ void *pack = malloc(size);
+ if (pack) {
+ memcpy(pack, ptr, size);
+ sobj->pack = pack;
+ sobj->ty = ty;
+ sobj->size = size;
+ } else {
+ PyObject_DEL((PyObject *) sobj);
+ sobj = 0;
+ }
+ }
+ return (PyObject *) sobj;
+}
+
+SWIGRUNTIME swig_type_info *
+PySwigPacked_UnpackData(PyObject *obj, void *ptr, size_t size)
+{
+ if (PySwigPacked_Check(obj)) {
+ PySwigPacked *sobj = (PySwigPacked *)obj;
+ if (sobj->size != size) return 0;
+ memcpy(ptr, sobj->pack, size);
+ return sobj->ty;
+ } else {
+ return 0;
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * pointers/data manipulation
+ * ----------------------------------------------------------------------------- */
+
+SWIGRUNTIMEINLINE PyObject *
+_SWIG_This(void)
+{
+ return PyString_FromString("this");
+}
+
+SWIGRUNTIME PyObject *
+SWIG_This(void)
+{
+ static PyObject *SWIG_STATIC_POINTER(swig_this) = _SWIG_This();
+ return swig_this;
+}
+
+/* #define SWIG_PYTHON_SLOW_GETSET_THIS */
+
+SWIGRUNTIME PySwigObject *
+SWIG_Python_GetSwigThis(PyObject *pyobj)
+{
+ if (PySwigObject_Check(pyobj)) {
+ return (PySwigObject *) pyobj;
+ } else {
+ PyObject *obj = 0;
+#if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && (PY_VERSION_HEX >= 0x02030000))
+ if (PyInstance_Check(pyobj)) {
+ obj = _PyInstance_Lookup(pyobj, SWIG_This());
+ } else {
+ PyObject **dictptr = _PyObject_GetDictPtr(pyobj);
+ if (dictptr != NULL) {
+ PyObject *dict = *dictptr;
+ obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0;
+ } else {
+#ifdef PyWeakref_CheckProxy
+ if (PyWeakref_CheckProxy(pyobj)) {
+ PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
+ return wobj ? SWIG_Python_GetSwigThis(wobj) : 0;
+ }
+#endif
+ obj = PyObject_GetAttr(pyobj,SWIG_This());
+ if (obj) {
+ Py_DECREF(obj);
+ } else {
+ if (PyErr_Occurred()) PyErr_Clear();
+ return 0;
+ }
+ }
+ }
+#else
+ obj = PyObject_GetAttr(pyobj,SWIG_This());
+ if (obj) {
+ Py_DECREF(obj);
+ } else {
+ if (PyErr_Occurred()) PyErr_Clear();
+ return 0;
+ }
+#endif
+ if (obj && !PySwigObject_Check(obj)) {
+ /* a PyObject is called 'this', try to get the 'real this'
+ PySwigObject from it */
+ return SWIG_Python_GetSwigThis(obj);
+ }
+ return (PySwigObject *)obj;
+ }
+}
+
+/* Acquire a pointer value */
+
+SWIGRUNTIME int
+SWIG_Python_AcquirePtr(PyObject *obj, int own) {
+ if (own == SWIG_POINTER_OWN) {
+ PySwigObject *sobj = SWIG_Python_GetSwigThis(obj);
+ if (sobj) {
+ int oldown = sobj->own;
+ sobj->own = own;
+ return oldown;
+ }
+ }
+ return 0;
+}
+
+/* Convert a pointer value */
+
+SWIGRUNTIME int
+SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) {
+ if (!obj) return SWIG_ERROR;
+ if (obj == Py_None) {
+ if (ptr) *ptr = 0;
+ return SWIG_OK;
+ } else {
+ PySwigObject *sobj = SWIG_Python_GetSwigThis(obj);
+ if (own)
+ *own = 0;
+ while (sobj) {
+ void *vptr = sobj->ptr;
+ if (ty) {
+ swig_type_info *to = sobj->ty;
+ if (to == ty) {
+ /* no type cast needed */
+ if (ptr) *ptr = vptr;
+ break;
+ } else {
+ swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
+ if (!tc) {
+ sobj = (PySwigObject *)sobj->next;
+ } else {
+ if (ptr) {
+ int newmemory = 0;
+ *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
+ if (newmemory == SWIG_CAST_NEW_MEMORY) {
+ assert(own);
+ if (own)
+ *own = *own | SWIG_CAST_NEW_MEMORY;
+ }
+ }
+ break;
+ }
+ }
+ } else {
+ if (ptr) *ptr = vptr;
+ break;
+ }
+ }
+ if (sobj) {
+ if (own)
+ *own = *own | sobj->own;
+ if (flags & SWIG_POINTER_DISOWN) {
+ sobj->own = 0;
+ }
+ return SWIG_OK;
+ } else {
+ int res = SWIG_ERROR;
+ if (flags & SWIG_POINTER_IMPLICIT_CONV) {
+ PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0;
+ if (data && !data->implicitconv) {
+ PyObject *klass = data->klass;
+ if (klass) {
+ PyObject *impconv;
+ data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/
+ impconv = SWIG_Python_CallFunctor(klass, obj);
+ data->implicitconv = 0;
+ if (PyErr_Occurred()) {
+ PyErr_Clear();
+ impconv = 0;
+ }
+ if (impconv) {
+ PySwigObject *iobj = SWIG_Python_GetSwigThis(impconv);
+ if (iobj) {
+ void *vptr;
+ res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0);
+ if (SWIG_IsOK(res)) {
+ if (ptr) {
+ *ptr = vptr;
+ /* transfer the ownership to 'ptr' */
+ iobj->own = 0;
+ res = SWIG_AddCast(res);
+ res = SWIG_AddNewMask(res);
+ } else {
+ res = SWIG_AddCast(res);
+ }
+ }
+ }
+ Py_DECREF(impconv);
+ }
+ }
+ }
+ }
+ return res;
+ }
+ }
+}
+
+/* Convert a function ptr value */
+
+SWIGRUNTIME int
+SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) {
+ if (!PyCFunction_Check(obj)) {
+ return SWIG_ConvertPtr(obj, ptr, ty, 0);
+ } else {
+ void *vptr = 0;
+
+ /* here we get the method pointer for callbacks */
+ const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc);
+ const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0;
+ if (desc) {
+ desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0;
+ if (!desc) return SWIG_ERROR;
+ }
+ if (ty) {
+ swig_cast_info *tc = SWIG_TypeCheck(desc,ty);
+ if (tc) {
+ int newmemory = 0;
+ *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
+ assert(!newmemory); /* newmemory handling not yet implemented */
+ } else {
+ return SWIG_ERROR;
+ }
+ } else {
+ *ptr = vptr;
+ }
+ return SWIG_OK;
+ }
+}
+
+/* Convert a packed value value */
+
+SWIGRUNTIME int
+SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) {
+ swig_type_info *to = PySwigPacked_UnpackData(obj, ptr, sz);
+ if (!to) return SWIG_ERROR;
+ if (ty) {
+ if (to != ty) {
+ /* check type cast? */
+ swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
+ if (!tc) return SWIG_ERROR;
+ }
+ }
+ return SWIG_OK;
+}
+
+/* -----------------------------------------------------------------------------
+ * Create a new pointer object
+ * ----------------------------------------------------------------------------- */
+
+/*
+ Create a new instance object, whitout calling __init__, and set the
+ 'this' attribute.
+*/
+
+SWIGRUNTIME PyObject*
+SWIG_Python_NewShadowInstance(PySwigClientData *data, PyObject *swig_this)
+{
+#if (PY_VERSION_HEX >= 0x02020000)
+ PyObject *inst = 0;
+ PyObject *newraw = data->newraw;
+ if (newraw) {
+ inst = PyObject_Call(newraw, data->newargs, NULL);
+ if (inst) {
+#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
+ PyObject **dictptr = _PyObject_GetDictPtr(inst);
+ if (dictptr != NULL) {
+ PyObject *dict = *dictptr;
+ if (dict == NULL) {
+ dict = PyDict_New();
+ *dictptr = dict;
+ PyDict_SetItem(dict, SWIG_This(), swig_this);
+ }
+ }
+#else
+ PyObject *key = SWIG_This();
+ PyObject_SetAttr(inst, key, swig_this);
+#endif
+ }
+ } else {
+ PyObject *dict = PyDict_New();
+ PyDict_SetItem(dict, SWIG_This(), swig_this);
+ inst = PyInstance_NewRaw(data->newargs, dict);
+ Py_DECREF(dict);
+ }
+ return inst;
+#else
+#if (PY_VERSION_HEX >= 0x02010000)
+ PyObject *inst;
+ PyObject *dict = PyDict_New();
+ PyDict_SetItem(dict, SWIG_This(), swig_this);
+ inst = PyInstance_NewRaw(data->newargs, dict);
+ Py_DECREF(dict);
+ return (PyObject *) inst;
+#else
+ PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type);
+ if (inst == NULL) {
+ return NULL;
+ }
+ inst->in_class = (PyClassObject *)data->newargs;
+ Py_INCREF(inst->in_class);
+ inst->in_dict = PyDict_New();
+ if (inst->in_dict == NULL) {
+ Py_DECREF(inst);
+ return NULL;
+ }
+#ifdef Py_TPFLAGS_HAVE_WEAKREFS
+ inst->in_weakreflist = NULL;
+#endif
+#ifdef Py_TPFLAGS_GC
+ PyObject_GC_Init(inst);
+#endif
+ PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this);
+ return (PyObject *) inst;
+#endif
+#endif
+}
+
+SWIGRUNTIME void
+SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this)
+{
+ PyObject *dict;
+#if (PY_VERSION_HEX >= 0x02020000) && !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
+ PyObject **dictptr = _PyObject_GetDictPtr(inst);
+ if (dictptr != NULL) {
+ dict = *dictptr;
+ if (dict == NULL) {
+ dict = PyDict_New();
+ *dictptr = dict;
+ }
+ PyDict_SetItem(dict, SWIG_This(), swig_this);
+ return;
+ }
+#endif
+ dict = PyObject_GetAttrString(inst, (char*)"__dict__");
+ PyDict_SetItem(dict, SWIG_This(), swig_this);
+ Py_DECREF(dict);
+}
+
+
+SWIGINTERN PyObject *
+SWIG_Python_InitShadowInstance(PyObject *args) {
+ PyObject *obj[2];
+ if (!SWIG_Python_UnpackTuple(args,(char*)"swiginit", 2, 2, obj)) {
+ return NULL;
+ } else {
+ PySwigObject *sthis = SWIG_Python_GetSwigThis(obj[0]);
+ if (sthis) {
+ PySwigObject_append((PyObject*) sthis, obj[1]);
+ } else {
+ SWIG_Python_SetSwigThis(obj[0], obj[1]);
+ }
+ return SWIG_Py_Void();
+ }
+}
+
+/* Create a new pointer object */
+
+SWIGRUNTIME PyObject *
+SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int flags) {
+ if (!ptr) {
+ return SWIG_Py_Void();
+ } else {
+ int own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0;
+ PyObject *robj = PySwigObject_New(ptr, type, own);
+ PySwigClientData *clientdata = type ? (PySwigClientData *)(type->clientdata) : 0;
+ if (clientdata && !(flags & SWIG_POINTER_NOSHADOW)) {
+ PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj);
+ if (inst) {
+ Py_DECREF(robj);
+ robj = inst;
+ }
+ }
+ return robj;
+ }
+}
+
+/* Create a new packed object */
+
+SWIGRUNTIMEINLINE PyObject *
+SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) {
+ return ptr ? PySwigPacked_New((void *) ptr, sz, type) : SWIG_Py_Void();
+}
+
+/* -----------------------------------------------------------------------------*
+ * Get type list
+ * -----------------------------------------------------------------------------*/
+
+#ifdef SWIG_LINK_RUNTIME
+void *SWIG_ReturnGlobalTypeList(void *);
+#endif
+
+SWIGRUNTIME swig_module_info *
+SWIG_Python_GetModule(void) {
+ static void *type_pointer = (void *)0;
+ /* first check if module already created */
+ if (!type_pointer) {
+#ifdef SWIG_LINK_RUNTIME
+ type_pointer = SWIG_ReturnGlobalTypeList((void *)0);
+#else
+ type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION,
+ (char*)"type_pointer" SWIG_TYPE_TABLE_NAME);
+ if (PyErr_Occurred()) {
+ PyErr_Clear();
+ type_pointer = (void *)0;
+ }
+#endif
+ }
+ return (swig_module_info *) type_pointer;
+}
+
+#if PY_MAJOR_VERSION < 2
+/* PyModule_AddObject function was introduced in Python 2.0. The following function
+ is copied out of Python/modsupport.c in python version 2.3.4 */
+SWIGINTERN int
+PyModule_AddObject(PyObject *m, char *name, PyObject *o)
+{
+ PyObject *dict;
+ if (!PyModule_Check(m)) {
+ PyErr_SetString(PyExc_TypeError,
+ "PyModule_AddObject() needs module as first arg");
+ return SWIG_ERROR;
+ }
+ if (!o) {
+ PyErr_SetString(PyExc_TypeError,
+ "PyModule_AddObject() needs non-NULL value");
+ return SWIG_ERROR;
+ }
+
+ dict = PyModule_GetDict(m);
+ if (dict == NULL) {
+ /* Internal error -- modules must have a dict! */
+ PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__",
+ PyModule_GetName(m));
+ return SWIG_ERROR;
+ }
+ if (PyDict_SetItemString(dict, name, o))
+ return SWIG_ERROR;
+ Py_DECREF(o);
+ return SWIG_OK;
+}
+#endif
+
+SWIGRUNTIME void
+SWIG_Python_DestroyModule(void *vptr)
+{
+ swig_module_info *swig_module = (swig_module_info *) vptr;
+ swig_type_info **types = swig_module->types;
+ size_t i;
+ for (i =0; i < swig_module->size; ++i) {
+ swig_type_info *ty = types[i];
+ if (ty->owndata) {
+ PySwigClientData *data = (PySwigClientData *) ty->clientdata;
+ if (data) PySwigClientData_Del(data);
+ }
+ }
+ Py_DECREF(SWIG_This());
+}
+
+SWIGRUNTIME void
+SWIG_Python_SetModule(swig_module_info *swig_module) {
+ static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} };/* Sentinel */
+
+ PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION,
+ swig_empty_runtime_method_table);
+ PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule);
+ if (pointer && module) {
+ PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer);
+ } else {
+ Py_XDECREF(pointer);
+ }
+}
+
+/* The python cached type query */
+SWIGRUNTIME PyObject *
+SWIG_Python_TypeCache(void) {
+ static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New();
+ return cache;
+}
+
+SWIGRUNTIME swig_type_info *
+SWIG_Python_TypeQuery(const char *type)
+{
+ PyObject *cache = SWIG_Python_TypeCache();
+ PyObject *key = PyString_FromString(type);
+ PyObject *obj = PyDict_GetItem(cache, key);
+ swig_type_info *descriptor;
+ if (obj) {
+ descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj);
+ } else {
+ swig_module_info *swig_module = SWIG_Python_GetModule();
+ descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type);
+ if (descriptor) {
+ obj = PyCObject_FromVoidPtr(descriptor, NULL);
+ PyDict_SetItem(cache, key, obj);
+ Py_DECREF(obj);
+ }
+ }
+ Py_DECREF(key);
+ return descriptor;
+}
+
+/*
+ For backward compatibility only
+*/
+#define SWIG_POINTER_EXCEPTION 0
+#define SWIG_arg_fail(arg) SWIG_Python_ArgFail(arg)
+#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags)
+
+SWIGRUNTIME int
+SWIG_Python_AddErrMesg(const char* mesg, int infront)
+{
+ if (PyErr_Occurred()) {
+ PyObject *type = 0;
+ PyObject *value = 0;
+ PyObject *traceback = 0;
+ PyErr_Fetch(&type, &value, &traceback);
+ if (value) {
+ PyObject *old_str = PyObject_Str(value);
+ Py_XINCREF(type);
+ PyErr_Clear();
+ if (infront) {
+ PyErr_Format(type, "%s %s", mesg, PyString_AsString(old_str));
+ } else {
+ PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg);
+ }
+ Py_DECREF(old_str);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+SWIGRUNTIME int
+SWIG_Python_ArgFail(int argnum)
+{
+ if (PyErr_Occurred()) {
+ /* add information about failing argument */
+ char mesg[256];
+ PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum);
+ return SWIG_Python_AddErrMesg(mesg, 1);
+ } else {
+ return 0;
+ }
+}
+
+SWIGRUNTIMEINLINE const char *
+PySwigObject_GetDesc(PyObject *self)
+{
+ PySwigObject *v = (PySwigObject *)self;
+ swig_type_info *ty = v ? v->ty : 0;
+ return ty ? ty->str : (char*)"";
+}
+
+SWIGRUNTIME void
+SWIG_Python_TypeError(const char *type, PyObject *obj)
+{
+ if (type) {
+#if defined(SWIG_COBJECT_TYPES)
+ if (obj && PySwigObject_Check(obj)) {
+ const char *otype = (const char *) PySwigObject_GetDesc(obj);
+ if (otype) {
+ PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'PySwigObject(%s)' is received",
+ type, otype);
+ return;
+ }
+ } else
+#endif
+ {
+ const char *otype = (obj ? obj->ob_type->tp_name : 0);
+ if (otype) {
+ PyObject *str = PyObject_Str(obj);
+ const char *cstr = str ? PyString_AsString(str) : 0;
+ if (cstr) {
+ PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received",
+ type, otype, cstr);
+ } else {
+ PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received",
+ type, otype);
+ }
+ Py_XDECREF(str);
+ return;
+ }
+ }
+ PyErr_Format(PyExc_TypeError, "a '%s' is expected", type);
+ } else {
+ PyErr_Format(PyExc_TypeError, "unexpected type is received");
+ }
+}
+
+
+/* Convert a pointer value, signal an exception on a type mismatch */
+SWIGRUNTIME void *
+SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) {
+ void *result;
+ if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) {
+ PyErr_Clear();
+ if (flags & SWIG_POINTER_EXCEPTION) {
+ SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj);
+ SWIG_Python_ArgFail(argnum);
+ }
+ }
+ return result;
+}
+
+
+#ifdef __cplusplus
+#if 0
+{ /* cc-mode */
+#endif
+}
+#endif
+
+
+
+#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0)
+
+#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else
+
+
+
+/* -------- TYPES TABLE (BEGIN) -------- */
+
+#define SWIGTYPE_p_char swig_types[0]
+static swig_type_info *swig_types[2];
+static swig_module_info swig_module = {swig_types, 1, 0, 0, 0, 0};
+#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
+#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
+
+/* -------- TYPES TABLE (END) -------- */
+
+#if (PY_VERSION_HEX <= 0x02000000)
+# if !defined(SWIG_PYTHON_CLASSIC)
+# error "This python version requires swig to be run with the '-classic' option"
+# endif
+#endif
+
+/*-----------------------------------------------
+ @(target):= _libecryptfs.so
+ ------------------------------------------------*/
+#define SWIG_init init_libecryptfs
+
+#define SWIG_name "_libecryptfs"
+
+#define SWIGVERSION 0x010336
+#define SWIG_VERSION SWIGVERSION
+
+
+#define SWIG_as_voidptr(a) (void *)((const void *)(a))
+#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a))
+
+
+#include "../include/ecryptfs.h"
+extern binary_data ecryptfs_passphrase_blob(char *salt, char *passphrase);
+extern binary_data ecryptfs_passphrase_sig_from_blob(char *blob);
+extern int ecryptfs_add_blob_to_keyring(char *blob, char *sig);
+
+
+SWIGINTERN swig_type_info*
+SWIG_pchar_descriptor(void)
+{
+ static int init = 0;
+ static swig_type_info* info = 0;
+ if (!init) {
+ info = SWIG_TypeQuery("_p_char");
+ init = 1;
+ }
+ return info;
+}
+
+
+SWIGINTERN int
+SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
+{
+ if (PyString_Check(obj)) {
+ char *cstr; Py_ssize_t len;
+ PyString_AsStringAndSize(obj, &cstr, &len);
+ if (cptr) {
+ if (alloc) {
+ /*
+ In python the user should not be able to modify the inner
+ string representation. To warranty that, if you define
+ SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string
+ buffer is always returned.
+
+ The default behavior is just to return the pointer value,
+ so, be careful.
+ */
+#if defined(SWIG_PYTHON_SAFE_CSTRINGS)
+ if (*alloc != SWIG_OLDOBJ)
+#else
+ if (*alloc == SWIG_NEWOBJ)
+#endif
+ {
+ *cptr = (char *)memcpy((char *)malloc((len + 1)*sizeof(char)), cstr, sizeof(char)*(len + 1));
+ *alloc = SWIG_NEWOBJ;
+ }
+ else {
+ *cptr = cstr;
+ *alloc = SWIG_OLDOBJ;
+ }
+ } else {
+ *cptr = PyString_AsString(obj);
+ }
+ }
+ if (psize) *psize = len + 1;
+ return SWIG_OK;
+ } else {
+ swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
+ if (pchar_descriptor) {
+ void* vptr = 0;
+ if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) {
+ if (cptr) *cptr = (char *) vptr;
+ if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0;
+ if (alloc) *alloc = SWIG_OLDOBJ;
+ return SWIG_OK;
+ }
+ }
+ }
+ return SWIG_TypeError;
+}
+
+
+
+
+
+ #define SWIG_From_long PyInt_FromLong
+
+
+SWIGINTERNINLINE PyObject *
+SWIG_From_int (int value)
+{
+ return SWIG_From_long (value);
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+SWIGINTERN PyObject *_wrap_ecryptfs_passphrase_blob(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ char *arg1 = (char *) 0 ;
+ char *arg2 = (char *) 0 ;
+ int res1 ;
+ char *buf1 = 0 ;
+ int alloc1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ binary_data result;
+
+ if (!PyArg_ParseTuple(args,(char *)"OO:ecryptfs_passphrase_blob",&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ecryptfs_passphrase_blob" "', argument " "1"" of type '" "char *""'");
+ }
+ arg1 = (char *)(buf1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ecryptfs_passphrase_blob" "', argument " "2"" of type '" "char *""'");
+ }
+ arg2 = (char *)(buf2);
+ result = ecryptfs_passphrase_blob(arg1,arg2);
+ {
+ resultobj = PyString_FromStringAndSize((char *)((&result)->data),(&result)->size);
+ }
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return resultobj;
+fail:
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ecryptfs_passphrase_sig_from_blob(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ char *arg1 = (char *) 0 ;
+ int res1 ;
+ char *buf1 = 0 ;
+ int alloc1 = 0 ;
+ PyObject * obj0 = 0 ;
+ binary_data result;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:ecryptfs_passphrase_sig_from_blob",&obj0)) SWIG_fail;
+ res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ecryptfs_passphrase_sig_from_blob" "', argument " "1"" of type '" "char *""'");
+ }
+ arg1 = (char *)(buf1);
+ result = ecryptfs_passphrase_sig_from_blob(arg1);
+ {
+ resultobj = PyString_FromStringAndSize((char *)((&result)->data),(&result)->size);
+ }
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ return resultobj;
+fail:
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_ecryptfs_add_blob_to_keyring(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ char *arg1 = (char *) 0 ;
+ char *arg2 = (char *) 0 ;
+ int res1 ;
+ char *buf1 = 0 ;
+ int alloc1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ int result;
+
+ if (!PyArg_ParseTuple(args,(char *)"OO:ecryptfs_add_blob_to_keyring",&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1);
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ecryptfs_add_blob_to_keyring" "', argument " "1"" of type '" "char *""'");
+ }
+ arg1 = (char *)(buf1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "ecryptfs_add_blob_to_keyring" "', argument " "2"" of type '" "char *""'");
+ }
+ arg2 = (char *)(buf2);
+ result = (int)ecryptfs_add_blob_to_keyring(arg1,arg2);
+ resultobj = SWIG_From_int((int)(result));
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return resultobj;
+fail:
+ if (alloc1 == SWIG_NEWOBJ) free((char*)buf1);
+ if (alloc2 == SWIG_NEWOBJ) free((char*)buf2);
+ return NULL;
+}
+
+
+static PyMethodDef SwigMethods[] = {
+ { (char *)"ecryptfs_passphrase_blob", _wrap_ecryptfs_passphrase_blob, METH_VARARGS, NULL},
+ { (char *)"ecryptfs_passphrase_sig_from_blob", _wrap_ecryptfs_passphrase_sig_from_blob, METH_VARARGS, NULL},
+ { (char *)"ecryptfs_add_blob_to_keyring", _wrap_ecryptfs_add_blob_to_keyring, METH_VARARGS, NULL},
+ { NULL, NULL, 0, NULL }
+};
+
+
+/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */
+
+static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0};
+
+static swig_type_info *swig_type_initial[] = {
+ &_swigt__p_char,
+};
+
+static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}};
+
+static swig_cast_info *swig_cast_initial[] = {
+ _swigc__p_char,
+};
+
+
+/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */
+
+static swig_const_info swig_const_table[] = {
+{0, 0, 0, 0.0, 0, 0}};
+
+#ifdef __cplusplus
+}
+#endif
+/* -----------------------------------------------------------------------------
+ * Type initialization:
+ * This problem is tough by the requirement that no dynamic
+ * memory is used. Also, since swig_type_info structures store pointers to
+ * swig_cast_info structures and swig_cast_info structures store pointers back
+ * to swig_type_info structures, we need some lookup code at initialization.
+ * The idea is that swig generates all the structures that are needed.
+ * The runtime then collects these partially filled structures.
+ * The SWIG_InitializeModule function takes these initial arrays out of
+ * swig_module, and does all the lookup, filling in the swig_module.types
+ * array with the correct data and linking the correct swig_cast_info
+ * structures together.
+ *
+ * The generated swig_type_info structures are assigned staticly to an initial
+ * array. We just loop through that array, and handle each type individually.
+ * First we lookup if this type has been already loaded, and if so, use the
+ * loaded structure instead of the generated one. Then we have to fill in the
+ * cast linked list. The cast data is initially stored in something like a
+ * two-dimensional array. Each row corresponds to a type (there are the same
+ * number of rows as there are in the swig_type_initial array). Each entry in
+ * a column is one of the swig_cast_info structures for that type.
+ * The cast_initial array is actually an array of arrays, because each row has
+ * a variable number of columns. So to actually build the cast linked list,
+ * we find the array of casts associated with the type, and loop through it
+ * adding the casts to the list. The one last trick we need to do is making
+ * sure the type pointer in the swig_cast_info struct is correct.
+ *
+ * First off, we lookup the cast->type name to see if it is already loaded.
+ * There are three cases to handle:
+ * 1) If the cast->type has already been loaded AND the type we are adding
+ * casting info to has not been loaded (it is in this module), THEN we
+ * replace the cast->type pointer with the type pointer that has already
+ * been loaded.
+ * 2) If BOTH types (the one we are adding casting info to, and the
+ * cast->type) are loaded, THEN the cast info has already been loaded by
+ * the previous module so we just ignore it.
+ * 3) Finally, if cast->type has not already been loaded, then we add that
+ * swig_cast_info to the linked list (because the cast->type) pointer will
+ * be correct.
+ * ----------------------------------------------------------------------------- */
+
+#ifdef __cplusplus
+extern "C" {
+#if 0
+} /* c-mode */
+#endif
+#endif
+
+#if 0
+#define SWIGRUNTIME_DEBUG
+#endif
+
+
+SWIGRUNTIME void
+SWIG_InitializeModule(void *clientdata) {
+ size_t i;
+ swig_module_info *module_head, *iter;
+ int found, init;
+
+ clientdata = clientdata;
+
+ /* check to see if the circular list has been setup, if not, set it up */
+ if (swig_module.next==0) {
+ /* Initialize the swig_module */
+ swig_module.type_initial = swig_type_initial;
+ swig_module.cast_initial = swig_cast_initial;
+ swig_module.next = &swig_module;
+ init = 1;
+ } else {
+ init = 0;
+ }
+
+ /* Try and load any already created modules */
+ module_head = SWIG_GetModule(clientdata);
+ if (!module_head) {
+ /* This is the first module loaded for this interpreter */
+ /* so set the swig module into the interpreter */
+ SWIG_SetModule(clientdata, &swig_module);
+ module_head = &swig_module;
+ } else {
+ /* the interpreter has loaded a SWIG module, but has it loaded this one? */
+ found=0;
+ iter=module_head;
+ do {
+ if (iter==&swig_module) {
+ found=1;
+ break;
+ }
+ iter=iter->next;
+ } while (iter!= module_head);
+
+ /* if the is found in the list, then all is done and we may leave */
+ if (found) return;
+ /* otherwise we must add out module into the list */
+ swig_module.next = module_head->next;
+ module_head->next = &swig_module;
+ }
+
+ /* When multiple interpeters are used, a module could have already been initialized in
+ a different interpreter, but not yet have a pointer in this interpreter.
+ In this case, we do not want to continue adding types... everything should be
+ set up already */
+ if (init == 0) return;
+
+ /* Now work on filling in swig_module.types */
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: size %d\n", swig_module.size);
+#endif
+ for (i = 0; i < swig_module.size; ++i) {
+ swig_type_info *type = 0;
+ swig_type_info *ret;
+ swig_cast_info *cast;
+
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
+#endif
+
+ /* if there is another module already loaded */
+ if (swig_module.next != &swig_module) {
+ type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name);
+ }
+ if (type) {
+ /* Overwrite clientdata field */
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: found type %s\n", type->name);
+#endif
+ if (swig_module.type_initial[i]->clientdata) {
+ type->clientdata = swig_module.type_initial[i]->clientdata;
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name);
+#endif
+ }
+ } else {
+ type = swig_module.type_initial[i];
+ }
+
+ /* Insert casting types */
+ cast = swig_module.cast_initial[i];
+ while (cast->type) {
+ /* Don't need to add information already in the list */
+ ret = 0;
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: look cast %s\n", cast->type->name);
+#endif
+ if (swig_module.next != &swig_module) {
+ ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name);
+#ifdef SWIGRUNTIME_DEBUG
+ if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name);
+#endif
+ }
+ if (ret) {
+ if (type == swig_module.type_initial[i]) {
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: skip old type %s\n", ret->name);
+#endif
+ cast->type = ret;
+ ret = 0;
+ } else {
+ /* Check for casting already in the list */
+ swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type);
+#ifdef SWIGRUNTIME_DEBUG
+ if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name);
+#endif
+ if (!ocast) ret = 0;
+ }
+ }
+
+ if (!ret) {
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name);
+#endif
+ if (type->cast) {
+ type->cast->prev = cast;
+ cast->next = type->cast;
+ }
+ type->cast = cast;
+ }
+ cast++;
+ }
+ /* Set entry in modules->types array equal to the type */
+ swig_module.types[i] = type;
+ }
+ swig_module.types[i] = 0;
+
+#ifdef SWIGRUNTIME_DEBUG
+ printf("**** SWIG_InitializeModule: Cast List ******\n");
+ for (i = 0; i < swig_module.size; ++i) {
+ int j = 0;
+ swig_cast_info *cast = swig_module.cast_initial[i];
+ printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
+ while (cast->type) {
+ printf("SWIG_InitializeModule: cast type %s\n", cast->type->name);
+ cast++;
+ ++j;
+ }
+ printf("---- Total casts: %d\n",j);
+ }
+ printf("**** SWIG_InitializeModule: Cast List ******\n");
+#endif
+}
+
+/* This function will propagate the clientdata field of type to
+* any new swig_type_info structures that have been added into the list
+* of equivalent types. It is like calling
+* SWIG_TypeClientData(type, clientdata) a second time.
+*/
+SWIGRUNTIME void
+SWIG_PropagateClientData(void) {
+ size_t i;
+ swig_cast_info *equiv;
+ static int init_run = 0;
+
+ if (init_run) return;
+ init_run = 1;
+
+ for (i = 0; i < swig_module.size; i++) {
+ if (swig_module.types[i]->clientdata) {
+ equiv = swig_module.types[i]->cast;
+ while (equiv) {
+ if (!equiv->converter) {
+ if (equiv->type && !equiv->type->clientdata)
+ SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata);
+ }
+ equiv = equiv->next;
+ }
+ }
+ }
+}
+
+#ifdef __cplusplus
+#if 0
+{
+ /* c-mode */
+#endif
+}
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* Python-specific SWIG API */
+#define SWIG_newvarlink() SWIG_Python_newvarlink()
+#define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr)
+#define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants)
+
+ /* -----------------------------------------------------------------------------
+ * global variable support code.
+ * ----------------------------------------------------------------------------- */
+
+ typedef struct swig_globalvar {
+ char *name; /* Name of global variable */
+ PyObject *(*get_attr)(void); /* Return the current value */
+ int (*set_attr)(PyObject *); /* Set the value */
+ struct swig_globalvar *next;
+ } swig_globalvar;
+
+ typedef struct swig_varlinkobject {
+ PyObject_HEAD
+ swig_globalvar *vars;
+ } swig_varlinkobject;
+
+ SWIGINTERN PyObject *
+ swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) {
+ return PyString_FromString("<Swig global variables>");
+ }
+
+ SWIGINTERN PyObject *
+ swig_varlink_str(swig_varlinkobject *v) {
+ PyObject *str = PyString_FromString("(");
+ swig_globalvar *var;
+ for (var = v->vars; var; var=var->next) {
+ PyString_ConcatAndDel(&str,PyString_FromString(var->name));
+ if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", "));
+ }
+ PyString_ConcatAndDel(&str,PyString_FromString(")"));
+ return str;
+ }
+
+ SWIGINTERN int
+ swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) {
+ PyObject *str = swig_varlink_str(v);
+ fprintf(fp,"Swig global variables ");
+ fprintf(fp,"%s\n", PyString_AsString(str));
+ Py_DECREF(str);
+ return 0;
+ }
+
+ SWIGINTERN void
+ swig_varlink_dealloc(swig_varlinkobject *v) {
+ swig_globalvar *var = v->vars;
+ while (var) {
+ swig_globalvar *n = var->next;
+ free(var->name);
+ free(var);
+ var = n;
+ }
+ }
+
+ SWIGINTERN PyObject *
+ swig_varlink_getattr(swig_varlinkobject *v, char *n) {
+ PyObject *res = NULL;
+ swig_globalvar *var = v->vars;
+ while (var) {
+ if (strcmp(var->name,n) == 0) {
+ res = (*var->get_attr)();
+ break;
+ }
+ var = var->next;
+ }
+ if (res == NULL && !PyErr_Occurred()) {
+ PyErr_SetString(PyExc_NameError,"Unknown C global variable");
+ }
+ return res;
+ }
+
+ SWIGINTERN int
+ swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) {
+ int res = 1;
+ swig_globalvar *var = v->vars;
+ while (var) {
+ if (strcmp(var->name,n) == 0) {
+ res = (*var->set_attr)(p);
+ break;
+ }
+ var = var->next;
+ }
+ if (res == 1 && !PyErr_Occurred()) {
+ PyErr_SetString(PyExc_NameError,"Unknown C global variable");
+ }
+ return res;
+ }
+
+ SWIGINTERN PyTypeObject*
+ swig_varlink_type(void) {
+ static char varlink__doc__[] = "Swig var link object";
+ static PyTypeObject varlink_type;
+ static int type_init = 0;
+ if (!type_init) {
+ const PyTypeObject tmp
+ = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /* Number of items in variable part (ob_size) */
+ (char *)"swigvarlink", /* Type name (tp_name) */
+ sizeof(swig_varlinkobject), /* Basic size (tp_basicsize) */
+ 0, /* Itemsize (tp_itemsize) */
+ (destructor) swig_varlink_dealloc, /* Deallocator (tp_dealloc) */
+ (printfunc) swig_varlink_print, /* Print (tp_print) */
+ (getattrfunc) swig_varlink_getattr, /* get attr (tp_getattr) */
+ (setattrfunc) swig_varlink_setattr, /* Set attr (tp_setattr) */
+ 0, /* tp_compare */
+ (reprfunc) swig_varlink_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ (reprfunc)swig_varlink_str, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ 0, /* tp_flags */
+ varlink__doc__, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+#if PY_VERSION_HEX >= 0x02020000
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */
+#endif
+#if PY_VERSION_HEX >= 0x02030000
+ 0, /* tp_del */
+#endif
+#ifdef COUNT_ALLOCS
+ 0,0,0,0 /* tp_alloc -> tp_next */
+#endif
+ };
+ varlink_type = tmp;
+ varlink_type.ob_type = &PyType_Type;
+ type_init = 1;
+ }
+ return &varlink_type;
+ }
+
+ /* Create a variable linking object for use later */
+ SWIGINTERN PyObject *
+ SWIG_Python_newvarlink(void) {
+ swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type());
+ if (result) {
+ result->vars = 0;
+ }
+ return ((PyObject*) result);
+ }
+
+ SWIGINTERN void
+ SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) {
+ swig_varlinkobject *v = (swig_varlinkobject *) p;
+ swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar));
+ if (gv) {
+ size_t size = strlen(name)+1;
+ gv->name = (char *)malloc(size);
+ if (gv->name) {
+ strncpy(gv->name,name,size);
+ gv->get_attr = get_attr;
+ gv->set_attr = set_attr;
+ gv->next = v->vars;
+ }
+ }
+ v->vars = gv;
+ }
+
+ SWIGINTERN PyObject *
+ SWIG_globals(void) {
+ static PyObject *_SWIG_globals = 0;
+ if (!_SWIG_globals) _SWIG_globals = SWIG_newvarlink();
+ return _SWIG_globals;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * constants/methods manipulation
+ * ----------------------------------------------------------------------------- */
+
+ /* Install Constants */
+ SWIGINTERN void
+ SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) {
+ PyObject *obj = 0;
+ size_t i;
+ for (i = 0; constants[i].type; ++i) {
+ switch(constants[i].type) {
+ case SWIG_PY_POINTER:
+ obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0);
+ break;
+ case SWIG_PY_BINARY:
+ obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype));
+ break;
+ default:
+ obj = 0;
+ break;
+ }
+ if (obj) {
+ PyDict_SetItemString(d, constants[i].name, obj);
+ Py_DECREF(obj);
+ }
+ }
+ }
+
+ /* -----------------------------------------------------------------------------*/
+ /* Fix SwigMethods to carry the callback ptrs when needed */
+ /* -----------------------------------------------------------------------------*/
+
+ SWIGINTERN void
+ SWIG_Python_FixMethods(PyMethodDef *methods,
+ swig_const_info *const_table,
+ swig_type_info **types,
+ swig_type_info **types_initial) {
+ size_t i;
+ for (i = 0; methods[i].ml_name; ++i) {
+ const char *c = methods[i].ml_doc;
+ if (c && (c = strstr(c, "swig_ptr: "))) {
+ int j;
+ swig_const_info *ci = 0;
+ const char *name = c + 10;
+ for (j = 0; const_table[j].type; ++j) {
+ if (strncmp(const_table[j].name, name,
+ strlen(const_table[j].name)) == 0) {
+ ci = &(const_table[j]);
+ break;
+ }
+ }
+ if (ci) {
+ size_t shift = (ci->ptype) - types;
+ swig_type_info *ty = types_initial[shift];
+ size_t ldoc = (c - methods[i].ml_doc);
+ size_t lptr = strlen(ty->name)+2*sizeof(void*)+2;
+ char *ndoc = (char*)malloc(ldoc + lptr + 10);
+ if (ndoc) {
+ char *buff = ndoc;
+ void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0;
+ if (ptr) {
+ strncpy(buff, methods[i].ml_doc, ldoc);
+ buff += ldoc;
+ strncpy(buff, "swig_ptr: ", 10);
+ buff += 10;
+ SWIG_PackVoidPtr(buff, ptr, ty->name, lptr);
+ methods[i].ml_doc = ndoc;
+ }
+ }
+ }
+ }
+ }
+ }
+
+#ifdef __cplusplus
+}
+#endif
+
+/* -----------------------------------------------------------------------------*
+ * Partial Init method
+ * -----------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+extern "C"
+#endif
+SWIGEXPORT void SWIG_init(void) {
+ PyObject *m, *d;
+
+ /* Fix SwigMethods to carry the callback ptrs when needed */
+ SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial);
+
+ m = Py_InitModule((char *) SWIG_name, SwigMethods);
+ d = PyModule_GetDict(m);
+
+ SWIG_InitializeModule(0);
+ SWIG_InstallConstants(d,swig_const_table);
+
+
+}
+
diff --git a/src/libecryptfs/Makefile.am b/src/libecryptfs/Makefile.am
new file mode 100644
index 0000000..590fdd6
--- /dev/null
+++ b/src/libecryptfs/Makefile.am
@@ -0,0 +1,28 @@
+MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+
+lib_LTLIBRARIES = libecryptfs.la
+
+pkgconfig_DATA = libecryptfs.pc
+
+libecryptfs_la_SOURCES = \
+ main.c \
+ messaging.c \
+ packets.c \
+ miscdev.c \
+ sysfs.c \
+ key_management.c \
+ decision_graph.c \
+ cmd_ln_parser.c \
+ module_mgr.c \
+ key_mod.c \
+ ecryptfs-stat.c \
+ $(top_srcdir)/src/key_mod/ecryptfs_key_mod_passphrase.c
+
+libecryptfs_la_LDFLAGS = \
+ -version-info @LIBECRYPTFS_LT_CURRENT@:@LIBECRYPTFS_LT_REVISION@:@LIBECRYPTFS_LT_AGE@ \
+ -no-undefined
+libecryptfs_la_CFLAGS = $(AM_CFLAGS) $(CRYPTO_CFLAGS) $(KEYUTILS_CFLAGS)
+libecryptfs_la_LIBADD = $(CRYPTO_LIBS) $(KEYUTILS_LIBS)
+
+splint:
+ splint -warnposix -preproc -unrecog -predboolint -boolops +matchanyintegral *.c
diff --git a/src/libecryptfs/Makefile.in b/src/libecryptfs/Makefile.in
new file mode 100644
index 0000000..ac376b0
--- /dev/null
+++ b/src/libecryptfs/Makefile.in
@@ -0,0 +1,875 @@
+# 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@
+subdir = src/libecryptfs
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(srcdir)/libecryptfs.pc.in $(top_srcdir)/depcomp
+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 = libecryptfs.pc
+CONFIG_CLEAN_VPATH_FILES =
+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; }; \
+ }
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)"
+LTLIBRARIES = $(lib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libecryptfs_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ $(am__DEPENDENCIES_1)
+am_libecryptfs_la_OBJECTS = libecryptfs_la-main.lo \
+ libecryptfs_la-messaging.lo libecryptfs_la-packets.lo \
+ libecryptfs_la-miscdev.lo libecryptfs_la-sysfs.lo \
+ libecryptfs_la-key_management.lo \
+ libecryptfs_la-decision_graph.lo \
+ libecryptfs_la-cmd_ln_parser.lo libecryptfs_la-module_mgr.lo \
+ libecryptfs_la-key_mod.lo libecryptfs_la-ecryptfs-stat.lo \
+ libecryptfs_la-ecryptfs_key_mod_passphrase.lo
+libecryptfs_la_OBJECTS = $(am_libecryptfs_la_OBJECTS)
+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 =
+libecryptfs_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(libecryptfs_la_CFLAGS) $(CFLAGS) $(libecryptfs_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+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 = $(libecryptfs_la_SOURCES)
+DIST_SOURCES = $(libecryptfs_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+DATA = $(pkgconfig_DATA)
+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
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+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
+lib_LTLIBRARIES = libecryptfs.la
+pkgconfig_DATA = libecryptfs.pc
+libecryptfs_la_SOURCES = \
+ main.c \
+ messaging.c \
+ packets.c \
+ miscdev.c \
+ sysfs.c \
+ key_management.c \
+ decision_graph.c \
+ cmd_ln_parser.c \
+ module_mgr.c \
+ key_mod.c \
+ ecryptfs-stat.c \
+ $(top_srcdir)/src/key_mod/ecryptfs_key_mod_passphrase.c
+
+libecryptfs_la_LDFLAGS = \
+ -version-info @LIBECRYPTFS_LT_CURRENT@:@LIBECRYPTFS_LT_REVISION@:@LIBECRYPTFS_LT_AGE@ \
+ -no-undefined
+
+libecryptfs_la_CFLAGS = $(AM_CFLAGS) $(CRYPTO_CFLAGS) $(KEYUTILS_CFLAGS)
+libecryptfs_la_LIBADD = $(CRYPTO_LIBS) $(KEYUTILS_LIBS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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/libecryptfs/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/libecryptfs/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):
+libecryptfs.pc: $(top_builddir)/config.status $(srcdir)/libecryptfs.pc.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ }
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+libecryptfs.la: $(libecryptfs_la_OBJECTS) $(libecryptfs_la_DEPENDENCIES) $(EXTRA_libecryptfs_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libecryptfs_la_LINK) -rpath $(libdir) $(libecryptfs_la_OBJECTS) $(libecryptfs_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecryptfs_la-cmd_ln_parser.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecryptfs_la-decision_graph.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecryptfs_la-ecryptfs-stat.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecryptfs_la-ecryptfs_key_mod_passphrase.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecryptfs_la-key_management.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecryptfs_la-key_mod.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecryptfs_la-main.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecryptfs_la-messaging.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecryptfs_la-miscdev.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecryptfs_la-module_mgr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecryptfs_la-packets.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecryptfs_la-sysfs.Plo@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 $@ $<
+
+libecryptfs_la-main.lo: main.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_la_CFLAGS) $(CFLAGS) -MT libecryptfs_la-main.lo -MD -MP -MF $(DEPDIR)/libecryptfs_la-main.Tpo -c -o libecryptfs_la-main.lo `test -f 'main.c' || echo '$(srcdir)/'`main.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecryptfs_la-main.Tpo $(DEPDIR)/libecryptfs_la-main.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main.c' object='libecryptfs_la-main.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_la_CFLAGS) $(CFLAGS) -c -o libecryptfs_la-main.lo `test -f 'main.c' || echo '$(srcdir)/'`main.c
+
+libecryptfs_la-messaging.lo: messaging.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_la_CFLAGS) $(CFLAGS) -MT libecryptfs_la-messaging.lo -MD -MP -MF $(DEPDIR)/libecryptfs_la-messaging.Tpo -c -o libecryptfs_la-messaging.lo `test -f 'messaging.c' || echo '$(srcdir)/'`messaging.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecryptfs_la-messaging.Tpo $(DEPDIR)/libecryptfs_la-messaging.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='messaging.c' object='libecryptfs_la-messaging.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_la_CFLAGS) $(CFLAGS) -c -o libecryptfs_la-messaging.lo `test -f 'messaging.c' || echo '$(srcdir)/'`messaging.c
+
+libecryptfs_la-packets.lo: packets.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_la_CFLAGS) $(CFLAGS) -MT libecryptfs_la-packets.lo -MD -MP -MF $(DEPDIR)/libecryptfs_la-packets.Tpo -c -o libecryptfs_la-packets.lo `test -f 'packets.c' || echo '$(srcdir)/'`packets.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecryptfs_la-packets.Tpo $(DEPDIR)/libecryptfs_la-packets.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='packets.c' object='libecryptfs_la-packets.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_la_CFLAGS) $(CFLAGS) -c -o libecryptfs_la-packets.lo `test -f 'packets.c' || echo '$(srcdir)/'`packets.c
+
+libecryptfs_la-miscdev.lo: miscdev.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_la_CFLAGS) $(CFLAGS) -MT libecryptfs_la-miscdev.lo -MD -MP -MF $(DEPDIR)/libecryptfs_la-miscdev.Tpo -c -o libecryptfs_la-miscdev.lo `test -f 'miscdev.c' || echo '$(srcdir)/'`miscdev.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecryptfs_la-miscdev.Tpo $(DEPDIR)/libecryptfs_la-miscdev.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='miscdev.c' object='libecryptfs_la-miscdev.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_la_CFLAGS) $(CFLAGS) -c -o libecryptfs_la-miscdev.lo `test -f 'miscdev.c' || echo '$(srcdir)/'`miscdev.c
+
+libecryptfs_la-sysfs.lo: sysfs.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_la_CFLAGS) $(CFLAGS) -MT libecryptfs_la-sysfs.lo -MD -MP -MF $(DEPDIR)/libecryptfs_la-sysfs.Tpo -c -o libecryptfs_la-sysfs.lo `test -f 'sysfs.c' || echo '$(srcdir)/'`sysfs.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecryptfs_la-sysfs.Tpo $(DEPDIR)/libecryptfs_la-sysfs.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sysfs.c' object='libecryptfs_la-sysfs.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_la_CFLAGS) $(CFLAGS) -c -o libecryptfs_la-sysfs.lo `test -f 'sysfs.c' || echo '$(srcdir)/'`sysfs.c
+
+libecryptfs_la-key_management.lo: key_management.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_la_CFLAGS) $(CFLAGS) -MT libecryptfs_la-key_management.lo -MD -MP -MF $(DEPDIR)/libecryptfs_la-key_management.Tpo -c -o libecryptfs_la-key_management.lo `test -f 'key_management.c' || echo '$(srcdir)/'`key_management.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecryptfs_la-key_management.Tpo $(DEPDIR)/libecryptfs_la-key_management.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='key_management.c' object='libecryptfs_la-key_management.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_la_CFLAGS) $(CFLAGS) -c -o libecryptfs_la-key_management.lo `test -f 'key_management.c' || echo '$(srcdir)/'`key_management.c
+
+libecryptfs_la-decision_graph.lo: decision_graph.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_la_CFLAGS) $(CFLAGS) -MT libecryptfs_la-decision_graph.lo -MD -MP -MF $(DEPDIR)/libecryptfs_la-decision_graph.Tpo -c -o libecryptfs_la-decision_graph.lo `test -f 'decision_graph.c' || echo '$(srcdir)/'`decision_graph.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecryptfs_la-decision_graph.Tpo $(DEPDIR)/libecryptfs_la-decision_graph.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='decision_graph.c' object='libecryptfs_la-decision_graph.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_la_CFLAGS) $(CFLAGS) -c -o libecryptfs_la-decision_graph.lo `test -f 'decision_graph.c' || echo '$(srcdir)/'`decision_graph.c
+
+libecryptfs_la-cmd_ln_parser.lo: cmd_ln_parser.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_la_CFLAGS) $(CFLAGS) -MT libecryptfs_la-cmd_ln_parser.lo -MD -MP -MF $(DEPDIR)/libecryptfs_la-cmd_ln_parser.Tpo -c -o libecryptfs_la-cmd_ln_parser.lo `test -f 'cmd_ln_parser.c' || echo '$(srcdir)/'`cmd_ln_parser.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecryptfs_la-cmd_ln_parser.Tpo $(DEPDIR)/libecryptfs_la-cmd_ln_parser.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='cmd_ln_parser.c' object='libecryptfs_la-cmd_ln_parser.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_la_CFLAGS) $(CFLAGS) -c -o libecryptfs_la-cmd_ln_parser.lo `test -f 'cmd_ln_parser.c' || echo '$(srcdir)/'`cmd_ln_parser.c
+
+libecryptfs_la-module_mgr.lo: module_mgr.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_la_CFLAGS) $(CFLAGS) -MT libecryptfs_la-module_mgr.lo -MD -MP -MF $(DEPDIR)/libecryptfs_la-module_mgr.Tpo -c -o libecryptfs_la-module_mgr.lo `test -f 'module_mgr.c' || echo '$(srcdir)/'`module_mgr.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecryptfs_la-module_mgr.Tpo $(DEPDIR)/libecryptfs_la-module_mgr.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='module_mgr.c' object='libecryptfs_la-module_mgr.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_la_CFLAGS) $(CFLAGS) -c -o libecryptfs_la-module_mgr.lo `test -f 'module_mgr.c' || echo '$(srcdir)/'`module_mgr.c
+
+libecryptfs_la-key_mod.lo: key_mod.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_la_CFLAGS) $(CFLAGS) -MT libecryptfs_la-key_mod.lo -MD -MP -MF $(DEPDIR)/libecryptfs_la-key_mod.Tpo -c -o libecryptfs_la-key_mod.lo `test -f 'key_mod.c' || echo '$(srcdir)/'`key_mod.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecryptfs_la-key_mod.Tpo $(DEPDIR)/libecryptfs_la-key_mod.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='key_mod.c' object='libecryptfs_la-key_mod.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_la_CFLAGS) $(CFLAGS) -c -o libecryptfs_la-key_mod.lo `test -f 'key_mod.c' || echo '$(srcdir)/'`key_mod.c
+
+libecryptfs_la-ecryptfs-stat.lo: ecryptfs-stat.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_la_CFLAGS) $(CFLAGS) -MT libecryptfs_la-ecryptfs-stat.lo -MD -MP -MF $(DEPDIR)/libecryptfs_la-ecryptfs-stat.Tpo -c -o libecryptfs_la-ecryptfs-stat.lo `test -f 'ecryptfs-stat.c' || echo '$(srcdir)/'`ecryptfs-stat.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecryptfs_la-ecryptfs-stat.Tpo $(DEPDIR)/libecryptfs_la-ecryptfs-stat.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ecryptfs-stat.c' object='libecryptfs_la-ecryptfs-stat.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_la_CFLAGS) $(CFLAGS) -c -o libecryptfs_la-ecryptfs-stat.lo `test -f 'ecryptfs-stat.c' || echo '$(srcdir)/'`ecryptfs-stat.c
+
+libecryptfs_la-ecryptfs_key_mod_passphrase.lo: $(top_srcdir)/src/key_mod/ecryptfs_key_mod_passphrase.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_la_CFLAGS) $(CFLAGS) -MT libecryptfs_la-ecryptfs_key_mod_passphrase.lo -MD -MP -MF $(DEPDIR)/libecryptfs_la-ecryptfs_key_mod_passphrase.Tpo -c -o libecryptfs_la-ecryptfs_key_mod_passphrase.lo `test -f '$(top_srcdir)/src/key_mod/ecryptfs_key_mod_passphrase.c' || echo '$(srcdir)/'`$(top_srcdir)/src/key_mod/ecryptfs_key_mod_passphrase.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecryptfs_la-ecryptfs_key_mod_passphrase.Tpo $(DEPDIR)/libecryptfs_la-ecryptfs_key_mod_passphrase.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$(top_srcdir)/src/key_mod/ecryptfs_key_mod_passphrase.c' object='libecryptfs_la-ecryptfs_key_mod_passphrase.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libecryptfs_la_CFLAGS) $(CFLAGS) -c -o libecryptfs_la-ecryptfs_key_mod_passphrase.lo `test -f '$(top_srcdir)/src/key_mod/ecryptfs_key_mod_passphrase.c' || echo '$(srcdir)/'`$(top_srcdir)/src/key_mod/ecryptfs_key_mod_passphrase.c
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-pkgconfigDATA: $(pkgconfig_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \
+ done
+
+uninstall-pkgconfigDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir)
+
+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
+
+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
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)"; 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:
+
+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-generic clean-libLTLIBRARIES clean-libtool \
+ 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-pkgconfigDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-libLTLIBRARIES
+
+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-libLTLIBRARIES uninstall-pkgconfigDATA
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libLTLIBRARIES clean-libtool 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-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-libLTLIBRARIES install-man install-pdf \
+ install-pdf-am install-pkgconfigDATA install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \
+ uninstall-libLTLIBRARIES uninstall-pkgconfigDATA
+
+
+splint:
+ splint -warnposix -preproc -unrecog -predboolint -boolops +matchanyintegral *.c
+
+# 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/libecryptfs/cmd_ln_parser.c b/src/libecryptfs/cmd_ln_parser.c
new file mode 100644
index 0000000..6c4284c
--- /dev/null
+++ b/src/libecryptfs/cmd_ln_parser.c
@@ -0,0 +1,443 @@
+/**
+ * Copyright (C) 2006 International Business Machines Corp.
+ * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
+ * Trevor Highland <trevor.highland@gmail.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.
+ */
+
+#ifndef S_SPLINT_S
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif /* S_SPLINT_S */
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <string.h>
+#ifndef S_SPLINT_S
+#include <stdio.h>
+#include <syslog.h>
+#endif /* S_SPLINT_S */
+#include <errno.h>
+#include <stdlib.h>
+#include <pwd.h>
+#include "../include/ecryptfs.h"
+
+#define MAX_TOK_LEN 128
+#define MAX_FILE_SIZE 0xa000
+
+int print_nvp_list(struct ecryptfs_name_val_pair *dst)
+{
+ syslog(LOG_ERR, "Printing nvp list\n");
+ while (dst) {
+ syslog(LOG_ERR, "name=%s\n", dst->name);
+ syslog(LOG_ERR, "val=%s\n", dst->value);
+ dst = dst->next;
+ }
+ return 0;
+}
+
+static int copy_nv_pair(struct ecryptfs_name_val_pair *dst,
+ struct ecryptfs_name_val_pair *src)
+{
+ int rc;
+
+ dst->flags = src->flags;
+ if ((rc = asprintf(&dst->name, "%s", src->name)) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ if ((rc = asprintf(&dst->value, "%s", src->value)) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+out:
+ return rc;
+}
+
+/**
+ * For each name in dst that is also in src, set the value in dst to
+ * that which is in src.
+ *
+ * For each name in src that is not in dst, append a copy of the node
+ * onto dst.
+ *
+ * TODO: This function sucks. Partially because the nv data structure
+ * sucks. Overhaul it sometime.
+ */
+int ecryptfs_nvp_list_union(struct ecryptfs_name_val_pair *dst,
+ struct ecryptfs_name_val_pair *src,
+ struct ecryptfs_name_val_pair *allowed_duplicates)
+{
+ int rc = 0;
+ struct ecryptfs_name_val_pair *dst_cursor;
+ struct ecryptfs_name_val_pair *src_cursor;
+
+ src_cursor = src->next;
+ while (src_cursor) {
+ int found_match;
+ struct ecryptfs_name_val_pair *prev_dst_cursor;
+ struct ecryptfs_name_val_pair *ad_cursor;
+
+ if (!src_cursor->name)
+ goto next_src_cursor;
+ found_match = 0;
+ prev_dst_cursor = dst;
+ dst_cursor = dst->next;
+ ad_cursor = allowed_duplicates->next;
+ while (ad_cursor) {
+ if (strcmp(src_cursor->name, ad_cursor->name) == 0) {
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO,
+ "Duplicates allowed for [%s]\n",
+ src_cursor->name);
+ while (dst_cursor) {
+ prev_dst_cursor = dst_cursor;
+ dst_cursor = dst_cursor->next;
+ }
+ goto do_insert;
+ }
+ ad_cursor = ad_cursor->next;
+ }
+ while (dst_cursor) {
+ if (!dst_cursor->name)
+ goto next_dst_cursor;
+ if (strcmp(src_cursor->name, dst_cursor->name) == 0) {
+ found_match = 1;
+ free(dst_cursor->value);
+ rc = asprintf(&dst_cursor->value, "%s",
+ src_cursor->value);
+ if (rc == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+ }
+next_dst_cursor:
+ prev_dst_cursor = dst_cursor;
+ dst_cursor = dst_cursor->next;
+ }
+do_insert:
+ if (!found_match) {
+ struct ecryptfs_name_val_pair *dst_tmp;
+ struct ecryptfs_name_val_pair *src_tmp;
+ int i;
+
+ prev_dst_cursor->next = dst_cursor =
+ malloc(sizeof(struct ecryptfs_name_val_pair));
+ memset(dst_cursor, 0,
+ sizeof(struct ecryptfs_name_val_pair));
+ if (!dst_cursor) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ dst_cursor->next = NULL;
+ if ((rc = copy_nv_pair(dst_cursor, src_cursor))) {
+ goto out;
+ }
+ dst_tmp = dst_cursor;
+ src_tmp = src_cursor;
+ /* TODO: Okay; this has officially become a
+ * hack. It's time to switch to a real tree
+ * structure for the name/value pair list. */
+ for (i = 0; i < NV_MAX_CHILDREN; i++) {
+ if (src_cursor->children[i]) {
+ if ((dst_cursor->children[i]
+ = malloc(sizeof(struct ecryptfs_name_val_pair)))
+ == NULL) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ memset(dst_cursor->children[i], 0,
+ sizeof(struct ecryptfs_name_val_pair));
+ copy_nv_pair(dst_cursor->children[i],
+ src_cursor->children[i]);
+ dst_tmp->next = dst_cursor->children[i];
+ prev_dst_cursor = dst_tmp;
+ dst_tmp = dst_tmp->next;
+ prev_dst_cursor->next = dst_tmp;
+ src_tmp = src_tmp->next;
+ if (src_tmp != src_cursor->children[i]) {
+ rc = -EINVAL;
+ syslog(LOG_ERR,
+ "Internal error: src_tmp"
+ "->next != src_cursor->c"
+ "hildren[%d]\n", i);
+ goto out;
+ }
+ }
+ }
+ dst_cursor = dst_tmp;
+ src_cursor = src_tmp;
+ }
+next_src_cursor:
+ src_cursor = src_cursor->next;
+ }
+out:
+ return rc;
+}
+
+int
+ecryptfs_parse_rc_file_fullpath(struct ecryptfs_name_val_pair *nvp_list_head,
+ char *fullpath)
+{
+ int rc;
+ int fd;
+
+ fd = open(fullpath, O_RDONLY);
+ if (fd == -1) {
+ rc = -errno;
+ goto out;
+ }
+ rc = parse_options_file(fd, nvp_list_head);
+ close(fd);
+out:
+ return rc;
+}
+
+int ecryptfs_parse_rc_file(struct ecryptfs_name_val_pair *nvp_list_head)
+{
+ char *home;
+ uid_t uid;
+ struct passwd *pw;
+ char *rcfile_fullpath;
+ int rc;
+
+ uid = getuid();
+ pw = getpwuid(uid);
+ if (!pw) {
+ rc = -EIO;
+ goto out;
+ }
+ home = pw->pw_dir;
+ rc = asprintf(&rcfile_fullpath, "%s/.ecryptfsrc", home);
+ if (rc == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = ecryptfs_parse_rc_file_fullpath(nvp_list_head, rcfile_fullpath);
+ free(rcfile_fullpath);
+out:
+ return rc;
+}
+
+int process_comma_tok(struct ecryptfs_name_val_pair **current, char *tok,
+ /*@null@*/ char *prefix)
+{
+ int tok_len;
+ char new_prefix[MAX_TOK_LEN];
+ char sub_token[MAX_TOK_LEN];
+ char *name = NULL;
+ char *value = NULL;
+ int i, j, st_len;
+ int rc = 0;
+
+ if (!tok || (tok && tok[0] == '\0')) {
+ goto out;
+ }
+ tok_len = (int)strlen(tok);
+ if (tok_len < 0 || tok_len > MAX_TOK_LEN) {
+ rc = -EINVAL;
+ goto out;
+ }
+ if (tok[0] == '=' || tok[0] == ':') {
+ rc = -EINVAL;
+ goto out;
+ }
+ j = 0;
+ if (tok_len > 4 && !memcmp(tok, "key=", 4))
+ for (i = 4; i < tok_len; i++) {
+ if (tok[i] == ':')
+ goto process_colon_list;
+ }
+ goto process_nv_pair;
+process_colon_list:
+ new_prefix[j] = '\0';
+ i = 0;
+ j = 0;
+ while (i < tok_len) {
+ if (tok[i] == ':') {
+ sub_token[j] = '\0';
+ if ((rc = process_comma_tok(current, sub_token, NULL)))
+ goto out;
+ j = 0;
+ } else
+ sub_token[j++] = tok[i];
+ i++;
+ }
+ sub_token[j] = '\0';
+ rc = process_comma_tok(current, sub_token, new_prefix);
+ goto out;
+process_nv_pair:
+ st_len = snprintf(sub_token, MAX_TOK_LEN, "%s%s",
+ (prefix ? prefix : ""), tok);
+ j = 0;
+ for (i = 0; i < st_len; i++)
+ if (sub_token[i] == '=') {
+ if (name)
+ free(name);
+ if (!(name = malloc(i + 1))) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ memcpy(name, sub_token, i);
+ name[i] = '\0';
+ j = i;
+ }
+ if (!name) {
+ if (!(name = malloc(i+1))) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ memcpy(name, sub_token, i);
+ name[i] = '\0';
+ } else {
+ if ((i-j) > 1) {
+ if (!(value = malloc(i - j + 1))) {
+ rc = -ENOMEM;
+ goto out_free_name;
+ }
+ memcpy(value, &sub_token[j+1], (i - j));
+ value[(i - j)] = '\0';
+ }
+ }
+ if (!((*current)->next =
+ malloc(sizeof(struct ecryptfs_name_val_pair)))) {
+ rc = -ENOMEM;
+ goto out_free_value;
+ }
+ memset((*current)->next, 0, sizeof(struct ecryptfs_name_val_pair));
+ if (strlen(name) == 0) {
+ free(name);
+ free(value);
+ } else {
+ *current = (*current)->next;
+ (*current)->name = name;
+ (*current)->value = value;
+ (*current)->next = NULL;
+ }
+ return rc;
+
+out_free_value:
+ free(value);
+out_free_name:
+ free(name);
+out:
+ return rc;
+}
+
+/**
+ * name=val,key=PKI:name1=val1:name2=val2,name=val...
+ */
+int generate_nv_list(struct ecryptfs_name_val_pair *head, char *buf)
+{
+ struct ecryptfs_name_val_pair *current = head;
+ char tok_str[MAX_TOK_LEN];
+
+ if (!buf)
+ return 0;
+
+ int buf_len = strlen(buf);
+ int i, j = 0;
+ int rc = 0;
+
+ for (i = 0; i < buf_len; i++) {
+ if (buf[i] == ',' || buf[i] == '\n') {
+ tok_str[j] = '\0';
+ if ((rc = process_comma_tok(&current, tok_str, NULL)))
+ goto out;
+ j = 0;
+ } else
+ tok_str[j++] = buf[i];
+ if (j == MAX_TOK_LEN)
+ goto out;
+ }
+ tok_str[j] = '\0';
+ if ((rc = process_comma_tok(&current, tok_str, NULL)))
+ goto out;
+out:
+ return rc;
+}
+
+int ecryptfs_parse_options(char *opts, struct ecryptfs_name_val_pair *head)
+{
+ return generate_nv_list(head, opts);
+}
+
+int parse_options_file(int fd, struct ecryptfs_name_val_pair *head)
+{
+ int rc = 0;
+ char *data;
+ off_t buf_size, pos;
+ struct stat filestat;
+
+ rc = fstat(fd, &filestat);
+ if (rc) {
+ syslog(LOG_ERR, "%s: fstat returned [%d] on fd [%d]\n",
+ __FUNCTION__, rc, fd);
+ goto out;
+ }
+ if (S_ISDIR(filestat.st_mode)) {
+ rc = -EISDIR;
+ goto out;
+ }
+ if (S_ISFIFO(filestat.st_mode)) {
+ buf_size = 1024;
+ } else {
+ buf_size = filestat.st_size;
+ }
+ if (buf_size > MAX_FILE_SIZE) {
+ syslog(LOG_ERR, "File size too large\n");
+ rc = -EFBIG;
+ goto out;
+ }
+ data = (char *)malloc(buf_size + 1);
+ if (!data) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ pos = 0;
+ while (1) {
+ rc = read(fd, data + pos, buf_size - pos);
+ if (rc == 0)
+ break;
+ if (rc == -1) {
+ rc = -errno;
+ syslog(LOG_ERR, "%s: read failed on fd [%d]; rc = [%d]\n",
+ __FUNCTION__, fd, rc);
+ goto out_free;
+ }
+ pos += rc;
+ if (pos >= buf_size) {
+ char *more_data;
+
+ buf_size *= 2;
+ more_data = (char *)realloc(data, buf_size + 1);
+ if (!more_data) {
+ rc = -ENOMEM;
+ goto out_free;
+ }
+ data = more_data;
+ }
+ }
+ data[pos] = '\0';
+ rc = generate_nv_list(head, data);
+out_free:
+ free(data);
+out:
+ return rc;
+}
diff --git a/src/libecryptfs/decision_graph.c b/src/libecryptfs/decision_graph.c
new file mode 100644
index 0000000..e319b46
--- /dev/null
+++ b/src/libecryptfs/decision_graph.c
@@ -0,0 +1,1213 @@
+/**
+ * Copyright (C) 2006 International Business Machines Corp.
+ * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
+ * Trevor Highland <trevor.highland@gmail.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 <stdint.h>
+#ifndef S_SPLINT_S
+#include <stdio.h>
+#include <syslog.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "../include/ecryptfs.h"
+#include "../include/decision_graph.h"
+
+int stack_push(struct val_node **head, void *val)
+{
+ struct val_node *node = malloc(sizeof(struct val_node));
+ int rc = 0;
+
+ if (!node) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ node->val = val;
+ node->next = *head;
+ *head = node;
+out:
+ return rc;
+}
+
+int stack_pop(struct val_node **head)
+{
+ struct val_node *tmp = (*head)->next;
+
+ free((*head)->val);
+ free(*head);
+ *head = tmp;
+ return 0;
+}
+
+int stack_pop_val(struct val_node **head, void **val)
+{
+ if (*head && val) {
+ struct val_node *tmp = (*head)->next;
+
+ *val = (*head)->val;
+ free(*head);
+ *head = tmp;
+ return 0;
+ }
+ return -1;
+}
+
+int free_name_val_pairs(struct ecryptfs_name_val_pair *pair)
+{
+ struct ecryptfs_name_val_pair *next;
+
+ while (pair) {
+ if (pair->value)
+ free(pair->value);
+ if (pair->name)
+ free(pair->name);
+ next = pair->next;
+ free(pair);
+ pair = next;
+ }
+ return 0;
+}
+
+int add_transition_node_to_param_node(struct param_node *param_node,
+ struct transition_node *trans_node)
+{
+ int rc;
+
+ if (param_node->num_transitions >= MAX_NUM_TRANSITIONS) {
+ syslog(LOG_ERR, "Too many transitions on node with primary "
+ "alias [%s]\n", param_node->mnt_opt_names[0]);
+ rc = -ENOMEM;
+ goto out;
+ }
+ memcpy(&(param_node->tl[param_node->num_transitions++]),
+ trans_node, sizeof(*trans_node));
+ rc = 0;
+out:
+ return rc;
+}
+
+/**
+ * set_exit_param_node_for_node
+ *
+ * Sets all NULL next_token's to exit_param_node
+ */
+int set_exit_param_node_for_node(struct param_node *param_node,
+ struct param_node *exit_param_node,
+ int recursive)
+{
+ int i;
+ int rc = 0;
+
+ for (i = 0; i < param_node->num_transitions; i++)
+ if (param_node->tl[i].next_token == NULL) {
+ param_node->tl[i].val = "default";
+ param_node->tl[i].pretty_val = "default";
+ param_node->tl[i].next_token = exit_param_node;
+ } else if (recursive) {
+ rc = set_exit_param_node_for_node(
+ param_node->tl[i].next_token,
+ exit_param_node, 1);
+ if (rc)
+ goto out;
+ }
+out:
+ return rc;
+}
+
+/**
+ * Sets the exit param node for all NULL transitions throughout an
+ * entire graph.
+ */
+int ecryptfs_set_exit_param_on_graph(struct param_node *param_node,
+ struct param_node *exit_param_node)
+{
+ return set_exit_param_node_for_node(param_node, exit_param_node, 1);
+}
+
+void ecryptfs_destroy_nvp(struct ecryptfs_name_val_pair *nvp)
+{
+ return;
+}
+
+int ecryptfs_delete_nvp(struct ecryptfs_name_val_pair *nvp_head,
+ struct ecryptfs_name_val_pair *nvp)
+{
+ int rc = 0;
+
+ while (nvp_head) {
+ if (nvp_head->next == nvp) {
+ nvp_head->next = nvp->next;
+ ecryptfs_destroy_nvp(nvp);
+ goto out;
+ }
+ nvp_head = nvp_head->next;
+ }
+ rc = -EINVAL;
+out:
+ return rc;
+}
+
+/**
+ * do_transition
+ * @ctx: The current eCryptfs library context
+ * @next: Set to the param_node that the transition engine determines
+ * is the next node
+ * @current: The current param_node from which we are transitioning
+ * @nvp_head: The name-value pair list that contains name-value pairs
+ * specified on the command line or provided via the
+ * .ecryptfsrc file. Whenever a param node needs a value,
+ * the decision graph logic first scans this list for a
+ * corresponding name-value pair
+ * @mnt_params: Head of mount option stack that the callback functions
+ * for the transition nodes in the param node populate
+ * @foo: An arbitrary data structure that the transition node callback
+ * functions create, reference, and destroy
+ *
+ * This function needs to compare transition nodes to options.
+ * It is currently comparing them to values provided to options.
+ * i.e., each transition is an option; this is incorrect.
+ */
+int do_transition(struct ecryptfs_ctx *ctx, struct param_node **next,
+ struct param_node *current,
+ struct ecryptfs_name_val_pair *nvp_head,
+ struct val_node **mnt_params, void **foo)
+{
+ static int repeated = 0;
+ static struct param_node *lastnode = NULL;
+ int i, rc;
+
+ if (current != lastnode)
+ repeated = 0;
+
+ lastnode = current;
+
+ for (i = 0; i < current->num_transitions; i++) {
+ struct transition_node *tn = &current->tl[i];
+ struct ecryptfs_name_val_pair *nvp = nvp_head->next;
+
+ if (tn->val && current->val
+ && strcmp(current->val, tn->val) == 0) {
+ rc = 0;
+ if (tn->trans_func) {
+ rc = tn->trans_func(ctx, current,
+ mnt_params, foo);
+ }
+ if ((*next = tn->next_token)) {
+ if (ecryptfs_verbosity) {
+ syslog(LOG_INFO,
+ "Transitioning from [%p]; name "
+ "= [%s] to [%p]; name = [%s] "
+ "per transition node's "
+ "next_token\n", current,
+ current->mnt_opt_names[0],
+ (*next),
+ (*next)->mnt_opt_names[0]);
+ }
+ return rc;
+ }
+ else return EINVAL;
+ }
+ while (nvp) {
+ int trans_func_tok_id = NULL_TOK;
+
+ if (tn->val && strcmp(nvp->name, tn->val)) {
+ nvp = nvp->next;
+ continue;
+ }
+ if (tn->trans_func)
+ trans_func_tok_id =
+ tn->trans_func(ctx, current,
+ mnt_params, foo);
+ if (trans_func_tok_id == MOUNT_ERROR) {
+ return trans_func_tok_id;
+ }
+ if (trans_func_tok_id == DEFAULT_TOK) {
+ if ((*next = tn->next_token))
+ return 0;
+ else
+ return -EINVAL;
+ } else if (trans_func_tok_id == NULL_TOK) {
+ if ((*next = tn->next_token))
+ return 0;
+ else
+ return -EINVAL;
+ }
+ nvp = nvp->next;
+ }
+ }
+ for (i = 0; i < current->num_transitions; i++) {
+ struct transition_node *tn = &current->tl[i];
+
+ if (tn->val && strcmp("default", tn->val) == 0) {
+ int trans_func_tok_id = NULL_TOK;
+
+ if (tn->trans_func)
+ trans_func_tok_id =
+ tn->trans_func(ctx, current,
+ mnt_params, foo);
+ if (trans_func_tok_id == WRONG_VALUE) {
+ if (ctx->verbosity ||
+ (current->flags & STDIN_REQUIRED)) {
+ if (++repeated >= 5)
+ return -EINVAL;
+ else {
+ *next = current;
+ return 0;
+ }
+ } else
+ return -EINVAL;
+ }
+ if (trans_func_tok_id == MOUNT_ERROR ||
+ trans_func_tok_id < 0)
+ return trans_func_tok_id;
+ if ((*next = tn->next_token))
+ return 0;
+ else return -EINVAL;
+ }
+ }
+ if (current->num_transitions)
+ return MOUNT_ERROR;
+ return NULL_TOK;
+}
+
+/**
+ * Try to find one of the aliases for this node in the list of
+ * name-value pairs. If found, set the value from that element in the
+ * list.
+ *
+ * Returns non-zero on error condition
+ */
+static int retrieve_val(int *value_retrieved,
+ struct ecryptfs_name_val_pair *nvp_head,
+ struct param_node *node)
+{
+ int i = node->num_mnt_opt_names;
+ int rc = 0;
+
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO, "%s: Called on node [%s]\n", __FUNCTION__,
+ node->mnt_opt_names[0]);
+ (*value_retrieved) = 0;
+ while (i > 0) {
+ struct ecryptfs_name_val_pair *temp = nvp_head->next;
+
+ i--;
+ while (temp) {
+ if (strcmp(temp->name, node->mnt_opt_names[i]) == 0
+ && !(temp->flags & ECRYPTFS_PROCESSED)) {
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO, "From param_node = "
+ "[%p]; mnt_opt_names[0] = [%s]"
+ ": Setting "
+ "ECRYPTFS_PROCESSED to nvp with "
+ "nvp->name = [%s]\n",
+ node, node->mnt_opt_names[0],
+ temp->name);
+ /* Prevent the same name/value pair
+ * from being consumed twice */
+ temp->flags |= ECRYPTFS_PROCESSED;
+ if (temp->value
+ && (strcmp(temp->value, "(null)") != 0)) {
+ if (asprintf(&node->val, "%s",
+ temp->value) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ } else
+ node->flags |= PARAMETER_SET;
+ (*value_retrieved) = 1;
+ goto out;
+ }
+ temp = temp->next;
+ }
+ }
+ if (node->default_val && (strcmp(node->default_val, "NULL") != 0)) {
+ if (asprintf(&node->val, "%s", node->default_val) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO, "%s: Value retrieved from "
+ "node->default_val = [%s]\n", __FUNCTION__,
+ node->default_val);
+ (*value_retrieved) = 1;
+ goto out;
+ }
+out:
+ return rc;
+}
+
+/**
+ * This function can prompt the user and/or check some list of values
+ * to get what it needs. Caller must free node->val if it winds up
+ * being non-NULL.
+ */
+static int alloc_and_get_val(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct ecryptfs_name_val_pair *nvp_head)
+{
+ char *verify_prompt;
+ char *verify;
+ int val;
+ int value_retrieved;
+ int i;
+ int rc = 0;
+ int tries = 0;
+
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO, "%s: Called on node->mnt_opt_names[0] = [%s]",
+ __FUNCTION__, node->mnt_opt_names[0]);
+ if (node->val) {
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO, "%s: node->val already set to [%s]\n",
+ __FUNCTION__, node->val);
+ goto out;
+ }
+ rc = retrieve_val(&value_retrieved, nvp_head, node);
+ if (rc) {
+ syslog(LOG_ERR, "%s: Error attempting to retrieve value; "
+ "rc = [%d]\n", __FUNCTION__, rc);
+ goto out;
+ }
+ if (value_retrieved) {
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO,
+ "%s: Value retrieved from default_val or from "
+ "parameter list; returning\n",
+ __FUNCTION__);
+ if (!(node->flags & ECRYPTFS_ALLOW_IMPLICIT_TRANSITION
+ && node->flags & ECRYPTFS_IMPLICIT_OVERRIDE_DEFAULT))
+ goto out;
+ }
+ if (node->flags & ECRYPTFS_ALLOW_IMPLICIT_TRANSITION
+ && !(node->flags & ECRYPTFS_NO_AUTO_TRANSITION)) {
+ for (i = 0; i < node->num_transitions; i++) {
+ if (node->tl[i].next_token)
+ rc = retrieve_val(&value_retrieved, nvp_head,
+ node->tl[i].next_token);
+ if (rc) {
+ syslog(LOG_ERR, "%s: Error attempting to "
+ "retrieve value; rc = [%d]\n",
+ __FUNCTION__, rc);
+ goto out;
+ }
+ if (value_retrieved) {
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO,
+ "%s: Value retrieved from "
+ "default_val or from parameter "
+ "list for successive "
+ "node at transition slot [%d]; "
+ "returning\n", __FUNCTION__, i);
+ rc = asprintf(&node->val, "%s",
+ node->tl[i].next_token->mnt_opt_names[0]);
+ if (rc == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+ goto out;
+ }
+ }
+ }
+ if (node->flags & ECRYPTFS_PARAM_FLAG_NO_VALUE) {
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO,
+ "%s: ECRYPTFS_PARAM_FLAG_NO_VALUE set\n",
+ __FUNCTION__);
+ goto out;
+ }
+ if (ctx->verbosity == 0 && !(node->flags & STDIN_REQUIRED)) {
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO, "%s: ctx->verbosity == 0 and "
+ "STDIN_REQUIRED not set\n", __FUNCTION__);
+ goto out;
+ }
+ if ((node->flags & PARAMETER_SET) && !(node->flags & STDIN_REQUIRED)) {
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO, "%s: PARAMETER_SET and "
+ "STDIN_REQUIRED not set\n", __FUNCTION__);
+ goto out;
+ }
+ if (ctx->get_string) {
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO, "%s: ctx->get_string defined\n",
+ __FUNCTION__);
+ if (node->flags & DISPLAY_TRANSITION_NODE_VALS) {
+ struct prompt_elem pe_head;
+ struct prompt_elem *pe;
+ char *prompt;
+ uint32_t prompt_len;
+ int i;
+
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO, "%s: DISPLAY_TRANSITION_NODE_"
+ "VALS set\n", __FUNCTION__);
+ memset(&pe_head, 0, sizeof(pe_head));
+ pe = &pe_head;
+ if ((node->num_transitions == 1)
+ && !(node->flags
+ & ECRYPTFS_PARAM_FORCE_DISPLAY_NODES)) {
+ if (asprintf(&(node->val), "%s",
+ node->tl[0].val) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+ goto out;
+ }
+ pe->next = malloc(sizeof(*pe));
+ if (!pe->next) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ pe = pe->next;
+ memset(pe, 0, sizeof(*pe));
+ rc = asprintf(&pe->str, "%s: \n", node->prompt);
+ if (rc == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+ for (i = 0; i < node->num_transitions; i++) {
+ pe->next = malloc(sizeof(*pe));
+ if (!pe->next) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ pe = pe->next;
+ memset(pe, 0, sizeof(*pe));
+ if (node->flags & ECRYPTFS_DISPLAY_PRETTY_VALS)
+ rc = asprintf(&pe->str, " %d) %s\n",
+ (i + 1),
+ node->tl[i].pretty_val);
+ else
+ rc = asprintf(&pe->str, " %d) %s\n",
+ (i + 1),
+ node->tl[i].val);
+ if (rc == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+ }
+ pe->next = malloc(sizeof(*pe));
+ if (!pe->next) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ pe = pe->next;
+ memset(pe, 0, sizeof(*pe));
+ if (node->suggested_val)
+ rc = asprintf(&pe->str, "Selection [%s]",
+ node->suggested_val);
+ else if (node->default_val)
+ rc = asprintf(&pe->str, "Selection [%s]",
+ node->default_val);
+ else
+ rc = asprintf(&pe->str, "Selection");
+ if (rc == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+ /* Convert prompt_elem linked list into
+ * single prompt string */
+ prompt_len = 0;
+ pe = pe_head.next;
+ while (pe) {
+ prompt_len += strlen(pe->str);
+ pe = pe->next;
+ }
+ prompt_len++;
+ i = 0;
+ prompt = malloc(prompt_len);
+ if (!prompt) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ pe = pe_head.next;
+ while (pe) {
+ struct prompt_elem *pe_tmp;
+
+ memcpy(&prompt[i], pe->str, strlen(pe->str));
+ i += strlen(pe->str);
+ pe_tmp = pe;
+ pe = pe->next;
+ free(pe_tmp->str);
+ free(pe_tmp);
+ }
+ prompt[i] = '\0';
+get_value:
+ if ((rc = (ctx->get_string)
+ (&(node->val), prompt,
+ (node->flags
+ & ECRYPTFS_PARAM_FLAG_ECHO_INPUT)))) {
+ free(prompt);
+ return rc;
+ }
+ val = atoi(node->val);
+ if (val > 0 && val <= node->num_transitions) {
+ free(node->val);
+ if (asprintf(&(node->val), "%s",
+ node->tl[val - 1].val) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ } else {
+ int valid_val;
+
+ if (node->val[0] == '\0') {
+ if (!node->suggested_val)
+ goto get_value;
+ rc = asprintf(&node->val, "%s",
+ node->suggested_val);
+ if (rc == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+ }
+ valid_val = 0;
+ for (i = 0; i < node->num_transitions; i++) {
+ if (strcmp(node->val, node->tl[i].val)
+ == 0) {
+ valid_val = 1;
+ break;
+ }
+ }
+ if (!valid_val)
+ goto get_value;
+ }
+ free(prompt);
+ return rc;
+ } else {
+ char *prompt;
+
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO, "%s: DISPLAY_TRANSITION_NODE_"
+ "VALS not set\n", __FUNCTION__);
+obtain_value:
+ if (++tries > 3) return EINVAL;
+ if (node->suggested_val)
+ rc = asprintf(&prompt, "%s [%s]", node->prompt,
+ node->suggested_val);
+ else
+ rc = asprintf(&prompt, "%s", node->prompt);
+ if (rc == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO,
+ "%s: node->mnt_opt_names[0] = [%s]\n; "
+ "node->flags = [0x%.8x]\n",
+ __FUNCTION__,
+ node->mnt_opt_names[0], node->flags);
+ rc = (ctx->get_string)
+ (&(node->val), prompt,
+ (node->flags
+ & ECRYPTFS_PARAM_FLAG_ECHO_INPUT));
+ free(prompt);
+ if (rc)
+ goto out;
+ if (node->val[0] == '\0' &&
+ (node->flags & ECRYPTFS_NONEMPTY_VALUE_REQUIRED)) {
+ fprintf(stderr,"Wrong input, non-empty value "
+ "required!\n");
+ goto obtain_value;
+ }
+ if (node->flags & VERIFY_VALUE) {
+ rc = asprintf(&verify_prompt, "Verify %s",
+ node->prompt);
+ if (rc == -1)
+ return -ENOMEM;
+ rc = (ctx->get_string)
+ (&verify, verify_prompt,
+ (node->flags
+ & ECRYPTFS_PARAM_FLAG_ECHO_INPUT));
+ free(verify_prompt);
+ if (rc)
+ return -EIO;
+ rc = strcmp(verify, node->val);
+ free(verify);
+ if (rc) {
+ free(node->val);
+ node->val = NULL;
+ goto obtain_value;
+ }
+ }
+ if (node->val[0] == '\0') {
+ free(node->val);
+ node->val = node->suggested_val;
+ }
+ return rc;
+ }
+ } else {
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO, "%s: ctx->get_string not defined",
+ __FUNCTION__);
+ }
+ rc = MOUNT_ERROR;
+out:
+ return rc;
+}
+
+static void get_verbosity(struct ecryptfs_name_val_pair *nvp_head,
+ int *verbosity)
+{
+ struct ecryptfs_name_val_pair *temp = nvp_head->next;
+
+ *verbosity = 1;
+ while (temp) {
+ if (strcmp(temp->name, "verbosity") == 0) {
+ *verbosity = atoi(temp->value);
+ return ;
+ }
+ temp = temp->next;
+ }
+ return;
+}
+
+int eval_param_tree(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct ecryptfs_name_val_pair *nvp_head,
+ struct val_node **mnt_params)
+{
+ void *foo = NULL;
+ int rc;
+
+ get_verbosity(nvp_head, &(ctx->verbosity));
+ do {
+ if (ecryptfs_verbosity) {
+ int i;
+
+ syslog(LOG_INFO, "%s: Calling alloc_and_get_val() on "
+ "node = [%p]; node->mnt_opt_names[0] = [%s]\n",
+ __FUNCTION__, node, node->mnt_opt_names[0]);
+ for (i = 0; i < node->num_transitions; i++) {
+ syslog(LOG_INFO,
+ "%s: node->tl[%d].val = [%s]\n",
+ __FUNCTION__, i, node->tl[i].val);
+ }
+ }
+ if ((rc = alloc_and_get_val(ctx, node, nvp_head)))
+ return rc;
+ } while (!(rc = do_transition(ctx, &node, node, nvp_head,
+ mnt_params, &foo)));
+ return rc;
+}
+
+int ecryptfs_eval_decision_graph(struct ecryptfs_ctx *ctx,
+ struct val_node **mnt_params,
+ struct param_node *root_node,
+ struct ecryptfs_name_val_pair *nvp_head) {
+ int rc;
+
+ memset(*mnt_params, 0, sizeof(struct val_node));
+ rc = eval_param_tree(ctx, root_node, nvp_head, mnt_params);
+ if ((rc > 0) && (rc != MOUNT_ERROR))
+ return 0;
+ return rc;
+}
+
+
+static void print_whitespace(FILE *file_stream, int depth)
+{
+ int i;
+
+ for (i = 0; i < depth; i++)
+ fprintf(file_stream, " ");
+}
+
+void ecryptfs_dump_param_node(FILE *file_stream,
+ struct param_node *param_node, int depth,
+ int recursive);
+
+void ecryptfs_dump_transition_node(FILE *file_stream,
+ struct transition_node *trans_node,
+ int depth, int recursive)
+{
+ print_whitespace(file_stream, depth);
+ fprintf(file_stream, "---------------\n");
+ print_whitespace(file_stream, depth);
+ fprintf(file_stream, "transition_node\n");
+ print_whitespace(file_stream, depth);
+ fprintf(file_stream, "---------------\n");
+ print_whitespace(file_stream, depth);
+ fprintf(file_stream, "val = [%s]\n", trans_node->val);
+ print_whitespace(file_stream, depth);
+ fprintf(file_stream, "next_token = [%p]\n", trans_node->next_token);
+ if (recursive && trans_node->next_token)
+ ecryptfs_dump_param_node(file_stream, trans_node->next_token,
+ depth + 1, recursive);
+ print_whitespace(file_stream, depth);
+ fprintf(file_stream, "---------------\n");
+}
+
+void ecryptfs_dump_param_node(FILE *file_stream,
+ struct param_node *param_node, int depth,
+ int recursive)
+{
+ int i;
+
+ print_whitespace(file_stream, depth);
+ fprintf(file_stream, "----------\n");
+ print_whitespace(file_stream, depth);
+ fprintf(file_stream, "param_node\n");
+ print_whitespace(file_stream, depth);
+ fprintf(file_stream, "----------\n");
+ print_whitespace(file_stream, depth);
+ fprintf(file_stream, "mnt_opt_names[0] = [%s]\n",
+ param_node->mnt_opt_names[0]);
+ print_whitespace(file_stream, depth);
+ fprintf(file_stream, "num_transitions = [%d]\n",
+ param_node->num_transitions);
+ for (i = 0; i < param_node->num_transitions; i++) {
+ print_whitespace(file_stream, depth);
+ fprintf(file_stream, "transition node [%d]:\n", i);
+ ecryptfs_dump_transition_node(file_stream, &param_node->tl[i],
+ depth + 1, recursive);
+ }
+ print_whitespace(file_stream, depth);
+ fprintf(file_stream, "----------\n");
+
+}
+
+void ecryptfs_dump_decision_graph(FILE *file_stream,
+ struct param_node *param_node, int depth)
+{
+ ecryptfs_dump_param_node(file_stream, param_node, depth, 1);
+}
+
+int ecryptfs_insert_params(struct ecryptfs_name_val_pair *nvp,
+ struct param_node *param_node)
+{
+ int i;
+ struct ecryptfs_name_val_pair *cursor = nvp;
+ int rc = 0;
+
+ while (cursor->next)
+ cursor = cursor->next;
+ for (i = 0; i < param_node->num_mnt_opt_names; i++) {
+ if ((cursor->next =
+ malloc(sizeof(struct ecryptfs_name_val_pair))) == NULL) {
+ syslog(LOG_ERR, "Error attempting to allocate nvp\n");
+ rc = -ENOMEM;
+ goto out;
+ }
+ cursor = cursor->next;
+ cursor->next = NULL;
+ if ((rc = asprintf(&cursor->name, "%s",
+ param_node->mnt_opt_names[i])) == -1) {
+ syslog(LOG_ERR, "Error attempting to allocate nvp "
+ "entry for param_node->mnt_opt_names[%d] = "
+ "[%s]\n", i, param_node->mnt_opt_names[i]);
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+ }
+ for (i = 0; i < param_node->num_transitions; i++) {
+ if (param_node->tl[i].next_token == NULL)
+ continue;
+ if ((rc =
+ ecryptfs_insert_params(cursor,
+ param_node->tl[i].next_token))) {
+ syslog(LOG_ERR, "Error inserting param; param_node->"
+ "mnt_opt_names[0] = [%s]; transition token "
+ "index = [%d]\n", param_node->mnt_opt_names[0],
+ i);
+ goto out;
+ }
+ }
+out:
+ return rc;
+}
+
+/**
+ * ecryptfs_insert_params_in_subgraph
+ *
+ * For all of the parameter nodes in the subgraph, append a name/value
+ * pair to the list with the nvp name set to the parameter node opt
+ * name.
+ */
+int ecryptfs_insert_params_in_subgraph(struct ecryptfs_name_val_pair *nvp,
+ struct transition_node *trans_node)
+{
+ int rc = 0;
+
+ if (trans_node->next_token)
+ rc = ecryptfs_insert_params(nvp, trans_node->next_token);
+
+ return rc;
+}
+
+static struct flag_map {
+ uint32_t flag_src;
+ uint32_t flag_dst;
+} nvp_flags_to_param_flags_map[] = {
+ {.flag_src = ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
+ .flag_dst = ECRYPTFS_PARAM_FLAG_ECHO_INPUT},
+};
+#define ECRYPTFS_NVP_FLAGS_TO_PARAM_FLAGS_MAP_SIZE 1
+
+static int ecryptfs_map_flags(uint32_t *param_flags, uint32_t nvp_flags)
+{
+ int i;
+
+ for (i = 0; i < ECRYPTFS_NVP_FLAGS_TO_PARAM_FLAGS_MAP_SIZE; i++)
+ if (nvp_flags & nvp_flags_to_param_flags_map[i].flag_src) {
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO, "Setting flag [0x%.8x]\n",
+ nvp_flags_to_param_flags_map[i].flag_dst);
+ (*param_flags) |=
+ nvp_flags_to_param_flags_map[i].flag_dst;
+ }
+ return 0;
+}
+
+struct ecryptfs_subgraph_ctx {
+ struct ecryptfs_key_mod *key_mod;
+ struct val_node head_val_node;
+};
+
+/**
+ * ecryptfs_enter_linear_subgraph_tf
+ * @ctx:
+ * @param_node:
+ * @mnt_params:
+ * @foo: Pointer memory in the activation record for
+ * eval_param_tree(). Transition node callback functions hang
+ * whatever they want off this pointer. In the case of the
+ * auto-generated linear subgraph, it's a struct containing a
+ * linked list of val_nodes; each param_node->val is duplicated
+ * to each val_node->val. For the last transition function, this
+ * linked list is converted into a parameter array for the key
+ * module. The head val_node is always empty and serves only as
+ * a placeholder.
+ *
+ * This is the entrance transition function callback. This means that
+ * it is a transition node to the key module selection parameter
+ * node. This means that the parameter node's value indicates the
+ * alias of the key module to which this function applies. That is why
+ * we call ecryptfs_find_key_mod() to get the key module. The exit
+ * transition function is going to need this key module struct so that
+ * it can attach the final parameter value array to it.
+ */
+static int
+ecryptfs_enter_linear_subgraph_tf(struct ecryptfs_ctx *ctx,
+ struct param_node *param_node,
+ struct val_node **mnt_params, void **foo)
+{
+ struct ecryptfs_subgraph_ctx *subgraph_ctx;
+ int rc = 0;
+
+ if ((subgraph_ctx = malloc(sizeof(struct ecryptfs_subgraph_ctx)))
+ == NULL) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ memset(subgraph_ctx, 0, sizeof(struct ecryptfs_subgraph_ctx));
+ if ((rc = ecryptfs_find_key_mod(&subgraph_ctx->key_mod, ctx,
+ param_node->val))) {
+ syslog(LOG_ERR, "%s: Cannot find key_mod for param_node with "
+ "val = [%s]\n", __FUNCTION__, param_node->val);
+ free(subgraph_ctx);
+ goto out;
+ }
+ (*foo) = (void *)subgraph_ctx;
+out:
+ return rc;
+}
+
+/**
+ * @foo: Contains a struct with a linked list of val_node
+ * structs. Parameter lists are going to be very short, so
+ * there's no list handling optimization here; we just keep
+ * everything in order.
+ */
+static int
+ecryptfs_linear_subgraph_val_tf(struct ecryptfs_ctx *ctx,
+ struct param_node *param_node,
+ struct val_node **mnt_params, void **foo)
+{
+ struct val_node *val_node;
+ struct val_node *walker;
+ struct ecryptfs_subgraph_ctx *subgraph_ctx;
+ int rc = 0;
+
+ if (param_node->val == NULL) {
+ syslog(LOG_WARNING, "No value supplied for parameter node with "
+ "primary opt name [%s]\n", param_node->mnt_opt_names[0]);
+ goto out;
+ }
+ if ((val_node = malloc(sizeof(struct val_node))) == NULL) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ memset(val_node, 0, sizeof(struct val_node));
+ if ((rc = asprintf((char **)&val_node->val, "%s", param_node->val))
+ == -1) {
+ free(val_node);
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+ subgraph_ctx = (struct ecryptfs_subgraph_ctx *)(*foo);
+ walker = &subgraph_ctx->head_val_node;
+ while (walker->next)
+ walker = walker->next;
+ walker->next = val_node;
+out:
+ return rc;
+}
+
+/**
+ * ecryptfs_exit_linear_subgraph_tf
+ * @foo: Linked list of val_node structs.
+ *
+ * This is executed when transitioning from the param_node immediately
+ * after the last param_node that deals with a value. The first
+ * element in the list is an empty placeholder and shall always
+ * exist. This function converts the parameter value linked list into
+ * a parameter value array for the module to use.
+ */
+static int
+ecryptfs_exit_linear_subgraph_tf(struct ecryptfs_ctx *ctx,
+ struct param_node *param_node,
+ struct val_node **mnt_params, void **foo)
+{
+ struct val_node *curr;
+ uint32_t num_param_vals = 0;
+ struct key_mod_param_val *param_vals;
+ struct ecryptfs_subgraph_ctx *subgraph_ctx;
+ char *sig_mnt_opt;
+ char sig[ECRYPTFS_SIG_SIZE_HEX + 1];
+ int i = 0;
+ int rc = 0;
+
+ subgraph_ctx = (struct ecryptfs_subgraph_ctx *)(*foo);
+ curr = subgraph_ctx->head_val_node.next;
+ while (curr) {
+ num_param_vals++;
+ curr = curr->next;
+ }
+ subgraph_ctx->key_mod->num_param_vals = num_param_vals;
+ if (num_param_vals == 0) {
+ subgraph_ctx->key_mod->param_vals = NULL;
+ goto out_free_subgraph_ctx;
+ }
+ param_vals = malloc(sizeof(struct key_mod_param_val) * num_param_vals);
+ if (param_vals == NULL) {
+ rc = -ENOMEM;
+ goto out_free_list_and_subgraph_ctx;
+ }
+ curr = subgraph_ctx->head_val_node.next;
+ while (curr) {
+ if (curr->val) {
+ if ((rc = asprintf(&param_vals[i].val, "%s",
+ (char *)curr->val)) == -1) {
+ free(param_vals);
+ rc = -ENOMEM;
+ goto out_free_list_and_subgraph_ctx;
+ }
+ } else
+ param_vals[i].val = NULL;
+ i++;
+ curr = curr->next;
+ }
+ subgraph_ctx->key_mod->param_vals = param_vals;
+ if ((rc = ecryptfs_add_key_module_key_to_keyring(
+ sig, subgraph_ctx->key_mod)) < 0) {
+ syslog(LOG_ERR, "Error attempting to add key to keyring for "
+ "key module [%s]; rc = [%d]\n",
+ subgraph_ctx->key_mod->alias, rc);
+ free(param_vals);
+ goto out_free_list_and_subgraph_ctx;
+ }
+ if ((rc = asprintf(&sig_mnt_opt, "ecryptfs_sig=%s", sig)) == -1) {
+ rc = -ENOMEM;
+ goto out_free_list_and_subgraph_ctx;
+ }
+ rc = stack_push(mnt_params, sig_mnt_opt);
+out_free_list_and_subgraph_ctx:
+ curr = subgraph_ctx->head_val_node.next;
+ while (curr) {
+ struct val_node *next;
+
+ next = curr->next;
+ if (curr->val)
+ free(curr->val);
+ free(curr);
+ curr = next;
+ }
+out_free_subgraph_ctx:
+ free(subgraph_ctx);
+
+ return rc;
+}
+
+/**
+ * ecryptfs_build_linear_subgraph
+ * @trans_node: This function allocates this new transition node into
+ * its generated subgraph
+ * @key_mod: The key module containing the parameter list to use as
+ * the basis for generating the subgraph
+ *
+ * Generates a subgraph of the decision tree from the set of
+ * parameters provided by the key module.
+ *
+ * Callbacks manage the conversion of the parameter node subgraph to
+ * the parameter value array that the module makes use of. The first
+ * callback initializes the val_node data structure to be an empty
+ * linked list of values. The subsequent callbacks append the
+ * parameter node values to the list. The last callback allocates a
+ * chunk of memory for the parameter values array
+ * (key_mod->param_vals), transfers the values in the list into that
+ * array, and frees the list. It then calls
+ * ecryptfs_add_key_module_key_to_keyring() with this parameter value
+ * list. This, in turn, calls ecryptfs_generate_key_payload(), which
+ * calls the module's get_blob() function and takes steps to generate
+ * the key signature. The exit callback appends an ecryptfs_sig=
+ * parameter to the mnt_params list.
+ *
+ * A dummy param_node is built by setting the NO_VALUE flag in
+ * param_node->flags; the transition_node that will be taken by
+ * default needs to have its value set to the string "default".
+ *
+ * The total number of param_node structs generated is the number of
+ * parameters plus two. The last two nodes are for (1) providing a
+ * callback to convert the nvp list to a params array and (2)
+ * providing a dummy node that can have its own transition set by
+ * libecryptfs to whatever it wants to set it to.
+ */
+int ecryptfs_build_linear_subgraph(struct transition_node **trans_node,
+ struct ecryptfs_key_mod *key_mod)
+{
+ struct param_node *param_node;
+ struct transition_node *tmp_tn;
+ struct key_mod_param *params;
+ uint32_t num_params;
+ uint32_t i;
+ int rc = 0;
+
+ if ((rc = key_mod->ops->get_params(&params, &num_params))) {
+ syslog(LOG_WARNING, "Key module [%s] returned error whilst "
+ "retrieving parameter list; rc = [%d]\n",
+ key_mod->alias, rc);
+ goto out;
+ }
+ if ((params == NULL) || (num_params == 0)) {
+ syslog(LOG_WARNING, "Key module [%s] has empty "
+ "parameter list\n", key_mod->alias);
+ rc = -EINVAL;
+ }
+ if (((*trans_node) = tmp_tn = malloc(sizeof(struct transition_node)))
+ == NULL) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ memset(tmp_tn, 0, sizeof(struct transition_node));
+ if ((rc = asprintf(&tmp_tn->val, "%s", key_mod->alias)) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ if ((rc = asprintf(&tmp_tn->pretty_val, "%s", key_mod->alias))
+ == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ tmp_tn->trans_func = &ecryptfs_enter_linear_subgraph_tf;
+ rc = 0;
+ param_node = NULL;
+ for (i = 0; params && i < num_params; i++) {
+ if ((param_node = malloc(sizeof(struct param_node))) == NULL) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ memset(param_node, 0, sizeof(struct param_node));
+ if ((rc = asprintf(&param_node->mnt_opt_names[0], "%s",
+ params[i].option)) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ param_node->num_mnt_opt_names = 1;
+ if (params[i].description) {
+ if ((rc = asprintf(&param_node->prompt, "%s",
+ params[i].description)) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ } else
+ if ((rc = asprintf(&param_node->prompt, "%s",
+ params[i].option)) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ if (params[i].default_val)
+ if ((rc = asprintf(&param_node->default_val, "%s",
+ params[i].default_val)) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ if (params[i].suggested_val)
+ if ((rc = asprintf(&param_node->suggested_val, "%s",
+ params[i].suggested_val)) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+ param_node->val_type = VAL_STR;
+ ecryptfs_map_flags(&param_node->flags, params[i].flags);
+ tmp_tn->next_token = param_node;
+ tmp_tn = &param_node->tl[0];
+ if ((rc = asprintf(&tmp_tn->val, "default")) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ tmp_tn->trans_func = &ecryptfs_linear_subgraph_val_tf;
+ param_node->num_transitions = 1;
+ }
+ if ((param_node = malloc(sizeof(struct param_node))) == NULL) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ memset(param_node, 0, sizeof(struct param_node));
+ if ((rc = asprintf(&param_node->mnt_opt_names[0],
+ "linear_subgraph_exit_dummy_node")) == -1) {
+ free(param_node);
+ rc = -ENOMEM;
+ goto out;
+ }
+ param_node->num_mnt_opt_names = 1;
+ param_node->flags |= ECRYPTFS_PARAM_FLAG_NO_VALUE;
+ tmp_tn->next_token = param_node;
+ tmp_tn = &param_node->tl[0];
+ if ((rc = asprintf(&tmp_tn->val, "default")) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+ param_node->num_transitions = 1;
+ tmp_tn->trans_func = &ecryptfs_exit_linear_subgraph_tf;
+out:
+ return rc;
+}
diff --git a/src/libecryptfs/ecryptfs-stat.c b/src/libecryptfs/ecryptfs-stat.c
new file mode 100644
index 0000000..488b72d
--- /dev/null
+++ b/src/libecryptfs/ecryptfs-stat.c
@@ -0,0 +1,188 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include "../include/ecryptfs.h"
+
+static uint64_t swab64(uint64_t x)
+{
+ return x<<56 | x>>56 |
+ (x & (uint64_t)0x000000000000ff00ULL)<<40 |
+ (x & (uint64_t)0x0000000000ff0000ULL)<<24 |
+ (x & (uint64_t)0x00000000ff000000ULL)<< 8 |
+ (x & (uint64_t)0x000000ff00000000ULL)>> 8 |
+ (x & (uint64_t)0x0000ff0000000000ULL)>>24 |
+ (x & (uint64_t)0x00ff000000000000ULL)>>40;
+}
+
+static int host_is_big_endian(void)
+{
+ uint32_t tmp_u32;
+ char tmp_str[sizeof(uint32_t)];
+
+ tmp_u32 = 0x00000001;
+ memcpy(tmp_str, (char *)&tmp_u32, sizeof(uint32_t));
+ if (tmp_str[0] == 0x01)
+ return 0; /* If the first byte contains 0x01, host is
+ little endian (e.g., x86). Reverse what's
+ read from disk. */
+ else
+ return 1; /* If the first byte contains 0x00, host is
+ * big endian (e.g., ppc). Just copy from
+ * disk. */
+}
+
+/**
+ * contains_ecryptfs_marker - check for the ecryptfs marker
+ * @data: The data block in which to check
+ *
+ * Returns one if marker found; zero if not found
+ */
+static int ecryptfs_contains_ecryptfs_marker(char *data)
+{
+ uint32_t m_1, m_2;
+ int big_endian;
+
+ big_endian = host_is_big_endian();
+ memcpy(&m_1, data, 4);
+ if (!big_endian)
+ m_1 = ntohl(m_1);
+ memcpy(&m_2, (data + 4), 4);
+ if (!big_endian)
+ m_2 = ntohl(m_2);
+ if ((m_1 ^ MAGIC_ECRYPTFS_MARKER) == m_2)
+ return 1;
+ return 0;
+}
+
+struct ecryptfs_flag_map_elem {
+ uint32_t file_flag;
+ uint32_t local_flag;
+};
+
+/* Add support for additional flags by adding elements here. */
+static struct ecryptfs_flag_map_elem ecryptfs_flag_map[] = {
+ {0x00000001, ECRYPTFS_ENABLE_HMAC},
+ {0x00000002, ECRYPTFS_ENCRYPTED},
+ {0x00000004, ECRYPTFS_METADATA_IN_XATTR}
+};
+
+/**
+ * ecryptfs_process_flags
+ * @crypt_stat: The cryptographic context
+ * @page_virt: Source data to be parsed
+ * @bytes_read: Updated with the number of bytes read
+ *
+ * Returns zero on success; non-zero if the flag set is invalid
+ */
+static int ecryptfs_process_flags(struct ecryptfs_crypt_stat_user *crypt_stat,
+ char *buf, int *bytes_read)
+{
+ int rc = 0;
+ size_t i;
+ uint32_t flags;
+ int big_endian;
+
+ big_endian = host_is_big_endian();
+ memcpy(&flags, buf, 4);
+ if (!big_endian)
+ flags = ntohl(flags);
+ for (i = 0; i < ((sizeof(ecryptfs_flag_map)
+ / sizeof(struct ecryptfs_flag_map_elem))); i++)
+ if (flags & ecryptfs_flag_map[i].file_flag) {
+ crypt_stat->flags |= ecryptfs_flag_map[i].local_flag;
+ } else
+ crypt_stat->flags &= ~(ecryptfs_flag_map[i].local_flag);
+ /* Version is in top 8 bits of the 32-bit flag vector */
+ crypt_stat->file_version = ((flags >> 24) & 0xFF);
+ (*bytes_read) = 4;
+ return rc;
+}
+
+#define ECRYPTFS_DONT_VALIDATE_HEADER_SIZE 0
+#define ECRYPTFS_VALIDATE_HEADER_SIZE 1
+static int
+ecryptfs_parse_header_metadata(struct ecryptfs_crypt_stat_user *crypt_stat,
+ char *buf, int *bytes_read,
+ int validate_header_size)
+{
+ int rc = 0;
+ uint32_t header_extent_size;
+ uint16_t num_header_extents_at_front;
+ int big_endian;
+
+ big_endian = host_is_big_endian();
+ memcpy(&header_extent_size, buf, sizeof(uint32_t));
+ if (!big_endian)
+ header_extent_size = ntohl(header_extent_size);
+ buf += sizeof(uint32_t);
+ memcpy(&num_header_extents_at_front, buf, sizeof(uint16_t));
+ if (!big_endian)
+ num_header_extents_at_front =
+ ntohs(num_header_extents_at_front);
+ crypt_stat->num_header_bytes_at_front =
+ (((size_t)num_header_extents_at_front
+ * (size_t)header_extent_size));
+ (*bytes_read) = (sizeof(uint32_t) + sizeof(uint16_t));
+ if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE)
+ && (crypt_stat->num_header_bytes_at_front
+ < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) {
+ rc = -EINVAL;
+ printf("%s Invalid header size: [%zu]\n", __FUNCTION__,
+ crypt_stat->num_header_bytes_at_front);
+ }
+ return rc;
+}
+
+int ecryptfs_parse_stat(struct ecryptfs_crypt_stat_user *crypt_stat, char *buf,
+ size_t buf_size)
+{
+ uint64_t file_size;
+ int bytes_read;
+ int big_endian;
+ int rc = 0;
+
+ if (buf_size < (ECRYPTFS_FILE_SIZE_BYTES
+ + MAGIC_ECRYPTFS_MARKER_SIZE_BYTES
+ + 4)) {
+ printf("%s: Invalid metadata size; must have at least [%zu] "
+ "bytes; there are only [%zu] bytes\n", __FUNCTION__,
+ (ECRYPTFS_FILE_SIZE_BYTES
+ + MAGIC_ECRYPTFS_MARKER_SIZE_BYTES
+ + 4), buf_size);
+ rc = -EINVAL;
+ goto out;
+ }
+ memset(crypt_stat, 0, sizeof(*crypt_stat));
+ memcpy(&file_size, buf, ECRYPTFS_FILE_SIZE_BYTES);
+ buf += ECRYPTFS_FILE_SIZE_BYTES;
+ big_endian = host_is_big_endian();
+ if (!big_endian)
+ file_size = swab64(file_size);
+ crypt_stat->file_size = file_size;
+ rc = ecryptfs_contains_ecryptfs_marker(buf);
+ if (rc != 1) {
+ printf("%s: Magic eCryptfs marker not found in header.\n",
+ __FUNCTION__);
+ rc = -EINVAL;
+ goto out;
+ }
+ buf += MAGIC_ECRYPTFS_MARKER_SIZE_BYTES;
+ rc = ecryptfs_process_flags(crypt_stat, buf, &bytes_read);
+ if (rc) {
+ printf("%s: Invalid header content.\n", __FUNCTION__);
+ goto out;
+ }
+ buf += bytes_read;
+ rc = ecryptfs_parse_header_metadata(crypt_stat, buf, &bytes_read,
+ ECRYPTFS_VALIDATE_HEADER_SIZE);
+ if (rc) {
+ printf("%s: Invalid header content.\n", __FUNCTION__);
+ goto out;
+ }
+ buf += bytes_read;
+/* rc = ecryptfs_parse_packet_set(crypt_stat, buf); */
+out:
+ return rc;
+}
diff --git a/src/libecryptfs/key_management.c b/src/libecryptfs/key_management.c
new file mode 100644
index 0000000..cea06d1
--- /dev/null
+++ b/src/libecryptfs/key_management.c
@@ -0,0 +1,860 @@
+/**
+ * Copyright (C) 2006 International Business Machines
+ * Copyright (C) 2011 Gazzang, Inc
+ * Author(s): Michael C. Thompson <mcthomps@us.ibm.com>
+ * Dustin Kirkland <dustin.kirkland@gazzang.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 <nss.h>
+#include <pk11func.h>
+#include <keyutils.h>
+#ifndef S_SPLINT_S
+#include <stdio.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <pwd.h>
+#include "../include/ecryptfs.h"
+
+#ifndef ENOKEY
+#warning ENOKEY is not defined in your errno.h; setting it to 126
+#define ENOKEY 126
+#endif
+
+/**
+ * @auth_tok: (out) This function will allocate; callee must free
+ * @auth_tok_sig: (out) Allocated memory this function fills in:
+ (ECRYPTFS_SIG_SIZE_HEX + 1)
+ * @fekek: (out) Allocated memory this function fills in: ECRYPTFS_MAX_KEY_BYTES
+ * @salt: (in) salt: ECRYPTFS_SALT_SIZE
+ * @passphrase: (in) passphrase: ECRYPTFS_MAX_PASSPHRASE_BYTES
+ */
+int ecryptfs_generate_passphrase_auth_tok(struct ecryptfs_auth_tok **auth_tok,
+ char *auth_tok_sig, char *fekek,
+ char *salt, char *passphrase)
+{
+ int rc;
+
+ *auth_tok = NULL;
+ rc = generate_passphrase_sig(auth_tok_sig, fekek, salt, passphrase);
+ if (rc) {
+ syslog(LOG_ERR, "Error generating passphrase signature; "
+ "rc = [%d]\n", rc);
+ rc = (rc < 0) ? rc : rc * -1;
+ goto out;
+ }
+ *auth_tok = malloc(sizeof(struct ecryptfs_auth_tok));
+ if (!*auth_tok) {
+ syslog(LOG_ERR, "Unable to allocate memory for auth_tok\n");
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = generate_payload(*auth_tok, auth_tok_sig, salt, fekek);
+ if (rc) {
+ syslog(LOG_ERR, "Error generating payload for auth tok key; "
+ "rc = [%d]\n", rc);
+ rc = (rc < 0) ? rc : rc * -1;
+ goto out;
+ }
+out:
+ return rc;
+}
+
+/**
+ * ecryptfs_passphrase_sig_from_blob
+ * @blob: Byte array of struct ecryptfs_auth_tok
+ *
+ * SWIG support function.
+ */
+binary_data ecryptfs_passphrase_sig_from_blob(char *blob)
+{
+ struct ecryptfs_auth_tok *auth_tok;
+ binary_data bd;
+
+ auth_tok = (struct ecryptfs_auth_tok *)blob;
+ bd.size = (ECRYPTFS_PASSWORD_SIG_SIZE + 1);
+ bd.data = auth_tok->token.password.signature;
+ return bd;
+}
+
+/**
+ * ecryptfs_passphrase_blob
+ * @salt: Hexadecimal representation of the salt value
+ * @passphrase: Passphrase
+ *
+ * SWIG support function.
+ */
+binary_data ecryptfs_passphrase_blob(char *salt, char *passphrase)
+{
+ unsigned char *blob;
+ struct ecryptfs_auth_tok *auth_tok;
+ char auth_tok_sig[ECRYPTFS_SIG_SIZE_HEX + 1];
+ char fekek[ECRYPTFS_MAX_KEY_BYTES];
+ binary_data bd;
+ int rc;
+
+ memset(&bd, 0, sizeof(bd));
+ rc = ecryptfs_generate_passphrase_auth_tok(&auth_tok, auth_tok_sig,
+ fekek, salt, passphrase);
+ if (rc) {
+ syslog(LOG_ERR, "%s: Error attempting to generate passphrase "
+ "authentication token blob; rc = [%d]\n", __FUNCTION__,
+ rc);
+ blob = NULL;
+ goto out;
+ }
+ blob = (unsigned char *)auth_tok;
+ bd.size = sizeof(struct ecryptfs_auth_tok);
+ bd.data = blob;
+out:
+ return bd;
+}
+
+
+int ecryptfs_remove_auth_tok_from_keyring(char *auth_tok_sig)
+{
+ int rc;
+
+ rc = (int)keyctl_search(KEY_SPEC_USER_KEYRING, "user", auth_tok_sig, 0);
+ if (rc < 0) {
+ rc = errno;
+ syslog(LOG_ERR, "Failed to find key with sig [%s]: %m\n",
+ auth_tok_sig);
+ goto out;
+ }
+ rc = keyctl_unlink(rc, KEY_SPEC_USER_KEYRING);
+ if (rc < 0) {
+ rc = errno;
+ syslog(LOG_ERR, "Failed to unlink key with sig [%s]: %s\n",
+ auth_tok_sig, strerror(rc));
+ goto out;
+ }
+ rc = 0;
+out:
+ return rc;
+}
+int ecryptfs_add_auth_tok_to_keyring(struct ecryptfs_auth_tok *auth_tok,
+ char *auth_tok_sig)
+{
+ int rc;
+
+ rc = (int)keyctl_search(KEY_SPEC_USER_KEYRING, "user", auth_tok_sig, 0);
+ if (rc != -1) { /* we already have this key in keyring; we're done */
+ rc = 1;
+ goto out;
+ } else if ((rc == -1) && (errno != ENOKEY)) {
+ int errnum = errno;
+
+ syslog(LOG_ERR, "keyctl_search failed: %m errno=[%d]\n",
+ errnum);
+ rc = (errnum < 0) ? errnum : errnum * -1;
+ goto out;
+ }
+ rc = add_key("user", auth_tok_sig, (void *)auth_tok,
+ sizeof(struct ecryptfs_auth_tok), KEY_SPEC_USER_KEYRING);
+ if (rc == -1) {
+ rc = -errno;
+ syslog(LOG_ERR, "Error adding key with sig [%s]; rc = [%d] "
+ "\"%m\"\n", auth_tok_sig, rc);
+ if (rc == -EDQUOT)
+ syslog(LOG_WARNING, "Error adding key to keyring - keyring is full\n");
+ goto out;
+ }
+ rc = 0;
+out:
+ return rc;
+}
+
+/**
+ * ecryptfs_add_blob_to_keyring
+ * @blob: Byte array containing struct ecryptfs_auth_tok
+ * @sig: Hexadecimal representation of the auth tok signature
+ *
+ * SWIG support function.
+ */
+int ecryptfs_add_blob_to_keyring(char *blob, char *sig)
+{
+ int rc;
+
+ rc = ecryptfs_add_auth_tok_to_keyring((struct ecryptfs_auth_tok *)blob,
+ sig);
+ return rc;
+}
+
+/**
+ * This is the common functionality used to put a password generated key into
+ * the keyring, shared by both non-interactive and interactive signature
+ * generation code.
+ *
+ * Returns 0 on add, 1 on pre-existed, negative on failure.
+ */
+int ecryptfs_add_passphrase_key_to_keyring(char *auth_tok_sig, char *passphrase,
+ char *salt)
+{
+ int rc;
+ char fekek[ECRYPTFS_MAX_KEY_BYTES];
+ struct ecryptfs_auth_tok *auth_tok = NULL;
+
+ rc = ecryptfs_generate_passphrase_auth_tok(&auth_tok, auth_tok_sig,
+ fekek, salt, passphrase);
+ if (rc) {
+ syslog(LOG_ERR, "%s: Error attempting to generate the "
+ "passphrase auth tok payload; rc = [%d]\n",
+ __FUNCTION__, rc);
+ goto out;
+ }
+ rc = ecryptfs_add_auth_tok_to_keyring(auth_tok, auth_tok_sig);
+ if (rc < 0) {
+ syslog(LOG_ERR, "%s: Error adding auth tok with sig [%s] to "
+ "the keyring; rc = [%d]\n", __FUNCTION__, auth_tok_sig,
+ rc);
+ goto out;
+ }
+out:
+ if (auth_tok) {
+ memset(auth_tok, 0, sizeof(*auth_tok));
+ free(auth_tok);
+ }
+ return rc;
+}
+
+int ecryptfs_wrap_passphrase_file(char *dest, char *wrapping_passphrase,
+ char *salt, char *src)
+{
+ int rc = 0;
+ ssize_t size;
+ int fd;
+ char *p = NULL;
+ char decrypted_passphrase[ECRYPTFS_MAX_PASSPHRASE_BYTES + 1];
+
+ memset(decrypted_passphrase, 0, sizeof(decrypted_passphrase));
+ if ((fd = open(src, O_RDONLY)) == -1) {
+ syslog(LOG_ERR, "Error attempting to open [%s] for reading\n",
+ src);
+ rc = -EIO;
+ goto out;
+ }
+ if ((size = read(fd, decrypted_passphrase,
+ ECRYPTFS_MAX_PASSPHRASE_BYTES)) <= 0) {
+ syslog(LOG_ERR, "Error attempting to read encrypted "
+ "passphrase from file [%s]; size = [%zd]\n",
+ src, size);
+ p = strrchr(decrypted_passphrase, '\n');
+ if (p) *p = '\0';
+ rc = -EIO;
+ close(fd);
+ goto out;
+ }
+ close(fd);
+ if (ecryptfs_wrap_passphrase(dest, wrapping_passphrase, salt,
+ decrypted_passphrase) == 0) {
+ unlink(src);
+ } else {
+ syslog(LOG_ERR, "Error attempting to wrap passphrase file "
+ "[%s]-> [%s]\n", src, dest);
+ rc = -EIO;
+ goto out;
+ }
+out:
+ return rc;
+}
+
+int ecryptfs_wrap_passphrase(char *filename, char *wrapping_passphrase,
+ char *wrapping_salt, char *decrypted_passphrase)
+{
+ char wrapping_auth_tok_sig[ECRYPTFS_SIG_SIZE_HEX + 1];
+ char wrapping_key[ECRYPTFS_MAX_KEY_BYTES];
+ char padded_decrypted_passphrase[ECRYPTFS_MAX_PASSPHRASE_BYTES +
+ ECRYPTFS_AES_BLOCK_SIZE + 1];
+ char encrypted_passphrase[ECRYPTFS_MAX_PASSPHRASE_BYTES +
+ ECRYPTFS_AES_BLOCK_SIZE + 1];
+ int encrypted_passphrase_pos = 0;
+ int decrypted_passphrase_pos = 0;
+ int tmp1_outlen = 0;
+ int tmp2_outlen = 0;
+ SECStatus err;
+ SECItem key_item;
+ PK11SymKey *sym_key = NULL;
+ PK11SlotInfo *slot = NULL;
+ PK11Context *enc_ctx = NULL;
+ SECItem *sec_param = NULL;
+ int encrypted_passphrase_bytes;
+ int decrypted_passphrase_bytes;
+ int fd;
+ ssize_t size;
+ int rc;
+
+ decrypted_passphrase_bytes = strlen(decrypted_passphrase);
+ if (decrypted_passphrase_bytes > ECRYPTFS_MAX_PASSPHRASE_BYTES) {
+ syslog(LOG_ERR, "Decrypted passphrase is [%d] bytes long; "
+ "[%d] is the max\n", decrypted_passphrase_bytes,
+ ECRYPTFS_MAX_PASSPHRASE_BYTES);
+ rc = -EIO;
+ goto out;
+ }
+ rc = generate_passphrase_sig(wrapping_auth_tok_sig, wrapping_key,
+ wrapping_salt, wrapping_passphrase);
+ if (rc) {
+ syslog(LOG_ERR, "Error generating passphrase signature; "
+ "rc = [%d]\n", rc);
+ rc = (rc < 0) ? rc : rc * -1;
+ goto out;
+ }
+ memset(padded_decrypted_passphrase, 0,
+ (ECRYPTFS_MAX_PASSPHRASE_BYTES + 1));
+ memcpy(padded_decrypted_passphrase, decrypted_passphrase,
+ decrypted_passphrase_bytes);
+ if ((decrypted_passphrase_bytes % ECRYPTFS_AES_BLOCK_SIZE) != 0)
+ decrypted_passphrase_bytes += (ECRYPTFS_AES_BLOCK_SIZE
+ - (decrypted_passphrase_bytes
+ % ECRYPTFS_AES_BLOCK_SIZE));
+ encrypted_passphrase_bytes = decrypted_passphrase_bytes;
+ NSS_NoDB_Init(NULL);
+ slot = PK11_GetBestSlot(CKM_AES_ECB, NULL);
+ key_item.data = (unsigned char *)wrapping_key;
+ key_item.len = ECRYPTFS_AES_KEY_BYTES;
+ sym_key = PK11_ImportSymKey(slot, CKM_AES_ECB, PK11_OriginUnwrap,
+ CKA_ENCRYPT, &key_item, NULL);
+ if (!sym_key) {
+ syslog(LOG_ERR, "%s: PK11_ImportSymKey() returned NULL\n",
+ __FUNCTION__);
+ rc = -EIO;
+ goto out;
+ }
+ sec_param = PK11_ParamFromIV(CKM_AES_ECB, NULL);
+ enc_ctx = PK11_CreateContextBySymKey(CKM_AES_ECB, CKA_ENCRYPT,
+ sym_key, sec_param);
+ err = PK11_CipherOp(
+ enc_ctx, (unsigned char *) encrypted_passphrase,
+ &tmp1_outlen, ECRYPTFS_MAX_PASSPHRASE_BYTES +
+ ECRYPTFS_AES_BLOCK_SIZE,
+ (unsigned char *) padded_decrypted_passphrase,
+ decrypted_passphrase_bytes);//ECRYPTFS_MAX_PASSPHRASE_BYTES);
+ if (err == SECFailure) {
+ syslog(LOG_ERR, "%s: PK11_CipherOp() error; "
+ "SECFailure = [%d]; PORT_GetError() = [%d]\n",
+ __FUNCTION__, SECFailure, PORT_GetError());
+ rc = - EIO;
+ goto nss_finish;
+ }
+ err = PK11_DigestFinal(
+ enc_ctx,
+ (unsigned char *) encrypted_passphrase + tmp1_outlen,
+ (unsigned int *) &tmp2_outlen,
+ (ECRYPTFS_MAX_PASSPHRASE_BYTES +
+ ECRYPTFS_AES_BLOCK_SIZE - tmp1_outlen));
+ if (err == SECFailure) {
+ syslog(LOG_ERR, "%s: PK11 error on digest final; "
+ "SECFailure = [%d]; PORT_GetError() = [%d]\n",
+ __FUNCTION__, SECFailure, PORT_GetError());
+ rc = - EIO;
+ }
+
+nss_finish:
+ if (enc_ctx)
+ PK11_DestroyContext(enc_ctx, PR_TRUE);
+ if (sym_key)
+ PK11_FreeSymKey(sym_key);
+ if (sec_param)
+ SECITEM_FreeItem(sec_param, PR_TRUE);
+ if (slot)
+ PK11_FreeSlot(slot);
+ if (rc)
+ goto out;
+ encrypted_passphrase_pos += tmp1_outlen + tmp2_outlen;
+ decrypted_passphrase_pos += tmp1_outlen + tmp2_outlen;
+ decrypted_passphrase_bytes -= tmp1_outlen + tmp2_outlen;
+ if (decrypted_passphrase_bytes != 0) {
+ syslog(LOG_ERR, "Wrong size of wrapped passphrase\n");
+ rc = - EIO;
+ goto out;
+ }
+ unlink(filename);
+ if ((fd = open(filename, (O_WRONLY | O_CREAT | O_EXCL),
+ (S_IRUSR | S_IWUSR))) == -1) {
+ syslog(LOG_ERR, "Error attempting to open [%s] for writing\n",
+ filename);
+ rc = -EIO;
+ goto out;
+ }
+ if ((size = write(fd, wrapping_auth_tok_sig,
+ ECRYPTFS_SIG_SIZE_HEX)) <= 0) {
+ syslog(LOG_ERR, "Error attempting to write encrypted "
+ "passphrase ([%d] bytes) to file [%s]; size = [%zu]\n",
+ encrypted_passphrase_bytes, filename, size);
+ rc = -EIO;
+ close(fd);
+ goto out;
+ }
+ if ((size = write(fd, encrypted_passphrase,
+ encrypted_passphrase_bytes)) <= 0) {
+ syslog(LOG_ERR, "Error attempting to write encrypted "
+ "passphrase ([%d] bytes) to file [%s]; size = [%zu]\n",
+ encrypted_passphrase_bytes, filename, size);
+ rc = -EIO;
+ close(fd);
+ goto out;
+ }
+ close(fd);
+ rc = 0;
+out:
+ return rc;
+}
+
+/**
+ * decryptfs_passphrase must be able to hold
+ * ECRYPTFS_MAX_PASSPHRASE_BYTES + 1 bytes
+ */
+int ecryptfs_unwrap_passphrase(char *decrypted_passphrase, char *filename,
+ char *wrapping_passphrase, char *wrapping_salt)
+{
+ char wrapping_auth_tok_sig[ECRYPTFS_SIG_SIZE_HEX + 1];
+ char wrapping_auth_tok_sig_from_file[ECRYPTFS_SIG_SIZE_HEX + 1];
+ char wrapping_key[ECRYPTFS_MAX_KEY_BYTES];
+ char encrypted_passphrase[ECRYPTFS_MAX_PASSPHRASE_BYTES + 1];
+ int encrypted_passphrase_pos = 0;
+ int decrypted_passphrase_pos = 0;
+ int tmp1_outlen = 0;
+ int tmp2_outlen = 0;
+ SECStatus err;
+ SECItem key_item;
+ PK11SymKey *sym_key = NULL;
+ PK11SlotInfo *slot = NULL;
+ PK11Context *enc_ctx = NULL;
+ SECItem *sec_param = NULL;
+ int encrypted_passphrase_bytes;
+ int fd;
+ ssize_t size;
+ int rc;
+
+ memset(wrapping_auth_tok_sig_from_file, 0,
+ sizeof(wrapping_auth_tok_sig_from_file));
+ memset(encrypted_passphrase, 0, sizeof(encrypted_passphrase));
+ rc = generate_passphrase_sig(wrapping_auth_tok_sig, wrapping_key,
+ wrapping_salt, wrapping_passphrase);
+ if (rc) {
+ syslog(LOG_ERR, "Error generating passphrase signature; "
+ "rc = [%d]\n", rc);
+ rc = (rc < 0) ? rc : rc * -1;
+ goto out;
+ }
+ if ((fd = open(filename, O_RDONLY)) == -1) {
+ syslog(LOG_ERR, "Error attempting to open [%s] for reading\n",
+ filename);
+ rc = -EIO;
+ goto out;
+ }
+ if ((size = read(fd, wrapping_auth_tok_sig_from_file,
+ ECRYPTFS_SIG_SIZE_HEX)) <= 0) {
+ syslog(LOG_ERR, "Error attempting to read encrypted "
+ "passphrase from file [%s]; size = [%zu]\n",
+ filename, size);
+ rc = -EIO;
+ close(fd);
+ goto out;
+ }
+ if ((size = read(fd, encrypted_passphrase,
+ ECRYPTFS_MAX_PASSPHRASE_BYTES)) <= 0) {
+ syslog(LOG_ERR, "Error attempting to read encrypted "
+ "passphrase from file [%s]; size = [%zu]\n",
+ filename, size);
+ rc = -EIO;
+ close(fd);
+ goto out;
+ }
+ close(fd);
+ if (memcmp(wrapping_auth_tok_sig_from_file, wrapping_auth_tok_sig,
+ ECRYPTFS_SIG_SIZE_HEX) != 0) {
+ syslog(LOG_ERR, "Incorrect wrapping key for file [%s]\n",
+ filename);
+ rc = -EIO;
+ goto out;
+ }
+ encrypted_passphrase_bytes = size;
+ NSS_NoDB_Init(NULL);
+ slot = PK11_GetBestSlot(CKM_AES_ECB, NULL);
+ key_item.data = (unsigned char *)wrapping_key;
+ key_item.len = ECRYPTFS_AES_KEY_BYTES;
+ sym_key = PK11_ImportSymKey(slot, CKM_AES_ECB, PK11_OriginUnwrap,
+ CKA_ENCRYPT, &key_item, NULL);
+ if (!sym_key) {
+ syslog(LOG_ERR, "%s: PK11_ImportSymKey() returned NULL\n",
+ __FUNCTION__);
+ rc = -EIO;
+ goto out;
+ }
+ sec_param = PK11_ParamFromIV(CKM_AES_ECB, NULL);
+ enc_ctx = PK11_CreateContextBySymKey(CKM_AES_ECB, CKA_DECRYPT,
+ sym_key, sec_param);
+ memset(decrypted_passphrase, 0, ECRYPTFS_MAX_PASSPHRASE_BYTES + 1);
+ err = PK11_CipherOp(
+ enc_ctx, (unsigned char *) decrypted_passphrase,
+ &tmp1_outlen, ECRYPTFS_MAX_PASSPHRASE_BYTES,
+ (unsigned char *) encrypted_passphrase,
+ encrypted_passphrase_bytes);//ECRYPTFS_MAX_PASSPHRASE_BYTES);
+ if (err == SECFailure) {
+ syslog(LOG_ERR, "%s: PK11_CipherOp() error; "
+ "SECFailure = [%d]; PORT_GetError() = [%d]\n",
+ __FUNCTION__, SECFailure, PORT_GetError());
+ rc = - EIO;
+ goto nss_finish;
+ }
+ err = PK11_DigestFinal(
+ enc_ctx,
+ (unsigned char *) decrypted_passphrase + tmp1_outlen,
+ (unsigned int *) &tmp2_outlen,
+ (ECRYPTFS_MAX_PASSPHRASE_BYTES - tmp1_outlen));
+ if (err == SECFailure) {
+ syslog(LOG_ERR, "%s: PK11 error on digest final; "
+ "SECFailure = [%d]; PORT_GetError() = [%d]\n",
+ __FUNCTION__, SECFailure, PORT_GetError());
+ rc = - EIO;
+ }
+
+nss_finish:
+ if (enc_ctx)
+ PK11_DestroyContext(enc_ctx, PR_TRUE);
+ if (sym_key)
+ PK11_FreeSymKey(sym_key);
+ if (sec_param)
+ SECITEM_FreeItem(sec_param, PR_TRUE);
+ if (slot)
+ PK11_FreeSlot(slot);
+ if (rc)
+ goto out;
+ encrypted_passphrase_pos += tmp1_outlen + tmp2_outlen;
+ decrypted_passphrase_pos += tmp1_outlen + tmp2_outlen;
+ encrypted_passphrase_bytes -= tmp1_outlen + tmp2_outlen;
+ if (encrypted_passphrase_bytes != 0) {
+ syslog(LOG_ERR, "Wrong size of unwrapped passphrase\n");
+ rc = - EIO;
+ goto out;
+ }
+out:
+ return rc;
+}
+
+/**
+ * ecryptfs_insert_wrapped_passphrase_into_keyring()
+ *
+ * Inserts two auth_tok objects into the user session keyring: a
+ * wrapping passphrase auth_tok and the unwrapped passphrase auth_tok.
+ *
+ * Returns the signature of the wrapped passphrase that is inserted
+ * into the user session keyring.
+ */
+int ecryptfs_insert_wrapped_passphrase_into_keyring(
+ char *auth_tok_sig, char *filename, char *wrapping_passphrase,
+ char *salt)
+{
+ char decrypted_passphrase[ECRYPTFS_MAX_PASSPHRASE_BYTES + 1] ;
+ int rc = 0;
+
+ if ((rc = ecryptfs_unwrap_passphrase(decrypted_passphrase, filename,
+ wrapping_passphrase, salt))) {
+ syslog(LOG_ERR, "Error attempting to unwrap passphrase from "
+ "file [%s]; rc = [%d]\n", filename, rc);
+ rc = -EIO;
+ goto out;
+ }
+ if ((rc = ecryptfs_add_passphrase_key_to_keyring(auth_tok_sig,
+ decrypted_passphrase,
+ ECRYPTFS_DEFAULT_SALT_FNEK_HEX)) < 0) {
+ syslog(LOG_ERR, "Error attempting to add filename encryption "
+ "key to user session keyring; rc = [%d]\n", rc);
+ goto out;
+ }
+ if ((rc = ecryptfs_add_passphrase_key_to_keyring(auth_tok_sig,
+ decrypted_passphrase,
+ salt)) < 0) {
+ syslog(LOG_ERR, "Error attempting to add passphrase key to "
+ "user session keyring; rc = [%d]\n", rc);
+ }
+out:
+ return rc;
+}
+
+/**
+ * ecryptfs_add_key_module_key_to_keyring
+ * @auth_tok_sig: (ECRYPTFS_SIG_SIZE_HEX + 1) bytes of allocated
+ * memory into which this function will write the
+ * expanded-hex key signature for the given key
+ * module
+ * @key_mod: Key module handle
+ *
+ * Inserts a key module key blob into the keyring, using the
+ * auth_tok_sig as the key signature.
+ *
+ * Returns =0 on successful addition, =1 if the key is already in the
+ * keyring, and <0 on failure.
+ */
+int
+ecryptfs_add_key_module_key_to_keyring(char *auth_tok_sig,
+ struct ecryptfs_key_mod *key_mod)
+{
+ size_t blob_size;
+ struct ecryptfs_auth_tok *auth_tok = NULL;
+ int rc;
+
+ if (key_mod->blob == NULL) {
+ if ((rc = (key_mod->ops->get_blob)(NULL, &blob_size,
+ key_mod->param_vals,
+ key_mod->num_param_vals))) {
+ syslog(LOG_ERR, "Error attempting to get blob from "
+ "key module; rc = [%d]\n", rc);
+ goto out;
+ }
+ } else {
+ blob_size = key_mod->blob_size;
+ }
+ if ((auth_tok = malloc(sizeof(struct ecryptfs_auth_tok) + blob_size))
+ == NULL) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ if ((rc = ecryptfs_generate_key_payload(auth_tok, key_mod, auth_tok_sig,
+ blob_size))) {
+ syslog(LOG_ERR, "Error initializing key from module; "
+ "rc = [%d]\n", rc);
+ goto out;
+ }
+ rc = (int)keyctl_search(KEY_SPEC_USER_KEYRING, "user", auth_tok_sig, 0);
+ if (rc != -1) { /* we already have this key in keyring; we're done */
+ rc = 1;
+ goto out;
+ }
+ rc = add_key("user", auth_tok_sig, (void *)auth_tok,
+ (sizeof(struct ecryptfs_auth_tok) + blob_size),
+ KEY_SPEC_USER_KEYRING);
+ if (rc < 0) {
+ rc = -errno;
+ syslog(LOG_ERR, "Error adding key with sig [%s]; rc ="
+ " [%d]\n", auth_tok_sig, rc);
+ if (rc == -EDQUOT)
+ syslog(LOG_WARNING, "Error adding key to keyring - keyring is full\n");
+ } else rc = 0;
+out:
+ if (auth_tok != NULL) {
+ memset(auth_tok, 0, (sizeof(struct ecryptfs_auth_tok) + blob_size));
+ free(auth_tok);
+ }
+ return rc;
+}
+
+int ecryptfs_read_salt_hex_from_rc(char *salt_hex)
+{
+ struct ecryptfs_name_val_pair nvp_list_head;
+ struct ecryptfs_name_val_pair *nvp;
+ int rc;
+
+ memset(&nvp_list_head, 0, sizeof(struct ecryptfs_name_val_pair));
+ rc = ecryptfs_parse_rc_file(&nvp_list_head);
+ if (rc) {
+ if (rc != -ENOENT && rc != -EACCES) {
+ syslog(LOG_WARNING,
+ "Error attempting to parse .ecryptfsrc file; "
+ "rc = [%d]", rc);
+ }
+ goto out;
+ }
+ nvp = nvp_list_head.next;
+ while (nvp) {
+ if (strcmp(nvp->name, "salt") == 0) {
+ int valsize;
+
+ if (!nvp->value)
+ goto next_iteration;
+ valsize = strlen(nvp->value);
+ if (valsize != ECRYPTFS_SALT_SIZE_HEX)
+ goto next_iteration;
+ memcpy(salt_hex, nvp->value, ECRYPTFS_SALT_SIZE_HEX);
+ goto out_free;
+ }
+next_iteration:
+ nvp = nvp->next;
+ }
+ rc = -EINVAL;
+out_free:
+ free_name_val_pairs(nvp_list_head.next);
+out:
+ return rc;
+}
+
+int ecryptfs_check_sig(char *auth_tok_sig, char *sig_cache_filename,
+ int *flags)
+{
+ int fd;
+ char tmp[ECRYPTFS_SIG_SIZE_HEX + 1];
+ ssize_t size;
+ int rc = 0;
+
+ memset(tmp, 0, sizeof(tmp));
+ (*flags) &= ~ECRYPTFS_SIG_FLAG_NOENT;
+ fd = open(sig_cache_filename, O_RDONLY);
+ if (fd == -1) {
+ (*flags) |= ECRYPTFS_SIG_FLAG_NOENT;
+ goto out;
+ }
+ while ((size = read(fd, tmp, (ECRYPTFS_SIG_SIZE_HEX + 1)))
+ == (ECRYPTFS_SIG_SIZE_HEX + 1)) {
+ if (memcmp(auth_tok_sig, tmp, ECRYPTFS_SIG_SIZE_HEX)
+ == 0) {
+ close(fd);
+ goto out;
+ }
+ memset(tmp, 0, sizeof(tmp));
+ }
+ close(fd);
+ (*flags) |= ECRYPTFS_SIG_FLAG_NOENT;
+out:
+ return rc;
+}
+
+int ecryptfs_append_sig(char *auth_tok_sig, char *sig_cache_filename)
+{
+ int fd;
+ ssize_t size;
+ char tmp[ECRYPTFS_SIG_SIZE_HEX + 1];
+ int rc = 0;
+
+ fd = open(sig_cache_filename, (O_WRONLY | O_CREAT),
+ (S_IRUSR | S_IWUSR));
+ if (fd == -1) {
+ syslog(LOG_ERR, "Open resulted in [%d]; [%m]\n", errno);
+ rc = -EIO;
+ goto out;
+ }
+ if (fchown(fd, getuid(), getgid()) == -1) {
+ syslog(LOG_WARNING, "Can't change ownership of sig file; "
+ "errno = [%d]; [%m]\n", errno);
+ }
+ lseek(fd, 0, SEEK_END);
+ memcpy(tmp, auth_tok_sig, ECRYPTFS_SIG_SIZE_HEX);
+ tmp[ECRYPTFS_SIG_SIZE_HEX] = '\n';
+ if ((size = write(fd, tmp, (ECRYPTFS_SIG_SIZE_HEX + 1))) !=
+ (ECRYPTFS_SIG_SIZE_HEX + 1)) {
+ syslog(LOG_ERR, "Write of sig resulted in [%zu]; errno = [%d]; "
+ "[%m]\n", size, errno);
+ rc = -EIO;
+ close(fd);
+ goto out;
+ }
+ close(fd);
+out:
+ return rc;
+}
+
+int ecryptfs_validate_keyring(void)
+{
+ long rc_long;
+ int rc = 0;
+
+ if ((rc_long = keyctl(KEYCTL_LINK, KEY_SPEC_USER_KEYRING,
+ KEY_SPEC_SESSION_KEYRING))) {
+ syslog(LOG_ERR, "Error attempting to link the user session "
+ "keyring into the session keyring\n");
+ rc = -EIO;
+ goto out;
+ }
+out:
+ return rc;
+}
+
+int ecryptfs_disable_echo(struct termios *saved_settings)
+{
+ struct termios current_settings;
+ int rc = 0;
+
+ rc = tcgetattr(0, &current_settings);
+ if (rc)
+ return rc;
+ *saved_settings = current_settings;
+ current_settings.c_lflag &= ~ECHO;
+ rc = tcsetattr(0, TCSANOW, &current_settings);
+ return rc;
+}
+
+int ecryptfs_enable_echo(struct termios *saved_settings)
+{
+ return tcsetattr(0, TCSANOW, saved_settings);
+}
+
+char *ecryptfs_get_passphrase(char *prompt) {
+ char *passphrase = NULL;
+ char *p;
+ struct termios current_settings;
+
+ if ((passphrase =
+ (char *)malloc(ECRYPTFS_MAX_PASSWORD_LENGTH+2)) == NULL) {
+ perror("malloc");
+ printf("\n");
+ return NULL;
+ }
+ if (prompt != NULL) {
+ printf("%s: ", prompt);
+ }
+ ecryptfs_disable_echo(&current_settings);
+ if (fgets(passphrase,
+ ECRYPTFS_MAX_PASSWORD_LENGTH+2, stdin) == NULL) {
+ ecryptfs_enable_echo(&current_settings);
+ printf("\n");
+ free(passphrase);
+ return NULL;
+ }
+ ecryptfs_enable_echo(&current_settings);
+ p = strrchr(passphrase, '\n');
+ if (p) *p = '\0';
+ if (prompt != NULL)
+ printf("\n");
+ if (strlen(passphrase) > ECRYPTFS_MAX_PASSWORD_LENGTH) {
+ fprintf(stderr,"Passphrase is too long. Use at most %u "
+ "characters long passphrase.\n",
+ ECRYPTFS_MAX_PASSWORD_LENGTH);
+ free(passphrase);
+ return NULL;
+ }
+ return passphrase;
+}
+
+char *ecryptfs_get_wrapped_passphrase_filename() {
+ struct passwd *pwd = NULL;
+ struct stat s;
+ char *filename = NULL;
+ if ((pwd = getpwuid(getuid())) == NULL) {
+ perror("getpwuid");
+ return NULL;
+ }
+ if ((asprintf(&filename,
+ "%s/.ecryptfs/wrapped-passphrase", pwd->pw_dir) < 0)) {
+ perror("asprintf");
+ return NULL;
+ }
+ if (stat(filename, &s) != 0) {
+ perror("stat");
+ return NULL;
+ }
+ return filename;
+}
diff --git a/src/libecryptfs/key_mod.c b/src/libecryptfs/key_mod.c
new file mode 100644
index 0000000..74ca0f3
--- /dev/null
+++ b/src/libecryptfs/key_mod.c
@@ -0,0 +1,434 @@
+/**
+ * Copyright (C) 2007 International Business Machines
+ * Author(s): Mike 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 <dirent.h>
+#include <stdlib.h>
+#include <string.h>
+#ifndef S_SPLINT_S
+#include <syslog.h>
+#include <stdio.h>
+#endif
+#include <errno.h>
+#include <fcntl.h>
+#include <dlfcn.h>
+#include <sys/stat.h>
+#include "../include/ecryptfs.h"
+
+static struct ecryptfs_key_mod_ops *
+(*builtin_get_key_mod_ops[])(void) = {
+ &passphrase_get_key_mod_ops,
+ NULL
+};
+
+/**
+ * ecryptfs_generate_sig_from_key_data
+ * @sig:
+ * @key_data:
+ * @key_data_len:
+ */
+int ecryptfs_generate_sig_from_key_data(unsigned char *sig,
+ unsigned char *key_data,
+ size_t key_data_len)
+{
+ uint32_t key_type;
+ int rc = 0;
+
+ memcpy(&key_type, key_data, sizeof(uint32_t));
+ key_type = ntohl(key_type);
+ switch (key_type) {
+ default:
+ rc = -EINVAL;
+ goto out;
+ };
+out:
+ return rc;
+}
+
+static int ecryptfs_dummy_init(char **alias)
+{
+ syslog(LOG_WARNING, "%s: Dummy function substituted for unimplemented "
+ "function in key module\n", __FUNCTION__);
+ (*alias) = NULL;
+ return 0;
+}
+
+static int ecryptfs_dummy_get_gen_key_params(struct key_mod_param **params,
+ uint32_t *num_params)
+{
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO,
+ "%s: Dummy function substituted for unimplemented "
+ "function in key module\n", __FUNCTION__);
+ (*params) = NULL;
+ (*num_params) = 0;
+ return 0;
+}
+
+static int
+ecryptfs_dummy_get_gen_key_subgraph_trans_node(struct transition_node **trans,
+ uint32_t version)
+{
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO,
+ "%s: Dummy function substituted for unimplemented "
+ "function in key module\n", __FUNCTION__);
+ (*trans) = NULL;
+ return 0;
+}
+
+static int
+ecryptfs_dummy_get_params(struct key_mod_param **params, uint32_t *num_params)
+{
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO,
+ "%s: Dummy function substituted for unimplemented "
+ "function in key module\n", __FUNCTION__);
+ (*params) = NULL;
+ (*num_params) = 0;
+ return 0;
+}
+
+static int
+ecryptfs_dummy_get_param_subgraph_trans_node(struct transition_node **trans,
+ uint32_t version)
+{
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO,
+ "%s: Dummy function substituted for unimplemented "
+ "function in key module\n", __FUNCTION__);
+ (*trans) = NULL;
+ return 0;
+}
+
+static int ecryptfs_dummy_get_blob(unsigned char *blob, size_t *blob_size,
+ struct key_mod_param_val *param_vals,
+ uint32_t num_param_vals)
+{
+ syslog(LOG_WARNING, "%s: Dummy function substituted for unimplemented "
+ "function in key module\n", __FUNCTION__);
+ (*blob_size) = 0;
+ return 0;
+}
+
+static int
+ecryptfs_dummy_get_key_data(unsigned char *key_data, size_t *key_data_len,
+ unsigned char *blob)
+{
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO,
+ "%s: Dummy function substituted for unimplemented "
+ "function in key module\n", __FUNCTION__);
+ (*key_data_len) = 0;
+ return 0;
+}
+
+static int
+ecryptfs_dummy_get_key_sig(unsigned char *sig, unsigned char *blob)
+{
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO,
+ "%s: Dummy function substituted for unimplemented "
+ "function in key module\n", __FUNCTION__);
+ sig[0] = '\0';
+ return 0;
+}
+
+static int ecryptfs_dummy_get_key_hint(unsigned char *hint, size_t *hint_len,
+ unsigned char *blob)
+{
+ if (ecryptfs_verbosity)
+ syslog(LOG_WARNING,
+ "%s: Dummy function substituted for unimplemented "
+ "function in key module\n", __FUNCTION__);
+ (*hint_len) = 0;
+ return 0;
+}
+
+static int
+ecryptfs_dummy_encrypt(char *to, size_t *to_size, char *from, size_t from_size,
+ unsigned char *blob, int blob_type)
+{
+ syslog(LOG_WARNING, "%s: Dummy function substituted for unimplemented "
+ "function in key module\n", __FUNCTION__);
+ (*to_size) = 0;
+ return 0;
+}
+
+static int
+ecryptfs_dummy_decrypt(char *to, size_t *to_size, char *from, size_t from_size,
+ unsigned char *blob, int blob_type)
+{
+ syslog(LOG_WARNING, "%s: Dummy function substituted for unimplemented "
+ "function in key module\n", __FUNCTION__);
+ (*to_size) = 0;
+ return 0;
+}
+
+static int ecryptfs_dummy_destroy(unsigned char *blob)
+{
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO,
+ "%s: Dummy function substituted for unimplemented "
+ "function in key module\n", __FUNCTION__);
+ return 0;
+}
+
+static int ecryptfs_dummy_finalize(void)
+{
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO,
+ "%s: Dummy function substituted for unimplemented "
+ "function in key module\n", __FUNCTION__);
+ return 0;
+}
+
+int ecryptfs_fill_in_dummy_ops(struct ecryptfs_key_mod_ops *key_mod_ops)
+{
+ if (!key_mod_ops->init)
+ key_mod_ops->init = &ecryptfs_dummy_init;
+ if (!key_mod_ops->get_gen_key_params)
+ key_mod_ops->get_gen_key_params =
+ &ecryptfs_dummy_get_gen_key_params;
+ if (!key_mod_ops->get_gen_key_subgraph_trans_node)
+ key_mod_ops->get_gen_key_subgraph_trans_node =
+ &ecryptfs_dummy_get_gen_key_subgraph_trans_node;
+ if (!key_mod_ops->get_params)
+ key_mod_ops->get_params = &ecryptfs_dummy_get_params;
+ if (!key_mod_ops->get_param_subgraph_trans_node)
+ key_mod_ops->get_param_subgraph_trans_node =
+ &ecryptfs_dummy_get_param_subgraph_trans_node;
+ if (!key_mod_ops->get_blob)
+ key_mod_ops->get_blob = &ecryptfs_dummy_get_blob;
+ if (!key_mod_ops->get_key_data)
+ key_mod_ops->get_key_data = &ecryptfs_dummy_get_key_data;
+ if (!key_mod_ops->get_key_sig)
+ key_mod_ops->get_key_sig = &ecryptfs_dummy_get_key_sig;
+ if (!key_mod_ops->get_key_hint)
+ key_mod_ops->get_key_hint = &ecryptfs_dummy_get_key_hint;
+ if (!key_mod_ops->encrypt)
+ key_mod_ops->encrypt = &ecryptfs_dummy_encrypt;
+ if (!key_mod_ops->decrypt)
+ key_mod_ops->decrypt = &ecryptfs_dummy_decrypt;
+ if (!key_mod_ops->destroy)
+ key_mod_ops->destroy = &ecryptfs_dummy_destroy;
+ if (!key_mod_ops->finalize)
+ key_mod_ops->finalize = &ecryptfs_dummy_finalize;
+ return 0;
+}
+
+/**
+ * Called from: src/libecryptfs/module_mgr.c::ecryptfs_process_decision_graph
+ */
+int ecryptfs_register_key_modules(struct ecryptfs_ctx* ctx)
+{
+ DIR *dp = NULL;
+ struct dirent *ep;
+ char *dir_name = NULL;
+ int i;
+ struct ecryptfs_key_mod *curr_key_mod = &(ctx->key_mod_list_head);
+ struct ecryptfs_key_mod_ops *(*walker)(void);
+ int rc = 0;
+
+ if (asprintf(&dir_name, "%s", ECRYPTFS_DEFAULT_KEY_MOD_DIR) == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ if (!(dp = opendir(dir_name))) {
+ syslog(LOG_WARNING,
+ "ERROR: Could not open key_mod directory\n");
+ rc = -EPERM;
+ goto out;
+ }
+ while ((ep = readdir(dp))) {
+ struct ecryptfs_key_mod *new_key_mod = NULL;
+ size_t dir_length;
+ char *path = NULL;
+ char *key_mod_dir = ECRYPTFS_DEFAULT_KEY_MOD_DIR;
+ void *handle;
+ struct ecryptfs_key_mod_ops *(*get_key_mod_ops)(void);
+
+ /* Check if file ends with .so */
+ dir_length = strlen(ep->d_name);
+ if ((dir_length < 3)
+ || strcmp((ep->d_name + (dir_length - 3)), ".so"))
+ continue;
+ if (asprintf(&path, "%s/%s", key_mod_dir, ep->d_name) == -1) {
+ syslog(LOG_ERR, "Out of memory\n");
+ closedir(dp);
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+ handle = dlopen(path, RTLD_LAZY);
+ if (!handle) {
+ syslog(LOG_ERR, "Could not open library handle\n");
+ goto end_loop;
+ }
+ get_key_mod_ops = (struct ecryptfs_key_mod_ops *(*)(void))
+ dlsym(handle, "get_key_mod_ops");
+ if (!get_key_mod_ops) {
+ syslog (LOG_ERR, "Error attempting to get the symbol "
+ "[get_key_mod_ops] from key module [%s]: "
+ "err = [%s]. The key module is likely using "
+ "the deprecated key module API.\n", path,
+ dlerror());
+ goto end_loop_dlclose;
+ }
+ new_key_mod = malloc(sizeof(struct ecryptfs_key_mod));
+ if (!new_key_mod) {
+ syslog(LOG_ERR, "Out of memory\n");
+ closedir(dp);
+ dlclose(handle);
+ free(path);
+ rc = -ENOMEM;
+ goto out;
+ }
+ memset(new_key_mod, 0, sizeof(struct ecryptfs_key_mod));
+ new_key_mod->ops = (get_key_mod_ops)();
+ if (!new_key_mod->ops) {
+ syslog (LOG_ERR, "Library function get_key_mod_ops() "
+ "failed to return ops for [%s]\n", path);
+ free(new_key_mod);
+ rc = 0;
+ goto end_loop_dlclose;
+ }
+ if ((rc = ecryptfs_fill_in_dummy_ops(new_key_mod->ops))) {
+ syslog (LOG_ERR, "Error attempting to fill in missing "
+ "key module operations for [%s]; rc = [%d]\n",
+ path, rc);
+ free(new_key_mod);
+ rc = 0;
+ goto end_loop_dlclose;
+ }
+ if ((rc = new_key_mod->ops->init(&new_key_mod->alias))) {
+ syslog(LOG_ERR, "Error initializing key module [%s]; "
+ "rc = [%d]\n", path, rc);
+ free(new_key_mod);
+ rc = 0;
+ goto end_loop_dlclose;
+ }
+ new_key_mod->lib_handle = handle;
+ new_key_mod->lib_path = path;
+ curr_key_mod->next = new_key_mod;
+ curr_key_mod = new_key_mod;
+ continue;
+ end_loop_dlclose:
+ dlclose(handle);
+ end_loop:
+ free(path);
+ }
+ closedir(dp);
+ i = 0;
+ walker = builtin_get_key_mod_ops[i];
+ while (walker) {
+ struct ecryptfs_key_mod *new_key_mod;
+ struct ecryptfs_key_mod *tmp_key_mod;
+
+ if (!(new_key_mod = malloc(sizeof(struct ecryptfs_key_mod)))) {
+ syslog(LOG_ERR, "Out of memory\n");
+ rc = -ENOMEM;
+ goto out;
+ }
+ memset(new_key_mod, 0, sizeof(struct ecryptfs_key_mod));
+ new_key_mod->ops = (walker)();
+ if (!new_key_mod->ops) {
+ syslog (LOG_ERR, "Library function get_key_mod_ops() "
+ "failed to return ops for built-in key "
+ "module in array position [%d]\n", i);
+ free(new_key_mod);
+ rc = 0;
+ goto end_loop_2;
+ }
+ if ((rc = new_key_mod->ops->init(&new_key_mod->alias))) {
+ syslog(LOG_ERR, "Error initializing key module in "
+ "array position [%d]\n", i);
+ free(new_key_mod);
+ rc = 0;
+ goto end_loop_2;
+ }
+ tmp_key_mod = ctx->key_mod_list_head.next;
+ while (tmp_key_mod) {
+ if (strcmp(tmp_key_mod->alias, new_key_mod->alias)
+ == 0) {
+ free(new_key_mod->alias);
+ free(new_key_mod);
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO,
+ "Preferring [%s] file over "
+ "built-in module for key module "
+ "with name [%s]\n",
+ tmp_key_mod->lib_path,
+ tmp_key_mod->alias);
+ goto end_loop_2;
+ }
+ tmp_key_mod = tmp_key_mod->next;
+ }
+ curr_key_mod->next = new_key_mod;
+ curr_key_mod = new_key_mod;
+end_loop_2:
+ i++;
+ walker = builtin_get_key_mod_ops[i];
+ }
+out:
+ free(dir_name);
+ return rc;
+}
+
+/**
+ * ecryptfs_find_key_mod
+ *
+ * Get the key_mod struct for the given alias.
+ */
+int ecryptfs_find_key_mod(struct ecryptfs_key_mod **key_mod,
+ struct ecryptfs_ctx *ctx, char *key_mod_alias)
+{
+ struct ecryptfs_key_mod *curr;
+ int rc = 0;
+
+ curr = ctx->key_mod_list_head.next;
+ while (curr) {
+ if (!strncmp(curr->alias, key_mod_alias,
+ strlen(curr->alias))) {
+ *key_mod = curr;
+ goto out;
+ }
+ curr = curr->next;
+ }
+ rc = 1;
+out:
+ return rc;
+}
+
+int ecryptfs_free_key_mod_list(struct ecryptfs_ctx *ctx)
+{
+ struct ecryptfs_key_mod *curr = ctx->key_mod_list_head.next;
+ struct ecryptfs_key_mod *temp;
+
+ while (curr) {
+ curr->ops->finalize();
+ dlclose (curr->lib_handle);
+ free(curr->lib_path);
+ temp = curr;
+ curr = curr->next;
+ free(temp);
+ }
+ ctx->key_mod_list_head.next = NULL;
+ return 0;
+}
diff --git a/src/libecryptfs/libecryptfs.pc.in b/src/libecryptfs/libecryptfs.pc.in
new file mode 100644
index 0000000..9900ec0
--- /dev/null
+++ b/src/libecryptfs/libecryptfs.pc.in
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libecryptfs
+Description: eCryptfs library
+Version: @PACKAGE_VERSION@
+Cflags: -I${includedir} @KEYUTILS_CFLAGS@
+Libs: @KEYUTILS_LIBS@ -L${libdir} -lecryptfs
diff --git a/src/libecryptfs/main.c b/src/libecryptfs/main.c
new file mode 100644
index 0000000..98bdc54
--- /dev/null
+++ b/src/libecryptfs/main.c
@@ -0,0 +1,881 @@
+/**
+ * Copyright (C) 2006 International Business Machines Corp.
+ * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
+ * Tyler Hicks <tyhicks@ou.edu>
+ *
+ * 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 <nss.h>
+#include <pk11func.h>
+#include <mntent.h>
+#ifndef S_SPLINT_S
+#include <stdio.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/mount.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <keyutils.h>
+#include <sys/ipc.h>
+#include <sys/param.h>
+#include <sys/shm.h>
+#include <sys/sem.h>
+#include "../include/ecryptfs.h"
+
+int ecryptfs_verbosity = 0;
+
+void ecryptfs_get_versions(int *major, int *minor, int *file_version)
+{
+ *major = ECRYPTFS_VERSION_MAJOR;
+ *minor = ECRYPTFS_VERSION_MINOR;
+ if (file_version)
+ *file_version = ECRYPTFS_SUPPORTED_FILE_VERSION;
+}
+
+inline void to_hex(char *dst, char *src, int src_size)
+{
+ int x;
+
+ for (x = 0; x < src_size; x++)
+ sprintf(&dst[x*2], "%.2x", (unsigned char)src[x] );
+ dst[src_size*2] = '\0';
+}
+
+void from_hex(char *dst, char *src, int dst_size)
+{
+ int x;
+ char tmp[3] = { 0, };
+
+ for (x = 0; x < dst_size; x++) {
+ tmp[0] = src[x * 2];
+ tmp[1] = src[x * 2 + 1];
+ dst[x] = (char)strtol(tmp, NULL, 16);
+ }
+}
+
+int do_hash(char *src, int src_size, char *dst, int algo)
+{
+ SECStatus err;
+
+ NSS_NoDB_Init(NULL);
+ err = PK11_HashBuf(algo, (unsigned char *)dst, (unsigned char *)src,
+ src_size);
+ if (err == SECFailure) {
+ syslog(LOG_ERR, "%s: PK11_HashBuf() error; SECFailure = [%d]; "
+ "PORT_GetError() = [%d]\n", __FUNCTION__, SECFailure,
+ PORT_GetError());
+ err = -EINVAL;
+ goto out;
+ }
+out:
+ return (int)err;
+}
+
+/* Read ecryptfs private mount from file
+ * Allocate and return a string
+ */
+char *ecryptfs_fetch_private_mnt(char *pw_dir) {
+ char *mnt_file = NULL;
+ char *mnt_default = NULL;
+ char *mnt = NULL;
+ FILE *fh = NULL;
+ /* Construct mnt file name */
+ if (asprintf(&mnt_default, "%s/%s", pw_dir, ECRYPTFS_PRIVATE_DIR) < 0
+ || mnt_default == NULL) {
+ perror("asprintf");
+ return NULL;
+ }
+ if (
+ asprintf(&mnt_file, "%s/.ecryptfs/%s.mnt", pw_dir, ECRYPTFS_PRIVATE_DIR) < 0
+ || mnt_file == NULL) {
+ perror("asprintf");
+ return NULL;
+ }
+ fh = fopen(mnt_file, "r");
+ if (fh == NULL) {
+ mnt = mnt_default;
+ } else {
+ flockfile(fh);
+ if ((mnt = (char *)malloc(MAXPATHLEN+1)) == NULL) {
+ fclose(fh);
+ perror("malloc");
+ return NULL;
+ }
+ if (fgets(mnt, MAXPATHLEN, fh) == NULL) {
+ free(mnt);
+ mnt = mnt_default;
+ } else {
+ /* Ensure that mnt doesn't contain newlines */
+ char *nl = strchr(mnt, '\n');
+ if (nl)
+ *nl = '\0';
+ }
+ fclose(fh);
+ }
+ if (mnt_file != NULL)
+ free(mnt_file);
+ if (mnt_default != NULL && mnt != mnt_default)
+ free(mnt_default);
+ return mnt;
+}
+
+
+/* Check if an ecryptfs private device or mount point is mounted.
+ * Return 1 if a filesystem in mtab matches dev && mnt && sig.
+ * Return 0 otherwise.
+ */
+int ecryptfs_private_is_mounted(char *dev, char *mnt, char *sig, int mounting) {
+ FILE *fh = NULL;
+ struct mntent *m = NULL;
+ char *opt = NULL;
+ int mounted;
+ if (sig && asprintf(&opt, "ecryptfs_sig=%s", sig) < 0) {
+ perror("asprintf");
+ return 0;
+ }
+ fh = setmntent("/proc/mounts", "r");
+ if (fh == NULL) {
+ perror("setmntent");
+ return 0;
+ }
+ mounted = 0;
+ flockfile(fh);
+ while ((m = getmntent(fh)) != NULL) {
+ if (strcmp(m->mnt_type, "ecryptfs") != 0)
+ /* Skip if this entry is not an ecryptfs mount */
+ continue;
+ if (mounting == 1) {
+ /* If mounting, return "already mounted" if EITHER the
+ * dev or the mnt dir shows up in mtab/mounts;
+ * regardless of the signature of such mounts;
+ */
+ if (dev != NULL && strcmp(m->mnt_fsname, dev) == 0) {
+ mounted = 1;
+ break;
+ }
+ if (mnt != NULL && strcmp(m->mnt_dir, mnt) == 0) {
+ mounted = 1;
+ break;
+ }
+ } else {
+ /* Otherwise, we're unmounting, and we need to be
+ * very conservative in finding a perfect match
+ * to unmount. The device, mountpoint, and signature
+ * must *all* match perfectly.
+ */
+ if (
+ strcmp(m->mnt_fsname, dev) == 0 &&
+ strcmp(m->mnt_dir, mnt) == 0 &&
+ (!opt || hasmntopt(m, opt) != NULL)
+ ) {
+ mounted = 1;
+ break;
+ }
+ }
+ }
+ endmntent(fh);
+ if (opt != NULL)
+ free(opt);
+ return mounted;
+}
+
+
+/**
+ * TODO: We need to support more hash algs
+ * @fekek: ECRYPTFS_MAX_KEY_BYTES bytes of allocated memory
+ *
+ * @passphrase A NULL-terminated char array
+ *
+ * @salt A salt
+ *
+ * @passphrase_sig An allocated char array into which the generated
+ * signature is written; PASSWORD_SIG_SIZE bytes should be allocated
+ *
+ */
+int
+generate_passphrase_sig(char *passphrase_sig, char *fekek,
+ char *salt, char *passphrase)
+{
+ char salt_and_passphrase[ECRYPTFS_MAX_PASSPHRASE_BYTES
+ + ECRYPTFS_SALT_SIZE];
+ int passphrase_size;
+ int alg = SEC_OID_SHA512;
+ int dig_len = SHA512_DIGEST_LENGTH;
+ char buf[SHA512_DIGEST_LENGTH];
+ int hash_iterations = ECRYPTFS_DEFAULT_NUM_HASH_ITERATIONS;
+ int rc = 0;
+
+ passphrase_size = strlen(passphrase);
+ if (passphrase_size > ECRYPTFS_MAX_PASSPHRASE_BYTES) {
+ passphrase_sig = NULL;
+ syslog(LOG_ERR, "Passphrase too large (%d bytes)\n",
+ passphrase_size);
+ return -EINVAL;
+ }
+ memcpy(salt_and_passphrase, salt, ECRYPTFS_SALT_SIZE);
+ memcpy((salt_and_passphrase + ECRYPTFS_SALT_SIZE), passphrase,
+ passphrase_size);
+ if ((rc = do_hash(salt_and_passphrase,
+ (ECRYPTFS_SALT_SIZE + passphrase_size), buf, alg))) {
+ return rc;
+ }
+ hash_iterations--;
+ while (hash_iterations--) {
+ if ((rc = do_hash(buf, dig_len, buf, alg))) {
+ return rc;
+ }
+ }
+ memcpy(fekek, buf, ECRYPTFS_MAX_KEY_BYTES);
+ if ((rc = do_hash(buf, dig_len, buf, alg))) {
+ return rc;
+ }
+ to_hex(passphrase_sig, buf, ECRYPTFS_SIG_SIZE);
+ return 0;
+}
+
+/**
+ * @return Zero on success
+ */
+int
+generate_payload(struct ecryptfs_auth_tok *auth_tok, char *passphrase_sig,
+ char *salt, char *session_key_encryption_key)
+{
+ int rc = 0;
+ int major, minor;
+
+ memset(auth_tok, 0, sizeof(struct ecryptfs_auth_tok));
+ ecryptfs_get_versions(&major, &minor, NULL);
+ auth_tok->version = (((uint16_t)(major << 8) & 0xFF00)
+ | ((uint16_t)minor & 0x00FF));
+ auth_tok->token_type = ECRYPTFS_PASSWORD;
+ strncpy((char *)auth_tok->token.password.signature, passphrase_sig,
+ ECRYPTFS_PASSWORD_SIG_SIZE);
+ memcpy(auth_tok->token.password.salt, salt, ECRYPTFS_SALT_SIZE);
+ memcpy(auth_tok->token.password.session_key_encryption_key,
+ session_key_encryption_key, ECRYPTFS_MAX_KEY_BYTES);
+ /* TODO: Make the hash parameterizable via policy */
+ auth_tok->token.password.session_key_encryption_key_bytes =
+ ECRYPTFS_MAX_KEY_BYTES;
+ auth_tok->token.password.flags |=
+ ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET;
+ /* The kernel code will encrypt the session key. */
+ auth_tok->session_key.encrypted_key[0] = 0;
+ auth_tok->session_key.encrypted_key_size = 0;
+ /* Default; subject to change by kernel eCryptfs */
+ auth_tok->token.password.hash_algo = PGP_DIGEST_ALGO_SHA512;
+ auth_tok->token.password.flags &= ~(ECRYPTFS_PERSISTENT_PASSWORD);
+ return rc;
+}
+
+/**
+ * @auth_tok: A previous call to get_blob() by the callee determined
+ * how much space to allocate at the end of the auth_tok
+ * memory for the blob; this memory is already allocated
+ * and ready to be written into
+ */
+int
+ecryptfs_generate_key_payload(struct ecryptfs_auth_tok *auth_tok,
+ struct ecryptfs_key_mod *key_mod,
+ char *sig, size_t blob_size)
+{
+ int major, minor;
+ unsigned char *key_data;
+ size_t key_data_len;
+ size_t blob_size_tmp;
+ int rc = 0;
+
+ memset(auth_tok, 0, sizeof(struct ecryptfs_auth_tok) + blob_size);
+ ecryptfs_get_versions(&major, &minor, NULL);
+ auth_tok->version = (((uint16_t)(major << 8) & 0xFF00)
+ | ((uint16_t)minor & 0x00FF));
+ auth_tok->token_type = ECRYPTFS_PRIVATE_KEY;
+ if (key_mod->blob == NULL) {
+ if ((rc = (key_mod->ops->get_blob)
+ (auth_tok->token.private_key.data, &blob_size_tmp,
+ key_mod->param_vals, key_mod->num_param_vals))) {
+ syslog(LOG_ERR, "Call into key module's get_blob "
+ "failed; rc = [%d]\n", rc);
+ goto out;
+ }
+ } else {
+ blob_size_tmp = key_mod->blob_size;
+ memcpy(auth_tok->token.private_key.data, key_mod->blob,
+ key_mod->blob_size);
+ }
+ if (blob_size != blob_size_tmp) {
+ rc = -EINVAL;
+ syslog(LOG_ERR, "BUG: blob_size != blob_size_tmp; key module "
+ "is having a hard time getting the two to match between "
+ "get_blob() calls, and this has probably led to memory "
+ "corruption. Bombing out.\n");
+ exit(1);
+ goto out;
+ }
+ if ((rc = (key_mod->ops->get_key_data)
+ (NULL, &key_data_len, auth_tok->token.private_key.data))) {
+ syslog(LOG_ERR, "Call into key module's get_key_data failed; "
+ "rc = [%d]\n", rc);
+ goto out;
+ }
+ if (key_data_len == 0) {
+ if ((rc = (key_mod->ops->get_key_sig)(
+ (unsigned char *)sig,
+ auth_tok->token.private_key.data))) {
+ syslog(LOG_ERR, "Call into key module's get_key_sig "
+ "failed; rc = [%d]\n", rc);
+ goto out;
+ }
+ } else {
+ if ((key_data = malloc(key_data_len)) == NULL) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ if ((rc = (key_mod->ops->get_key_data)
+ (key_data, &key_data_len,
+ auth_tok->token.private_key.data))) {
+ syslog(LOG_ERR, "Call into key module's get_key_data "
+ "failed; rc = [%d]\n", rc);
+ goto out;
+ }
+ if ((rc = ecryptfs_generate_sig_from_key_data(
+ (unsigned char *)sig, key_data, key_data_len))) {
+ syslog(LOG_ERR, "Error attempting to generate "
+ "signature from key data; rc = [%d]\n", rc);
+ goto out;
+ }
+ if (sig[0] == '\0') {
+ if ((rc = (key_mod->ops->get_key_sig)(
+ (unsigned char *)sig,
+ auth_tok->token.private_key.data))) {
+ syslog(LOG_ERR, "Call into key module's "
+ "get_key_sig failed; rc = [%d]\n", rc);
+ goto out;
+ }
+ }
+ }
+ strncpy(auth_tok->token.private_key.key_mod_alias, key_mod->alias,
+ ECRYPTFS_MAX_KEY_MOD_NAME_BYTES);
+ /* TODO: Get rid of this */
+ auth_tok->token.private_key.key_size = ECRYPTFS_MAX_KEY_MOD_NAME_BYTES;
+ auth_tok->token.private_key.data_len = blob_size;
+ memcpy(auth_tok->token.private_key.signature, sig,
+ ECRYPTFS_SIG_SIZE_HEX);
+ auth_tok->token.private_key.signature[ECRYPTFS_SIG_SIZE_HEX] = '\0';
+out:
+ return rc;
+}
+
+static int zombie_semaphore_get(void)
+{
+ int sem_id;
+ struct semid_ds semid_ds;
+ struct sembuf sb;
+ int i;
+ int rc;
+
+ sem_id = semget(ECRYPTFS_SEM_KEY, 1, (0666 | IPC_EXCL | IPC_CREAT));
+ if (sem_id >= 0) {
+ sb.sem_op = 1;
+ sb.sem_flg = 0;
+ sb.sem_num = 0;
+
+ rc = semop(sem_id, &sb, 1);
+ if (rc == -1) {
+ semctl(sem_id, 0, IPC_RMID);
+ syslog(LOG_ERR, "Error initializing semaphore\n");
+ rc = -1;
+ goto out;
+ }
+ } else if (errno == EEXIST) {
+ int initialized = 0;
+
+ sem_id = semget(ECRYPTFS_SEM_KEY, 1, 0);
+ if (sem_id < 0) {
+ syslog(LOG_ERR, "Error getting existing semaphore");
+ rc = -1;
+ goto out;
+ }
+#define RETRY_LIMIT 3
+ for (i = 0; i < RETRY_LIMIT; i++) {
+ semctl(sem_id, 0, IPC_STAT, &semid_ds);
+ if (semid_ds.sem_otime != 0) {
+ initialized = 1;
+ break;
+ } else
+ sleep(1);
+ }
+ if (!initialized) {
+ syslog(LOG_ERR, "Waited too long for initialized "
+ "semaphore; something's wrong\n");
+ rc = -1;
+ goto out;
+ }
+ } else {
+ syslog(LOG_ERR, "Error attempting to get semaphore\n");
+ rc = -1;
+ goto out;
+ }
+ rc = sem_id;
+out:
+ return rc;
+}
+
+static void zombie_semaphore_lock(int sem_id)
+{
+ struct sembuf sb;
+ int i;
+ int rc;
+
+ sb.sem_num = 0;
+ sb.sem_op = -1;
+ sb.sem_flg = IPC_NOWAIT;
+ for (i = 0; i < RETRY_LIMIT; i++) {
+ rc = semop(sem_id, &sb, 1);
+ if (rc == -1 && errno == EAGAIN) {
+ sleep(1);
+ } else if (rc == -1) {
+ syslog(LOG_ERR, "Error locking semaphore; errno "
+ "string = [%m]\n");
+ goto out;
+ } else
+ goto out;
+ }
+ syslog(LOG_ERR, "Error locking semaphore; hit max retries\n");
+out:
+ return;
+}
+
+static void zombie_semaphore_unlock(int sem_id)
+{
+ struct sembuf sb;
+ int rc;
+
+ sb.sem_num = 0;
+ sb.sem_op = 1;
+ sb.sem_flg = 0;
+ rc = semop(sem_id, &sb, 1);
+ if (rc == -1) {
+ syslog(LOG_ERR, "Error unlocking semaphore\n");
+ goto out;
+ }
+out:
+ return;
+}
+
+static int get_zombie_shared_mem_locked(int *shm_id, int *sem_id)
+{
+ int rc;
+
+ (*sem_id) = zombie_semaphore_get();
+ if ((*sem_id) == -1) {
+ syslog(LOG_ERR, "Error attempting to get zombie semaphore\n");
+ rc = -EIO;
+ goto out;
+ }
+ zombie_semaphore_lock((*sem_id));
+ rc = shmget(ECRYPTFS_SHM_KEY, ECRYPTFS_SHM_SIZE, (0666 | IPC_CREAT
+ | IPC_EXCL));
+ if (rc == -1 && errno == EEXIST)
+ rc = shmget(ECRYPTFS_SHM_KEY, ECRYPTFS_SHM_SIZE, 0);
+ else {
+ char *shm_virt;
+
+ if (rc == -1) {
+ syslog(LOG_ERR, "Error allocating shared memory; "
+ "errno string = [%m]\n");
+ rc = -EIO;
+ zombie_semaphore_unlock((*sem_id));
+ goto out;
+ }
+
+ (*shm_id) = rc;
+ shm_virt = shmat((*shm_id), NULL, 0);
+ if (shm_virt == (void *)-1) {
+ syslog(LOG_ERR, "Error attaching to newly allocated "
+ "shared memory; errno string = [%m]\n");
+ rc = -EIO;
+ zombie_semaphore_unlock((*sem_id));
+ goto out;
+ }
+ memset(shm_virt, 0, ECRYPTFS_SHM_SIZE);
+ if ((rc = shmdt(shm_virt))) {
+ rc = -EIO;
+ zombie_semaphore_unlock((*sem_id));
+ goto out;
+ }
+ rc = shmget(ECRYPTFS_SHM_KEY, ECRYPTFS_SHM_SIZE, 0);
+ }
+ if (rc == -1) {
+ syslog(LOG_ERR, "Error attempting to get identifier for "
+ "shared memory with key [0x%.8x]\n", ECRYPTFS_SHM_KEY);
+ rc = -EIO;
+ zombie_semaphore_unlock((*sem_id));
+ goto out;
+ }
+ (*shm_id) = rc;
+ rc = 0;
+out:
+ return rc;
+}
+
+static int list_pid_sid_pairs(int shm_id)
+{
+ pid_t sid_tmp;
+ pid_t pid_tmp;
+ char *shm_virt;
+ int i;
+ int rc;
+
+ if (sizeof(pid_t) != sizeof(uint32_t)) {
+ syslog(LOG_ERR, "sizeof(pid_t) != sizeof(uint32_t); the code "
+ "needs some tweaking to work on this architecture\n");
+ rc = -EINVAL;
+ goto out;
+ }
+ shm_virt = shmat(shm_id, NULL, 0);
+ if (shm_virt == (void *)-1) {
+ rc = -EIO;
+ goto out;
+ }
+ i = 0;
+ memcpy(&sid_tmp, &shm_virt[i], sizeof(pid_t));
+ i += sizeof(pid_t);
+ sid_tmp = ntohl(sid_tmp); /* uint32_t */
+ memcpy(&pid_tmp, &shm_virt[i], sizeof(pid_t));
+ i += sizeof(pid_t);
+ pid_tmp = ntohl(pid_tmp); /* uint32_t */
+ while (!(sid_tmp == 0 && pid_tmp == 0)) {
+ if ((i + (2 * sizeof(pid_t))) > ECRYPTFS_SHM_SIZE)
+ break;
+ memcpy(&sid_tmp, &shm_virt[i], sizeof(pid_t));
+ i += sizeof(pid_t);
+ sid_tmp = ntohl(sid_tmp); /* uint32_t */
+ memcpy(&pid_tmp, &shm_virt[i], sizeof(pid_t));
+ i += sizeof(pid_t);
+ pid_tmp = ntohl(pid_tmp); /* uint32_t */
+ }
+ if ((rc = shmdt(shm_virt)))
+ rc = -EIO;
+out:
+ return rc;
+}
+
+static int find_pid_for_this_sid(pid_t *pid, int shm_id)
+{
+ pid_t sid_tmp;
+ pid_t sid;
+ pid_t pid_tmp;
+ pid_t this_pid;
+ char *shm_virt;
+ int i;
+ int rc;
+
+ (*pid) = 0;
+ if (sizeof(pid_t) != sizeof(uint32_t)) {
+ syslog(LOG_ERR, "sizeof(pid_t) != sizeof(uint32_t); the code "
+ "needs some tweaking to work on this architecture\n");
+ rc = -EINVAL;
+ goto out;
+ }
+ shm_virt = shmat(shm_id, NULL, 0);
+ if (shm_virt == (void *)-1) {
+ rc = -EIO;
+ goto out;
+ }
+ i = 0;
+ memcpy(&sid_tmp, &shm_virt[i], sizeof(pid_t));
+ i += sizeof(pid_t);
+ sid_tmp = ntohl(sid_tmp); /* uint32_t */
+ memcpy(&pid_tmp, &shm_virt[i], sizeof(pid_t));
+ i += sizeof(pid_t);
+ pid_tmp = ntohl(pid_tmp); /* uint32_t */
+ this_pid = getpid();
+ sid = getsid(this_pid);
+ while (!(sid_tmp == 0 && pid_tmp == 0)) {
+ if (sid_tmp == sid) {
+ (*pid) = pid_tmp;
+ goto end_search;
+ }
+ if ((i + (2 * sizeof(pid_t))) > ECRYPTFS_SHM_SIZE)
+ break;
+ memcpy(&sid_tmp, &shm_virt[i], sizeof(pid_t));
+ i += sizeof(pid_t);
+ sid_tmp = ntohl(sid_tmp); /* uint32_t */
+ memcpy(&pid_tmp, &shm_virt[i], sizeof(pid_t));
+ i += sizeof(pid_t);
+ pid_tmp = ntohl(pid_tmp); /* uint32_t */
+ }
+end_search:
+ if ((rc = shmdt(shm_virt))) {
+ rc = -EIO;
+ (*pid) = 0;
+ }
+out:
+ return rc;
+}
+
+static int remove_pid_for_this_sid(int shm_id)
+{
+ pid_t sid_tmp;
+ pid_t sid;
+ pid_t pid_tmp;
+ pid_t pid;
+ pid_t this_pid;
+ char *shm_virt;
+ int i;
+ int rc;
+
+ pid = 0;
+ if (sizeof(pid_t) != sizeof(uint32_t)) {
+ syslog(LOG_ERR, "sizeof(pid_t) != sizeof(uint32_t); the code "
+ "needs some tweaking to work on this architecture\n");
+ rc = -EINVAL;
+ goto out;
+ }
+ shm_virt = shmat(shm_id, NULL, 0);
+ if (shm_virt == (void *)-1) {
+ rc = -EIO;
+ goto out;
+ }
+ i = 0;
+ memcpy(&sid_tmp, &shm_virt[i], sizeof(pid_t));
+ i += sizeof(pid_t);
+ sid_tmp = ntohl(sid_tmp); /* uint32_t */
+ memcpy(&pid_tmp, &shm_virt[i], sizeof(pid_t));
+ i += sizeof(pid_t);
+ pid_tmp = ntohl(pid_tmp); /* uint32_t */
+ this_pid = getpid();
+ sid = getsid(this_pid);
+ while (!(sid_tmp == 0 && pid_tmp == 0)) {
+ if (sid_tmp == sid) {
+ pid = pid_tmp;
+ break;
+ }
+ if ((i + (2 * sizeof(pid_t))) > ECRYPTFS_SHM_SIZE)
+ break;
+ memcpy(&sid_tmp, &shm_virt[i], sizeof(pid_t));
+ i += sizeof(pid_t);
+ sid_tmp = ntohl(sid_tmp); /* uint32_t */
+ memcpy(&pid_tmp, &shm_virt[i], sizeof(pid_t));
+ i += sizeof(pid_t);
+ pid_tmp = ntohl(pid_tmp); /* uint32_t */
+ }
+ if (pid != 0) {
+ char *tmp;
+ int remainder = (ECRYPTFS_SHM_SIZE - i);
+
+ if (remainder != 0) {
+ if ((tmp = malloc(remainder)) == NULL) {
+ rc = -ENOMEM;
+ shmdt(shm_virt);
+ goto out;
+ }
+ memcpy(tmp, &shm_virt[i], remainder);
+ i -= (2 * sizeof(pid_t));
+ memcpy(&shm_virt[i], tmp, remainder);
+ i += remainder;
+ } else
+ i -= (2 * sizeof(pid_t));
+ memset(&shm_virt[i], 0, (2 * sizeof(pid_t)));
+ if (remainder != 0)
+ free(tmp);
+ }
+ if ((rc = shmdt(shm_virt)))
+ rc = -EIO;
+out:
+ return rc;
+}
+
+static int add_sid_pid_pair_to_shm(int shm_id)
+{
+ pid_t sid_tmp;
+ pid_t sid;
+ pid_t pid_tmp;
+ pid_t pid;
+ char *shm_virt;
+ int i;
+ int rc;
+
+ if (sizeof(pid_t) != sizeof(uint32_t)) {
+ syslog(LOG_ERR, "sizeof(pid_t) != sizeof(uint32_t); the code "
+ "needs some tweaking to work on this architecture\n");
+ rc = -EINVAL;
+ goto out;
+ }
+ shm_virt = shmat(shm_id, NULL, 0);
+ if (shm_virt == (void *)-1) {
+ syslog(LOG_ERR, "Error attaching to shared memory; error "
+ "string = [%m]\n");
+ shm_virt = shmat(shm_id, NULL, 0);
+ if (shm_virt == (void *)-1) {
+ syslog(LOG_ERR, "Error attaching to shared memory; error "
+ "string = [%m]\n");
+ rc = -EIO;
+ goto out;
+ }
+ rc = -EIO;
+ goto out;
+ }
+ i = 0;
+ memcpy(&sid_tmp, &shm_virt[i], sizeof(pid_t));
+ i += sizeof(pid_t);
+ sid_tmp = ntohl(sid_tmp); /* uint32_t */
+ memcpy(&pid_tmp, &shm_virt[i], sizeof(pid_t));
+ i += sizeof(pid_t);
+ pid_tmp = ntohl(pid_tmp); /* uint32_t */
+ while (!(sid_tmp == 0 && pid_tmp == 0)) {
+ if ((i + (2 * sizeof(pid_t))) > ECRYPTFS_SHM_SIZE) {
+ syslog(LOG_ERR,
+ "No space left in shared memory region\n");
+ rc = -ENOMEM;
+ shmdt(shm_virt);
+ goto out;
+ }
+ memcpy(&sid_tmp, &shm_virt[i], sizeof(pid_t));
+ i += sizeof(pid_t);
+ sid_tmp = ntohl(sid_tmp); /* uint32_t */
+ memcpy(&pid_tmp, &shm_virt[i], sizeof(pid_t));
+ i += sizeof(pid_t);
+ pid_tmp = ntohl(pid_tmp); /* uint32_t */
+ }
+ pid = getpid();
+ sid = getsid(pid);
+ sid = htonl(sid);
+ pid = htonl(pid);
+ i -= (2 * sizeof(pid_t));
+ memcpy(&shm_virt[i], &sid, sizeof(pid_t));
+ i += sizeof(pid_t);
+ memcpy(&shm_virt[i], &pid, sizeof(pid_t));
+ i += sizeof(pid_t);
+ if ((i + (2 * sizeof(pid_t))) <= ECRYPTFS_SHM_SIZE)
+ memset(&shm_virt[i], 0, (i + (2 * sizeof(pid_t))));
+ if ((rc = shmdt(shm_virt))) {
+ syslog(LOG_ERR, "Error detaching from shared memory\n");
+ rc = -EIO;
+ }
+out:
+ return rc;
+}
+
+int ecryptfs_set_zombie_session_placeholder(void)
+{
+ int shm_id;
+ int sem_id;
+ int rc = 0;
+
+ if ((rc = get_zombie_shared_mem_locked(&shm_id, &sem_id))) {
+ syslog(LOG_ERR,
+ "Error getting shared memory segment\n");
+ goto out;
+ }
+ if ((rc = add_sid_pid_pair_to_shm(shm_id))) {
+ syslog(LOG_ERR, "Error adding sid/pid pair to shared memory "
+ "segment; rc = [%d]\n", rc);
+ zombie_semaphore_unlock(sem_id);
+ goto out;
+ }
+ zombie_semaphore_unlock(sem_id);
+ sleep(ECRYPTFS_ZOMBIE_SLEEP_SECONDS);
+ if ((rc = get_zombie_shared_mem_locked(&shm_id, &sem_id))) {
+ syslog(LOG_ERR,
+ "Error getting shared memory segment\n");
+ goto out;
+ }
+ if ((rc = remove_pid_for_this_sid(shm_id))) {
+ syslog(LOG_ERR, "Error attempting to remove pid/sid "
+ "pair from shared memory segment; rc = [%d]\n",
+ rc);
+ zombie_semaphore_unlock(sem_id);
+ goto out;
+ }
+ zombie_semaphore_unlock(sem_id);
+ exit(1);
+out:
+ return rc;
+}
+
+int ecryptfs_kill_and_clear_zombie_session_placeholder(void)
+{
+ int shm_id;
+ int sem_id;
+ int pid;
+ int rc = 0;
+
+ if ((rc = get_zombie_shared_mem_locked(&shm_id, &sem_id))) {
+ syslog(LOG_ERR, "Error getting shared memory segment\n");
+ goto out;
+ }
+ if ((rc = find_pid_for_this_sid(&pid, shm_id))) {
+ syslog(LOG_ERR, "Error finding pid for sid in shared memory "
+ "segment; rc = [%d]\n", rc);
+ zombie_semaphore_unlock(sem_id);
+ goto out;
+ }
+ if (pid == 0) {
+ syslog(LOG_WARNING, "No valid pid found for this sid\n");
+ } else {
+ if ((rc = kill(pid, SIGKILL))) {
+ syslog(LOG_ERR, "Error attempting to kill process "
+ "[%d]; rc = [%d]; errno string = [%m]\n", pid,
+ rc);
+ }
+ if ((rc = remove_pid_for_this_sid(shm_id))) {
+ syslog(LOG_ERR, "Error attempting to remove pid/sid "
+ "pair from shared memory segment; rc = [%d]\n",
+ rc);
+ zombie_semaphore_unlock(sem_id);
+ goto out;
+ }
+ }
+ zombie_semaphore_unlock(sem_id);
+out:
+ return rc;
+}
+
+int ecryptfs_list_zombie_session_placeholders(void)
+{
+ int shm_id;
+ int sem_id;
+ int rc = 0;
+
+ if ((rc = get_zombie_shared_mem_locked(&shm_id, &sem_id))) {
+ syslog(LOG_ERR,
+ "Error getting shared memory segment\n");
+ goto out;
+ }
+ if ((rc = list_pid_sid_pairs(shm_id))) {
+ syslog(LOG_ERR, "Error listing sid/pid pairs in shared memory "
+ "segment; rc = [%d]\n", rc);
+ zombie_semaphore_unlock(sem_id);
+ goto out;
+ }
+ zombie_semaphore_unlock(sem_id);
+out:
+ return rc;
+}
+
+static struct ecryptfs_ctx_ops ctx_ops;
+
+struct ecryptfs_ctx_ops *cryptfs_get_ctx_opts (void)
+{
+ return &ctx_ops;
+}
+
diff --git a/src/libecryptfs/messaging.c b/src/libecryptfs/messaging.c
new file mode 100644
index 0000000..9dd669e
--- /dev/null
+++ b/src/libecryptfs/messaging.c
@@ -0,0 +1,188 @@
+/**
+ * Userspace side of communications with eCryptfs kernel module.
+ *
+ * Copyright (C) 2008 International Business Machines Corp.
+ * 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 <errno.h>
+#include <syslog.h>
+#include <string.h>
+#include <sys/types.h>
+#include "../include/ecryptfs.h"
+
+/**
+ * ecryptfs_write_packet_length
+ * @dest: The byte array target into which to write the
+ * length. Must have at least 5 bytes allocated.
+ * @size: The length to write.
+ * @packet_size_length: The number of bytes used to encode the
+ * packet length is written to this address.
+ *
+ * Returns zero on success; non-zero on error.
+ */
+int ecryptfs_write_packet_length(char *dest, size_t size,
+ size_t *packet_size_length)
+{
+ int rc = 0;
+
+ if (size < 192) {
+ dest[0] = size;
+ (*packet_size_length) = 1;
+ } else if (size < 65536) {
+ dest[0] = (((size - 192) / 256) + 192);
+ dest[1] = ((size - 192) % 256);
+ (*packet_size_length) = 2;
+ } else {
+ rc = -EINVAL;
+ syslog(LOG_ERR, "Unsupported packet size: [%zu]\n",
+ size);
+ }
+ return rc;
+}
+
+/**
+ * ecryptfs_parse_packet_length
+ * @data: Pointer to memory containing length at offset
+ * @size: This function writes the decoded size to this memory
+ * address; zero on error
+ * @length_size: The number of bytes occupied by the encoded length
+ *
+ * Returns zero on success
+ */
+int ecryptfs_parse_packet_length(unsigned char *data, size_t *size,
+ size_t *length_size)
+{
+ int rc = 0;
+
+ (*length_size) = 0;
+ (*size) = 0;
+ if (data[0] < 192) {
+ /* One-byte length */
+ (*size) = data[0];
+ (*length_size) = 1;
+ } else if (data[0] < 224) {
+ /* Two-byte length */
+ (*size) = ((data[0] - 192) * 256);
+ (*size) += (data[1] + 192);
+ (*length_size) = 2;
+ } else if (data[0] == 255) {
+ /* Five-byte length; we're not supposed to see this */
+ rc = -EINVAL;
+ syslog(LOG_ERR, "Five-byte packet length not "
+ "supported\n");
+ goto out;
+ } else {
+ rc = -EINVAL;
+ syslog(LOG_ERR, "Error parsing packet length\n");
+ goto out;
+ }
+out:
+ return rc;
+}
+
+/**
+ * Called with mctx_mux held
+ */
+int ecryptfs_init_messaging(struct ecryptfs_messaging_ctx *mctx, uint32_t type)
+{
+ int rc = 0;
+
+ memset(mctx, 0, sizeof(*mctx));
+ switch (type) {
+ case ECRYPTFS_MESSAGING_TYPE_MISCDEV:
+ mctx->type = ECRYPTFS_MESSAGING_TYPE_MISCDEV;
+ rc = ecryptfs_init_miscdev(&mctx->ctx.miscdev_ctx);
+ break;
+ case ECRYPTFS_MESSAGING_TYPE_NETLINK:
+ /* No longer supported */
+ default:
+ rc = -EINVAL;
+ goto out;
+ };
+out:
+ return rc;
+}
+
+int ecryptfs_messaging_exit(struct ecryptfs_messaging_ctx *mctx)
+{
+ int rc = 0;
+
+ switch (mctx->type) {
+ case ECRYPTFS_MESSAGING_TYPE_MISCDEV:
+ ecryptfs_release_miscdev(&mctx->ctx.miscdev_ctx);
+ break;
+ default:
+ rc = -EINVAL;
+ goto out;
+ };
+out:
+ return rc;
+}
+
+/**
+ * ecryptfs_send_message
+ * @mctx: Parent context for eCryptfs messaging with the kernel
+ * @msg: Message to send (struct ecryptfs_message with data appended)
+ * @msg_type: Message type to send
+ * @msg_flags: Flags for sending message
+ * @msg_seq: Message sequence number
+ *
+ */
+int ecryptfs_send_message(struct ecryptfs_messaging_ctx *mctx,
+ struct ecryptfs_message *msg,
+ unsigned char msg_type, uint16_t msg_flags,
+ uint32_t msg_seq)
+{
+ int rc = 0;
+
+ switch (mctx->type) {
+ case ECRYPTFS_MESSAGING_TYPE_MISCDEV:
+ rc = ecryptfs_send_miscdev(&mctx->ctx.miscdev_ctx, msg,
+ msg_type, msg_flags, msg_seq);
+ if (rc) {
+ syslog(LOG_ERR, "%s: Failed to register miscdev daemon "
+ "with the eCryptfs kernel module; rc = [%d]\n",
+ __FUNCTION__, rc);
+ }
+ break;
+ default:
+ rc = -EINVAL;
+ goto out;
+ };
+out:
+ return rc;
+}
+
+int ecryptfs_run_daemon(struct ecryptfs_messaging_ctx *mctx)
+{
+ int rc;
+
+ switch (mctx->type) {
+ case ECRYPTFS_MESSAGING_TYPE_MISCDEV:
+ rc = ecryptfs_run_miscdev_daemon(&mctx->ctx.miscdev_ctx);
+ if (rc)
+ goto out;
+ break;
+ default:
+ rc = -EINVAL;
+ goto out;
+ }
+out:
+ return rc;
+}
diff --git a/src/libecryptfs/miscdev.c b/src/libecryptfs/miscdev.c
new file mode 100644
index 0000000..54ebbf2
--- /dev/null
+++ b/src/libecryptfs/miscdev.c
@@ -0,0 +1,277 @@
+/**
+ * Userspace side of procfs communications with eCryptfs kernel
+ * module.
+ *
+ * Copyright (C) 2008 International Business Machines Corp.
+ * 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 <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <unistd.h>
+#ifndef S_SPLINT_S
+#include <stdio.h>
+#include <syslog.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "../include/ecryptfs.h"
+
+int ecryptfs_send_miscdev(struct ecryptfs_miscdev_ctx *miscdev_ctx,
+ struct ecryptfs_message *msg, uint8_t msg_type,
+ uint16_t msg_flags, uint32_t msg_seq)
+{
+ uint32_t miscdev_msg_data_size;
+ size_t packet_len_size;
+ size_t packet_len;
+ uint32_t msg_seq_be32;
+ uint32_t i;
+ ssize_t written;
+ char packet_len_str[3];
+ char *miscdev_msg_data;
+ int rc = 0;
+
+ /* miscdevfs packet format:
+ * Octet 0: Type
+ * Octets 1-4: network byte order msg_ctx->counter
+ * Octets 5-N0: Size of struct ecryptfs_message to follow
+ * Octets N0-N1: struct ecryptfs_message (including data)
+ *
+ * Octets 5-N1 not written if the packet type does not
+ * include a message */
+ if (msg) {
+ packet_len = (sizeof(*msg) + msg->data_len);
+ rc = ecryptfs_write_packet_length(packet_len_str, packet_len,
+ &packet_len_size);
+ if (rc)
+ goto out;
+ } else {
+ packet_len_size = 0;
+ packet_len = 0;
+ }
+ miscdev_msg_data_size = (1 + 4 + packet_len_size + packet_len);
+ miscdev_msg_data = malloc(miscdev_msg_data_size);
+ if (!miscdev_msg_data) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ msg_seq_be32 = htonl(msg_seq);
+ i = 0;
+ miscdev_msg_data[i++] = msg_type;
+ memcpy(&miscdev_msg_data[i], (void *)&msg_seq_be32, 4);
+ i += 4;
+ if (msg) {
+ memcpy(&miscdev_msg_data[i], packet_len_str, packet_len_size);
+ i += packet_len_size;
+ memcpy(&miscdev_msg_data[i], (void *)msg, packet_len);
+ }
+ written = write(miscdev_ctx->miscdev_fd, miscdev_msg_data,
+ miscdev_msg_data_size);
+ if (written == -1) {
+ rc = -EIO;
+ syslog(LOG_ERR, "Failed to send eCryptfs miscdev message; "
+ "errno msg = [%m]\n");
+ }
+ free(miscdev_msg_data);
+out:
+ return rc;
+}
+
+/**
+ * ecryptfs_recv_miscdev
+ * @msg: Allocated in this function; callee must deallocate
+ */
+int ecryptfs_recv_miscdev(struct ecryptfs_miscdev_ctx *miscdev_ctx,
+ struct ecryptfs_message **msg, uint32_t *msg_seq,
+ uint8_t *msg_type)
+{
+ ssize_t read_bytes;
+ uint32_t miscdev_msg_data_size;
+ size_t packet_len_size;
+ size_t packet_len;
+ uint32_t msg_seq_be32;
+ uint32_t i;
+ char *miscdev_msg_data;
+ int rc = 0;
+
+ miscdev_msg_data = malloc(ECRYPTFS_MSG_MAX_SIZE);
+ if (!miscdev_msg_data) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ read_bytes = read(miscdev_ctx->miscdev_fd, miscdev_msg_data,
+ ECRYPTFS_MSG_MAX_SIZE);
+ if (read_bytes == -1) {
+ rc = -EIO;
+ syslog(LOG_ERR, "%s: Error attempting to read message from "
+ "miscdev handle; errno msg = [%m]\n", __FUNCTION__);
+ goto out;
+ }
+ if (read_bytes < (1 + 4)) {
+ rc = -EINVAL;
+ syslog(LOG_ERR, "%s: Received invalid packet from kernel; "
+ "read_bytes = [%zu]; minimum possible packet site is "
+ "[%d]\n", __FUNCTION__, read_bytes,
+ (1 + 4));
+ goto out;
+ }
+ i = 0;
+ (*msg_type) = miscdev_msg_data[i++];
+ memcpy((void *)&msg_seq_be32, &miscdev_msg_data[i], 4);
+ i += 4;
+ (*msg_seq) = ntohl(msg_seq_be32);
+ if ((*msg_type) == ECRYPTFS_MSG_REQUEST) {
+ rc = ecryptfs_parse_packet_length((unsigned char *)
+ &miscdev_msg_data[i],
+ &packet_len,
+ &packet_len_size);
+ if (rc)
+ goto out;
+ i += packet_len_size;
+ } else {
+ packet_len_size = 0;
+ packet_len = 0;
+ }
+ miscdev_msg_data_size = (1 + 4 + packet_len_size + packet_len);
+ if (miscdev_msg_data_size != (size_t)read_bytes) {
+ rc = -EINVAL;
+ syslog(LOG_ERR, "%s: Invalid packet. (1 + 4 + "
+ "packet_len_size=[%zu] + packet_len=[%zu])=[%zu] != "
+ "read_bytes=[%zu]\n", __FUNCTION__, packet_len_size,
+ packet_len, (1 + 4 + packet_len_size + packet_len),
+ read_bytes);
+ goto out;
+ }
+ (*msg) = malloc(packet_len);
+ if (!(*msg)) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ memcpy((void *)(*msg), (void *)&miscdev_msg_data[i], packet_len);
+out:
+ free(miscdev_msg_data);
+ return rc;
+}
+
+int ecryptfs_init_miscdev(struct ecryptfs_miscdev_ctx *miscdev_ctx)
+{
+ int rc = 0;
+
+ miscdev_ctx->miscdev_fd = open(ECRYPTFS_DEFAULT_MISCDEV_FULLPATH_0,
+ O_RDWR);
+ if (miscdev_ctx->miscdev_fd == -1) {
+ syslog(LOG_ERR, "%s: Error whilst attempting to open "
+ "[%s]; errno msg = [%m]\n", __FUNCTION__,
+ ECRYPTFS_DEFAULT_MISCDEV_FULLPATH_0);
+ } else
+ goto out;
+ miscdev_ctx->miscdev_fd = open(ECRYPTFS_DEFAULT_MISCDEV_FULLPATH_1,
+ O_RDWR);
+ if (miscdev_ctx->miscdev_fd == -1) {
+ syslog(LOG_ERR, "%s: Error whilst attempting to open "
+ "[%s]; errno msg = [%m]\n", __FUNCTION__,
+ ECRYPTFS_DEFAULT_MISCDEV_FULLPATH_1);
+ rc = -EIO;
+ }
+out:
+ return rc;
+}
+
+void ecryptfs_release_miscdev(struct ecryptfs_miscdev_ctx *miscdev_ctx)
+{
+ close(miscdev_ctx->miscdev_fd);
+}
+
+int init_miscdev_daemon(void)
+{
+ return 0;
+}
+
+int ecryptfs_run_miscdev_daemon(struct ecryptfs_miscdev_ctx *miscdev_ctx)
+{
+ struct ecryptfs_message *emsg;
+ struct ecryptfs_ctx ctx;
+ uint32_t msg_seq;
+ uint8_t msg_type;
+ int error_count = 0;
+ int rc;
+
+ memset(&ctx, 0, sizeof(struct ecryptfs_ctx));
+ rc = ecryptfs_register_key_modules(&ctx);
+ if (rc) {
+ syslog(LOG_ERR, "Failed to register key modules; rc = [%d]\n",
+ rc);
+ goto out;
+ }
+receive:
+ emsg = NULL;
+ rc = ecryptfs_recv_miscdev(miscdev_ctx, &emsg, &msg_seq, &msg_type);
+ if (rc < 0) {
+ syslog(LOG_ERR, "Error while receiving eCryptfs message "
+ "errno = [%d]; errno msg = [%m]\n", errno);
+ error_count++;
+ if (error_count > ECRYPTFS_MSG_ERROR_COUNT_THRESHOLD) {
+ syslog(LOG_ERR, "Messaging error threshold exceeded "
+ "maximum of [%d]; terminating daemon\n",
+ ECRYPTFS_MSG_ERROR_COUNT_THRESHOLD);
+ rc = -EIO;
+ goto out;
+ }
+ } else if (msg_type == ECRYPTFS_MSG_HELO) {
+ syslog(LOG_DEBUG, "Received eCryptfs HELO message from the "
+ "kernel\n");
+ error_count = 0;
+ } else if (msg_type == ECRYPTFS_MSG_QUIT) {
+ syslog(LOG_DEBUG, "Received eCryptfs QUIT message from the "
+ "kernel\n");
+ free(emsg);
+ rc = 0;
+ goto out;
+ } else if (msg_type == ECRYPTFS_MSG_REQUEST) {
+ struct ecryptfs_message *reply = NULL;
+
+ rc = parse_packet(&ctx, emsg, &reply);
+ if (rc) {
+ syslog(LOG_ERR, "Failed to miscdevess packet\n");
+ free(reply);
+ goto free_emsg;
+ }
+ reply->index = emsg->index;
+ rc = ecryptfs_send_miscdev(miscdev_ctx, reply,
+ ECRYPTFS_MSG_RESPONSE, 0, msg_seq);
+ if (rc < 0) {
+ syslog(LOG_ERR, "Failed to send message in response to "
+ "kernel request\n");
+ }
+ free(reply);
+ error_count = 0;
+ } else
+ syslog(LOG_DEBUG, "Received unrecognized message type [%d]\n",
+ msg_type);
+free_emsg:
+ free(emsg);
+ goto receive;
+out:
+ ecryptfs_free_key_mod_list(&ctx);
+ return rc;
+}
diff --git a/src/libecryptfs/module_mgr.c b/src/libecryptfs/module_mgr.c
new file mode 100644
index 0000000..f9470d9
--- /dev/null
+++ b/src/libecryptfs/module_mgr.c
@@ -0,0 +1,998 @@
+/**
+ * Copyright (C) 2006 International Business Machines
+ * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com>
+ * Trevor Highland <trevor.highland@gmail.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 <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include "../include/ecryptfs.h"
+#include "../include/decision_graph.h"
+
+static struct param_node key_module_select_node = {
+ .num_mnt_opt_names = 1,
+ .mnt_opt_names = {"key"},
+ .prompt = "Select key type to use for newly created files",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .flags = DISPLAY_TRANSITION_NODE_VALS | ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
+ .num_transitions = 0,
+ .tl = {{0}}
+};
+
+/**
+ * sig_param_node_callback
+ *
+ * The eCryptfs utilities may modify the decision graph
+ * in-flight. This is one example of that happening.
+ *
+ * By default, root_param_node will pull a "sig=" option out of the
+ * already-supplied name/value pair list and skip the key module
+ * selection stage altogether. If there is no "sig=" option provided
+ * in the list (condition: node->val == NULL), then change the
+ * next_token transition node pointer to point to the key module
+ * selection node.
+ */
+static int
+sig_param_node_callback(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **head, void **foo)
+{
+ char *param;
+ int rc = 0;
+
+ if (!node->val) {
+ node->tl[0].next_token = &key_module_select_node;
+ goto out;
+ }
+ if (strcmp(node->val, "NULL") == 0) {
+ node->tl[0].next_token = &key_module_select_node;
+ goto out;
+ }
+ rc = asprintf(&param, "ecryptfs_sig=%s", node->val);
+ if (rc == -1) {
+ rc = -ENOMEM;
+ syslog(LOG_ERR, "Out of memory\n");
+ goto out;
+ }
+ rc = stack_push(head, param);
+out:
+ return rc;
+}
+
+static struct param_node ecryptfs_cipher_param_node;
+
+static struct param_node root_param_node = {
+ .num_mnt_opt_names = 1,
+ .mnt_opt_names = {"sig"},
+ .prompt = "Existing key signature",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = "NULL",
+ .flags = ECRYPTFS_PARAM_FLAG_NO_VALUE | ECRYPTFS_NO_AUTO_TRANSITION,
+ .num_transitions = 1,
+ .tl = {{.val = "default",
+ .pretty_val = "default",
+ .next_token = &ecryptfs_cipher_param_node,
+ .trans_func = sig_param_node_callback}}
+};
+
+/* returns:
+ * on_null for str == NULL
+ * 1 for str=="yes" or "y"
+ * 0 for str=="no" or "n"
+ * -1 elsewhere */
+static int is_yes(const char *str, int on_null)
+{
+ if (str) {
+ if (!strcmp(str,"y") || !strcmp(str,"yes"))
+ return 1;
+ if (!strcmp(str,"no") || !strcmp(str,"n"))
+ return 0;
+ } else
+ return on_null;
+
+ return -1;
+}
+
+
+/* returns: 0 for success
+ * WRONG_VALUE if node->val is none of 'yes','y','no','n'
+ * <0 for error
+ */
+static int stack_push_if_yes(struct param_node *node, struct val_node **head,
+ char *opt_name)
+{
+ int rc;
+
+ if (((rc=is_yes(node->val, 0)) == 1) || (node->flags & PARAMETER_SET)) {
+ rc = stack_push(head, opt_name);
+ } else if (rc == -1)
+ rc = WRONG_VALUE;
+ free(node->val);
+ node->val = NULL;
+ return rc;
+}
+
+static int get_hmac(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **head, void **foo)
+{
+ return stack_push_if_yes(node, head, "ecryptfs_hmac");
+}
+
+static int get_passthrough(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **head, void **foo)
+{
+ return stack_push_if_yes(node, head, "ecryptfs_passthrough");
+}
+
+static int get_xattr(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **head, void **foo)
+{
+ return stack_push_if_yes(node, head, "ecryptfs_xattr_metadata");
+}
+
+static int get_encrypted_passthrough(struct ecryptfs_ctx *ctx,
+ struct param_node *node,
+ struct val_node **head, void **foo)
+{
+ return stack_push_if_yes(node, head, "ecryptfs_encrypted_view");
+}
+
+static struct param_node end_param_node = {
+ .num_mnt_opt_names = 1,
+ .mnt_opt_names = {"end"},
+ .prompt = "end",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .flags = ECRYPTFS_PARAM_FLAG_NO_VALUE,
+ .num_transitions = 0,
+ .tl = {{.val = "default",
+ .pretty_val = "default",
+ .next_token = NULL,
+ .trans_func = NULL}}
+};
+
+static struct param_node enable_filename_crypto_param_node;
+
+static int filename_crypto_fnek_sig_callback(struct ecryptfs_ctx *ctx,
+ struct param_node *node,
+ struct val_node **head, void **foo)
+{
+ char *param;
+ int rc = 0;
+
+ if (!node->val) {
+ node->flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT;
+ enable_filename_crypto_param_node.tl[0].next_token =
+ node->tl[0].next_token;
+ node->tl[0].next_token = &enable_filename_crypto_param_node;
+ goto out;
+ }
+ if (strcmp(node->val, "NULL") == 0) {
+ node->flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT;
+ enable_filename_crypto_param_node.tl[0].next_token =
+ node->tl[0].next_token;
+ node->tl[0].next_token = &enable_filename_crypto_param_node;
+ goto out;
+ }
+ rc = asprintf(&param, "ecryptfs_fnek_sig=%s", node->val);
+ if (rc == -1) {
+ rc = -ENOMEM;
+ syslog(LOG_ERR, "Out of memory\n");
+ goto out;
+ }
+ rc = stack_push(head, param);
+out:
+ return rc;
+}
+
+static struct param_node filename_crypto_fnek_sig_param_node = {
+ .num_mnt_opt_names = 1,
+ .mnt_opt_names = {"ecryptfs_fnek_sig"},
+ .prompt = "Filename Encryption Key (FNEK) Signature",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .suggested_val = NULL,
+ .flags = ECRYPTFS_PARAM_FLAG_NO_VALUE | ECRYPTFS_NO_AUTO_TRANSITION,
+ .num_transitions = 1,
+ .tl = {{.val = "default",
+ .pretty_val = "default",
+ .next_token = &end_param_node,
+ .trans_func = filename_crypto_fnek_sig_callback}}
+};
+
+static int get_enable_filename_crypto(struct ecryptfs_ctx *ctx,
+ struct param_node *node,
+ struct val_node **head, void **foo)
+{
+ int yn, rc = 0;
+
+ if (((yn=is_yes(node->val, 0)) > 0)
+ || (node->flags & PARAMETER_SET)) {
+ int i;
+ struct val_node *val_node;
+
+ for (i = 0;
+ i < filename_crypto_fnek_sig_param_node.num_transitions;
+ i++)
+ filename_crypto_fnek_sig_param_node.tl[i].next_token =
+ node->tl[0].next_token;
+ node->tl[0].next_token = &filename_crypto_fnek_sig_param_node;
+ val_node = (*head);
+ while (val_node) {
+ if (strncmp(val_node->val, "ecryptfs_sig=", 13) == 0) {
+ rc = asprintf(&filename_crypto_fnek_sig_param_node.suggested_val,
+ "%s",
+ &((char *)val_node->val)[13]);
+ if (rc == -1) {
+ rc = -ENOMEM;
+ syslog(LOG_ERR,
+ "%s: No memory whilst "
+ "attempting to write [%s]\n",
+ __FUNCTION__,
+ &((char *)val_node->val)[13]);
+ goto out_free;
+ }
+ rc = 0;
+ break;
+ }
+ val_node = val_node->next;
+ }
+ } else if (node->val) {
+ if (yn < 0)
+ rc = WRONG_VALUE;
+ } else {
+ /* default: no */;
+ }
+out_free:
+ if (node->val) {
+ free(node->val);
+ node->val = NULL;
+ }
+ return rc;
+}
+
+static struct param_node enable_filename_crypto_param_node = {
+ .num_mnt_opt_names = 1,
+ .mnt_opt_names = {"ecryptfs_enable_filename_crypto"},
+ .prompt = "Enable filename encryption (y/n)",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
+ .num_transitions = 1,
+ .tl = {{.val = "default",
+ .pretty_val = "default",
+ .next_token = &filename_crypto_fnek_sig_param_node,
+ .trans_func = get_enable_filename_crypto}}
+};
+
+static struct param_node ecryptfs_version_support_node = {
+ .num_mnt_opt_names = 1,
+ .mnt_opt_names = {"end"},
+ .prompt = "end",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .flags = ECRYPTFS_PARAM_FLAG_NO_VALUE,
+ .num_transitions = 1,
+ .tl = {{.val = "default",
+ .pretty_val = "default",
+ .next_token = NULL,
+ .trans_func = NULL}}
+};
+
+static struct param_node encrypted_passthrough_param_node = {
+ .num_mnt_opt_names = 1,
+ .mnt_opt_names = {"ecryptfs_encrypted_view"},
+ .prompt = "Pass through encrypted versions of all files (y/N)",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = "n",
+ .flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
+ .num_transitions = 1,
+ .tl = {{.val = "default",
+ .pretty_val = "default",
+ .next_token = &end_param_node,
+ .trans_func = get_encrypted_passthrough}}
+};
+
+static struct param_node xattr_param_node = {
+ .num_mnt_opt_names = 1,
+ .mnt_opt_names = {"ecryptfs_xattr"},
+ .prompt = "Write metadata to extended attribute region (y/N)",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = "n",
+ .flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
+ .num_transitions = 1,
+ .tl = {{.val = "default",
+ .pretty_val = "default",
+ .next_token = &end_param_node,
+ .trans_func = get_xattr}}
+};
+
+static struct param_node passthrough_param_node = {
+ .num_mnt_opt_names = 1,
+ .mnt_opt_names = {"ecryptfs_passthrough"},
+ .prompt = "Enable plaintext passthrough (y/n)",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
+ .num_transitions = 1,
+ .tl = {{.val = "default",
+ .pretty_val = "default",
+ .next_token = &end_param_node,
+ .trans_func = get_passthrough}}
+};
+
+static struct param_node hmac_param_node = {
+ .num_mnt_opt_names = 1,
+ .mnt_opt_names = {"ecryptfs_hmac"},
+ .prompt = "Enable HMAC integrity verification (y/N)",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .flags = ECRYPTFS_PARAM_FLAG_ECHO_INPUT,
+ .num_transitions = 1,
+ .tl = {{.val = "default",
+ .pretty_val = "default",
+ .next_token = &end_param_node,
+ .trans_func = get_hmac}}
+};
+
+static struct param_node ecryptfs_key_bytes_param_node = {
+ .num_mnt_opt_names = 1,
+ .mnt_opt_names = {"ecryptfs_key_bytes"},
+ .prompt = "Select key bytes",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .flags = (DISPLAY_TRANSITION_NODE_VALS
+ | ECRYPTFS_PARAM_FORCE_DISPLAY_NODES
+ | ECRYPTFS_PARAM_FLAG_ECHO_INPUT),
+ .num_transitions = 0,
+ .tl = {{0}}
+};
+
+static struct supported_key_bytes {
+ char *cipher_name;
+ uint32_t key_bytes;
+} supported_key_bytes[] = {
+ {"aes", 16},
+ {"aes", 32},
+ {"aes", 24},
+ {"anubis", 16},
+ {"anubis", 32},
+ {"des3_ede", 24},
+ {"serpent", 16},
+ {"serpent", 32},
+ {"tnepres", 16},
+ {"tnepres", 32},
+ {"tea", 16},
+ {"xeta", 16},
+ {"xtea", 16},
+ {"cast5", 16},
+ {"cast6", 16},
+ {"cast6", 32},
+ {"twofish", 16},
+ {"twofish", 32},
+ {"blowfish", 16},
+ {"blowfish", 32},
+ {"blowfish", 56},
+ {"khazad", 16},
+ {"arc4", 16},
+ {"arc4", 32},
+ {NULL, 0}
+};
+
+static int tf_ecryptfs_key_bytes(struct ecryptfs_ctx *ctx,
+ struct param_node *node,
+ struct val_node **head, void **foo)
+{
+ char *opt;
+ int rc = 0;
+
+ rc = asprintf(&opt, "ecryptfs_key_bytes=%s", node->val);
+ free(node->val);
+ node->val = NULL;
+ if (rc == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = stack_push(head, opt);
+out:
+ return rc;
+}
+
+static int init_ecryptfs_key_bytes_param_node(char *cipher_name,
+ uint32_t min, uint32_t max)
+{
+ int i;
+ int rc = 0;
+
+ i = 0;
+ while (supported_key_bytes[i].cipher_name) {
+ if ((supported_key_bytes[i].key_bytes >= min) &&
+ (supported_key_bytes[i].key_bytes <= max) &&
+ (strcmp(cipher_name, supported_key_bytes[i].cipher_name)
+ == 0)) {
+ struct transition_node *tn;
+
+ tn = &ecryptfs_key_bytes_param_node.tl[
+ ecryptfs_key_bytes_param_node.num_transitions];
+ rc = asprintf(&tn->val, "%"PRIu32,
+ supported_key_bytes[i].key_bytes);
+ if (rc == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+ if (!ecryptfs_key_bytes_param_node.suggested_val) {
+ rc = asprintf(&ecryptfs_key_bytes_param_node.suggested_val,
+ "%"PRIu32,
+ supported_key_bytes[i].key_bytes);
+ if (rc == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+ }
+ tn->next_token = &ecryptfs_version_support_node;
+ tn->trans_func = tf_ecryptfs_key_bytes;
+ ecryptfs_key_bytes_param_node.num_transitions++;
+ }
+ i++;
+ }
+ if (ecryptfs_key_bytes_param_node.num_transitions == 0) {
+ syslog(LOG_ERR, "Error initializing key_bytes selection: "
+ "there is no posibility left for used params\n");
+ return -EINVAL;
+ }
+out:
+ return rc;
+}
+
+static int parse_key_bytes(uint32_t *bytes, const char *str)
+{
+ uintmax_t tmp;
+ char *eptr;
+
+ if (str[0] == '-')
+ return -ERANGE;
+
+ errno = 0;
+ tmp = strtoumax(str, &eptr, 10);
+ if (eptr == str)
+ return -EINVAL;
+ else if (tmp == UINTMAX_MAX && errno == ERANGE)
+ return -ERANGE;
+ else if (tmp > UINT32_MAX)
+ return -ERANGE;
+
+ *bytes = (uint32_t)tmp;
+ return 0;
+}
+
+static int tf_ecryptfs_cipher(struct ecryptfs_ctx *ctx, struct param_node *node,
+ struct val_node **head, void **foo)
+{
+ char *opt;
+ int rc;
+ uint32_t min = 0, max = 999999;
+ struct val_node *tmp = *head, *tmpprev = NULL;
+
+ while (tmp) {
+ char *ptr;
+ int popval = 0;
+ if (tmp->val && (strstr(tmp->val,"max_key_bytes=") != NULL) &&
+ ((ptr=strchr(tmp->val,'=')) != NULL)) {
+ rc = parse_key_bytes(&max, ++ptr);
+ if (rc)
+ return rc;
+ popval = 1;
+ }
+ if (tmp->val && (strstr(tmp->val,"min_key_bytes=") != NULL) &&
+ ((ptr=strchr(tmp->val,'=')) != NULL)) {
+ rc = parse_key_bytes(&min, ++ptr);
+ if (rc)
+ return rc;
+ popval = 1;
+ }
+ if (popval) {
+ if (tmp == *head)
+ *head = (*head)->next;
+ stack_pop(&tmp);
+ if (tmpprev != NULL)
+ tmpprev->next = tmp;
+ }
+ tmpprev = tmp;
+ tmp = tmp->next;
+ }
+
+ rc = init_ecryptfs_key_bytes_param_node(node->val, min, max);
+ if (rc) {
+ syslog(LOG_ERR, "%s: Error initializing key_bytes param node; "
+ "rc = [%d]\n", __FUNCTION__, rc);
+ goto out;
+ }
+ rc = asprintf(&opt, "ecryptfs_cipher=%s", node->val);
+ free(node->val);
+ node->val = NULL;
+ if (rc == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO, "%s: Pushing onto stack; opt = [%s]\n",
+ __FUNCTION__, opt);
+ rc = stack_push(head, opt);
+out:
+ return rc;
+}
+
+static struct param_node ecryptfs_cipher_param_node = {
+ .num_mnt_opt_names = 1,
+ .mnt_opt_names = {"ecryptfs_cipher"},
+ .prompt = "Select cipher",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .flags = (DISPLAY_TRANSITION_NODE_VALS | ECRYPTFS_DISPLAY_PRETTY_VALS
+ | ECRYPTFS_PARAM_FLAG_ECHO_INPUT),
+ .num_transitions = 0,
+ .tl = {{0}}
+};
+
+static struct cipher_descriptor {
+ char *name;
+ uint32_t blocksize;
+ uint32_t min_keysize;
+ uint32_t max_keysize;
+} cipher_descriptors[] = {
+ {"aes", 16, 16, 32},
+ {"blowfish", 8, 16, 56},
+ {"des3_ede", 8, 24, 24},
+ {"twofish", 16, 16, 32},
+ {"cast6", 16, 16, 32},
+ {"cast5", 8, 5, 16},
+ {NULL, 0, 0, 0}
+};
+
+static int init_ecryptfs_cipher_param_node()
+{
+ struct cipher_descriptor *cd = cipher_descriptors;
+ int rc = 0;
+
+ while (cd && cd->name) {
+ struct transition_node *tn;
+
+ if (ecryptfs_cipher_param_node.num_transitions
+ >= MAX_NUM_TRANSITIONS) {
+ syslog(LOG_WARNING, "%s: Exceeded maximum number of "
+ "transition nodes [%d] whilst constructing "
+ "cipher list\n", __FUNCTION__,
+ MAX_NUM_TRANSITIONS);
+ goto out;
+ }
+ tn = &ecryptfs_cipher_param_node.tl[
+ ecryptfs_cipher_param_node.num_transitions];
+ rc = asprintf(&tn->val, "%s", cd->name);
+ if (rc == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+ if (!ecryptfs_cipher_param_node.suggested_val) {
+ rc = asprintf(&ecryptfs_cipher_param_node.suggested_val,
+ "%s", cd->name);
+ if (rc == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+ }
+ rc = asprintf(&tn->pretty_val, "%s: blocksize = %d; "
+ "min keysize = %d; max keysize = %d", cd->name,
+ cd->blocksize, cd->min_keysize, cd->max_keysize);
+ if (rc == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+ tn->next_token = &ecryptfs_key_bytes_param_node;
+ tn->trans_func = tf_ecryptfs_cipher;
+ ecryptfs_cipher_param_node.num_transitions++;
+ cd++;
+ }
+out:
+ return rc;
+}
+
+static int
+another_key_param_node_callback(struct ecryptfs_ctx *ctx,
+ struct param_node *node,
+ struct val_node **head, void **foo)
+{
+ struct ecryptfs_name_val_pair *nvp = ctx->nvp_head->next;
+ int rc = 0;
+
+ while (nvp) {
+ int i;
+
+ if (nvp->flags & ECRYPTFS_PROCESSED) {
+ nvp = nvp->next;
+ continue;
+ }
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO, "Comparing nvp->name = [%s] to "
+ "key_module_select_node.mnt_opt_names[0] = "
+ "[%s]\n", nvp->name,
+ key_module_select_node.mnt_opt_names[0]);
+ if (strcmp(nvp->name,
+ key_module_select_node.mnt_opt_names[0]) != 0) {
+ nvp = nvp->next;
+ continue;
+ }
+ for (i = 0; i < key_module_select_node.num_transitions; i++)
+ if (strcmp(nvp->value,
+ key_module_select_node.tl[i].val) == 0) {
+ node->tl[0].next_token =
+ &key_module_select_node;
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO,
+ "Found another nvp match\n");
+ goto out;
+ }
+ nvp = nvp->next;
+ }
+ node->tl[0].next_token = &ecryptfs_cipher_param_node;
+out:
+ return rc;
+}
+
+/**
+ * Check for the existence of another transition node match in the
+ * name/value pair list.
+ */
+static struct param_node another_key_param_node = {
+ .num_mnt_opt_names = 1,
+ .mnt_opt_names = {"another_key"},
+ .prompt = "Internal check for another key",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = "NULL",
+ .flags = ECRYPTFS_PARAM_FLAG_NO_VALUE | ECRYPTFS_NO_AUTO_TRANSITION,
+ .num_transitions = 1,
+ .tl = {{.val = "default",
+ .pretty_val = "default",
+ .next_token = &ecryptfs_cipher_param_node,
+ .trans_func = another_key_param_node_callback}}
+};
+
+static int
+fill_in_decision_graph_based_on_version_support(struct param_node *root,
+ uint32_t version)
+{
+ struct param_node *last_param_node = &ecryptfs_version_support_node;
+ int rc;
+
+ ecryptfs_set_exit_param_on_graph(root, &another_key_param_node);
+ rc = init_ecryptfs_cipher_param_node();
+ if (rc) {
+ syslog(LOG_ERR,
+ "%s: Error initializing cipher list; rc = [%d]\n",
+ __FUNCTION__, rc);
+ goto out;
+ }
+ if (ecryptfs_supports_plaintext_passthrough(version)) {
+ int i;
+
+ for (i = 0; i < last_param_node->num_transitions; i++)
+ last_param_node->tl[i].next_token =
+ &passthrough_param_node;
+ rc = asprintf(&passthrough_param_node.suggested_val, "n");
+ if (rc == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+ last_param_node = &passthrough_param_node;
+ }
+ if (ecryptfs_supports_hmac(version)) {
+ int i;
+
+ for (i = 0; i < last_param_node->num_transitions; i++)
+ last_param_node->tl[i].next_token =
+ &hmac_param_node;
+ last_param_node = &hmac_param_node;
+ }
+ if (ecryptfs_supports_xattr(version)) {
+ int i;
+
+ for (i = 0; i < last_param_node->num_transitions; i++)
+ last_param_node->tl[i].next_token = &xattr_param_node;
+ last_param_node = &xattr_param_node;
+ for (i = 0; i < last_param_node->num_transitions; i++)
+ last_param_node->tl[i].next_token =
+ &encrypted_passthrough_param_node;
+ last_param_node = &encrypted_passthrough_param_node;
+ }
+ if (ecryptfs_supports_filename_encryption(version)) {
+ int i;
+
+ rc = asprintf(&enable_filename_crypto_param_node.suggested_val,
+ "n");
+ if (rc == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+ for (i = 0; i < last_param_node->num_transitions; i++)
+ last_param_node->tl[i].next_token =
+ &filename_crypto_fnek_sig_param_node;
+ last_param_node = &filename_crypto_fnek_sig_param_node;
+ }
+out:
+ return rc;
+}
+
+static struct param_node dummy_param_node = {
+ .num_mnt_opt_names = 1,
+ .mnt_opt_names = {"dummy"},
+ .prompt = "dummy",
+ .val_type = VAL_STR,
+ .val = NULL,
+ .display_opts = NULL,
+ .default_val = NULL,
+ .flags = ECRYPTFS_PARAM_FLAG_NO_VALUE,
+ .num_transitions = 0,
+ .tl = {{.val = "default",
+ .pretty_val = "default",
+ .next_token = NULL,
+ .trans_func = NULL}}
+};
+
+/**
+ * ecryptfs_process_decision_graph
+ * @key_module_only: Only process the key module; set this if you are,
+ * for instance, only inserting the key into the
+ * user session keyring
+ *
+ * Called from: utils/mount.ecryptfs.c::main()
+ *
+ * Some values may be duplicated. For instance, if the user specifies
+ * two keys of the same type, then we want to process both keys:
+ *
+ * key=passphrase:passwd=pass1,key=passphrase:passwd=pass1
+ *
+ *
+ */
+int ecryptfs_process_decision_graph(struct ecryptfs_ctx *ctx,
+ struct val_node **mnt_params,
+ uint32_t version, char *opts_str,
+ int key_module_only)
+{
+ struct ecryptfs_name_val_pair nvp_head;
+ struct ecryptfs_name_val_pair rc_file_nvp_head;
+ struct ecryptfs_key_mod *key_mod;
+ struct ecryptfs_name_val_pair allowed_duplicates;
+ struct ecryptfs_name_val_pair *ad_cursor;
+ int rc;
+
+ ad_cursor = &allowed_duplicates;
+ ad_cursor->next = NULL;
+ /* Start with the key module type. Generate the options from
+ * the detected modules that are available */
+ rc = ecryptfs_register_key_modules(ctx);
+ if (rc) {
+ syslog(LOG_ERR, "Error attempting to get key module list; "
+ "rc = [%d]\n", rc);
+ goto out;
+ }
+ if ((ad_cursor->next = malloc(sizeof(allowed_duplicates))) == NULL) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ ad_cursor = ad_cursor->next;
+ ad_cursor->next = NULL;
+ if ((rc = asprintf(&ad_cursor->name, "%s",
+ key_module_select_node.mnt_opt_names[0])) == -1) {
+ rc = -ENOMEM;
+ goto out_free_allowed_duplicates;
+ }
+ key_module_select_node.num_transitions = 0;
+ key_mod = ctx->key_mod_list_head.next;
+ while (key_mod) {
+ struct transition_node *trans_node;
+
+ if ((rc =
+ key_mod->ops->get_param_subgraph_trans_node(&trans_node,
+ version))) {
+ syslog(LOG_INFO, "Key module [%s] does not have a "
+ "subgraph transition node; attempting to build "
+ "a linear subgraph from its parameter list\n",
+ key_mod->alias);
+ if ((rc = ecryptfs_build_linear_subgraph(&trans_node,
+ key_mod))) {
+ syslog(LOG_WARNING, "Error attempting to build "
+ "linear subgraph for key module [%s]; "
+ "excluding; rc = [%d]\n",
+ key_mod->alias, rc);
+ key_mod = key_mod->next;
+ continue;
+ }
+ }
+ if (trans_node == NULL) {
+ if ((rc = ecryptfs_build_linear_subgraph(&trans_node,
+ key_mod))) {
+ syslog(LOG_WARNING, "Error attempting to build "
+ "linear subgraph for key module [%s]; "
+ "excluding; rc = [%d]\n",
+ key_mod->alias, rc);
+ key_mod = key_mod->next;
+ continue;
+ }
+ }
+ if ((rc =
+ add_transition_node_to_param_node(&key_module_select_node,
+ trans_node))) {
+ syslog(LOG_ERR, "Error attempting to add transition "
+ "node to param node; rc = [%d]\n", rc);
+ goto out_free_allowed_duplicates;
+ }
+ /* Key module parameters may be duplicated, since
+ * the user may specify multiple keys. Make sure that
+ * the allowed_duplicates list has the parameters for
+ * this key module. */
+ if ((rc = ecryptfs_insert_params_in_subgraph(ad_cursor,
+ trans_node))) {
+ syslog(LOG_ERR, "Error attempting to insert allowed "
+ "duplicate parameters into subgraph for key "
+ "module; rc = [%d]\n", rc);
+ goto out_free_allowed_duplicates;
+ }
+ key_mod = key_mod->next;
+ }
+ if (key_module_only == ECRYPTFS_ASK_FOR_ALL_MOUNT_OPTIONS) {
+ rc = fill_in_decision_graph_based_on_version_support(
+ &key_module_select_node, version);
+ if (rc) {
+ syslog(LOG_ERR, "%s: Error attempting to fill in "
+ "decision graph; rc = [%d]\n", __FUNCTION__, rc);
+ goto out;
+ }
+ } else
+ ecryptfs_set_exit_param_on_graph(&key_module_select_node,
+ &dummy_param_node);
+ memset(&nvp_head, 0, sizeof(struct ecryptfs_name_val_pair));
+ memset(&rc_file_nvp_head, 0, sizeof(struct ecryptfs_name_val_pair));
+ ecryptfs_parse_rc_file(&rc_file_nvp_head);
+ rc = ecryptfs_parse_options(opts_str, &nvp_head);
+ ecryptfs_nvp_list_union(&rc_file_nvp_head, &nvp_head,
+ &allowed_duplicates);
+ if (ecryptfs_verbosity) {
+ struct ecryptfs_name_val_pair *nvp_item = rc_file_nvp_head.next;
+
+ while (nvp_item) {
+ if (ecryptfs_verbosity)
+ syslog(LOG_INFO, "name = [%s]; value = [%s]\n",
+ nvp_item->name, nvp_item->value);
+ nvp_item = nvp_item->next;
+ }
+ }
+ ctx->nvp_head = &rc_file_nvp_head;
+ rc = ecryptfs_eval_decision_graph(ctx, mnt_params, &root_param_node,
+ &rc_file_nvp_head);
+out_free_allowed_duplicates:
+ ad_cursor = allowed_duplicates.next;
+ while (ad_cursor) {
+ struct ecryptfs_name_val_pair *next;
+
+ next = ad_cursor->next;
+ free(ad_cursor->name);
+ free(ad_cursor);
+ ad_cursor = next;
+ }
+out:
+ return rc;
+}
+
+int ecryptfs_process_key_gen_decision_graph(struct ecryptfs_ctx *ctx,
+ uint32_t version)
+{
+ struct ecryptfs_name_val_pair nvp_head;
+ struct ecryptfs_key_mod *key_mod;
+ struct val_node *mnt_params;
+ int rc;
+
+ if ((mnt_params = malloc(sizeof(struct val_node))) == NULL) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ memset(mnt_params, 0, sizeof(struct val_node));
+ if ((rc = ecryptfs_register_key_modules(ctx))) {
+ syslog(LOG_ERR, "Error attempting to get key module list; "
+ "rc = [%d]\n", rc);
+ goto out;
+ }
+ key_module_select_node.num_transitions = 0;
+ key_mod = ctx->key_mod_list_head.next;
+ while (key_mod) {
+ struct transition_node *trans_node;
+
+ if ((rc =
+ key_mod->ops->get_gen_key_subgraph_trans_node(&trans_node,
+ version))) {
+ syslog(LOG_INFO, "Key module [%s] does not have a "
+ "key generation subgraph transition node\n",
+ key_mod->alias);
+ /* TODO: Implement key generation linear subgraph */
+ key_mod = key_mod->next;
+ continue;
+ }
+ if (trans_node == NULL) {
+ syslog(LOG_INFO, "Key module [%s] does not have a "
+ "key generation subgraph transition node\n",
+ key_mod->alias);
+ /* TODO: Implement key generation linear subgraph */
+ key_mod = key_mod->next;
+ continue;
+ }
+ if ((rc =
+ add_transition_node_to_param_node(&key_module_select_node,
+ trans_node))) {
+ syslog(LOG_ERR, "Error attempting to add transition "
+ "node to param node; rc = [%d]\n", rc);
+ goto out;
+ }
+ key_mod = key_mod->next;
+ }
+ ecryptfs_set_exit_param_on_graph(&key_module_select_node,
+ &dummy_param_node);
+ memset(&nvp_head, 0, sizeof(struct ecryptfs_name_val_pair));
+ ctx->nvp_head = &nvp_head;
+ key_module_select_node.flags |= ECRYPTFS_PARAM_FORCE_DISPLAY_NODES;
+ ecryptfs_eval_decision_graph(ctx, &mnt_params, &key_module_select_node,
+ &nvp_head);
+out:
+ free(mnt_params);
+ return rc;
+}
diff --git a/src/libecryptfs/packets.c b/src/libecryptfs/packets.c
new file mode 100644
index 0000000..d8dc8a0
--- /dev/null
+++ b/src/libecryptfs/packets.c
@@ -0,0 +1,369 @@
+/**
+ * Userspace side of communications with eCryptfs kernel module.
+ *
+ * Copyright (C) 2004-2006 International Business Machines Corp.
+ * Author(s): Trevor S. Highland <trevor.highland@gmail.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>
+#ifndef S_SPLINT_S
+#include <syslog.h>
+#include <stdio.h>
+#endif
+#include <string.h>
+#include <unistd.h>
+#include <keyutils.h>
+#include <stdlib.h>
+#include "../include/ecryptfs.h"
+
+#define ECRYPTFS_PACKET_STATUS_GOOD 0
+#define ECRYPTFS_PACKET_STATUS_BAD -1
+
+/**
+ * key_mod_encrypt
+ * @encrypted_key: This function will allocate this memory and encrypt
+ * the key into it
+ * @encrypted_key_size: The size of the encrypted key; note that the
+ * actual amount of memory allocated by this
+ * function may be more than this
+ * @ctx:
+ * @auth_tok: The authentication token structure in the user session
+ * keyring; this contains the key module state blob
+ * @decrypted_key:
+ * @decrypted_key_size:
+ *
+ *
+ *
+ * Called from parse_packet()
+ */
+static int
+key_mod_encrypt(char **encrypted_key, size_t *encrypted_key_size,
+ struct ecryptfs_ctx *ctx, struct ecryptfs_auth_tok *auth_tok,
+ char *decrypted_key, size_t decrypted_key_size)
+{
+ struct ecryptfs_key_mod *key_mod;
+ int rc;
+
+ if (ecryptfs_find_key_mod(&key_mod, ctx,
+ auth_tok->token.private_key.key_mod_alias)) {
+ rc = -EINVAL;
+ syslog(LOG_ERR, "Failed to locate desired key module\n");
+ goto out;
+ }
+ /* TODO: Include support for a hint rather than just a blob */
+ if ((rc = key_mod->ops->encrypt(NULL, encrypted_key_size, decrypted_key,
+ decrypted_key_size,
+ auth_tok->token.private_key.data,
+ ECRYPTFS_BLOB_TYPE_BLOB))) {
+ syslog(LOG_ERR, "Error attempting to get encrypted key size "
+ "from key module; rc = [%d]\n", rc);
+ goto out;
+ }
+ if ((*encrypted_key_size) == 0) {
+ rc = -EINVAL;
+ syslog(LOG_ERR, "Encrypted key size reported by key module "
+ "encrypt function is 0\n");
+ goto out;
+ }
+ /* The first call just told us how much memory to
+ * allocate. The actual key size may be less, so we don't
+ * worry about ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES until the
+ * second call. */
+ if (((*encrypted_key) = malloc(*encrypted_key_size)) == NULL) {
+ rc = -errno;
+ syslog(LOG_ERR, "Failed to allocate memory: [%m]\n");
+ goto out;
+ }
+ if ((rc = key_mod->ops->encrypt((*encrypted_key), encrypted_key_size,
+ decrypted_key, decrypted_key_size,
+ auth_tok->token.private_key.data,
+ ECRYPTFS_BLOB_TYPE_BLOB))) {
+ syslog(LOG_ERR, "Failed to encrypt key; rc = [%d]\n", rc);
+ goto out;
+ }
+ if ((*encrypted_key_size) > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) {
+ rc = -EINVAL;
+ syslog(LOG_ERR, "Encrypted key size reported by key module "
+ "encrypt function is [%zu]; max is [%d]\n",
+ (*encrypted_key_size), ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES);
+ free(*encrypted_key);
+ (*encrypted_key_size) = 0;
+ goto out;
+ }
+out:
+ return rc;
+}
+
+static int
+key_mod_decrypt(char **decrypted_key, size_t *decrypted_key_size,
+ struct ecryptfs_ctx *ctx, struct ecryptfs_auth_tok *auth_tok,
+ char *encrypted_key, size_t encrypted_key_size)
+{
+ struct ecryptfs_key_mod *key_mod;
+ int rc;
+
+ if (ecryptfs_find_key_mod(&key_mod, ctx,
+ auth_tok->token.private_key.key_mod_alias)) {
+ rc = -EINVAL;
+ syslog(LOG_ERR, "Failed to locate desired key module\n");
+ goto out;
+ }
+ if ((rc = key_mod->ops->decrypt(NULL, decrypted_key_size,
+ encrypted_key, encrypted_key_size,
+ auth_tok->token.private_key.data,
+ ECRYPTFS_BLOB_TYPE_BLOB))) {
+ syslog(LOG_ERR, "Failed to get size for decrypted key\n");
+ goto out;
+ }
+ if ((*decrypted_key_size) == 0) {
+ rc = -EINVAL;
+ syslog(LOG_ERR, "Decrypted key size reported by key module "
+ "decrypt function is 0\n");
+ goto out;
+ }
+ /* The first call just told us how much memory to
+ * allocate. The actual key size may be less, so we don't
+ * worry about ECRYPTFS_MAX_KEY_BYTES until the second
+ * call. */
+ if (((*decrypted_key) = malloc(*decrypted_key_size)) == NULL) {
+ rc = -ENOMEM;
+ syslog(LOG_ERR, "Failed to allocate memory\n");
+ goto out;
+ }
+ if ((rc = key_mod->ops->decrypt(*decrypted_key, decrypted_key_size,
+ encrypted_key, encrypted_key_size,
+ auth_tok->token.private_key.data,
+ ECRYPTFS_BLOB_TYPE_BLOB))) {
+ syslog(LOG_ERR, "Failed to decrypt key\n");
+ goto out;
+ }
+ if ((*decrypted_key_size) > ECRYPTFS_MAX_KEY_BYTES) {
+ rc = -EINVAL;
+ syslog(LOG_ERR, "Decrypted key size reported by key module "
+ "decrypt function is [%zu]; max is [%d]\n",
+ (*decrypted_key_size), ECRYPTFS_MAX_KEY_BYTES);
+ free(*decrypted_key);
+ (*decrypted_key_size) = 0;
+ goto out;
+ }
+out:
+ return rc;
+}
+
+static int write_failure_packet(size_t tag,
+ struct ecryptfs_message **reply)
+{
+ unsigned char *data;
+ size_t i = 0;
+ int rc = 0;
+
+ *reply = malloc(sizeof(struct ecryptfs_message) + 2);
+ if (!*reply) {
+ rc = -errno;
+ syslog(LOG_ERR, "Failed to allocate memory: %m\n");
+ goto out;
+ }
+ data = (*reply)->data;
+ data[i++] = tag;
+ data[i++] = ECRYPTFS_PACKET_STATUS_BAD;
+ (*reply)->data_len = i;
+out:
+ return rc;
+}
+
+static int write_tag_65_packet(unsigned char *key, size_t key_size,
+ struct ecryptfs_message **reply)
+{
+ unsigned char *data;
+ size_t data_len;
+ size_t length_size;
+ size_t i = 0;
+ int rc = 0;
+
+ data_len = key_size + 4;
+ *reply = malloc(sizeof(struct ecryptfs_message) + data_len);
+ if (!*reply) {
+ rc = -errno;
+ syslog(LOG_ERR, "Failed to allocate memory: %m\n");
+ goto out;
+ }
+ data = (*reply)->data;
+ data[i++] = ECRYPTFS_TAG_65_PACKET;
+ data[i++] = ECRYPTFS_PACKET_STATUS_GOOD;
+ rc = ecryptfs_write_packet_length((char*)&data[i], key_size, &length_size);
+ if (rc) {
+ syslog(LOG_ERR, "Invalid packet format\n");
+ goto out;
+ }
+ i += length_size;
+ memcpy(&data[i], key, key_size);
+ i += key_size;
+ (*reply)->data_len = i;
+out:
+ return rc;
+}
+
+static int
+write_tag_67_packet(char *key, size_t key_size,
+ struct ecryptfs_message **reply)
+{
+ unsigned char *data;
+ size_t data_len;
+ size_t length_size;
+ size_t i = 0;
+ int rc = 0;
+
+ data_len = key_size + 4;
+ *reply = malloc(sizeof(struct ecryptfs_message) + data_len);
+ if (!*reply) {
+ rc = -errno;
+ syslog(LOG_ERR, "Failed to allocate memory: %m\n");
+ goto out;
+ }
+ data = (*reply)->data;
+ data[i++] = ECRYPTFS_TAG_67_PACKET;
+ data[i++] = ECRYPTFS_PACKET_STATUS_GOOD;
+ rc = ecryptfs_write_packet_length((char *)&data[i], key_size, &length_size);
+ if (rc) {
+ syslog(LOG_ERR, "Invalid packet format\n");
+ goto out;
+ }
+ i += length_size;
+ memcpy(&data[i], key, key_size);
+ i += key_size;
+ (*reply)->data_len = data_len;
+out:
+ return rc;
+}
+
+int parse_packet(struct ecryptfs_ctx *ctx,
+ struct ecryptfs_message *emsg,
+ struct ecryptfs_message **reply)
+{
+ struct ecryptfs_auth_tok *auth_tok = NULL;
+ size_t i = 0;
+ size_t data_size;
+ size_t key_size;
+ size_t length_size;
+ size_t key_out_size;
+ unsigned char *signature = NULL;
+ unsigned char packet_type;
+ char *key = NULL;
+ char *key_out = NULL;
+ key_serial_t key_sub;
+ int rc;
+
+ packet_type = emsg->data[i++];
+ if ((rc = ecryptfs_parse_packet_length(&emsg->data[i], &data_size,
+ &length_size))) {
+ syslog(LOG_ERR, "Invalid packet format\n");
+ goto write_failure;
+ }
+ i += length_size;
+ signature = malloc(data_size + 1);
+ if (!signature) {
+ rc = -errno;
+ syslog(LOG_ERR, "Failed to allocate memory: %m\n");
+ goto write_failure;
+ }
+ memcpy(signature, &emsg->data[i], data_size);
+ signature[data_size] = '\0';
+ i += data_size;
+ rc = ecryptfs_parse_packet_length(&emsg->data[i], &key_size,
+ &length_size);
+ if (rc) {
+ syslog(LOG_ERR, "Invalid packet format\n");
+ goto write_failure;
+ }
+ i += length_size;
+ if ((key = malloc(key_size)) == NULL) {
+ rc = -ENOMEM;
+ syslog(LOG_ERR, "Failed to allocate memory\n");
+ goto write_failure;
+ }
+ memcpy(key, &emsg->data[i], key_size);
+ i += key_size;
+ key_sub = request_key("user", (char *)signature, NULL,
+ KEY_SPEC_USER_KEYRING);
+ if (key_sub < 0) {
+ syslog(LOG_ERR, "Could not find key with signature: "
+ "[%s]\n", signature);
+ rc = -EINVAL;
+ goto write_failure;
+ }
+ rc = keyctl_read_alloc(key_sub, (void **)(&auth_tok));
+ switch (packet_type) {
+ case ECRYPTFS_TAG_64_PACKET:
+ if ((rc = key_mod_decrypt(&key_out, &key_out_size, ctx,
+ auth_tok, key, key_size))) {
+ syslog(LOG_ERR, "Failed to decrypt key; rc = [%d]\n",
+ rc);
+ rc = write_failure_packet(ECRYPTFS_TAG_65_PACKET,
+ reply);
+ goto write_failure;
+ }
+ if ((rc = write_tag_65_packet((unsigned char *)key_out,
+ key_out_size, reply))) {
+ syslog(LOG_ERR, "Failed to write decrypted "
+ "key via tag 65 packet\n");
+ goto write_failure;
+ }
+ break;
+ case ECRYPTFS_TAG_66_PACKET:
+ rc = key_mod_encrypt(&key_out, &key_out_size, ctx, auth_tok,
+ key, key_size);
+ if (rc) {
+ syslog(LOG_ERR, "Failed to encrypt public "
+ "key\n");
+ goto write_failure;
+ }
+ rc = write_tag_67_packet(key_out, key_out_size, reply);
+ if (rc) {
+ syslog(LOG_ERR, "Failed to write encrypted "
+ "key to tag 67 packet\n");
+ goto write_failure;
+ }
+ break;
+ default:
+ syslog(LOG_ERR, "Unrecognized packet type: [%d]\n",
+ packet_type);
+ rc = -EINVAL;
+ break;
+ }
+ free(key);
+ free(signature);
+ free(key_out);
+ memset(auth_tok, 0, (sizeof(struct ecryptfs_auth_tok)
+ + auth_tok->token.private_key.data_len));
+ free(auth_tok);
+ return rc;
+write_failure:
+ if(packet_type == ECRYPTFS_TAG_66_PACKET)
+ rc = write_failure_packet(ECRYPTFS_TAG_67_PACKET, reply);
+ else
+ rc = write_failure_packet(ECRYPTFS_TAG_65_PACKET, reply);
+ free(key);
+ free(signature);
+ free(key_out);
+ if (auth_tok) {
+ memset(auth_tok, 0, (sizeof(struct ecryptfs_auth_tok)
+ + auth_tok->token.private_key.data_len));
+ free(auth_tok);
+ }
+ return rc;
+}
diff --git a/src/libecryptfs/sysfs.c b/src/libecryptfs/sysfs.c
new file mode 100644
index 0000000..7022404
--- /dev/null
+++ b/src/libecryptfs/sysfs.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2006 International Business Machines Corp.
+ * Author: Mike Halcrow <mhalcrow@us.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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 <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifndef S_SPLINT_S
+#include <stdio.h>
+#endif
+#include <string.h>
+#include <errno.h>
+#include <mntent.h>
+#include <stdlib.h>
+#include "../include/ecryptfs.h"
+
+static int get_sysfs_mountpoint(char *mnt, int *mnt_size)
+{
+ FILE *fp;
+ struct mntent *mntent;
+ int rc;
+
+ fp = fopen("/etc/mtab", "r");
+ if (!fp) {
+ rc = -errno;
+ goto out;
+ }
+ while ((mntent = getmntent(fp)))
+ if (strcmp(mntent->mnt_type, "sysfs") == 0) {
+ *mnt_size = strlen(mntent->mnt_dir);
+ if (mnt)
+ memcpy(mnt, mntent->mnt_dir, *mnt_size);
+ rc = 0;
+ fclose(fp);
+ goto out;
+ }
+ fclose(fp);
+ /* Default to /sys if not found in /etc/mtab */
+ *mnt_size = strlen("/sys");
+ if (mnt)
+ memcpy(mnt, "/sys", strlen("/sys"));
+ rc = 0;
+out:
+ return rc;
+}
+
+int ecryptfs_get_version(uint32_t *version)
+{
+ char *mnt;
+ char *handle;
+ char version_str[16];
+ ssize_t size;
+ int mnt_size;
+ int fd;
+ int rc;
+
+ rc = get_sysfs_mountpoint(NULL, &mnt_size);
+ if (rc)
+ goto out;
+ mnt = malloc(mnt_size + 1);
+ if (!mnt) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = get_sysfs_mountpoint(mnt, &mnt_size);
+ if (rc) {
+ free(mnt);
+ goto out;
+ }
+ mnt[mnt_size] = '\0';
+ rc = asprintf(&handle, "%s/fs/ecryptfs/version", mnt);
+ free(mnt);
+ if (rc == -1) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ rc = 0;
+ fd = open(handle, O_RDONLY);
+ /* We can attempt to modprobe ecryptfs, which might help if we're
+ * being called by code running as root
+ */
+ if (fd == -1 && errno == ENOENT &&
+ system("/sbin/modprobe ecryptfs 2>/dev/null") != -1)
+ fd = open(handle, O_RDONLY);
+ free(handle);
+ if (fd == -1) {
+ rc = -EINVAL;
+ goto out;
+ }
+ size = read(fd, version_str, 16);
+ close(fd);
+ if (size == -1 || size == 0) {
+ rc = -EINVAL;
+ goto out;
+ }
+ *version = atoi(version_str);
+out:
+ return rc;
+}
+
+struct ecryptfs_version_str_map_elem {
+ uint32_t flag;
+ char *str;
+} ecryptfs_version_str_map[] = {
+ {ECRYPTFS_VERSIONING_PASSPHRASE, "passphrase"},
+ {ECRYPTFS_VERSIONING_PUBKEY, "Userspace daemon support"},
+ {ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH, "plaintext passthrough"},
+ {ECRYPTFS_VERSIONING_POLICY, "policy"},
+ {ECRYPTFS_VERSIONING_XATTR, "metadata in extended attribute"},
+ {ECRYPTFS_VERSIONING_MISCDEV, "/dev/ecryptfs daemon interface"},
+ {ECRYPTFS_VERSIONING_HMAC, "hmac"},
+ {ECRYPTFS_VERSIONING_FILENAME_ENCRYPTION, "filename encryption"},
+ {ECRYPTFS_VERSIONING_GCM, "gcm cipher block chaining"},
+};
+
+/**
+ * positive on yes; zero on no
+ */
+int ecryptfs_supports_passphrase(uint32_t version)
+{
+ return (version & ECRYPTFS_VERSIONING_PASSPHRASE);
+}
+
+int ecryptfs_supports_pubkey(uint32_t version)
+{
+ return (version & ECRYPTFS_VERSIONING_PUBKEY);
+}
+
+int ecryptfs_supports_plaintext_passthrough(uint32_t version)
+{
+ return (version & ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH);
+}
+
+int ecryptfs_supports_hmac(uint32_t version)
+{
+ return (version & ECRYPTFS_VERSIONING_HMAC);
+}
+
+int ecryptfs_supports_filename_encryption(uint32_t version)
+{
+ return (version & ECRYPTFS_VERSIONING_FILENAME_ENCRYPTION);
+}
+
+int ecryptfs_supports_policy(uint32_t version)
+{
+ return (version & ECRYPTFS_VERSIONING_POLICY);
+}
+
+int ecryptfs_supports_xattr(uint32_t version)
+{
+ return (version & ECRYPTFS_VERSIONING_XATTR);
+}
diff --git a/src/pam_ecryptfs/Makefile.am b/src/pam_ecryptfs/Makefile.am
new file mode 100644
index 0000000..39cec26
--- /dev/null
+++ b/src/pam_ecryptfs/Makefile.am
@@ -0,0 +1,17 @@
+MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
+
+if BUILD_PAM
+pam_LTLIBRARIES = pam_ecryptfs.la
+
+# Needed until libtool-2
+install-data-hook: install-pamLTLIBRARIES
+ rm -f "$(DESTDIR)$(pamdir)/pam_ecryptfs.la"
+ rm -f "$(DESTDIR)$(pamdir)/pam_ecryptfs.a"
+uninstall-local:
+ rm -f "$(DESTDIR)$(pamdir)/pam_ecryptfs.so"
+endif
+
+pam_ecryptfs_la_SOURCES = pam_ecryptfs.c
+pam_ecryptfs_la_CFLAGS = $(AM_CFLAGS)
+pam_ecryptfs_la_LIBADD = $(top_builddir)/src/libecryptfs/libecryptfs.la $(PAM_LIBS)
+pam_ecryptfs_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version -shared
diff --git a/src/pam_ecryptfs/Makefile.in b/src/pam_ecryptfs/Makefile.in
new file mode 100644
index 0000000..276c970
--- /dev/null
+++ b/src/pam_ecryptfs/Makefile.in
@@ -0,0 +1,747 @@
+# 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@
+subdir = src/pam_ecryptfs
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/depcomp
+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 =
+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; }; \
+ }
+am__installdirs = "$(DESTDIR)$(pamdir)"
+LTLIBRARIES = $(pam_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+pam_ecryptfs_la_DEPENDENCIES = \
+ $(top_builddir)/src/libecryptfs/libecryptfs.la \
+ $(am__DEPENDENCIES_1)
+am_pam_ecryptfs_la_OBJECTS = pam_ecryptfs_la-pam_ecryptfs.lo
+pam_ecryptfs_la_OBJECTS = $(am_pam_ecryptfs_la_OBJECTS)
+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 =
+pam_ecryptfs_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(pam_ecryptfs_la_CFLAGS) $(CFLAGS) $(pam_ecryptfs_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+@BUILD_PAM_TRUE@am_pam_ecryptfs_la_rpath = -rpath $(pamdir)
+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 = $(pam_ecryptfs_la_SOURCES)
+DIST_SOURCES = $(pam_ecryptfs_la_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
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALL_LINGUAS = @ALL_LINGUAS@
+AMTAR = @AMTAR@
+AM_CPPFLAGS = @AM_CPPFLAGS@
+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
+@BUILD_PAM_TRUE@pam_LTLIBRARIES = pam_ecryptfs.la
+pam_ecryptfs_la_SOURCES = pam_ecryptfs.c
+pam_ecryptfs_la_CFLAGS = $(AM_CFLAGS)
+pam_ecryptfs_la_LIBADD = $(top_builddir)/src/libecryptfs/libecryptfs.la $(PAM_LIBS)
+pam_ecryptfs_la_LDFLAGS = $(AM_LDFLAGS) -module -avoid-version -shared
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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/pam_ecryptfs/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/pam_ecryptfs/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-pamLTLIBRARIES: $(pam_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(pam_LTLIBRARIES)'; test -n "$(pamdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(pamdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(pamdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(pamdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(pamdir)"; \
+ }
+
+uninstall-pamLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pam_LTLIBRARIES)'; test -n "$(pamdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(pamdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(pamdir)/$$f"; \
+ done
+
+clean-pamLTLIBRARIES:
+ -test -z "$(pam_LTLIBRARIES)" || rm -f $(pam_LTLIBRARIES)
+ @list='$(pam_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_ecryptfs.la: $(pam_ecryptfs_la_OBJECTS) $(pam_ecryptfs_la_DEPENDENCIES) $(EXTRA_pam_ecryptfs_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(pam_ecryptfs_la_LINK) $(am_pam_ecryptfs_la_rpath) $(pam_ecryptfs_la_OBJECTS) $(pam_ecryptfs_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_ecryptfs_la-pam_ecryptfs.Plo@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 $@ $<
+
+pam_ecryptfs_la-pam_ecryptfs.lo: pam_ecryptfs.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_ecryptfs_la_CFLAGS) $(CFLAGS) -MT pam_ecryptfs_la-pam_ecryptfs.lo -MD -MP -MF $(DEPDIR)/pam_ecryptfs_la-pam_ecryptfs.Tpo -c -o pam_ecryptfs_la-pam_ecryptfs.lo `test -f 'pam_ecryptfs.c' || echo '$(srcdir)/'`pam_ecryptfs.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pam_ecryptfs_la-pam_ecryptfs.Tpo $(DEPDIR)/pam_ecryptfs_la-pam_ecryptfs.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pam_ecryptfs.c' object='pam_ecryptfs_la-pam_ecryptfs.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_ecryptfs_la_CFLAGS) $(CFLAGS) -c -o pam_ecryptfs_la-pam_ecryptfs.lo `test -f 'pam_ecryptfs.c' || echo '$(srcdir)/'`pam_ecryptfs.c
+
+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
+
+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
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(pamdir)"; 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:
+
+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)
+@BUILD_PAM_FALSE@uninstall-local:
+@BUILD_PAM_FALSE@install-data-hook:
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-pamLTLIBRARIES \
+ 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-pamLTLIBRARIES
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+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-local uninstall-pamLTLIBRARIES
+
+.MAKE: install-am install-data-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-pamLTLIBRARIES 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-data \
+ install-data-am install-data-hook install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man \
+ install-pamLTLIBRARIES install-pdf install-pdf-am install-ps \
+ install-ps-am install-strip installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+ uninstall-am uninstall-local uninstall-pamLTLIBRARIES
+
+
+# Needed until libtool-2
+@BUILD_PAM_TRUE@install-data-hook: install-pamLTLIBRARIES
+@BUILD_PAM_TRUE@ rm -f "$(DESTDIR)$(pamdir)/pam_ecryptfs.la"
+@BUILD_PAM_TRUE@ rm -f "$(DESTDIR)$(pamdir)/pam_ecryptfs.a"
+@BUILD_PAM_TRUE@uninstall-local:
+@BUILD_PAM_TRUE@ rm -f "$(DESTDIR)$(pamdir)/pam_ecryptfs.so"
+
+# 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/pam_ecryptfs/pam_ecryptfs.c b/src/pam_ecryptfs/pam_ecryptfs.c
new file mode 100644
index 0000000..49b42b5
--- /dev/null
+++ b/src/pam_ecryptfs/pam_ecryptfs.c
@@ -0,0 +1,519 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*-
+ *
+ * pam_ecryptfs.c: PAM module that sends the user's authentication
+ * tokens into the kernel keyring.
+ *
+ * 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 <stdint.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <syslog.h>
+#include <limits.h>
+#include <pwd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fsuid.h>
+#include <grp.h>
+#include <fcntl.h>
+#include <security/pam_modules.h>
+#include <security/pam_ext.h>
+#include "../include/ecryptfs.h"
+
+#define PRIVATE_DIR "Private"
+
+/* returns: 0 if file does not exist, 1 if it exists, <0 for error */
+static int file_exists_dotecryptfs(const char *homedir, char *filename)
+{
+ char *file_path;
+ int rc = 0;
+ struct stat s;
+ if (asprintf(&file_path, "%s/.ecryptfs/%s", homedir, filename) == -1)
+ return -ENOMEM;
+ if (stat(file_path, &s) != 0) {
+ if (errno != ENOENT)
+ rc = -errno;
+ goto out;
+ }
+ rc = 1;
+out:
+ free(file_path);
+ return rc;
+}
+
+static int wrap_passphrase_if_necessary(const char *username, uid_t uid, char *wrapped_pw_filename, char *passphrase, char *salt)
+{
+ char *unwrapped_pw_filename = NULL;
+ struct stat s;
+ int rc = 0;
+
+ rc = asprintf(&unwrapped_pw_filename, "/dev/shm/.ecryptfs-%s", username);
+ if (rc == -1) {
+ syslog(LOG_ERR, "pam_ecryptfs: Unable to allocate memory\n");
+ return -ENOMEM;
+ }
+ /* If /dev/shm/.ecryptfs-$USER exists and owned by the user
+ and ~/.ecryptfs/wrapped-passphrase does not exist
+ and a passphrase is set:
+ wrap the unwrapped passphrase file */
+ if (stat(unwrapped_pw_filename, &s) == 0 && (s.st_uid == uid) &&
+ stat(wrapped_pw_filename, &s) != 0 &&
+ passphrase != NULL && *passphrase != '\0' &&
+ username != NULL && *username != '\0') {
+ setuid(uid);
+ rc = ecryptfs_wrap_passphrase_file(wrapped_pw_filename, passphrase, salt, unwrapped_pw_filename);
+ if (rc != 0) {
+ syslog(LOG_ERR, "pam_ecryptfs: Error wrapping cleartext password; " "rc = [%d]\n", rc);
+ }
+ return rc;
+ }
+ return 0;
+}
+
+PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ uid_t uid = 0, oeuid = 0;
+ long ngroups_max = sysconf(_SC_NGROUPS_MAX);
+ gid_t gid = 0, oegid = 0, groups[ngroups_max+1];
+ int ngids = 0;
+ char *homedir = NULL;
+ const char *username;
+ char *passphrase = NULL;
+ char salt[ECRYPTFS_SALT_SIZE];
+ char salt_hex[ECRYPTFS_SALT_SIZE_HEX];
+ char *auth_tok_sig = NULL;
+ char *private_mnt = NULL;
+ pid_t child_pid, tmp_pid;
+ long rc;
+
+ rc = pam_get_user(pamh, &username, NULL);
+ if (rc == PAM_SUCCESS) {
+ struct passwd *pwd;
+
+ pwd = getpwnam(username);
+ if (pwd) {
+ uid = pwd->pw_uid;
+ gid = pwd->pw_gid;
+ homedir = pwd->pw_dir;
+ }
+ } else {
+ syslog(LOG_ERR, "pam_ecryptfs: Error getting passwd info for user [%s]; rc = [%ld]\n", username, rc);
+ goto out;
+ }
+
+ oeuid = geteuid();
+ oegid = getegid();
+ if ((ngids = getgroups(sizeof(groups)/sizeof(gid_t), groups)) < 0) {
+ syslog(LOG_ERR, "pam_ecryptfs: geteuid error");
+ goto outnouid;
+ }
+
+ if (setegid(gid) < 0 || setgroups(1, &gid) < 0 || seteuid(uid) < 0) {
+ syslog(LOG_ERR, "pam_ecryptfs: seteuid error");
+ goto out;
+ }
+
+ if (!file_exists_dotecryptfs(homedir, "auto-mount"))
+ goto out;
+ private_mnt = ecryptfs_fetch_private_mnt(homedir);
+ if (ecryptfs_private_is_mounted(NULL, private_mnt, NULL, 1)) {
+ syslog(LOG_DEBUG, "pam_ecryptfs: %s: %s is already mounted\n", __FUNCTION__, homedir);
+ /* If private/home is already mounted, then we can skip
+ costly loading of keys */
+ goto out;
+ }
+ if(file_exists_dotecryptfs(homedir, "wrapping-independent") == 1)
+ rc = pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, &passphrase, "Encryption passphrase: ");
+ else
+ rc = pam_get_item(pamh, PAM_AUTHTOK, (const void **)&passphrase);
+ if (rc != PAM_SUCCESS) {
+ syslog(LOG_ERR, "pam_ecryptfs: Error retrieving passphrase; rc = [%ld]\n",
+ rc);
+ goto out;
+ }
+ auth_tok_sig = malloc(ECRYPTFS_SIG_SIZE_HEX + 1);
+ if (!auth_tok_sig) {
+ rc = -ENOMEM;
+ syslog(LOG_ERR, "pam_ecryptfs: Out of memory\n");
+ 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 ((child_pid = fork()) == 0) {
+ /* temp regain uid 0 to drop privs */
+ seteuid(oeuid);
+ /* setgroups() already called */
+ if (setgid(gid) < 0 || setuid(uid) < 0)
+ goto out_child;
+
+ if (passphrase == NULL) {
+ syslog(LOG_ERR, "pam_ecryptfs: NULL passphrase; aborting\n");
+ rc = -EINVAL;
+ goto out_child;
+ }
+ if ((rc = ecryptfs_validate_keyring())) {
+ syslog(LOG_WARNING, "pam_ecryptfs: Cannot validate keyring integrity\n");
+ }
+ rc = 0;
+ if ((argc == 1)
+ && (memcmp(argv[0], "unwrap\0", 7) == 0)) {
+ char *wrapped_pw_filename;
+
+ rc = asprintf(
+ &wrapped_pw_filename, "%s/.ecryptfs/%s",
+ homedir,
+ ECRYPTFS_DEFAULT_WRAPPED_PASSPHRASE_FILENAME);
+ if (rc == -1) {
+ syslog(LOG_ERR, "pam_ecryptfs: Unable to allocate memory\n");
+ rc = -ENOMEM;
+ goto out_child;
+ }
+ if (wrap_passphrase_if_necessary(username, uid, wrapped_pw_filename, passphrase, salt) == 0) {
+ syslog(LOG_DEBUG, "pam_ecryptfs: Passphrase file wrapped");
+ } else {
+ goto out_child;
+ }
+ rc = ecryptfs_insert_wrapped_passphrase_into_keyring(
+ auth_tok_sig, wrapped_pw_filename, passphrase,
+ salt);
+ free(wrapped_pw_filename);
+ } else {
+ rc = ecryptfs_add_passphrase_key_to_keyring(
+ auth_tok_sig, passphrase, salt);
+ }
+ if (rc == 1) {
+ goto out_child;
+ }
+ if (rc) {
+ syslog(LOG_ERR, "pam_ecryptfs: Error adding passphrase key token to user session keyring; rc = [%ld]\n", rc);
+ goto out_child;
+ }
+ if (fork() == 0) {
+ if ((rc = ecryptfs_set_zombie_session_placeholder())) {
+ syslog(LOG_ERR, "pam_ecryptfs: Error attempting to create and register zombie process; rc = [%ld]\n", rc);
+ }
+ }
+out_child:
+ free(auth_tok_sig);
+ exit(0);
+ }
+ tmp_pid = waitpid(child_pid, NULL, 0);
+ if (tmp_pid == -1)
+ syslog(LOG_WARNING, "pam_ecryptfs: waitpid() returned with error condition\n");
+out:
+
+ seteuid(oeuid);
+ setegid(oegid);
+ setgroups(ngids, groups);
+
+outnouid:
+ if (private_mnt != NULL)
+ free(private_mnt);
+ if (auth_tok_sig != NULL)
+ free(auth_tok_sig);
+ return PAM_SUCCESS;
+}
+
+PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ return PAM_SUCCESS;
+}
+
+static struct passwd *fetch_pwd(pam_handle_t *pamh)
+{
+ long rc;
+ const char *username = NULL;
+ struct passwd *pwd = NULL;
+
+ rc = pam_get_user(pamh, &username, NULL);
+ if (rc != PAM_SUCCESS || username == NULL) {
+ syslog(LOG_ERR, "pam_ecryptfs: Error getting passwd info for user [%s]; rc = [%ld]\n", username, rc);
+ return NULL;
+ }
+ pwd = getpwnam(username);
+ if (pwd == NULL) {
+ syslog(LOG_ERR, "pam_ecryptfs: Error getting passwd info for user [%s]; rc = [%ld]\n", username, rc);
+ return NULL;
+ }
+ return pwd;
+}
+
+static int private_dir(pam_handle_t *pamh, int mount)
+{
+ int rc, fd;
+ struct passwd *pwd = NULL;
+ char *sigfile = NULL;
+ char *autofile = NULL;
+ char *recorded = NULL;
+ char *a;
+ char *automount = "auto-mount";
+ char *autoumount = "auto-umount";
+ struct stat s;
+ pid_t pid;
+
+ if ((pwd = fetch_pwd(pamh)) == NULL) {
+ /* fetch_pwd() logged a message */
+ return 1;
+ }
+ if (mount == 1) {
+ a = automount;
+ } else {
+ a = autoumount;
+ }
+ if (
+ (asprintf(&autofile, "%s/.ecryptfs/%s", pwd->pw_dir, a) < 0)
+ || autofile == NULL) {
+ syslog(LOG_ERR, "pam_ecryptfs: Error allocating memory for autofile name");
+ return 1;
+ }
+ if (
+ (asprintf(&sigfile, "%s/.ecryptfs/%s.sig", pwd->pw_dir,
+ PRIVATE_DIR) < 0) || sigfile == NULL) {
+ syslog(LOG_ERR, "pam_ecryptfs: Error allocating memory for sigfile name");
+ return 1;
+ }
+ if (stat(sigfile, &s) != 0) {
+ /* No sigfile, no need to mount private dir */
+ goto out;
+ }
+ if (!S_ISREG(s.st_mode)) {
+ /* No sigfile, no need to mount private dir */
+ goto out;
+ }
+ if ((pid = fork()) < 0) {
+ syslog(LOG_ERR, "pam_ecryptfs: Error setting up private mount");
+ return 1;
+ }
+ if (pid == 0) {
+ if (mount == 1) {
+ if ((asprintf(&recorded,
+ "%s/.ecryptfs/.wrapped-passphrase.recorded",
+ pwd->pw_dir) < 0) || recorded == NULL) {
+ syslog(LOG_ERR, "pam_ecryptfs: Error allocating memory for recorded name");
+ exit(1);
+ }
+ if (stat(recorded, &s) != 0 && stat("/usr/share/ecryptfs-utils/ecryptfs-record-passphrase", &s) == 0) {
+ /* User has not recorded their passphrase */
+ unlink("/var/lib/update-notifier/user.d/ecryptfs-record-passphrase");
+ symlink("/usr/share/ecryptfs-utils/ecryptfs-record-passphrase", "/var/lib/update-notifier/user.d/ecryptfs-record-passphrase");
+ fd = open("/var/lib/update-notifier/dpkg-run-stamp", O_WRONLY|O_CREAT|O_NONBLOCK, 0666);
+ if (fd != -1)
+ close(fd);
+ }
+ if (stat(autofile, &s) != 0) {
+ /* User does not want to auto-mount */
+ syslog(LOG_DEBUG, "pam_ecryptfs: Skipping automatic eCryptfs mount");
+ exit(0);
+ }
+ clearenv();
+ if (setgroups(1, &pwd->pw_gid) < 0 || setgid(pwd->pw_gid) < 0)
+ return -1;
+ /* run mount.ecryptfs_private as the user */
+ if (setresuid(pwd->pw_uid, pwd->pw_uid, pwd->pw_uid) < 0)
+ return -1;
+ execl("/sbin/mount.ecryptfs_private",
+ "mount.ecryptfs_private", NULL);
+ } else {
+ if (stat(autofile, &s) != 0) {
+ /* User does not want to auto-unmount */
+ syslog(LOG_DEBUG, "pam_ecryptfs: Skipping automatic eCryptfs unmount");
+ exit(0);
+ }
+ clearenv();
+ if (setgroups(1, &pwd->pw_gid) < 0 || setgid(pwd->pw_gid) < 0)
+ return -1;
+ /* run umount.ecryptfs_private as the user */
+ if (setresuid(pwd->pw_uid, pwd->pw_uid, pwd->pw_uid) < 0)
+ return -1;
+ execl("/sbin/umount.ecryptfs_private",
+ "umount.ecryptfs_private", NULL);
+ exit(1);
+ }
+ exit(1);
+ } else {
+ waitpid(pid, &rc, 0);
+ }
+out:
+ return 0;
+}
+
+static int mount_private_dir(pam_handle_t *pamh)
+{
+ return private_dir(pamh, 1);
+}
+
+static int umount_private_dir(pam_handle_t *pamh)
+{
+ return private_dir(pamh, 0);
+}
+
+PAM_EXTERN int
+pam_sm_open_session(pam_handle_t *pamh, int flags,
+ int argc, const char *argv[])
+{
+ mount_private_dir(pamh);
+ return PAM_SUCCESS;
+}
+
+PAM_EXTERN int
+pam_sm_close_session(pam_handle_t *pamh, int flags,
+ int argc, const char *argv[])
+{
+ umount_private_dir(pamh);
+ return PAM_SUCCESS;
+}
+
+PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
+ int argc, const char **argv)
+{
+ uid_t uid = 0, oeuid = 0;
+ long ngroups_max = sysconf(_SC_NGROUPS_MAX);
+ gid_t gid = 0, oegid = 0, groups[ngroups_max+1];
+ int ngids = 0;
+ char *homedir = NULL;
+ const char *username;
+ char *old_passphrase = NULL;
+ char *new_passphrase = NULL;
+ char *wrapped_pw_filename;
+ char salt[ECRYPTFS_SALT_SIZE];
+ char salt_hex[ECRYPTFS_SALT_SIZE_HEX];
+ pid_t child_pid, tmp_pid;
+ int rc = PAM_SUCCESS;
+
+ rc = pam_get_user(pamh, &username, NULL);
+ if (rc == PAM_SUCCESS) {
+ struct passwd *pwd;
+
+ pwd = getpwnam(username);
+ if (pwd) {
+ uid = pwd->pw_uid;
+ gid = pwd->pw_gid;
+ homedir = pwd->pw_dir;
+ }
+ } else {
+ syslog(LOG_ERR, "pam_ecryptfs: Error getting passwd info for user [%s]; rc = [%d]\n", username, rc);
+ goto out;
+ }
+
+ oeuid = geteuid();
+ oegid = getegid();
+ if ((ngids = getgroups(sizeof(groups)/sizeof(gid_t), groups)) < 0) {
+ syslog(LOG_ERR, "pam_ecryptfs: geteuid error");
+ goto outnouid;
+ }
+
+ if (setegid(gid) < 0 || setgroups(1, &gid) < 0 || seteuid(uid) < 0) {
+ syslog(LOG_ERR, "pam_ecryptfs: seteuid error");
+ goto out;
+ }
+
+ if ((rc = pam_get_item(pamh, PAM_OLDAUTHTOK,
+ (const void **)&old_passphrase))
+ != PAM_SUCCESS) {
+ syslog(LOG_ERR, "pam_ecryptfs: Error retrieving old passphrase; rc = [%d]\n", rc);
+ goto out;
+ }
+ /* On the first pass, do nothing except check that we have a password */
+ if ((flags & PAM_PRELIM_CHECK)) {
+ if (!old_passphrase)
+ {
+ syslog(LOG_WARNING, "pam_ecryptfs: PAM passphrase change module retrieved a NULL passphrase; nothing to do\n");
+ rc = PAM_AUTHTOK_RECOVER_ERR;
+ }
+ goto out;
+ }
+ if ((rc = pam_get_item(pamh, PAM_AUTHTOK,
+ (const void **)&new_passphrase))
+ != PAM_SUCCESS) {
+ syslog(LOG_ERR, "pam_ecryptfs: Error retrieving new passphrase; rc = [%d]\n", rc);
+ goto out;
+ }
+ if ((rc = asprintf(&wrapped_pw_filename, "%s/.ecryptfs/%s", homedir,
+ ECRYPTFS_DEFAULT_WRAPPED_PASSPHRASE_FILENAME))
+ == -1) {
+ syslog(LOG_ERR, "pam_ecryptfs: Unable to allocate memory\n");
+ rc = -ENOMEM;
+ goto out;
+ }
+ if ((rc = ecryptfs_read_salt_hex_from_rc(salt_hex))) {
+ from_hex(salt, ECRYPTFS_DEFAULT_SALT_HEX, ECRYPTFS_SALT_SIZE);
+ } else {
+ from_hex(salt, salt_hex, ECRYPTFS_SALT_SIZE);
+ }
+ if (wrap_passphrase_if_necessary(username, uid, wrapped_pw_filename, new_passphrase, salt) == 0) {
+ syslog(LOG_DEBUG, "pam_ecryptfs: Passphrase file wrapped");
+ } else {
+ goto out;
+ }
+
+ if (!old_passphrase || !new_passphrase || *new_passphrase == '\0') {
+ syslog(LOG_WARNING, "pam_ecryptfs: PAM passphrase change module retrieved at least one NULL passphrase; nothing to do\n");
+ rc = PAM_AUTHTOK_RECOVER_ERR;
+ goto out;
+ }
+ rc = PAM_SUCCESS;
+ if ((child_pid = fork()) == 0) {
+ char passphrase[ECRYPTFS_MAX_PASSWORD_LENGTH + 1];
+
+ /* temp regain uid 0 to drop privs */
+ seteuid(oeuid);
+ /* setgroups() already called */
+ if (setgid(gid) < 0 || setuid(uid) < 0)
+ goto out_child;
+
+ if ((rc = ecryptfs_unwrap_passphrase(passphrase,
+ wrapped_pw_filename,
+ old_passphrase, salt))) {
+ syslog(LOG_ERR, "pam_ecryptfs: Error attempting to unwrap passphrase; rc = [%d]\n", rc);
+ goto out_child;
+ }
+ if ((rc = ecryptfs_wrap_passphrase(wrapped_pw_filename,
+ new_passphrase, salt,
+ passphrase))) {
+ syslog(LOG_ERR, "pam_ecryptfs: Error attempting to wrap passphrase; rc = [%d]", rc);
+ goto out_child;
+ }
+out_child:
+ exit(0);
+ }
+ if ((tmp_pid = waitpid(child_pid, NULL, 0)) == -1)
+ syslog(LOG_WARNING, "pam_ecryptfs: waitpid() returned with error condition\n");
+ free(wrapped_pw_filename);
+out:
+
+ seteuid(oeuid);
+ setegid(oegid);
+ setgroups(ngids, groups);
+
+outnouid:
+ return rc;
+}
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=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ 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, &current_settings);
+ if (rc)
+ return rc;
+ *saved_settings = current_settings;
+ current_settings.c_lflag &= ~ECHO;
+ rc = tcsetattr(0, TCSANOW, &current_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;
+}
+