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