From eee068778cb28ecf3c14e1bf843a95547d72c42d Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 18:14:06 +0200 Subject: Adding upstream version 2.2.40. Signed-off-by: Daniel Baumann --- g13/ChangeLog-2011 | 14 + g13/Makefile.am | 83 ++++ g13/Makefile.in | 1071 ++++++++++++++++++++++++++++++++++++++++++++++++++++ g13/all-tests.scm | 35 ++ g13/backend.c | 296 +++++++++++++++ g13/backend.h | 49 +++ g13/be-dmcrypt.c | 116 ++++++ g13/be-dmcrypt.h | 36 ++ g13/be-encfs.c | 471 +++++++++++++++++++++++ g13/be-encfs.h | 41 ++ g13/be-truecrypt.c | 37 ++ g13/be-truecrypt.h | 28 ++ g13/call-syshelp.c | 631 +++++++++++++++++++++++++++++++ g13/call-syshelp.h | 42 +++ g13/create.c | 303 +++++++++++++++ g13/create.h | 29 ++ g13/g13-common.c | 86 +++++ g13/g13-common.h | 96 +++++ g13/g13-syshelp.c | 740 ++++++++++++++++++++++++++++++++++++ g13/g13-syshelp.h | 96 +++++ g13/g13.c | 1050 +++++++++++++++++++++++++++++++++++++++++++++++++++ g13/g13.h | 60 +++ g13/g13tuple.c | 340 +++++++++++++++++ g13/g13tuple.h | 52 +++ g13/keyblob.c | 207 ++++++++++ g13/keyblob.h | 162 ++++++++ g13/mount.c | 265 +++++++++++++ g13/mount.h | 31 ++ g13/mountinfo.c | 198 ++++++++++ g13/mountinfo.h | 40 ++ g13/runner.c | 539 ++++++++++++++++++++++++++ g13/runner.h | 76 ++++ g13/server.c | 783 ++++++++++++++++++++++++++++++++++++++ g13/server.h | 32 ++ g13/sh-blockdev.c | 152 ++++++++ g13/sh-cmd.c | 917 ++++++++++++++++++++++++++++++++++++++++++++ g13/sh-dmcrypt.c | 1043 ++++++++++++++++++++++++++++++++++++++++++++++++++ g13/suspend.c | 145 +++++++ g13/suspend.h | 26 ++ g13/t-g13tuple.c | 223 +++++++++++ 40 files changed, 10641 insertions(+) create mode 100644 g13/ChangeLog-2011 create mode 100644 g13/Makefile.am create mode 100644 g13/Makefile.in create mode 100644 g13/all-tests.scm create mode 100644 g13/backend.c create mode 100644 g13/backend.h create mode 100644 g13/be-dmcrypt.c create mode 100644 g13/be-dmcrypt.h create mode 100644 g13/be-encfs.c create mode 100644 g13/be-encfs.h create mode 100644 g13/be-truecrypt.c create mode 100644 g13/be-truecrypt.h create mode 100644 g13/call-syshelp.c create mode 100644 g13/call-syshelp.h create mode 100644 g13/create.c create mode 100644 g13/create.h create mode 100644 g13/g13-common.c create mode 100644 g13/g13-common.h create mode 100644 g13/g13-syshelp.c create mode 100644 g13/g13-syshelp.h create mode 100644 g13/g13.c create mode 100644 g13/g13.h create mode 100644 g13/g13tuple.c create mode 100644 g13/g13tuple.h create mode 100644 g13/keyblob.c create mode 100644 g13/keyblob.h create mode 100644 g13/mount.c create mode 100644 g13/mount.h create mode 100644 g13/mountinfo.c create mode 100644 g13/mountinfo.h create mode 100644 g13/runner.c create mode 100644 g13/runner.h create mode 100644 g13/server.c create mode 100644 g13/server.h create mode 100644 g13/sh-blockdev.c create mode 100644 g13/sh-cmd.c create mode 100644 g13/sh-dmcrypt.c create mode 100644 g13/suspend.c create mode 100644 g13/suspend.h create mode 100644 g13/t-g13tuple.c (limited to 'g13') diff --git a/g13/ChangeLog-2011 b/g13/ChangeLog-2011 new file mode 100644 index 0000000..5d372c2 --- /dev/null +++ b/g13/ChangeLog-2011 @@ -0,0 +1,14 @@ +2011-12-01 Werner Koch + + NB: ChangeLog files are no longer manually maintained. Starting + on December 1st, 2011 we put change information only in the GIT + commit log, and generate a top-level ChangeLog file from logs at + "make dist". See doc/HACKING for details. + +2009-11-04 Werner Koch + + Under initial development - no need for a ChangeLog. + +Local Variables: +buffer-read-only: t +End: diff --git a/g13/Makefile.am b/g13/Makefile.am new file mode 100644 index 0000000..b8cb342 --- /dev/null +++ b/g13/Makefile.am @@ -0,0 +1,83 @@ +# g13/Makefile.am +# Copyright (C) 2009 Free Software Foundation, Inc. +# +# This file is part of GnuPG. +# +# GnuPG 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 3 of the License, or +# (at your option) any later version. +# +# GnuPG 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 . + +## Process this file with automake to produce Makefile.in + +EXTRA_DIST = ChangeLog-2011 all-tests.scm + +bin_PROGRAMS = g13 +sbin_PROGRAMS = g13-syshelp + +noinst_PROGRAMS = $(module_tests) +if DISABLE_TESTS +TESTS = +else +TESTS = $(module_tests) +endif + +AM_CPPFLAGS = + +include $(top_srcdir)/am/cmacros.am + +AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_CFLAGS) $(NPTH_CFLAGS) + +g13_SOURCES = \ + g13.c g13.h \ + g13-common.c g13-common.h \ + keyblob.c keyblob.h \ + g13tuple.c g13tuple.h \ + server.c server.h \ + create.c create.h \ + mount.c mount.h \ + suspend.c suspend.h \ + mountinfo.c mountinfo.h \ + call-syshelp.c call-syshelp.h \ + runner.c runner.h \ + backend.c backend.h \ + be-encfs.c be-encfs.h \ + be-truecrypt.c be-truecrypt.h \ + be-dmcrypt.c be-dmcrypt.h + +g13_LDADD = $(libcommonpth) \ + $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(NPTH_LIBS) \ + $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV) + + +g13_syshelp_SOURCES = \ + g13-syshelp.c g13-syshelp.h \ + g13-common.c g13-common.h \ + keyblob.c keyblob.h \ + g13tuple.c g13tuple.h \ + sh-cmd.c \ + sh-blockdev.c \ + sh-dmcrypt.c + +g13_syshelp_LDADD = $(libcommon) \ + $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) \ + $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV) + + +module_tests = t-g13tuple +t_common_ldadd = $(libcommon) $(LIBGCRYPT_LIBS) \ + $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) $(LIBICONV) + +t_g13tuple_SOURCES = t-g13tuple.c g13tuple.c +t_g13tuple_LDADD = $(t_common_ldadd) + + +$(PROGRAMS) : $(libcommon) $(libcommonpth) diff --git a/g13/Makefile.in b/g13/Makefile.in new file mode 100644 index 0000000..7a0a3aa --- /dev/null +++ b/g13/Makefile.in @@ -0,0 +1,1071 @@ +# Makefile.in generated by automake 1.16.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 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@ + +# g13/Makefile.am +# Copyright (C) 2009 Free Software Foundation, Inc. +# +# This file is part of GnuPG. +# +# GnuPG 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 3 of the License, or +# (at your option) any later version. +# +# GnuPG 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 . + +# cmacros.am - C macro definitions +# Copyright (C) 2004 Free Software Foundation, Inc. +# +# This file is part of GnuPG. +# +# GnuPG 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 3 of the License, or +# (at your option) any later version. +# +# GnuPG 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 . + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +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@ +bin_PROGRAMS = g13$(EXEEXT) +sbin_PROGRAMS = g13-syshelp$(EXEEXT) +noinst_PROGRAMS = $(am__EXEEXT_1) +@DISABLE_TESTS_FALSE@TESTS = $(am__EXEEXT_1) +@HAVE_DOSISH_SYSTEM_FALSE@am__append_1 = -DGNUPG_BINDIR="\"$(bindir)\"" \ +@HAVE_DOSISH_SYSTEM_FALSE@ -DGNUPG_LIBEXECDIR="\"$(libexecdir)\"" \ +@HAVE_DOSISH_SYSTEM_FALSE@ -DGNUPG_LIBDIR="\"$(libdir)/@PACKAGE@\"" \ +@HAVE_DOSISH_SYSTEM_FALSE@ -DGNUPG_DATADIR="\"$(datadir)/@PACKAGE@\"" \ +@HAVE_DOSISH_SYSTEM_FALSE@ -DGNUPG_SYSCONFDIR="\"$(sysconfdir)/@PACKAGE@\"" \ +@HAVE_DOSISH_SYSTEM_FALSE@ -DGNUPG_LOCALSTATEDIR="\"$(localstatedir)\"" + + +# If a specific protect tool program has been defined, pass its name +# to cc. Note that these macros should not be used directly but via +# the gnupg_module_name function. +@GNUPG_AGENT_PGM_TRUE@am__append_2 = -DGNUPG_DEFAULT_AGENT="\"@GNUPG_AGENT_PGM@\"" +@GNUPG_PINENTRY_PGM_TRUE@am__append_3 = -DGNUPG_DEFAULT_PINENTRY="\"@GNUPG_PINENTRY_PGM@\"" +@GNUPG_SCDAEMON_PGM_TRUE@am__append_4 = -DGNUPG_DEFAULT_SCDAEMON="\"@GNUPG_SCDAEMON_PGM@\"" +@GNUPG_DIRMNGR_PGM_TRUE@am__append_5 = -DGNUPG_DEFAULT_DIRMNGR="\"@GNUPG_DIRMNGR_PGM@\"" +@GNUPG_PROTECT_TOOL_PGM_TRUE@am__append_6 = -DGNUPG_DEFAULT_PROTECT_TOOL="\"@GNUPG_PROTECT_TOOL_PGM@\"" +@GNUPG_DIRMNGR_LDAP_PGM_TRUE@am__append_7 = -DGNUPG_DEFAULT_DIRMNGR_LDAP="\"@GNUPG_DIRMNGR_LDAP_PGM@\"" +subdir = g13 +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/autobuild.m4 \ + $(top_srcdir)/m4/codeset.m4 $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/gpg-error.m4 $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/isc-posix.m4 $(top_srcdir)/m4/ksba.m4 \ + $(top_srcdir)/m4/lcmessage.m4 $(top_srcdir)/m4/ldap.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libassuan.m4 \ + $(top_srcdir)/m4/libgcrypt.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/npth.m4 $(top_srcdir)/m4/ntbtls.m4 \ + $(top_srcdir)/m4/pkg.m4 $(top_srcdir)/m4/po.m4 \ + $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/m4/readline.m4 \ + $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \ + $(top_srcdir)/m4/tar-ustar.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(SHELL) $(top_srcdir)/build-aux/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" +am__EXEEXT_1 = t-g13tuple$(EXEEXT) +PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) $(sbin_PROGRAMS) +am_g13_OBJECTS = g13.$(OBJEXT) g13-common.$(OBJEXT) keyblob.$(OBJEXT) \ + g13tuple.$(OBJEXT) server.$(OBJEXT) create.$(OBJEXT) \ + mount.$(OBJEXT) suspend.$(OBJEXT) mountinfo.$(OBJEXT) \ + call-syshelp.$(OBJEXT) runner.$(OBJEXT) backend.$(OBJEXT) \ + be-encfs.$(OBJEXT) be-truecrypt.$(OBJEXT) be-dmcrypt.$(OBJEXT) +g13_OBJECTS = $(am_g13_OBJECTS) +am__DEPENDENCIES_1 = +g13_DEPENDENCIES = $(libcommonpth) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am_g13_syshelp_OBJECTS = g13-syshelp.$(OBJEXT) g13-common.$(OBJEXT) \ + keyblob.$(OBJEXT) g13tuple.$(OBJEXT) sh-cmd.$(OBJEXT) \ + sh-blockdev.$(OBJEXT) sh-dmcrypt.$(OBJEXT) +g13_syshelp_OBJECTS = $(am_g13_syshelp_OBJECTS) +g13_syshelp_DEPENDENCIES = $(libcommon) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +am_t_g13tuple_OBJECTS = t-g13tuple.$(OBJEXT) g13tuple.$(OBJEXT) +t_g13tuple_OBJECTS = $(am_t_g13tuple_OBJECTS) +am__DEPENDENCIES_2 = $(libcommon) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +t_g13tuple_DEPENDENCIES = $(am__DEPENDENCIES_2) +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)/build-aux/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/backend.Po ./$(DEPDIR)/be-dmcrypt.Po \ + ./$(DEPDIR)/be-encfs.Po ./$(DEPDIR)/be-truecrypt.Po \ + ./$(DEPDIR)/call-syshelp.Po ./$(DEPDIR)/create.Po \ + ./$(DEPDIR)/g13-common.Po ./$(DEPDIR)/g13-syshelp.Po \ + ./$(DEPDIR)/g13.Po ./$(DEPDIR)/g13tuple.Po \ + ./$(DEPDIR)/keyblob.Po ./$(DEPDIR)/mount.Po \ + ./$(DEPDIR)/mountinfo.Po ./$(DEPDIR)/runner.Po \ + ./$(DEPDIR)/server.Po ./$(DEPDIR)/sh-blockdev.Po \ + ./$(DEPDIR)/sh-cmd.Po ./$(DEPDIR)/sh-dmcrypt.Po \ + ./$(DEPDIR)/suspend.Po ./$(DEPDIR)/t-g13tuple.Po +am__mv = mv -f +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 = $(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 = $(g13_SOURCES) $(g13_syshelp_SOURCES) $(t_g13tuple_SOURCES) +DIST_SOURCES = $(g13_SOURCES) $(g13_syshelp_SOURCES) \ + $(t_g13tuple_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/am/cmacros.am \ + $(top_srcdir)/build-aux/depcomp \ + $(top_srcdir)/build-aux/mkinstalldirs +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +AWK_HEX_NUMBER_OPTION = @AWK_HEX_NUMBER_OPTION@ +BUILD_FILEVERSION = @BUILD_FILEVERSION@ +BUILD_HOSTNAME = @BUILD_HOSTNAME@ +BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@ +BUILD_REVISION = @BUILD_REVISION@ +BUILD_TIMESTAMP = @BUILD_TIMESTAMP@ +BUILD_VERSION = @BUILD_VERSION@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DL_LIBS = @DL_LIBS@ +DNSLIBS = @DNSLIBS@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENCFS = @ENCFS@ +EXEEXT = @EXEEXT@ +FUSERMOUNT = @FUSERMOUNT@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GNUPG_AGENT_PGM = @GNUPG_AGENT_PGM@ +GNUPG_DIRMNGR_LDAP_PGM = @GNUPG_DIRMNGR_LDAP_PGM@ +GNUPG_DIRMNGR_PGM = @GNUPG_DIRMNGR_PGM@ +GNUPG_PINENTRY_PGM = @GNUPG_PINENTRY_PGM@ +GNUPG_PROTECT_TOOL_PGM = @GNUPG_PROTECT_TOOL_PGM@ +GNUPG_SCDAEMON_PGM = @GNUPG_SCDAEMON_PGM@ +GPGKEYS_LDAP = @GPGKEYS_LDAP@ +GPGRT_CONFIG = @GPGRT_CONFIG@ +GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@ +GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@ +GPG_ERROR_LIBS = @GPG_ERROR_LIBS@ +GPG_ERROR_MT_CFLAGS = @GPG_ERROR_MT_CFLAGS@ +GPG_ERROR_MT_LIBS = @GPG_ERROR_MT_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +KSBA_CFLAGS = @KSBA_CFLAGS@ +KSBA_CONFIG = @KSBA_CONFIG@ +KSBA_LIBS = @KSBA_LIBS@ +LBER_LIBS = @LBER_LIBS@ +LDAPLIBS = @LDAPLIBS@ +LDAP_CPPFLAGS = @LDAP_CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBASSUAN_CFLAGS = @LIBASSUAN_CFLAGS@ +LIBASSUAN_CONFIG = @LIBASSUAN_CONFIG@ +LIBASSUAN_LIBS = @LIBASSUAN_LIBS@ +LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@ +LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@ +LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@ +LIBGNUTLS_CFLAGS = @LIBGNUTLS_CFLAGS@ +LIBGNUTLS_LIBS = @LIBGNUTLS_LIBS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBOBJS = @LIBOBJS@ +LIBREADLINE = @LIBREADLINE@ +LIBS = @LIBS@ +LIBUSB_CPPFLAGS = @LIBUSB_CPPFLAGS@ +LIBUSB_LIBS = @LIBUSB_LIBS@ +LIBUTIL_LIBS = @LIBUTIL_LIBS@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NETLIBS = @NETLIBS@ +NPTH_CFLAGS = @NPTH_CFLAGS@ +NPTH_CONFIG = @NPTH_CONFIG@ +NPTH_LIBS = @NPTH_LIBS@ +NTBTLS_CFLAGS = @NTBTLS_CFLAGS@ +NTBTLS_CONFIG = @NTBTLS_CONFIG@ +NTBTLS_LIBS = @NTBTLS_LIBS@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_GT = @PACKAGE_GT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSUB = @POSUB@ +RANLIB = @RANLIB@ +SENDMAIL = @SENDMAIL@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SHRED = @SHRED@ +SQLITE3_CFLAGS = @SQLITE3_CFLAGS@ +SQLITE3_LIBS = @SQLITE3_LIBS@ +STRIP = @STRIP@ +SYSROOT = @SYSROOT@ +SYS_SOCKET_H = @SYS_SOCKET_H@ +TAR = @TAR@ +USE_C99_CFLAGS = @USE_C99_CFLAGS@ +USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +W32SOCKLIBS = @W32SOCKLIBS@ +WINDRES = @WINDRES@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +YAT2M = @YAT2M@ +ZLIBS = @ZLIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +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@ +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@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = $(datadir)/locale +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = ChangeLog-2011 all-tests.scm + +# NB: AM_CFLAGS may also be used by tools running on the build +# platform to create source files. +AM_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" $(am__append_1) \ + $(am__append_2) $(am__append_3) $(am__append_4) \ + $(am__append_5) $(am__append_6) $(am__append_7) +@HAVE_W32CE_SYSTEM_FALSE@extra_sys_libs = + +# Under Windows we use LockFileEx. WindowsCE provides this only on +# the WindowsMobile 6 platform and thus we need to use the coredll6 +# import library. We also want to use a stacksize of 256k instead of +# the 2MB which is the default with cegcc. 256k is the largest stack +# we use with pth. +@HAVE_W32CE_SYSTEM_TRUE@extra_sys_libs = -lcoredll6 +@HAVE_W32CE_SYSTEM_FALSE@extra_bin_ldflags = +@HAVE_W32CE_SYSTEM_TRUE@extra_bin_ldflags = -Wl,--stack=0x40000 +resource_objs = + +# Convenience macros +libcommon = ../common/libcommon.a +libcommonpth = ../common/libcommonpth.a +libcommontls = ../common/libcommontls.a +libcommontlsnpth = ../common/libcommontlsnpth.a +AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_CFLAGS) $(NPTH_CFLAGS) +g13_SOURCES = \ + g13.c g13.h \ + g13-common.c g13-common.h \ + keyblob.c keyblob.h \ + g13tuple.c g13tuple.h \ + server.c server.h \ + create.c create.h \ + mount.c mount.h \ + suspend.c suspend.h \ + mountinfo.c mountinfo.h \ + call-syshelp.c call-syshelp.h \ + runner.c runner.h \ + backend.c backend.h \ + be-encfs.c be-encfs.h \ + be-truecrypt.c be-truecrypt.h \ + be-dmcrypt.c be-dmcrypt.h + +g13_LDADD = $(libcommonpth) \ + $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(NPTH_LIBS) \ + $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV) + +g13_syshelp_SOURCES = \ + g13-syshelp.c g13-syshelp.h \ + g13-common.c g13-common.h \ + keyblob.c keyblob.h \ + g13tuple.c g13tuple.h \ + sh-cmd.c \ + sh-blockdev.c \ + sh-dmcrypt.c + +g13_syshelp_LDADD = $(libcommon) \ + $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) \ + $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV) + +module_tests = t-g13tuple +t_common_ldadd = $(libcommon) $(LIBGCRYPT_LIBS) \ + $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) $(LIBICONV) + +t_g13tuple_SOURCES = t-g13tuple.c g13tuple.c +t_g13tuple_LDADD = $(t_common_ldadd) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .o .obj .rc +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/am/cmacros.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) --gnu g13/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu g13/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__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(top_srcdir)/am/cmacros.am $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(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 \ + ; 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) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(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: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) +install-sbinPROGRAMS: $(sbin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + ; 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) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-sbinPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || 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)$(sbindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(sbindir)" && rm -f $$files + +clean-sbinPROGRAMS: + -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) + +g13$(EXEEXT): $(g13_OBJECTS) $(g13_DEPENDENCIES) $(EXTRA_g13_DEPENDENCIES) + @rm -f g13$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(g13_OBJECTS) $(g13_LDADD) $(LIBS) + +g13-syshelp$(EXEEXT): $(g13_syshelp_OBJECTS) $(g13_syshelp_DEPENDENCIES) $(EXTRA_g13_syshelp_DEPENDENCIES) + @rm -f g13-syshelp$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(g13_syshelp_OBJECTS) $(g13_syshelp_LDADD) $(LIBS) + +t-g13tuple$(EXEEXT): $(t_g13tuple_OBJECTS) $(t_g13tuple_DEPENDENCIES) $(EXTRA_t_g13tuple_DEPENDENCIES) + @rm -f t-g13tuple$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(t_g13tuple_OBJECTS) $(t_g13tuple_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/backend.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/be-dmcrypt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/be-encfs.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/be-truecrypt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/call-syshelp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/create.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/g13-common.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/g13-syshelp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/g13.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/g13tuple.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keyblob.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mount.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mountinfo.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/runner.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh-blockdev.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh-cmd.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sh-dmcrypt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/suspend.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-g13tuple.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.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 -o $@ $< + +.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 -o $@ `$(CYGPATH_W) '$<'` + +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 + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(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) +installdirs: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)"; 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." +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-noinstPROGRAMS \ + clean-sbinPROGRAMS mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/backend.Po + -rm -f ./$(DEPDIR)/be-dmcrypt.Po + -rm -f ./$(DEPDIR)/be-encfs.Po + -rm -f ./$(DEPDIR)/be-truecrypt.Po + -rm -f ./$(DEPDIR)/call-syshelp.Po + -rm -f ./$(DEPDIR)/create.Po + -rm -f ./$(DEPDIR)/g13-common.Po + -rm -f ./$(DEPDIR)/g13-syshelp.Po + -rm -f ./$(DEPDIR)/g13.Po + -rm -f ./$(DEPDIR)/g13tuple.Po + -rm -f ./$(DEPDIR)/keyblob.Po + -rm -f ./$(DEPDIR)/mount.Po + -rm -f ./$(DEPDIR)/mountinfo.Po + -rm -f ./$(DEPDIR)/runner.Po + -rm -f ./$(DEPDIR)/server.Po + -rm -f ./$(DEPDIR)/sh-blockdev.Po + -rm -f ./$(DEPDIR)/sh-cmd.Po + -rm -f ./$(DEPDIR)/sh-dmcrypt.Po + -rm -f ./$(DEPDIR)/suspend.Po + -rm -f ./$(DEPDIR)/t-g13tuple.Po + -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-sbinPROGRAMS + +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 ./$(DEPDIR)/backend.Po + -rm -f ./$(DEPDIR)/be-dmcrypt.Po + -rm -f ./$(DEPDIR)/be-encfs.Po + -rm -f ./$(DEPDIR)/be-truecrypt.Po + -rm -f ./$(DEPDIR)/call-syshelp.Po + -rm -f ./$(DEPDIR)/create.Po + -rm -f ./$(DEPDIR)/g13-common.Po + -rm -f ./$(DEPDIR)/g13-syshelp.Po + -rm -f ./$(DEPDIR)/g13.Po + -rm -f ./$(DEPDIR)/g13tuple.Po + -rm -f ./$(DEPDIR)/keyblob.Po + -rm -f ./$(DEPDIR)/mount.Po + -rm -f ./$(DEPDIR)/mountinfo.Po + -rm -f ./$(DEPDIR)/runner.Po + -rm -f ./$(DEPDIR)/server.Po + -rm -f ./$(DEPDIR)/sh-blockdev.Po + -rm -f ./$(DEPDIR)/sh-cmd.Po + -rm -f ./$(DEPDIR)/sh-dmcrypt.Po + -rm -f ./$(DEPDIR)/suspend.Po + -rm -f ./$(DEPDIR)/t-g13tuple.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-sbinPROGRAMS + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \ + check-am clean clean-binPROGRAMS clean-generic \ + clean-noinstPROGRAMS clean-sbinPROGRAMS cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + 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-sbinPROGRAMS install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-binPROGRAMS uninstall-sbinPROGRAMS + +.PRECIOUS: Makefile + + +@HAVE_W32_SYSTEM_TRUE@.rc.o: +@HAVE_W32_SYSTEM_TRUE@ $(WINDRES) $(DEFAULT_INCLUDES) $(INCLUDES) "$<" "$@" + +$(PROGRAMS) : $(libcommon) $(libcommonpth) + +# 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/g13/all-tests.scm b/g13/all-tests.scm new file mode 100644 index 0000000..69b1f24 --- /dev/null +++ b/g13/all-tests.scm @@ -0,0 +1,35 @@ +;; Copyright (C) 2017 g10 Code GmbH +;; +;; This file is part of GnuPG. +;; +;; GnuPG 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 3 of the License, or +;; (at your option) any later version. +;; +;; GnuPG 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 . + +(export all-tests + ;; Parse the Makefile.am to find all tests. + + (load (with-path "makefile.scm")) + + (define (expander filename port key) + (parse-makefile port key)) + + (define (parse filename key) + (parse-makefile-expand filename expander key)) + + (map (lambda (name) + (test::binary #f + (path-join "g13" name) + (path-join (getenv "objdir") "g13" name))) + (parse-makefile-expand (in-srcdir "g13" "Makefile.am") + (lambda (filename port key) (parse-makefile port key)) + "module_tests"))) diff --git a/g13/backend.c b/g13/backend.c new file mode 100644 index 0000000..a0a2675 --- /dev/null +++ b/g13/backend.c @@ -0,0 +1,296 @@ +/* backend.c - Dispatcher to the various backends. + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "g13.h" +#include "../common/i18n.h" +#include "../common/sysutils.h" +#include "keyblob.h" +#include "backend.h" +#include "be-encfs.h" +#include "be-truecrypt.h" +#include "be-dmcrypt.h" +#include "call-syshelp.h" + +#define no_such_backend(a) _no_such_backend ((a), __func__) +static gpg_error_t +_no_such_backend (int conttype, const char *func) +{ + log_error ("invalid backend %d given in %s - this is most likely a bug\n", + conttype, func); + return gpg_error (GPG_ERR_INTERNAL); +} + + +/* Parse NAME and return the corresponding content type. If the name + is not known, a error message is printed and zero returned. If + NAME is NULL the supported backend types are listed and 0 is + returned. */ +int +be_parse_conttype_name (const char *name) +{ + static struct { const char *name; int conttype; } names[] = { + { "encfs", CONTTYPE_ENCFS }, + { "dm-crypt", CONTTYPE_DM_CRYPT } + }; + int i; + + if (!name) + { + log_info ("Known backend types:\n"); + for (i=0; i < DIM (names); i++) + log_info (" %s\n", names[i].name); + return 0; + } + + for (i=0; i < DIM (names); i++) + { + if (!strcmp (names[i].name, name)) + return names[i].conttype; + } + + log_error ("invalid backend type '%s' given\n", name); + return 0; +} + + +/* Return true if CONTTYPE is supported by us. */ +int +be_is_supported_conttype (int conttype) +{ + switch (conttype) + { + case CONTTYPE_ENCFS: + case CONTTYPE_DM_CRYPT: + return 1; + + default: + return 0; + } +} + + +/* Create a lock file for the container FNAME and store the lock at + * R_LOCK and return 0. On error return an error code and store NULL + * at R_LOCK. */ +gpg_error_t +be_take_lock_for_create (ctrl_t ctrl, const char *fname, dotlock_t *r_lock) +{ + gpg_error_t err; + dotlock_t lock = NULL; + struct stat sb; + + *r_lock = NULL; + + /* A DM-crypt container requires special treatment by using the + syshelper functions. */ + if (ctrl->conttype == CONTTYPE_DM_CRYPT) + { + /* */ + err = call_syshelp_set_device (ctrl, fname); + goto leave; + } + + + /* A quick check to see that no container with that name already + exists. */ + if (!gnupg_access (fname, F_OK)) + { + err = gpg_error (GPG_ERR_EEXIST); + goto leave; + } + + /* Take a lock and proceed with the creation. If there is a lock we + immediately return an error because for creation it does not make + sense to wait. */ + lock = dotlock_create (fname, 0); + if (!lock) + { + err = gpg_error_from_syserror (); + goto leave; + } + if (dotlock_take (lock, 0)) + { + err = gpg_error_from_syserror (); + goto leave; + } + + /* Check again that the file does not exist. */ + err = gnupg_stat (fname, &sb)? 0 : gpg_error (GPG_ERR_EEXIST); + + leave: + if (!err) + { + *r_lock = lock; + lock = NULL; + } + dotlock_destroy (lock); + return err; +} + + +/* If the backend requires a separate file or directory for the + container, return its name by computing it from FNAME which gives + the g13 filename. The new file name is allocated and stored at + R_NAME, if this is expected to be a directory true is stored at + R_ISDIR. If no detached name is expected or an error occurs NULL + is stored at R_NAME. The function returns 0 on success or an error + code. */ +gpg_error_t +be_get_detached_name (int conttype, const char *fname, + char **r_name, int *r_isdir) +{ + *r_name = NULL; + *r_isdir = 0; + switch (conttype) + { + case CONTTYPE_ENCFS: + return be_encfs_get_detached_name (fname, r_name, r_isdir); + + case CONTTYPE_DM_CRYPT: + return 0; + + default: + return no_such_backend (conttype); + } +} + + +gpg_error_t +be_create_new_keys (int conttype, membuf_t *mb) +{ + switch (conttype) + { + case CONTTYPE_ENCFS: + return be_encfs_create_new_keys (mb); + + case CONTTYPE_TRUECRYPT: + return be_truecrypt_create_new_keys (mb); + + case CONTTYPE_DM_CRYPT: + return 0; + + default: + return no_such_backend (conttype); + } +} + + +/* Dispatcher to the backend's create function. */ +gpg_error_t +be_create_container (ctrl_t ctrl, int conttype, + const char *fname, int fd, tupledesc_t tuples, + unsigned int *r_id) +{ + (void)fd; /* Not yet used. */ + + switch (conttype) + { + case CONTTYPE_ENCFS: + return be_encfs_create_container (ctrl, fname, tuples, r_id); + + case CONTTYPE_DM_CRYPT: + return be_dmcrypt_create_container (ctrl); + + default: + return no_such_backend (conttype); + } +} + + +/* Dispatcher to the backend's mount function. */ +gpg_error_t +be_mount_container (ctrl_t ctrl, int conttype, + const char *fname, const char *mountpoint, + tupledesc_t tuples, unsigned int *r_id) +{ + switch (conttype) + { + case CONTTYPE_ENCFS: + return be_encfs_mount_container (ctrl, fname, mountpoint, tuples, r_id); + + case CONTTYPE_DM_CRYPT: + return be_dmcrypt_mount_container (ctrl, fname, mountpoint, tuples); + + default: + return no_such_backend (conttype); + } +} + + +/* Dispatcher to the backend's umount function. */ +gpg_error_t +be_umount_container (ctrl_t ctrl, int conttype, const char *fname) +{ + switch (conttype) + { + case CONTTYPE_ENCFS: + return gpg_error (GPG_ERR_NOT_SUPPORTED); + + case CONTTYPE_DM_CRYPT: + return be_dmcrypt_umount_container (ctrl, fname); + + default: + return no_such_backend (conttype); + } +} + + +/* Dispatcher to the backend's suspend function. */ +gpg_error_t +be_suspend_container (ctrl_t ctrl, int conttype, const char *fname) +{ + switch (conttype) + { + case CONTTYPE_ENCFS: + return gpg_error (GPG_ERR_NOT_SUPPORTED); + + case CONTTYPE_DM_CRYPT: + return be_dmcrypt_suspend_container (ctrl, fname); + + default: + return no_such_backend (conttype); + } +} + + +/* Dispatcher to the backend's resume function. */ +gpg_error_t +be_resume_container (ctrl_t ctrl, int conttype, const char *fname, + tupledesc_t tuples) +{ + switch (conttype) + { + case CONTTYPE_ENCFS: + return gpg_error (GPG_ERR_NOT_SUPPORTED); + + case CONTTYPE_DM_CRYPT: + return be_dmcrypt_resume_container (ctrl, fname, tuples); + + default: + return no_such_backend (conttype); + } +} diff --git a/g13/backend.h b/g13/backend.h new file mode 100644 index 0000000..2805d99 --- /dev/null +++ b/g13/backend.h @@ -0,0 +1,49 @@ +/* backend.h - Defs for the dispatcher to the various backends. + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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 . + */ + +#ifndef G13_BACKEND_H +#define G13_BACKEND_H + +#include "../common/membuf.h" +#include "g13tuple.h" + +int be_parse_conttype_name (const char *name); +int be_is_supported_conttype (int conttype); +gpg_error_t be_take_lock_for_create (ctrl_t ctrl, const char *fname, + dotlock_t *r_lock); +gpg_error_t be_get_detached_name (int conttype, const char *fname, + char **r_name, int *r_isdir); +gpg_error_t be_create_new_keys (int conttype, membuf_t *mb); + +gpg_error_t be_create_container (ctrl_t ctrl, int conttype, + const char *fname, int fd, + tupledesc_t tuples, + unsigned int *r_id); +gpg_error_t be_mount_container (ctrl_t ctrl, int conttype, + const char *fname, const char *mountpoint, + tupledesc_t tuples, + unsigned int *r_id); +gpg_error_t be_umount_container (ctrl_t ctrl, int conttype, const char *fname); +gpg_error_t be_suspend_container (ctrl_t ctrl, int conttype, + const char *fname); +gpg_error_t be_resume_container (ctrl_t ctrl, int conttype, + const char *fname, tupledesc_t tuples); + + +#endif /*G13_BACKEND_H*/ diff --git a/g13/be-dmcrypt.c b/g13/be-dmcrypt.c new file mode 100644 index 0000000..59b586d --- /dev/null +++ b/g13/be-dmcrypt.c @@ -0,0 +1,116 @@ +/* be-dmcrypt.c - The DM-Crypt based backend + * Copyright (C) 2015 Werner Koch + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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 . + */ + +#include +#include +#include +#include +#include +#include + +#include "g13.h" +#include "../common/i18n.h" +#include "keyblob.h" +#include "call-syshelp.h" +#include "be-dmcrypt.h" + + +/* Create the container using the current device. + * information in TUPLES. */ +gpg_error_t +be_dmcrypt_create_container (ctrl_t ctrl) +{ + gpg_error_t err; + + err = call_syshelp_run_create (ctrl, CONTTYPE_DM_CRYPT); + + return err; +} + + +/* Mount the container described by the filename FNAME and the keyblob + * information in TUPLES. On success the runner id is stored at R_ID. */ +gpg_error_t +be_dmcrypt_mount_container (ctrl_t ctrl, + const char *fname, const char *mountpoint, + tupledesc_t tuples) +{ + gpg_error_t err; + + err = call_syshelp_set_device (ctrl, fname); + if (err) + goto leave; + + err = call_syshelp_run_mount (ctrl, CONTTYPE_DM_CRYPT, mountpoint, tuples); + + leave: + return err; +} + + +/* Unmount the container described by the filename FNAME. */ +gpg_error_t +be_dmcrypt_umount_container (ctrl_t ctrl, const char *fname) +{ + gpg_error_t err; + + err = call_syshelp_set_device (ctrl, fname); + if (err) + goto leave; + + err = call_syshelp_run_umount (ctrl, CONTTYPE_DM_CRYPT); + + leave: + return err; +} + + +/* Suspend the container described by the filename FNAME. */ +gpg_error_t +be_dmcrypt_suspend_container (ctrl_t ctrl, const char *fname) +{ + gpg_error_t err; + + err = call_syshelp_set_device (ctrl, fname); + if (err) + goto leave; + + err = call_syshelp_run_suspend (ctrl, CONTTYPE_DM_CRYPT); + + leave: + return err; +} + + +/* Resume the container described by the filename FNAME and the keyblob + * information in TUPLES. */ +gpg_error_t +be_dmcrypt_resume_container (ctrl_t ctrl, const char *fname, tupledesc_t tuples) +{ + gpg_error_t err; + + err = call_syshelp_set_device (ctrl, fname); + if (err) + goto leave; + + err = call_syshelp_run_resume (ctrl, CONTTYPE_DM_CRYPT, tuples); + + leave: + return err; +} diff --git a/g13/be-dmcrypt.h b/g13/be-dmcrypt.h new file mode 100644 index 0000000..cc0fce5 --- /dev/null +++ b/g13/be-dmcrypt.h @@ -0,0 +1,36 @@ +/* be-dmcrypt.h - Public defs for the DM-Crypt based backend + * Copyright (C) 2015 Werner Koch + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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 . + */ + +#ifndef G13_BE_DMCRYPT_H +#define G13_BE_DMCRYPT_H + +#include "backend.h" + +gpg_error_t be_dmcrypt_create_container (ctrl_t ctrl); +gpg_error_t be_dmcrypt_mount_container (ctrl_t ctrl, + const char *fname, + const char *mountpoint, + tupledesc_t tuples); +gpg_error_t be_dmcrypt_umount_container (ctrl_t ctrl, const char *fname); +gpg_error_t be_dmcrypt_suspend_container (ctrl_t ctrl, const char *fname); +gpg_error_t be_dmcrypt_resume_container (ctrl_t ctrl, const char *fname, + tupledesc_t tuples); + + +#endif /*G13_BE_DMCRYPT_H*/ diff --git a/g13/be-encfs.c b/g13/be-encfs.c new file mode 100644 index 0000000..0e2c68b --- /dev/null +++ b/g13/be-encfs.c @@ -0,0 +1,471 @@ +/* be-encfs.c - The EncFS based backend + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "g13.h" +#include "../common/i18n.h" +#include "keyblob.h" +#include "be-encfs.h" +#include "runner.h" +#include "../common/sysutils.h" +#include "../common/exechelp.h" + + +/* Command values used to run the encfs tool. */ +enum encfs_cmds + { + ENCFS_CMD_CREATE, + ENCFS_CMD_MOUNT, + ENCFS_CMD_UMOUNT + }; + + +/* An object to keep the private state of the encfs tool. It is + released by encfs_handler_cleanup. */ +struct encfs_parm_s +{ + enum encfs_cmds cmd; /* The current command. */ + tupledesc_t tuples; /* NULL or the tuples object. */ + char *mountpoint; /* The mountpoint. */ +}; +typedef struct encfs_parm_s *encfs_parm_t; + + +static gpg_error_t +send_cmd_bin (runner_t runner, const void *data, size_t datalen) +{ + return runner_send_line (runner, data, datalen); +} + + +static gpg_error_t +send_cmd (runner_t runner, const char *string) +{ + log_debug ("sending command -->%s<--\n", string); + return send_cmd_bin (runner, string, strlen (string)); +} + + + +static void +run_umount_helper (const char *mountpoint) +{ + gpg_error_t err; + const char pgmname[] = FUSERMOUNT; + const char *args[3]; + + args[0] = "-u"; + args[1] = mountpoint; + args[2] = NULL; + + err = gnupg_spawn_process_detached (pgmname, args, NULL); + if (err) + log_error ("failed to run '%s': %s\n", + pgmname, gpg_strerror (err)); +} + + +/* Handle one line of the encfs tool's output. This function is + allowed to modify the content of BUFFER. */ +static gpg_error_t +handle_status_line (runner_t runner, const char *line, + enum encfs_cmds cmd, tupledesc_t tuples) +{ + gpg_error_t err; + + /* Check that encfs understands our new options. */ + if (!strncmp (line, "$STATUS$", 8)) + { + for (line +=8; *line && spacep (line); line++) + ; + log_info ("got status '%s'\n", line); + if (!strcmp (line, "fuse_main_start")) + { + /* Send a special error code back to let the caller know + that everything has been setup by encfs. */ + err = gpg_error (GPG_ERR_UNFINISHED); + } + else + err = 0; + } + else if (!strncmp (line, "$PROMPT$", 8)) + { + for (line +=8; *line && spacep (line); line++) + ; + log_info ("got prompt '%s'\n", line); + if (!strcmp (line, "create_root_dir")) + err = send_cmd (runner, cmd == ENCFS_CMD_CREATE? "y":"n"); + else if (!strcmp (line, "create_mount_point")) + err = send_cmd (runner, "y"); + else if (!strcmp (line, "passwd") + || !strcmp (line, "new_passwd")) + { + if (tuples) + { + size_t n; + const void *value; + + value = find_tuple (tuples, KEYBLOB_TAG_ENCKEY, &n); + if (!value) + err = gpg_error (GPG_ERR_INV_SESSION_KEY); + else if ((err = send_cmd_bin (runner, value, n))) + { + if (gpg_err_code (err) == GPG_ERR_BUG + && gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT) + err = gpg_error (GPG_ERR_INV_SESSION_KEY); + } + } + else + err = gpg_error (GPG_ERR_NO_DATA); + } + else + err = send_cmd (runner, ""); /* Default to send an empty line. */ + } + else if (strstr (line, "encfs: unrecognized option '")) + err = gpg_error (GPG_ERR_INV_ENGINE); + else + err = 0; + + return err; +} + + +/* The main processing function as used by the runner. */ +static gpg_error_t +encfs_handler (void *opaque, runner_t runner, const char *status_line) +{ + encfs_parm_t parm = opaque; + gpg_error_t err; + + if (!parm || !runner) + return gpg_error (GPG_ERR_BUG); + if (!status_line) + { + /* Runner requested internal flushing - nothing to do here. */ + return 0; + } + + err = handle_status_line (runner, status_line, parm->cmd, parm->tuples); + if (gpg_err_code (err) == GPG_ERR_UNFINISHED + && gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT) + { + err = 0; + /* No more need for the tuples. */ + destroy_tupledesc (parm->tuples); + parm->tuples = NULL; + + if (parm->cmd == ENCFS_CMD_CREATE) + { + /* The encfs tool keeps on running after creation of the + container. We don't want that and thus need to stop the + encfs process. */ + run_umount_helper (parm->mountpoint); + /* In case the umount helper does not work we try to kill + the engine. FIXME: We should figure out how to make + fusermount work. */ + runner_cancel (runner); + } + } + + return err; +} + + +/* Called by the runner to cleanup the private data. */ +static void +encfs_handler_cleanup (void *opaque) +{ + encfs_parm_t parm = opaque; + + if (!parm) + return; + + destroy_tupledesc (parm->tuples); + xfree (parm->mountpoint); + xfree (parm); +} + + +/* Run the encfs tool. */ +static gpg_error_t +run_encfs_tool (ctrl_t ctrl, enum encfs_cmds cmd, + const char *rawdir, const char *mountpoint, tupledesc_t tuples, + unsigned int *r_id) +{ + gpg_error_t err; + encfs_parm_t parm; + runner_t runner = NULL; + int outbound[2] = { -1, -1 }; + int inbound[2] = { -1, -1 }; + const char *pgmname; + const char *argv[10]; + pid_t pid = (pid_t)(-1); + int idx; + + (void)ctrl; + + parm = xtrycalloc (1, sizeof *parm); + if (!parm) + { + err = gpg_error_from_syserror (); + goto leave; + } + parm->cmd = cmd; + parm->tuples = ref_tupledesc (tuples); + parm->mountpoint = xtrystrdup (mountpoint); + if (!parm->mountpoint) + { + err = gpg_error_from_syserror (); + goto leave; + } + + err = runner_new (&runner, "encfs"); + if (err) + goto leave; + + err = gnupg_create_inbound_pipe (inbound, NULL, 0); + if (!err) + err = gnupg_create_outbound_pipe (outbound, NULL, 0); + if (err) + { + log_error (_("error creating a pipe: %s\n"), gpg_strerror (err)); + goto leave; + } + + pgmname = ENCFS; + idx = 0; + argv[idx++] = "-f"; + if (opt.verbose) + argv[idx++] = "-v"; + argv[idx++] = "--stdinpass"; + argv[idx++] = "--annotate"; + argv[idx++] = rawdir; + argv[idx++] = mountpoint; + argv[idx++] = NULL; + assert (idx <= DIM (argv)); + + err = gnupg_spawn_process_fd (pgmname, argv, + outbound[0], -1, inbound[1], &pid); + if (err) + { + log_error ("error spawning '%s': %s\n", pgmname, gpg_strerror (err)); + goto leave; + } + close (outbound[0]); outbound[0] = -1; + close ( inbound[1]); inbound[1] = -1; + + runner_set_fds (runner, inbound[0], outbound[1]); + inbound[0] = -1; /* Now owned by RUNNER. */ + outbound[1] = -1; /* Now owned by RUNNER. */ + + runner_set_handler (runner, encfs_handler, encfs_handler_cleanup, parm); + parm = NULL; /* Now owned by RUNNER. */ + + runner_set_pid (runner, pid); + pid = (pid_t)(-1); /* The process is now owned by RUNNER. */ + + err = runner_spawn (runner); + if (err) + goto leave; + + *r_id = runner_get_rid (runner); + log_info ("running '%s' in the background\n", pgmname); + + leave: + if (inbound[0] != -1) + close (inbound[0]); + if (inbound[1] != -1) + close (inbound[1]); + if (outbound[0] != -1) + close (outbound[0]); + if (outbound[1] != -1) + close (outbound[1]); + if (pid != (pid_t)(-1)) + { + gnupg_wait_process (pgmname, pid, 1, NULL); + gnupg_release_process (pid); + } + runner_release (runner); + encfs_handler_cleanup (parm); + return err; +} + + + + + +/* See be_get_detached_name for a description. Note that the + dispatcher code makes sure that NULL is stored at R_NAME before + calling us. */ +gpg_error_t +be_encfs_get_detached_name (const char *fname, char **r_name, int *r_isdir) +{ + char *result; + + if (!fname || !*fname) + return gpg_error (GPG_ERR_INV_ARG); + + result = strconcat (fname, ".d", NULL); + if (!result) + return gpg_error_from_syserror (); + *r_name = result; + *r_isdir = 1; + return 0; +} + + +/* Create a new session key and append it as a tuple to the memory + buffer MB. + + The EncFS daemon takes a passphrase from stdin and internally + mangles it by means of some KDF from OpenSSL. We want to store a + binary key but we need to make sure that certain characters are not + used because the EncFS utility reads it from stdin and obviously + acts on some of the characters. This we replace CR (in case of an + MSDOS version of EncFS), LF (the delimiter used by EncFS) and Nul + (because it is unlikely to work). We use 32 bytes (256 bit) + because that is sufficient for the largest cipher (AES-256) and in + addition gives enough margin for a possible entropy degradation by + the KDF. */ +gpg_error_t +be_encfs_create_new_keys (membuf_t *mb) +{ + char *buffer; + int i, j; + + /* Allocate a buffer of 32 bytes plus 8 spare bytes we may need to + replace the unwanted values. */ + buffer = xtrymalloc_secure (32+8); + if (!buffer) + return gpg_error_from_syserror (); + + /* Randomize the buffer. STRONG random should be enough as it is a + good compromise between security and performance. The + anticipated usage of this tool is the quite often creation of new + containers and thus this should not deplete the system's entropy + tool too much. */ + gcry_randomize (buffer, 32+8, GCRY_STRONG_RANDOM); + for (i=j=0; i < 32; i++) + { + if (buffer[i] == '\r' || buffer[i] == '\n' || buffer[i] == 0 ) + { + /* Replace. */ + if (j == 8) + { + /* Need to get more random. */ + gcry_randomize (buffer+32, 8, GCRY_STRONG_RANDOM); + j = 0; + } + buffer[i] = buffer[32+j]; + j++; + } + } + + /* Store the key. */ + append_tuple (mb, KEYBLOB_TAG_ENCKEY, buffer, 32); + + /* Free the temporary buffer. */ + wipememory (buffer, 32+8); /* A failsafe extra wiping. */ + xfree (buffer); + + return 0; +} + + +/* Create the container described by the filename FNAME and the keyblob + information in TUPLES. */ +gpg_error_t +be_encfs_create_container (ctrl_t ctrl, const char *fname, tupledesc_t tuples, + unsigned int *r_id) +{ + gpg_error_t err; + int dummy; + char *containername = NULL; + char *mountpoint = NULL; + + err = be_encfs_get_detached_name (fname, &containername, &dummy); + if (err) + goto leave; + + mountpoint = xtrystrdup ("/tmp/.#g13_XXXXXX"); + if (!mountpoint) + { + err = gpg_error_from_syserror (); + goto leave; + } + if (!gnupg_mkdtemp (mountpoint)) + { + err = gpg_error_from_syserror (); + log_error (_("can't create directory '%s': %s\n"), + "/tmp/.#g13_XXXXXX", gpg_strerror (err)); + goto leave; + } + + err = run_encfs_tool (ctrl, ENCFS_CMD_CREATE, containername, mountpoint, + tuples, r_id); + + /* In any case remove the temporary mount point. */ + if (rmdir (mountpoint)) + log_error ("error removing temporary mount point '%s': %s\n", + mountpoint, gpg_strerror (gpg_error_from_syserror ())); + + + leave: + xfree (containername); + xfree (mountpoint); + return err; +} + + +/* Mount the container described by the filename FNAME and the keyblob + information in TUPLES. On success the runner id is stored at R_ID. */ +gpg_error_t +be_encfs_mount_container (ctrl_t ctrl, + const char *fname, const char *mountpoint, + tupledesc_t tuples, unsigned int *r_id) +{ + gpg_error_t err; + int dummy; + char *containername = NULL; + + if (!mountpoint) + { + log_error ("the encfs backend requires an explicit mountpoint\n"); + err = gpg_error (GPG_ERR_NOT_SUPPORTED); + goto leave; + } + + err = be_encfs_get_detached_name (fname, &containername, &dummy); + if (err) + goto leave; + + err = run_encfs_tool (ctrl, ENCFS_CMD_MOUNT, containername, mountpoint, + tuples, r_id); + + leave: + xfree (containername); + return err; +} diff --git a/g13/be-encfs.h b/g13/be-encfs.h new file mode 100644 index 0000000..1f1b8b3 --- /dev/null +++ b/g13/be-encfs.h @@ -0,0 +1,41 @@ +/* be-encfs.h - Public defs for the EncFS based backend + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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 . + */ + +#ifndef G13_BE_ENCFS_H +#define G13_BE_ENCFS_H + +#include "backend.h" + +gpg_error_t be_encfs_get_detached_name (const char *fname, + char **r_name, int *r_isdir); +gpg_error_t be_encfs_create_new_keys (membuf_t *mb); + +gpg_error_t be_encfs_create_container (ctrl_t ctrl, + const char *fname, + tupledesc_t tuples, + unsigned int *r_id); + +gpg_error_t be_encfs_mount_container (ctrl_t ctrl, + const char *fname, + const char *mountpoint, + tupledesc_t tuples, + unsigned int *r_id); + + +#endif /*G13_BE_ENCFS_H*/ diff --git a/g13/be-truecrypt.c b/g13/be-truecrypt.c new file mode 100644 index 0000000..1ce992f --- /dev/null +++ b/g13/be-truecrypt.c @@ -0,0 +1,37 @@ +/* be-truecrypt.c - The Truecrypt based backend + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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 . + */ + +#include +#include +#include +#include +#include +#include + +#include "g13.h" +#include "../common/i18n.h" +#include "be-truecrypt.h" + + +gpg_error_t +be_truecrypt_create_new_keys (membuf_t *mb) +{ + (void)mb; + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); +} diff --git a/g13/be-truecrypt.h b/g13/be-truecrypt.h new file mode 100644 index 0000000..d6d1e84 --- /dev/null +++ b/g13/be-truecrypt.h @@ -0,0 +1,28 @@ +/* be-truecrypt.h - Public defs for the Truecrypt based backend + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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 . + */ + +#ifndef G13_BE_TRUECRYPT_H +#define G13_BE_TRUECRYPT_H + +#include "backend.h" + +gpg_error_t be_truecrypt_create_new_keys (membuf_t *mb); + + +#endif /*G13_BE_TRUECRYPT_H*/ diff --git a/g13/call-syshelp.c b/g13/call-syshelp.c new file mode 100644 index 0000000..b160ba3 --- /dev/null +++ b/g13/call-syshelp.c @@ -0,0 +1,631 @@ +/* call-syshelp.c - Communication with g13-syshelp + * Copyright (C) 2015 Werner Koch + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "g13.h" +#include +#include "../common/i18n.h" +#include "g13tuple.h" +#include "keyblob.h" +#include "../common/membuf.h" +#include "create.h" +#include "call-syshelp.h" + + +/* Local data for this module. A pointer to this is stored in the + CTRL object of each connection. */ +struct call_syshelp_s +{ + assuan_context_t assctx; /* The Assuan context for the current + g13-syshep connection. */ +}; + + +/* Parameter used with the CREATE command. */ +struct create_parm_s +{ + assuan_context_t ctx; + ctrl_t ctrl; + membuf_t plaintext; + unsigned int expect_plaintext:1; + unsigned int got_plaintext:1; +}; + + +/* Parameter used with the MOUNT command. */ +struct mount_parm_s +{ + assuan_context_t ctx; + ctrl_t ctrl; + const void *keyblob; + size_t keybloblen; +}; + + + + + +/* Fork off the syshelp tool if this has not already been done. On + success stores the current Assuan context for the syshelp tool at + R_CTX. */ +static gpg_error_t +start_syshelp (ctrl_t ctrl, assuan_context_t *r_ctx) +{ + gpg_error_t err; + assuan_context_t ctx; + assuan_fd_t no_close_list[3]; + int i; + + *r_ctx = NULL; + + if (ctrl->syshelp_local && (*r_ctx = ctrl->syshelp_local->assctx)) + return 0; /* Already set. */ + + if (opt.verbose) + log_info ("starting a new syshelp\n"); + + if (!ctrl->syshelp_local) + { + ctrl->syshelp_local = xtrycalloc (1, sizeof *ctrl->syshelp_local); + if (!ctrl->syshelp_local) + return gpg_error_from_syserror (); + } + + if (es_fflush (NULL)) + { + err = gpg_error_from_syserror (); + log_error ("error flushing pending output: %s\n", gpg_strerror (err)); + return err; + } + + i = 0; + if (log_get_fd () != -1) + no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ()); + no_close_list[i++] = assuan_fd_from_posix_fd (es_fileno (es_stderr)); + no_close_list[i] = ASSUAN_INVALID_FD; + + err = assuan_new (&ctx); + if (err) + { + log_error ("can't allocate assuan context: %s\n", gpg_strerror (err)); + return err; + } + + /* Call userv to start g13-syshelp. This userv script needs to be + * installed under the name "gnupg-g13-syshelp": + * + * if ( glob service-user root + * ) + * reset + * suppress-args + * execute /home/wk/b/gnupg/g13/g13-syshelp -v + * else + * error Nothing to do for this service-user + * fi + * quit + */ + { + const char *argv[4]; + + argv[0] = "userv"; + argv[1] = "root"; + argv[2] = "gnupg-g13-syshelp"; + argv[3] = NULL; + + err = assuan_pipe_connect (ctx, "/usr/bin/userv", argv, + no_close_list, NULL, NULL, 0); + } + if (err) + { + log_error ("can't connect to '%s': %s %s\n", + "g13-syshelp", gpg_strerror (err), gpg_strsource (err)); + log_info ("(is userv and its gnupg-g13-syshelp script installed?)\n"); + assuan_release (ctx); + return err; + } + + *r_ctx = ctrl->syshelp_local->assctx = ctx; + + if (DBG_IPC) + log_debug ("connection to g13-syshelp established\n"); + + return 0; +} + + +/* Release local resources associated with CTRL. */ +void +call_syshelp_release (ctrl_t ctrl) +{ + if (!ctrl) + return; + if (ctrl->syshelp_local) + { + assuan_release (ctrl->syshelp_local->assctx); + ctrl->syshelp_local->assctx = NULL; + xfree (ctrl->syshelp_local); + ctrl->syshelp_local = NULL; + } +} + + + +/* Staus callback for call_syshelp_find_device. */ +static gpg_error_t +finddevice_status_cb (void *opaque, const char *line) +{ + char **r_blockdev = opaque; + char *p; + + if ((p = has_leading_keyword (line, "BLOCKDEV")) && *p && !*r_blockdev) + { + *r_blockdev = xtrystrdup (p); + if (!*r_blockdev) + return gpg_error_from_syserror (); + } + + return 0; +} + + +/* Send the FINDDEVICE command to the syshelper. On success the name + * of the block device is stored at R_BLOCKDEV. */ +gpg_error_t +call_syshelp_find_device (ctrl_t ctrl, const char *name, char **r_blockdev) +{ + gpg_error_t err; + assuan_context_t ctx; + char *line = NULL; + char *blockdev = NULL; /* The result. */ + + *r_blockdev = NULL; + + err = start_syshelp (ctrl, &ctx); + if (err) + goto leave; + + line = xtryasprintf ("FINDDEVICE %s", name); + if (!line) + { + err = gpg_error_from_syserror (); + goto leave; + } + err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, + finddevice_status_cb, &blockdev); + if (err) + goto leave; + if (!blockdev) + { + log_error ("status line for successful FINDDEVICE missing\n"); + err = gpg_error (GPG_ERR_UNEXPECTED); + goto leave; + } + *r_blockdev = blockdev; + blockdev = NULL; + + leave: + xfree (blockdev); + xfree (line); + return err; +} + + + +static gpg_error_t +getkeyblob_data_cb (void *opaque, const void *data, size_t datalen) +{ + membuf_t *mb = opaque; + + if (data) + put_membuf (mb, data, datalen); + + return 0; +} + + +/* Send the GTEKEYBLOB command to the syshelper. On success the + * encrypted keyblpob is stored at (R_ENCKEYBLOB,R_ENCKEYBLOBLEN). */ +gpg_error_t +call_syshelp_get_keyblob (ctrl_t ctrl, + void **r_enckeyblob, size_t *r_enckeybloblen) +{ + gpg_error_t err; + assuan_context_t ctx; + membuf_t mb; + + *r_enckeyblob = NULL; + *r_enckeybloblen = 0; + init_membuf (&mb, 512); + + err = start_syshelp (ctrl, &ctx); + if (err) + goto leave; + + err = assuan_transact (ctx, "GETKEYBLOB", + getkeyblob_data_cb, &mb, + NULL, NULL, NULL, NULL); + if (err) + goto leave; + *r_enckeyblob = get_membuf (&mb, r_enckeybloblen); + if (!*r_enckeyblob) + err = gpg_error_from_syserror (); + + leave: + xfree (get_membuf (&mb, NULL)); + return err; +} + + + +/* Send the DEVICE command to the syshelper. FNAME is the name of the + device. */ +gpg_error_t +call_syshelp_set_device (ctrl_t ctrl, const char *fname) +{ + gpg_error_t err; + assuan_context_t ctx; + char *line = NULL; + + err = start_syshelp (ctrl, &ctx); + if (err) + goto leave; + + line = xtryasprintf ("DEVICE %s", fname); + if (!line) + { + err = gpg_error_from_syserror (); + goto leave; + } + err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); + + leave: + xfree (line); + return err; +} + + + +static gpg_error_t +create_status_cb (void *opaque, const char *line) +{ + struct create_parm_s *parm = opaque; + + if (has_leading_keyword (line, "PLAINTEXT_FOLLOWS")) + parm->expect_plaintext = 1; + + return 0; +} + + +static gpg_error_t +create_data_cb (void *opaque, const void *data, size_t datalen) +{ + struct create_parm_s *parm = opaque; + gpg_error_t err = 0; + + if (!parm->expect_plaintext) + { + log_error ("status line for data missing\n"); + err = gpg_error (GPG_ERR_UNEXPECTED); + } + else if (data) + { + put_membuf (&parm->plaintext, data, datalen); + } + else + { + parm->expect_plaintext = 0; + parm->got_plaintext = 1; + } + + return err; +} + + +static gpg_error_t +create_inq_cb (void *opaque, const char *line) +{ + struct create_parm_s *parm = opaque; + gpg_error_t err; + + if (has_leading_keyword (line, "ENCKEYBLOB")) + { + void *plaintext; + size_t plaintextlen; + + if (!parm->got_plaintext) + err = gpg_error (GPG_ERR_UNEXPECTED); + else if (!(plaintext = get_membuf (&parm->plaintext, &plaintextlen))) + err = gpg_error_from_syserror (); + else + { + void *ciphertext; + size_t ciphertextlen; + + log_printhex (plaintext, plaintextlen, "plain"); + err = g13_encrypt_keyblob (parm->ctrl, + plaintext, plaintextlen, + &ciphertext, &ciphertextlen); + wipememory (plaintext, plaintextlen); + xfree (plaintext); + if (err) + log_error ("error encrypting keyblob: %s\n", gpg_strerror (err)); + else + { + err = assuan_send_data (parm->ctx, ciphertext, ciphertextlen); + xfree (ciphertext); + if (err) + log_error ("sending ciphertext to g13-syshelp failed: %s\n", + gpg_strerror (err)); + } + } + } + else + err = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE); + + return err; +} + + +/* Run the CREATE command on the current device. CONTTYPES gives the + requested content type for the new container. */ +gpg_error_t +call_syshelp_run_create (ctrl_t ctrl, int conttype) +{ + gpg_error_t err; + assuan_context_t ctx; + struct create_parm_s parm; + + memset (&parm, 0, sizeof parm); + + err = start_syshelp (ctrl, &ctx); + if (err) + goto leave; + + /* tty_get ("waiting for debugger"); */ + /* tty_kill_prompt (); */ + + parm.ctx = ctx; + parm.ctrl = ctrl; + init_membuf (&parm.plaintext, 512); + if (conttype == CONTTYPE_DM_CRYPT) + { + err = assuan_transact (ctx, "CREATE dm-crypt", + create_data_cb, &parm, + create_inq_cb, &parm, + create_status_cb, &parm); + } + else + { + log_error ("invalid backend type %d given\n", conttype); + err = GPG_ERR_INTERNAL; + goto leave; + } + + leave: + xfree (get_membuf (&parm.plaintext, NULL)); + return err; +} + + + +static gpg_error_t +mount_status_cb (void *opaque, const char *line) +{ + struct mount_parm_s *parm = opaque; + + /* Nothing right now. */ + (void)parm; + (void)line; + + return 0; +} + + +/* Inquire callback for MOUNT and RESUME. */ +static gpg_error_t +mount_inq_cb (void *opaque, const char *line) +{ + struct mount_parm_s *parm = opaque; + gpg_error_t err; + + if (has_leading_keyword (line, "KEYBLOB")) + { + int setconfidential = !assuan_get_flag (parm->ctx, ASSUAN_CONFIDENTIAL); + + if (setconfidential) + assuan_begin_confidential (parm->ctx); + err = assuan_send_data (parm->ctx, parm->keyblob, parm->keybloblen); + if (setconfidential) + assuan_end_confidential (parm->ctx); + if (err) + log_error ("sending keyblob to g13-syshelp failed: %s\n", + gpg_strerror (err)); + } + else + err = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE); + + return err; +} + + +/* + * Run the MOUNT command on the current device. CONTTYPES gives the + * requested content type for the new container. MOUNTPOINT the + * desired mount point or NULL for default. + */ +gpg_error_t +call_syshelp_run_mount (ctrl_t ctrl, int conttype, const char *mountpoint, + tupledesc_t tuples) +{ + gpg_error_t err; + assuan_context_t ctx; + struct mount_parm_s parm; + + memset (&parm, 0, sizeof parm); + + err = start_syshelp (ctrl, &ctx); + if (err) + goto leave; + + /* tty_get ("waiting for debugger"); */ + /* tty_kill_prompt (); */ + + parm.ctx = ctx; + parm.ctrl = ctrl; + if (conttype == CONTTYPE_DM_CRYPT) + { + ref_tupledesc (tuples); + parm.keyblob = get_tupledesc_data (tuples, &parm.keybloblen); + err = assuan_transact (ctx, "MOUNT dm-crypt", + NULL, NULL, + mount_inq_cb, &parm, + mount_status_cb, &parm); + unref_tupledesc (tuples); + } + else + { + (void)mountpoint; /* Not used. */ + log_error ("invalid backend type %d given\n", conttype); + err = GPG_ERR_INTERNAL; + goto leave; + } + + leave: + return err; +} + + + +/* + * Run the UMOUNT command on the current device. CONTTYPES gives the + * content type of the container (fixme: Do we really need this?). + */ +gpg_error_t +call_syshelp_run_umount (ctrl_t ctrl, int conttype) +{ + gpg_error_t err; + assuan_context_t ctx; + + err = start_syshelp (ctrl, &ctx); + if (err) + goto leave; + + if (conttype == CONTTYPE_DM_CRYPT) + { + err = assuan_transact (ctx, "UMOUNT dm-crypt", + NULL, NULL, + NULL, NULL, + NULL, NULL); + } + else + { + log_error ("invalid backend type %d given\n", conttype); + err = GPG_ERR_INTERNAL; + goto leave; + } + + leave: + return err; +} + + + +/* + * Run the SUSPEND command on the current device. CONTTYPES gives the + * requested content type for the new container. + */ +gpg_error_t +call_syshelp_run_suspend (ctrl_t ctrl, int conttype) +{ + gpg_error_t err; + assuan_context_t ctx; + + err = start_syshelp (ctrl, &ctx); + if (err) + goto leave; + + if (conttype == CONTTYPE_DM_CRYPT) + { + err = assuan_transact (ctx, "SUSPEND dm-crypt", + NULL, NULL, + NULL, NULL, + NULL, NULL); + } + else + { + log_error ("invalid backend type %d given\n", conttype); + err = GPG_ERR_INTERNAL; + goto leave; + } + + leave: + return err; +} + + + +/* Run the RESUME command on the current device. CONTTYPES gives the + requested content type for the container. */ +gpg_error_t +call_syshelp_run_resume (ctrl_t ctrl, int conttype, tupledesc_t tuples) +{ + gpg_error_t err; + assuan_context_t ctx; + struct mount_parm_s parm; + + memset (&parm, 0, sizeof parm); + + err = start_syshelp (ctrl, &ctx); + if (err) + goto leave; + + /* tty_get ("waiting for debugger"); */ + /* tty_kill_prompt (); */ + + parm.ctx = ctx; + parm.ctrl = ctrl; + if (conttype == CONTTYPE_DM_CRYPT) + { + ref_tupledesc (tuples); + parm.keyblob = get_tupledesc_data (tuples, &parm.keybloblen); + err = assuan_transact (ctx, "RESUME dm-crypt", + NULL, NULL, + mount_inq_cb, &parm, + NULL, NULL); + unref_tupledesc (tuples); + } + else + { + log_error ("invalid backend type %d given\n", conttype); + err = GPG_ERR_INTERNAL; + goto leave; + } + + leave: + return err; +} diff --git a/g13/call-syshelp.h b/g13/call-syshelp.h new file mode 100644 index 0000000..3e83829 --- /dev/null +++ b/g13/call-syshelp.h @@ -0,0 +1,42 @@ +/* call-syshelp.h - Communication with g13-syshelp + * Copyright (C) 2015 Werner Koch + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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 . + */ + +#ifndef GNUPG_G13_CALL_SYSHELP_H +#define GNUPG_G13_CALL_SYSHELP_H + +#include "g13tuple.h" + +void call_syshelp_release (ctrl_t ctrl); +gpg_error_t call_syshelp_find_device (ctrl_t ctrl, + const char *name, char **r_blockdev); +gpg_error_t call_syshelp_get_keyblob (ctrl_t ctrl, + void **r_enckeyblob, + size_t *r_enckeybloblen); +gpg_error_t call_syshelp_set_device (ctrl_t ctrl, const char *fname); +gpg_error_t call_syshelp_run_create (ctrl_t ctrl, int conttype); +gpg_error_t call_syshelp_run_mount (ctrl_t ctrl, int conttype, + const char *mountpoint, + tupledesc_t tuples); +gpg_error_t call_syshelp_run_umount (ctrl_t ctrl, int conttype); +gpg_error_t call_syshelp_run_suspend (ctrl_t ctrl, int conttype); +gpg_error_t call_syshelp_run_resume (ctrl_t ctrl, int conttype, + tupledesc_t tuples); + + +#endif /*GNUPG_G13_CALL_SYSHELP_H*/ diff --git a/g13/create.c b/g13/create.c new file mode 100644 index 0000000..ac4d130 --- /dev/null +++ b/g13/create.c @@ -0,0 +1,303 @@ +/* create.c - Create a new crypto container + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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 . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "g13.h" +#include "../common/i18n.h" +#include "create.h" + +#include "keyblob.h" +#include "backend.h" +#include "g13tuple.h" +#include "../common/sysutils.h" +#include "../common/call-gpg.h" + +/* Create a new blob with all the session keys and other meta + information which are to be stored encrypted in the crypto + container header. On success the malloced blob is stored at R_BLOB + and its length at R_BLOBLEN. On error an error code is returned + and (R_BLOB,R_BLOBLEN) are set to (NULL,0). + + The format of this blob is a sequence of tag-length-value tuples. + All tuples have this format: + + 2 byte TAG Big endian unsigned integer (0..65535) + described by the KEYBLOB_TAG_ constants. + 2 byte LENGTH Big endian unsigned integer (0..65535) + giving the length of the value. + length bytes VALUE The value described by the tag. + + The first tag in a keyblob must be a BLOBVERSION. The other tags + depend on the type of the container as described by the CONTTYPE + tag. See keyblob.h for details. */ +static gpg_error_t +create_new_keyblob (ctrl_t ctrl, int is_detached, + void **r_blob, size_t *r_bloblen) +{ + gpg_error_t err; + unsigned char twobyte[2]; + membuf_t mb; + + *r_blob = NULL; + *r_bloblen = 0; + + init_membuf_secure (&mb, 512); + + append_tuple (&mb, KEYBLOB_TAG_BLOBVERSION, "\x01", 1); + + twobyte[0] = (ctrl->conttype >> 8); + twobyte[1] = (ctrl->conttype); + append_tuple (&mb, KEYBLOB_TAG_CONTTYPE, twobyte, 2); + if (is_detached) + append_tuple (&mb, KEYBLOB_TAG_DETACHED, NULL, 0); + + err = be_create_new_keys (ctrl->conttype, &mb); + if (err) + goto leave; + + /* Just for testing. */ + append_tuple (&mb, KEYBLOB_TAG_FILLER, "filler", 6); + + *r_blob = get_membuf (&mb, r_bloblen); + if (!*r_blob) + { + err = gpg_error_from_syserror (); + *r_bloblen = 0; + } + else + log_debug ("used keyblob size is %zu\n", *r_bloblen); + + leave: + xfree (get_membuf (&mb, NULL)); + return err; +} + + + +/* Encrypt the keyblob (KEYBLOB,KEYBLOBLEN) and store the result at + (R_ENCBLOB, R_ENCBLOBLEN). Returns 0 on success or an error code. + On error R_EKYBLOB is set to NULL. Depending on the keys set in + CTRL the result is a single OpenPGP binary message, a single + special OpenPGP packet encapsulating a CMS message or a + concatenation of both with the CMS packet being the last. */ +gpg_error_t +g13_encrypt_keyblob (ctrl_t ctrl, void *keyblob, size_t keybloblen, + void **r_encblob, size_t *r_encbloblen) +{ + gpg_error_t err; + + /* FIXME: For now we only implement OpenPGP. */ + err = gpg_encrypt_blob (ctrl, opt.gpg_program, opt.gpg_arguments, + keyblob, keybloblen, + ctrl->recipients, + r_encblob, r_encbloblen); + + return err; +} + + +/* Write a new file under the name FILENAME with the keyblob and an + appropriate header. This function is called with a lock file in + place and after checking that the filename does not exists. */ +static gpg_error_t +write_keyblob (const char *filename, + const void *keyblob, size_t keybloblen) +{ + gpg_error_t err; + estream_t fp; + unsigned char packet[32]; + size_t headerlen, paddinglen; + + fp = es_fopen (filename, "wbx"); + if (!fp) + { + err = gpg_error_from_syserror (); + log_error ("error creating new container '%s': %s\n", + filename, gpg_strerror (err)); + return err; + } + + /* Allow for an least 8 times larger keyblob to accommodate for + future key changes. Round it up to 4096 byte. */ + headerlen = ((32 + 8 * keybloblen + 16) + 4095) / 4096 * 4096; + paddinglen = headerlen - 32 - keybloblen; + assert (paddinglen >= 16); + + packet[0] = (0xc0|61); /* CTB for the private packet type 0x61. */ + packet[1] = 0xff; /* 5 byte length packet, value 20. */ + packet[2] = 0; + packet[3] = 0; + packet[4] = 0; + packet[5] = 26; + memcpy (packet+6, "GnuPG/G13", 10); /* Packet subtype. */ + packet[16] = 1; /* G13 packet format version. */ + packet[17] = 0; /* Reserved. */ + packet[18] = 0; /* Reserved. */ + packet[19] = 0; /* OS Flag. */ + packet[20] = (headerlen >> 24); /* Total length of header. */ + packet[21] = (headerlen >> 16); + packet[22] = (headerlen >> 8); + packet[23] = (headerlen); + packet[24] = 1; /* Number of header copies. */ + packet[25] = 0; /* Number of header copies at the end. */ + packet[26] = 0; /* Reserved. */ + packet[27] = 0; /* Reserved. */ + packet[28] = 0; /* Reserved. */ + packet[29] = 0; /* Reserved. */ + packet[30] = 0; /* Reserved. */ + packet[31] = 0; /* Reserved. */ + + if (es_fwrite (packet, 32, 1, fp) != 1) + goto writeerr; + + if (es_fwrite (keyblob, keybloblen, 1, fp) != 1) + goto writeerr; + + /* Write the padding. */ + packet[0] = (0xc0|61); /* CTB for Private packet type 0x61. */ + packet[1] = 0xff; /* 5 byte length packet, value 20. */ + packet[2] = (paddinglen-6) >> 24; + packet[3] = (paddinglen-6) >> 16; + packet[4] = (paddinglen-6) >> 8; + packet[5] = (paddinglen-6); + memcpy (packet+6, "GnuPG/PAD", 10); /* Packet subtype. */ + if (es_fwrite (packet, 16, 1, fp) != 1) + goto writeerr; + memset (packet, 0, 32); + for (paddinglen-=16; paddinglen >= 32; paddinglen -= 32) + if (es_fwrite (packet, 32, 1, fp) != 1) + goto writeerr; + if (paddinglen) + if (es_fwrite (packet, paddinglen, 1, fp) != 1) + goto writeerr; + + if (es_fclose (fp)) + { + err = gpg_error_from_syserror (); + log_error ("error closing '%s': %s\n", + filename, gpg_strerror (err)); + remove (filename); + return err; + } + + return 0; + + + writeerr: + err = gpg_error_from_syserror (); + log_error ("error writing header to '%s': %s\n", + filename, gpg_strerror (err)); + es_fclose (fp); + remove (filename); + return err; +} + + + +/* Create a new container under the name FILENAME and initialize it + using the current settings. If the file already exists an error is + returned. */ +gpg_error_t +g13_create_container (ctrl_t ctrl, const char *filename) +{ + gpg_error_t err; + dotlock_t lock; + void *keyblob = NULL; + size_t keybloblen; + void *enckeyblob = NULL; + size_t enckeybloblen; + char *detachedname = NULL; + int detachedisdir; + tupledesc_t tuples = NULL; + unsigned int dummy_rid; + + if (!ctrl->recipients) + return gpg_error (GPG_ERR_NO_PUBKEY); + + err = be_take_lock_for_create (ctrl, filename, &lock); + if (err) + goto leave; + + /* And a possible detached file or directory may not exist either. */ + err = be_get_detached_name (ctrl->conttype, filename, + &detachedname, &detachedisdir); + if (err) + goto leave; + if (detachedname) + { + struct stat sb; + + if (!gnupg_stat (detachedname, &sb)) + { + err = gpg_error (GPG_ERR_EEXIST); + goto leave; + } + } + + if (ctrl->conttype != CONTTYPE_DM_CRYPT) + { + /* Create a new keyblob. */ + err = create_new_keyblob (ctrl, !!detachedname, &keyblob, &keybloblen); + if (err) + goto leave; + + /* Encrypt that keyblob. */ + err = g13_encrypt_keyblob (ctrl, keyblob, keybloblen, + &enckeyblob, &enckeybloblen); + if (err) + goto leave; + + /* Put a copy of the keyblob into a tuple structure. */ + err = create_tupledesc (&tuples, keyblob, keybloblen); + if (err) + goto leave; + keyblob = NULL; + /* if (opt.verbose) */ + /* dump_keyblob (tuples); */ + + /* Write out the header, the encrypted keyblob and some padding. */ + err = write_keyblob (filename, enckeyblob, enckeybloblen); + if (err) + goto leave; + } + + /* Create and append the container. FIXME: We should pass the + estream object in addition to the filename, so that the backend + can append the container to the g13 file. */ + err = be_create_container (ctrl, ctrl->conttype, filename, -1, tuples, + &dummy_rid); + + + leave: + destroy_tupledesc (tuples); + xfree (detachedname); + xfree (enckeyblob); + xfree (keyblob); + dotlock_destroy (lock); + + return err; +} diff --git a/g13/create.h b/g13/create.h new file mode 100644 index 0000000..ccb954a --- /dev/null +++ b/g13/create.h @@ -0,0 +1,29 @@ +/* create.h - Defs to create a new crypto container + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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 . + */ + +#ifndef G13_CREATE_H +#define G13_CREATE_H + +gpg_error_t g13_encrypt_keyblob (ctrl_t ctrl, + void *keyblob, size_t keybloblen, + void **r_encblob, size_t *r_encbloblen); +gpg_error_t g13_create_container (ctrl_t ctrl, const char *filename); + + +#endif /*G13_CREATE_H*/ diff --git a/g13/g13-common.c b/g13/g13-common.c new file mode 100644 index 0000000..35cb131 --- /dev/null +++ b/g13/g13-common.c @@ -0,0 +1,86 @@ +/* g13-common.c - Common code for G13 modules + * Copyright (C) 2009, 2015 Werner Koch + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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 . + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include "g13-common.h" +#include +#include +#include "../common/i18n.h" +#include "../common/sysutils.h" + + + +/* Global variable to keep an error count. */ +int g13_errors_seen = 0; + + + +/* Note: This function is used by signal handlers!. */ +static void +emergency_cleanup (void) +{ + gcry_control (GCRYCTL_TERM_SECMEM); +} + + +/* Wrapper around gnupg_init_signals. */ +void +g13_init_signals (void) +{ + gnupg_init_signals (0, emergency_cleanup); +} + + +/* Install a regular exit handler to make real sure that the secure + memory gets wiped out. */ +void +g13_install_emergency_cleanup (void) +{ + if (atexit (emergency_cleanup)) + { + log_error ("atexit failed\n"); + g13_exit (2); + } +} + + +/* Use this function instead of exit() in all g13 modules. */ +void +g13_exit (int rc) +{ + gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE); + if (opt.debug & DBG_MEMSTAT_VALUE) + { + gcry_control( GCRYCTL_DUMP_MEMORY_STATS ); + gcry_control( GCRYCTL_DUMP_RANDOM_STATS ); + } + if (opt.debug) + gcry_control (GCRYCTL_DUMP_SECMEM_STATS ); + emergency_cleanup (); + rc = rc? rc : log_get_errorcount(0)? 2 : g13_errors_seen? 1 : 0; + exit (rc); +} diff --git a/g13/g13-common.h b/g13/g13-common.h new file mode 100644 index 0000000..42b8dee --- /dev/null +++ b/g13/g13-common.h @@ -0,0 +1,96 @@ +/* g13.h - Global definitions for G13. + * Copyright (C) 2009 Free Software Foundation, Inc. + * Copyright (C) 2009, 2015 Werner Koch. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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 . + */ + +#ifndef G13_COMMON_H +#define G13_COMMON_H + +#ifdef GPG_ERR_SOURCE_DEFAULT +#error GPG_ERR_SOURCE_DEFAULT already defined +#endif +#define GPG_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_G13 +#include + +#include "../common/util.h" +#include "../common/status.h" +#include "../common/session-env.h" +#include "../common/strlist.h" + +/* Debug values and macros. */ +#define DBG_MOUNT_VALUE 1 /* Debug mount or device stuff. */ +#define DBG_CRYPTO_VALUE 4 /* Debug low level crypto. */ +#define DBG_MEMORY_VALUE 32 /* Debug memory allocation stuff. */ +#define DBG_MEMSTAT_VALUE 128 /* Show memory statistics. */ +#define DBG_IPC_VALUE 1024 /* Debug assuan communication. */ + +#define DBG_MOUNT (opt.debug & DBG_MOUNT_VALUE) +#define DBG_CRYPTO (opt.debug & DBG_CRYPTO_VALUE) +#define DBG_MEMORY (opt.debug & DBG_MEMORY_VALUE) +#define DBG_IPC (opt.debug & DBG_IPC_VALUE) + +/* A large struct named "opt" to keep global flags. Note that this + struct is used by g13 and g13-syshelp and thus some fields may only + make sense for one of them. */ +EXTERN_UNLESS_MAIN_MODULE +struct +{ + unsigned int debug; /* Debug flags (DBG_foo_VALUE). */ + int verbose; /* Verbosity level. */ + int quiet; /* Be as quiet as possible. */ + int dry_run; /* Don't change any persistent data. */ + + const char *config_filename; /* Name of the used config file. */ + + /* Filename of the AGENT program. */ + const char *agent_program; + + /* Filename of the GPG program. Unless set via an program option it + is initialized at the first engine startup to the standard gpg + filename. */ + const char *gpg_program; + + /* GPG arguments. XXX: Currently it is not possible to set them. */ + strlist_t gpg_arguments; + + /* Environment variables passed along to the engine. */ + char *display; + char *ttyname; + char *ttytype; + char *lc_ctype; + char *lc_messages; + char *xauthority; + char *pinentry_user_data; + session_env_t session_env; + + /* Name of the output file - FIXME: what is this? */ + const char *outfile; + +} opt; + + +/*-- g13-common.c --*/ +void g13_init_signals (void); +void g13_install_emergency_cleanup (void); +void g13_exit (int rc); + +/*-- server.c and g13-sh-cmd.c --*/ +gpg_error_t g13_status (ctrl_t ctrl, int no, ...) GPGRT_ATTR_SENTINEL(0); + + +#endif /*G13_COMMON_H*/ diff --git a/g13/g13-syshelp.c b/g13/g13-syshelp.c new file mode 100644 index 0000000..65d5c25 --- /dev/null +++ b/g13/g13-syshelp.c @@ -0,0 +1,740 @@ +/* g13-syshelp.c - Helper for disk key management with GnuPG + * Copyright (C) 2015 Werner Koch + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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 . + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_PWD_H +# include +#endif +#include + +#define INCLUDED_BY_MAIN_MODULE 1 +#include "g13-syshelp.h" + +#include +#include + +#include "../common/i18n.h" +#include "../common/sysutils.h" +#include "../common/asshelp.h" +#include "../common/init.h" +#include "keyblob.h" + + +enum cmd_and_opt_values { + aNull = 0, + oQuiet = 'q', + oVerbose = 'v', + oRecipient = 'r', + + aGPGConfList = 500, + + oDebug, + oDebugLevel, + oDebugAll, + oDebugNone, + oDebugWait, + oDebugAllowCoreDump, + oLogFile, + oNoLogFile, + oAuditLog, + + oOutput, + + oAgentProgram, + oGpgProgram, + oType, + + oDisplay, + oTTYname, + oTTYtype, + oLCctype, + oLCmessages, + oXauthority, + + oStatusFD, + oLoggerFD, + + oNoVerbose, + oNoSecmemWarn, + oHomedir, + oDryRun, + oNoDetach, + + oNoRandomSeedFile, + oFakedSystemTime + }; + + +static ARGPARSE_OPTS opts[] = { + + ARGPARSE_s_n (oDryRun, "dry-run", N_("do not make any changes")), + + ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")), + ARGPARSE_s_n (oQuiet, "quiet", N_("be somewhat more quiet")), + + ARGPARSE_s_s (oDebug, "debug", "@"), + ARGPARSE_s_s (oDebugLevel, "debug-level", + N_("|LEVEL|set the debugging level to LEVEL")), + ARGPARSE_s_n (oDebugAll, "debug-all", "@"), + ARGPARSE_s_n (oDebugNone, "debug-none", "@"), + ARGPARSE_s_i (oDebugWait, "debug-wait", "@"), + ARGPARSE_s_n (oDebugAllowCoreDump, "debug-allow-core-dump", "@"), + + ARGPARSE_end () +}; + + +/* The list of supported debug flags. */ +static struct debug_flags_s debug_flags [] = + { + { DBG_MOUNT_VALUE , "mount" }, + { DBG_CRYPTO_VALUE , "crypto" }, + { DBG_MEMORY_VALUE , "memory" }, + { DBG_MEMSTAT_VALUE, "memstat" }, + { DBG_IPC_VALUE , "ipc" }, + { 0, NULL } + }; + + +/* The timer tick interval used by the idle task. */ +#define TIMERTICK_INTERVAL_SEC (1) + +/* It is possible that we are currently running under setuid permissions. */ +static int maybe_setuid = 1; + +/* Helper to implement --debug-level and --debug. */ +static const char *debug_level; +static unsigned int debug_value; + + +/* Local prototypes. */ +static void g13_syshelp_deinit_default_ctrl (ctrl_t ctrl); +static void release_tab_items (tab_item_t tab); +static tab_item_t parse_g13tab (const char *username); + + + +static const char * +my_strusage( int level ) +{ + const char *p; + + switch (level) + { + case 9: p = "GPL-3.0-or-later"; break; + case 11: p = "@G13@-syshelp (@GNUPG@)"; + break; + case 13: p = VERSION; break; + case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break; + case 17: p = PRINTABLE_OS_NAME; break; + case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); + break; + case 1: + case 40: p = _("Usage: @G13@-syshelp [options] [files] (-h for help)"); + break; + case 41: + p = _("Syntax: @G13@-syshelp [options] [files]\n" + "Helper to perform root-only tasks for g13\n"); + break; + + case 31: p = "\nHome: "; break; + case 32: p = gnupg_homedir (); break; + + default: p = NULL; break; + } + return p; +} + + +/* Setup the debugging. With a DEBUG_LEVEL of NULL only the active + debug flags are propagated to the subsystems. With DEBUG_LEVEL + set, a specific set of debug flags is set; and individual debugging + flags will be added on top. */ +static void +set_debug (void) +{ + int numok = (debug_level && digitp (debug_level)); + int numlvl = numok? atoi (debug_level) : 0; + + if (!debug_level) + ; + else if (!strcmp (debug_level, "none") || (numok && numlvl < 1)) + opt.debug = 0; + else if (!strcmp (debug_level, "basic") || (numok && numlvl <= 2)) + opt.debug = DBG_IPC_VALUE|DBG_MOUNT_VALUE; + else if (!strcmp (debug_level, "advanced") || (numok && numlvl <= 5)) + opt.debug = DBG_IPC_VALUE|DBG_MOUNT_VALUE; + else if (!strcmp (debug_level, "expert") || (numok && numlvl <= 8)) + opt.debug = (DBG_IPC_VALUE|DBG_MOUNT_VALUE|DBG_CRYPTO_VALUE); + else if (!strcmp (debug_level, "guru") || numok) + { + opt.debug = ~0; + /* if (numok) */ + /* opt.debug &= ~(DBG_HASHING_VALUE); */ + } + else + { + log_error (_("invalid debug-level '%s' given\n"), debug_level); + g13_exit(2); + } + + opt.debug |= debug_value; + + if (opt.debug && !opt.verbose) + opt.verbose = 1; + if (opt.debug) + opt.quiet = 0; + + if (opt.debug & DBG_CRYPTO_VALUE ) + gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1); + gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose); + + if (opt.debug) + parse_debug_flag (NULL, &opt.debug, debug_flags); +} + + +int +main ( int argc, char **argv) +{ + ARGPARSE_ARGS pargs; + int orig_argc; + char **orig_argv; + gpg_error_t err = 0; + /* const char *fname; */ + int may_coredump; + char *last_configname = NULL; + const char *configname = NULL; + int debug_argparser = 0; + int no_more_options = 0; + char *logfile = NULL; + /* int debug_wait = 0; */ + int use_random_seed = 1; + /* int nodetach = 0; */ + /* int nokeysetup = 0; */ + struct server_control_s ctrl; + + /*mtrace();*/ + + early_system_init (); + gnupg_reopen_std (G13_NAME "-syshelp"); + set_strusage (my_strusage); + gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); + + log_set_prefix (G13_NAME "-syshelp", GPGRT_LOG_WITH_PREFIX); + + /* Make sure that our subsystems are ready. */ + i18n_init (); + init_common_subsystems (&argc, &argv); + + /* Take extra care of the random pool. */ + gcry_control (GCRYCTL_USE_SECURE_RNDPOOL); + + may_coredump = disable_core_dumps (); + + g13_init_signals (); + + dotlock_create (NULL, 0); /* Register locking cleanup. */ + + opt.session_env = session_env_new (); + if (!opt.session_env) + log_fatal ("error allocating session environment block: %s\n", + strerror (errno)); + + /* First check whether we have a debug option on the commandline. */ + orig_argc = argc; + orig_argv = argv; + pargs.argc = &argc; + pargs.argv = &argv; + pargs.flags= (ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION); + while (gnupg_argparse (NULL, &pargs, opts)) + { + switch (pargs.r_opt) + { + case oDebug: + case oDebugAll: + debug_argparser++; + break; + } + } + /* Reset the flags. */ + pargs.flags &= ~(ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION); + + /* Initialize the secure memory. */ + gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); + maybe_setuid = 0; + + /* + * Now we are now working under our real uid + */ + + /* Setup malloc hooks. */ + { + struct assuan_malloc_hooks malloc_hooks; + + malloc_hooks.malloc = gcry_malloc; + malloc_hooks.realloc = gcry_realloc; + malloc_hooks.free = gcry_free; + assuan_set_malloc_hooks (&malloc_hooks); + } + + /* Prepare libassuan. */ + assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); + /*assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH);*/ + setup_libassuan_logging (&opt.debug, NULL); + + /* Setup a default control structure for command line mode. */ + memset (&ctrl, 0, sizeof ctrl); + g13_syshelp_init_default_ctrl (&ctrl); + ctrl.no_server = 1; + ctrl.status_fd = -1; /* No status output. */ + + /* The configuraton directories for use by gpgrt_argparser. */ + gnupg_set_confdir (GNUPG_CONFDIR_SYS, gnupg_sysconfdir ()); + gnupg_set_confdir (GNUPG_CONFDIR_USER, gnupg_homedir ()); + + argc = orig_argc; + argv = orig_argv; + pargs.argc = &argc; + pargs.argv = &argv; + pargs.flags |= (ARGPARSE_FLAG_RESET + | ARGPARSE_FLAG_KEEP + | ARGPARSE_FLAG_SYS + | ARGPARSE_FLAG_USER); + + while (!no_more_options + && gnupg_argparser (&pargs, opts, G13_NAME"-syshelp" EXTSEP_S "conf")) + { + switch (pargs.r_opt) + { + case ARGPARSE_CONFFILE: + { + if (debug_argparser) + log_info (_("reading options from '%s'\n"), + pargs.r_type? pargs.r.ret_str: "[cmdline]"); + if (pargs.r_type) + { + xfree (last_configname); + last_configname = xstrdup (pargs.r.ret_str); + configname = last_configname; + } + else + configname = NULL; + } + break; + + case oQuiet: opt.quiet = 1; break; + + case oDryRun: opt.dry_run = 1; break; + + case oVerbose: + opt.verbose++; + gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose); + break; + case oNoVerbose: + opt.verbose = 0; + gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose); + break; + + case oLogFile: logfile = pargs.r.ret_str; break; + case oNoLogFile: logfile = NULL; break; + + case oNoDetach: /*nodetach = 1; */break; + + case oDebug: + if (parse_debug_flag (pargs.r.ret_str, &opt.debug, debug_flags)) + { + pargs.r_opt = ARGPARSE_INVALID_ARG; + pargs.err = ARGPARSE_PRINT_ERROR; + } + break; + case oDebugAll: debug_value = ~0; break; + case oDebugNone: debug_value = 0; break; + case oDebugLevel: debug_level = pargs.r.ret_str; break; + case oDebugWait: /*debug_wait = pargs.r.ret_int; */break; + case oDebugAllowCoreDump: + may_coredump = enable_core_dumps (); + break; + + case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break; + case oLoggerFD: log_set_fd (pargs.r.ret_int ); break; + + case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break; + + case oFakedSystemTime: + { + time_t faked_time = isotime2epoch (pargs.r.ret_str); + if (faked_time == (time_t)(-1)) + faked_time = (time_t)strtoul (pargs.r.ret_str, NULL, 10); + gnupg_set_time (faked_time, 0); + } + break; + + case oNoSecmemWarn: gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); break; + + case oNoRandomSeedFile: use_random_seed = 0; break; + + default: + pargs.err = configname? ARGPARSE_PRINT_WARNING:ARGPARSE_PRINT_ERROR; + break; + } + } + gnupg_argparse (NULL, &pargs, NULL); /* Release internal state. */ + + if (!last_configname) + opt.config_filename = make_filename (gnupg_homedir (), + G13_NAME"-syshelp" EXTSEP_S "conf", + NULL); + else + { + opt.config_filename = last_configname; + last_configname = NULL; + } + + if (log_get_errorcount(0)) + g13_exit(2); + + /* Now that we have the options parsed we need to update the default + control structure. */ + g13_syshelp_init_default_ctrl (&ctrl); + + if (may_coredump && !opt.quiet) + log_info (_("WARNING: program may create a core file!\n")); + + if (logfile) + { + log_set_file (logfile); + log_set_prefix (NULL, GPGRT_LOG_WITH_PREFIX | GPGRT_LOG_WITH_TIME | GPGRT_LOG_WITH_PID); + } + + if (gnupg_faked_time_p ()) + { + gnupg_isotime_t tbuf; + + log_info (_("WARNING: running with faked system time: ")); + gnupg_get_isotime (tbuf); + dump_isotime (tbuf); + log_printf ("\n"); + } + + /* Print any pending secure memory warnings. */ + gcry_control (GCRYCTL_RESUME_SECMEM_WARN); + + /* Setup the debug flags for all subsystems. */ + set_debug (); + + /* Install a regular exit handler to make real sure that the secure + memory gets wiped out. */ + g13_install_emergency_cleanup (); + + /* Terminate if we found any error until now. */ + if (log_get_errorcount(0)) + g13_exit (2); + + /* Set the standard GnuPG random seed file. */ + if (use_random_seed) + { + char *p = make_filename (gnupg_homedir (), "random_seed", NULL); + gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p); + xfree(p); + } + + /* Get the UID of the caller. */ +#if defined(HAVE_PWD_H) && defined(HAVE_GETPWUID) + { + const char *uidstr; + struct passwd *pwd = NULL; + + uidstr = getenv ("USERV_UID"); + + /* Print a quick note if we are not started via userv. */ + if (!uidstr) + { + if (getuid ()) + { + log_info ("WARNING: Not started via userv\n"); + ctrl.fail_all_cmds = 1; + } + ctrl.client.uid = getuid (); + } + else + { + unsigned long myuid; + + errno = 0; + myuid = strtoul (uidstr, NULL, 10); + if (myuid == ULONG_MAX && errno) + { + log_info ("WARNING: Started via broken userv: %s\n", + strerror (errno)); + ctrl.fail_all_cmds = 1; + ctrl.client.uid = getuid (); + } + else + ctrl.client.uid = (uid_t)myuid; + } + + pwd = getpwuid (ctrl.client.uid); + if (!pwd || !*pwd->pw_name) + { + log_info ("WARNING: Name for UID not found: %s\n", strerror (errno)); + ctrl.fail_all_cmds = 1; + ctrl.client.uname = xstrdup ("?"); + } + else + ctrl.client.uname = xstrdup (pwd->pw_name); + + /* Check that the user name does not contain a directory + separator. */ + if (strchr (ctrl.client.uname, '/')) + { + log_info ("WARNING: Invalid user name passed\n"); + ctrl.fail_all_cmds = 1; + } + } +#else /*!HAVE_PWD_H || !HAVE_GETPWUID*/ + log_info ("WARNING: System does not support required syscalls\n"); + ctrl.fail_all_cmds = 1; + ctrl.client.uid = getuid (); + ctrl.client.uname = xstrdup ("?"); +#endif /*!HAVE_PWD_H || !HAVE_GETPWUID*/ + + /* Read the table entries for this user. */ + if (!ctrl.fail_all_cmds + && !(ctrl.client.tab = parse_g13tab (ctrl.client.uname))) + ctrl.fail_all_cmds = 1; + + /* Start the server. */ + err = syshelp_server (&ctrl); + if (err) + log_error ("server exited with error: %s <%s>\n", + gpg_strerror (err), gpg_strsource (err)); + + /* Cleanup. */ + g13_syshelp_deinit_default_ctrl (&ctrl); + g13_exit (0); + return 8; /*NOTREACHED*/ +} + + +/* Store defaults into the per-connection CTRL object. */ +void +g13_syshelp_init_default_ctrl (ctrl_t ctrl) +{ + ctrl->conttype = CONTTYPE_DM_CRYPT; +} + +/* Release all resources allocated by default in the CTRl object. */ +static void +g13_syshelp_deinit_default_ctrl (ctrl_t ctrl) +{ + xfree (ctrl->client.uname); + release_tab_items (ctrl->client.tab); +} + + +/* Release the list of g13tab itejms at TAB. */ +static void +release_tab_items (tab_item_t tab) +{ + while (tab) + { + tab_item_t next = tab->next; + xfree (tab->mountpoint); + xfree (tab); + tab = next; + } +} + + +void +g13_syshelp_i_know_what_i_am_doing (void) +{ + const char * const yesfile = "Yes-g13-I-know-what-I-am-doing"; + char *fname; + + fname = make_filename (gnupg_sysconfdir (), yesfile, NULL); + if (gnupg_access (fname, F_OK)) + { + log_info ("*******************************************************\n"); + log_info ("* The G13 support for DM-Crypt is new and not matured.\n"); + log_info ("* Bugs or improper use may delete all your disks!\n"); + log_info ("* To confirm that you are ware of this risk, create\n"); + log_info ("* the file '%s'.\n", fname); + log_info ("*******************************************************\n"); + exit (1); + } + xfree (fname); +} + + +/* Parse the /etc/gnupg/g13tab for user USERNAME. Return a table for + the user on success. Return NULL on error and print + diagnostics. */ +static tab_item_t +parse_g13tab (const char *username) +{ + gpg_error_t err; + int c, n; + char line[512]; + char *p; + char *fname; + estream_t fp; + int lnr; + char **words = NULL; + tab_item_t table = NULL; + tab_item_t *tabletail, ti; + + fname = make_filename (gnupg_sysconfdir (), G13_NAME"tab", NULL); + fp = es_fopen (fname, "r"); + if (!fp) + { + err = gpg_error_from_syserror (); + log_error (_("error opening '%s': %s\n"), fname, gpg_strerror (err)); + goto leave; + } + + tabletail = &table; + err = 0; + lnr = 0; + while (es_fgets (line, DIM(line)-1, fp)) + { + lnr++; + n = strlen (line); + if (!n || line[n-1] != '\n') + { + /* Eat until end of line. */ + while ((c=es_getc (fp)) != EOF && c != '\n') + ; + err = gpg_error (*line? GPG_ERR_LINE_TOO_LONG + : GPG_ERR_INCOMPLETE_LINE); + log_error (_("file '%s', line %d: %s\n"), + fname, lnr, gpg_strerror (err)); + continue; + } + line[--n] = 0; /* Chop the LF. */ + if (n && line[n-1] == '\r') + line[--n] = 0; /* Chop an optional CR. */ + + /* Allow for empty lines and spaces */ + for (p=line; spacep (p); p++) + ; + if (!*p || *p == '#') + continue; + + /* Parse the line. The format is + * [