aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2021-02-09 18:41:43 +0100
committerWerner Koch <wk@gnupg.org>2021-02-09 18:42:25 +0100
commit209b7113f3493bd829ec5c90275ff95a273d9dd4 (patch)
treed10fabdb0133451bd989def4ee5c11b3e7143b41
parent390f597868a5b5934f21f81ebf6ff110b6792283 (diff)
downloadgnupg-209b7113f3493bd829ec5c90275ff95a273d9dd4.tar.gz
tools: Remove the symcryptrun tool.
* tools/symcryptrun.c: Remove. * tools/Makefile.am: Ditto. * doc/tools.texi: Remove man page. * configure.ac: Remove build option and tests used only by this tool. * Makefile.am (AM_DISTCHECK_CONFIGURE_FLAGS): Do not build symcryptrun. -- symcryptrun is too ancient to be of any use and has not been tested in many years. Thus we should not distribute it anymore.
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac22
-rw-r--r--doc/Makefile.am2
-rw-r--r--doc/tools.texi123
-rw-r--r--po/POTFILES.in1
-rw-r--r--tools/Makefile.am13
-rw-r--r--tools/symcryptrun.c1019
7 files changed, 3 insertions, 1179 deletions
diff --git a/Makefile.am b/Makefile.am
index 064ea88ef..9daeccc6f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -30,7 +30,7 @@ RELEASE_ARCHIVE_SUFFIX = gnupg/v2.3
# Autoconf flags.
ACLOCAL_AMFLAGS = -I m4
AM_DISTCHECK_CONFIGURE_FLAGS = --enable-gnupg-builddir-envvar \
- --enable-all-tests --enable-symcryptrun --enable-g13 \
+ --enable-all-tests --enable-g13 \
--enable-gpgtar --enable-wks-tools --disable-ntbtls
GITLOG_TO_CHANGELOG=gitlog-to-changelog
diff --git a/configure.ac b/configure.ac
index ea64ce19a..171847a33 100644
--- a/configure.ac
+++ b/configure.ac
@@ -126,7 +126,6 @@ GNUPG_BUILD_PROGRAM(g13, no)
GNUPG_BUILD_PROGRAM(dirmngr, yes)
GNUPG_BUILD_PROGRAM(keyboxd, yes)
GNUPG_BUILD_PROGRAM(doc, yes)
-GNUPG_BUILD_PROGRAM(symcryptrun, no)
# We use gpgtar to unpack test data, hence we always build it. If the
# user opts out, we simply don't install it.
GNUPG_BUILD_PROGRAM(gpgtar, yes)
@@ -982,26 +981,6 @@ AC_DEFINE_UNQUOTED(FUSERMOUNT,
"${FUSERMOUNT}", [defines the filename of the fusermount program])
-# Checks for dirmngr
-
-
-#
-# Checks for symcryptrun:
-#
-
-# libutil has openpty() and login_tty().
-AC_CHECK_LIB(util, openpty,
- [ LIBUTIL_LIBS="$LIBUTIL_LIBS -lutil"
- AC_DEFINE(HAVE_LIBUTIL,1,
- [defined if libutil is available])
- ])
-AC_SUBST(LIBUTIL_LIBS)
-
-# shred is used to clean temporary plain text files.
-AC_PATH_PROG(SHRED, shred, /usr/bin/shred)
-AC_DEFINE_UNQUOTED(SHRED,
- "${SHRED}", [defines the filename of the shred program])
-
#
# Check whether the nPth library is available
@@ -1798,7 +1777,6 @@ AM_CONDITIONAL(BUILD_G13, test "$build_g13" = "yes")
AM_CONDITIONAL(BUILD_DIRMNGR, test "$build_dirmngr" = "yes")
AM_CONDITIONAL(BUILD_KEYBOXD, test "$build_keyboxd" = "yes")
AM_CONDITIONAL(BUILD_DOC, test "$build_doc" = "yes")
-AM_CONDITIONAL(BUILD_SYMCRYPTRUN, test "$build_symcryptrun" = "yes")
AM_CONDITIONAL(BUILD_GPGTAR, test "$build_gpgtar" = "yes")
AM_CONDITIONAL(BUILD_WKS_TOOLS, test "$build_wks_tools" = "yes")
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 1ad86e5b7..cf5563142 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -96,7 +96,7 @@ myman_sources = gnupg7.texi gpg.texi gpgsm.texi gpg-agent.texi \
gpg-card.texi
myman_pages = gpgsm.1 gpg-agent.1 dirmngr.8 scdaemon.1 \
watchgnupg.1 gpgconf.1 addgnupghome.8 gpg-preset-passphrase.1 \
- gpg-connect-agent.1 gpgparsemail.1 symcryptrun.1 gpgtar.1 \
+ gpg-connect-agent.1 gpgparsemail.1 gpgtar.1 \
applygnupgdefaults.8 gpg-wks-client.1 gpg-wks-server.1 \
dirmngr-client.1 gpg-card.1 gpg-check-pattern.1
if USE_GPG2_HACK
diff --git a/doc/tools.texi b/doc/tools.texi
index 8eb77401e..c48ba4b4a 100644
--- a/doc/tools.texi
+++ b/doc/tools.texi
@@ -19,7 +19,6 @@ GnuPG comes with a couple of smaller tools:
* gpg-connect-agent:: Communicate with a running agent.
* dirmngr-client:: How to use the Dirmngr client tool.
* gpgparsemail:: Parse a mail message into an annotated format
-* symcryptrun:: Call a simple symmetric encryption tool.
* gpgtar:: Encrypt or sign files into an archive.
* gpg-check-pattern:: Check a passphrase on stdin against the patternfile.
@end menu
@@ -1842,128 +1841,6 @@ The @command{gpgparsemail} is a utility currently only useful for
debugging. Run it with @code{--help} for usage information.
-
-@c
-@c SYMCRYPTRUN
-@c
-@node symcryptrun
-@section Call a simple symmetric encryption tool
-@manpage symcryptrun.1
-@ifset manverb
-.B symcryptrun
-\- Call a simple symmetric encryption tool
-@end ifset
-
-@mansect synopsis
-@ifset manverb
-.B symcryptrun
-.B \-\-class
-.I class
-.B \-\-program
-.I program
-.B \-\-keyfile
-.I keyfile
-.RB [ --decrypt | --encrypt ]
-.RI [ inputfile ]
-@end ifset
-
-@mansect description
-Sometimes simple encryption tools are already in use for a long time
-and there might be a desire to integrate them into the GnuPG
-framework. The protocols and encryption methods might be non-standard
-or not even properly documented, so that a full-fledged encryption
-tool with an interface like @command{gpg} is not doable.
-@command{symcryptrun} provides a solution: It operates by calling the
-external encryption/decryption module and provides a passphrase for a
-key using the standard @command{pinentry} based mechanism through
-@command{gpg-agent}.
-
-Note, that @command{symcryptrun} is only available if GnuPG has been
-configured with @samp{--enable-symcryptrun} at build time.
-
-@menu
-* Invoking symcryptrun:: List of all commands and options.
-@end menu
-
-@manpause
-@node Invoking symcryptrun
-@subsection List of all commands and options
-
-@noindent
-@command{symcryptrun} is invoked this way:
-
-@example
-symcryptrun --class CLASS --program PROGRAM --keyfile KEYFILE
- [--decrypt | --encrypt] [inputfile]
-@end example
-@mancont
-
-For encryption, the plain text must be provided on STDIN or as the
-argument @var{inputfile}, and the ciphertext will be output to STDOUT.
-For decryption vice versa.
-
-@var{CLASS} describes the calling conventions of the external tool.
-Currently it must be given as @samp{confucius}. @var{PROGRAM} is
-the full filename of that external tool.
-
-For the class @samp{confucius} the option @option{--keyfile} is
-required; @var{keyfile} is the name of a file containing the secret key,
-which may be protected by a passphrase. For detailed calling
-conventions, see the source code.
-
-@noindent
-Note, that @command{gpg-agent} must be running before starting
-@command{symcryptrun}.
-
-@noindent
-The following additional options may be used:
-
-@table @gnupgtabopt
-@item -v
-@itemx --verbose
-@opindex verbose
-Output additional information while running.
-
-@item -q
-@item --quiet
-@opindex q
-@opindex quiet
-Try to be as quiet as possible.
-
-@include opt-homedir.texi
-
-
-@item --log-file @var{file}
-@opindex log-file
-Append all logging output to @var{file}. Use @file{socket://} to log
-to socket. Default is to write logging information to STDERR.
-
-@end table
-
-@noindent
-The possible exit status codes of @command{symcryptrun} are:
-
-@table @code
-@item 0
- Success.
-@item 1
- Some error occurred.
-@item 2
- No valid passphrase was provided.
-@item 3
- The operation was canceled by the user.
-
-@end table
-
-@mansect see also
-@ifset isman
-@command{gpg}(1),
-@command{gpgsm}(1),
-@command{gpg-agent}(1),
-@end ifset
-@include see-also-note.texi
-
-
@c
@c GPGTAR
@c
diff --git a/po/POTFILES.in b/po/POTFILES.in
index a5a23398e..f299fac32 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -126,7 +126,6 @@ tools/gpg-connect-agent.c
tools/gpgconf-comp.c
tools/gpgconf.c
tools/no-libgcrypt.c
-tools/symcryptrun.c
tools/gpg-check-pattern.c
tools/gpg-card.c
tools/card-misc.c
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 81e8b43b2..4ece726b3 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -37,12 +37,6 @@ AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS) $(LIBASSUAN_CFLAGS)
sbin_SCRIPTS = addgnupghome applygnupgdefaults
-if BUILD_SYMCRYPTRUN
- symcryptrun = symcryptrun
-else
- symcryptrun =
-endif
-
if BUILD_WKS_TOOLS
gpg_wks_server = gpg-wks-server
else
@@ -51,7 +45,7 @@ endif
libexec_PROGRAMS = gpg-wks-client
-bin_PROGRAMS = gpgconf gpg-connect-agent gpg-card ${symcryptrun}
+bin_PROGRAMS = gpgconf gpg-connect-agent gpg-card
if !HAVE_W32_SYSTEM
bin_PROGRAMS += watchgnupg gpgparsemail ${gpg_wks_server} gpgsplit
else
@@ -115,11 +109,6 @@ gpgconf_w32_LDFLAGS = $(gpgconf_LDFLAGS) -Wl,-subsystem,windows
gpgparsemail_SOURCES = gpgparsemail.c rfc822parse.c rfc822parse.h
gpgparsemail_LDADD =
-symcryptrun_SOURCES = symcryptrun.c
-symcryptrun_LDADD = $(LIBUTIL_LIBS) $(common_libs) $(pwquery_libs) \
- $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) \
- $(LIBICONV) $(NETLIBS) $(W32SOCKLIBS) $(LIBASSUAN_LIBS)
-
watchgnupg_SOURCES = watchgnupg.c
watchgnupg_LDADD = $(NETLIBS)
diff --git a/tools/symcryptrun.c b/tools/symcryptrun.c
deleted file mode 100644
index 59838f6df..000000000
--- a/tools/symcryptrun.c
+++ /dev/null
@@ -1,1019 +0,0 @@
-/* symcryptrun.c - Tool to call simple symmetric encryption tools.
- * Copyright (C) 2005, 2007 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 <https://www.gnu.org/licenses/>.
- */
-
-
-/* Sometimes simple encryption tools are already in use for a long
- time and there is a desire to integrate them into the GnuPG
- framework. The protocols and encryption methods might be
- non-standard or not even properly documented, so that a
- full-fledged encryption tool with an interface like gpg is not
- doable. This simple wrapper program provides a solution: It
- operates by calling the encryption/decryption module and providing
- the passphrase for a key (or even the key directly) using the
- standard pinentry mechanism through gpg-agent. */
-
-/* This program is invoked in the following way:
-
- symcryptrun --class CLASS --program PROGRAM --keyfile KEYFILE \
- [--decrypt | --encrypt]
-
- For encryption, the plain text must be provided on STDIN, and the
- ciphertext will be output to STDOUT. For decryption vice versa.
-
- CLASS can currently only be "confucius".
-
- PROGRAM must be the path to the crypto engine.
-
- KEYFILE must contain the secret key, which may be protected by a
- passphrase. The passphrase is retrieved via the pinentry program.
-
-
- The GPG Agent _must_ be running before starting symcryptrun.
-
- The possible exit status codes:
-
- 0 Success
- 1 Some error occurred
- 2 No valid passphrase was provided
- 3 The operation was canceled by the user
-
- Other classes may be added in the future. */
-
-#define SYMC_BAD_PASSPHRASE 2
-#define SYMC_CANCELED 3
-
-
-#include <config.h>
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-#ifdef HAVE_PTY_H
-#include <pty.h>
-#else
-#ifdef HAVE_TERMIOS_H
-#include <termios.h>
-#endif
-#ifdef HAVE_UTIL_H
-#include <util.h>
-#endif
-#ifdef HAVE_LIBUTIL_H
-#include <libutil.h>
-#endif
-#endif
-
-#ifdef HAVE_UTMP_H
-#include <utmp.h>
-#endif
-#include <ctype.h>
-#ifdef HAVE_LOCALE_H
-#include <locale.h>
-#endif
-#ifdef HAVE_LANGINFO_CODESET
-#include <langinfo.h>
-#endif
-#include <gpg-error.h>
-
-#include "../common/i18n.h"
-#include "../common/util.h"
-#include "../common/init.h"
-#include "../common/sysutils.h"
-
-/* FIXME: Bah. For spwq_secure_free. */
-#define SIMPLE_PWQUERY_IMPLEMENTATION 1
-#include "../common/simple-pwquery.h"
-
-
-/* From simple-gettext.c. */
-
-/* We assume to have 'unsigned long int' value with at least 32 bits. */
-#define HASHWORDBITS 32
-
-/* The so called 'hashpjw' function by P.J. Weinberger
- [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
- 1986, 1987 Bell Telephone Laboratories, Inc.] */
-
-static __inline__ ulong
-hash_string( const char *str_param )
-{
- unsigned long int hval, g;
- const char *str = str_param;
-
- hval = 0;
- while (*str != '\0')
- {
- hval <<= 4;
- hval += (unsigned long int) *str++;
- g = hval & ((unsigned long int) 0xf << (HASHWORDBITS - 4));
- if (g != 0)
- {
- hval ^= g >> (HASHWORDBITS - 8);
- hval ^= g;
- }
- }
- return hval;
-}
-
-
-/* Constants to identify the commands and options. */
-enum cmd_and_opt_values
- {
- aNull = 0,
- oQuiet = 'q',
- oVerbose = 'v',
-
- oNoVerbose = 500,
- oOptions,
- oNoOptions,
- oLogFile,
- oHomedir,
- oClass,
- oProgram,
- oKeyfile,
- oDecrypt,
- oEncrypt,
- oInput
- };
-
-
-/* The list of commands and options. */
-static gpgrt_opt_t opts[] = {
-
- ARGPARSE_group(300, N_("@\nCommands:\n ")),
-
- ARGPARSE_c(oDecrypt, "decrypt", N_("decryption modus")),
- ARGPARSE_c(oEncrypt, "encrypt", N_("encryption modus")),
-
- ARGPARSE_group(301, N_("@\nOptions:\n ")),
-
- ARGPARSE_s_s(oClass, "class", N_("tool class (confucius)")),
- ARGPARSE_s_s(oProgram, "program", N_("program filename")),
-
- ARGPARSE_s_s(oKeyfile, "keyfile", N_("secret key file (required)")),
- ARGPARSE_s_s(oInput, "inputfile", N_("input file name (default stdin)")),
- ARGPARSE_s_n(oVerbose, "verbose", N_("verbose")),
- ARGPARSE_s_n(oQuiet, "quiet", N_("quiet")),
- ARGPARSE_s_s(oLogFile, "log-file", N_("use a log file for the server")),
- ARGPARSE_conffile(oOptions, "options", N_("|FILE|read options from FILE")),
-
- /* Hidden options. */
- ARGPARSE_s_n(oNoVerbose, "no-verbose", "@"),
- ARGPARSE_s_s(oHomedir, "homedir", "@"),
- ARGPARSE_noconffile(oNoOptions, "no-options", "@"),
-
- ARGPARSE_end ()
-};
-
-
-/* We keep all global options in the structure OPT. */
-struct
-{
- int verbose; /* Verbosity level. */
- int quiet; /* Be extra quiet. */
- const char *homedir; /* Configuration directory name */
-
- char *class;
- char *program;
- char *keyfile;
- char *input;
-} opt;
-
-
-/* Print usage information and provide strings for help. */
-static const char *
-my_strusage (int level)
-{
- const char *p;
-
- switch (level)
- {
- case 9: p = "GPL-3.0-or-later"; break;
- case 11: p = "symcryptrun (@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 <@EMAIL@>.\n"); break;
-
- case 1:
- case 40: p = _("Usage: symcryptrun [options] (-h for help)");
- break;
- case 41:
- p = _("Syntax: symcryptrun --class CLASS --program PROGRAM "
- "--keyfile KEYFILE [options...] COMMAND [inputfile]\n"
- "Call a simple symmetric encryption tool\n");
- break;
- case 31: p = "\nHome: "; break;
- case 32: p = gnupg_homedir (); break;
- case 33: p = "\n"; break;
-
- default: p = NULL; break;
- }
- return p;
-}
-
-
-
-/* This is in the GNU C library in unistd.h. */
-
-#ifndef TEMP_FAILURE_RETRY
-/* Evaluate EXPRESSION, and repeat as long as it returns -1 with 'errno'
- set to EINTR. */
-
-# define TEMP_FAILURE_RETRY(expression) \
- (__extension__ \
- ({ long int __result; \
- do __result = (long int) (expression); \
- while (__result == -1L && errno == EINTR); \
- __result; }))
-#endif
-
-/* Unlink a file, and shred it if SHRED is true. */
-int
-remove_file (char *name, int shred)
-{
- if (!shred)
- return unlink (name);
- else
- {
- int status;
- pid_t pid;
-
- pid = fork ();
- if (pid == 0)
- {
- /* Child. */
-
- /* -f forces file to be writable, and -u unlinks it afterwards. */
- char *args[] = { SHRED, "-uf", name, NULL };
-
- execv (SHRED, args);
- _exit (127);
- }
- else if (pid < 0)
- {
- /* Fork failed. */
- status = -1;
- }
- else
- {
- /* Parent. */
-
- if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
- status = -1;
- }
-
- if (!WIFEXITED (status))
- {
- log_error (_("%s on %s aborted with status %i\n"),
- SHRED, name, status);
- unlink (name);
- return 1;
- }
- else if (WEXITSTATUS (status))
- {
- log_error (_("%s on %s failed with status %i\n"), SHRED, name,
- WEXITSTATUS (status));
- unlink (name);
- return 1;
- }
-
- return 0;
- }
-}
-
-
-/* Class Confucius.
-
- "Don't worry that other people don't know you;
- worry that you don't know other people." Analects--1.16. */
-
-/* Create temporary directory with mode 0700. Returns a dynamically
- allocated string with the filename of the directory. */
-static char *
-confucius_mktmpdir (void)
-{
- char *name, *p;
-
- p = getenv ("TMPDIR");
- if (!p || !*p)
- p = "/tmp";
- if (p[strlen (p) - 1] == '/')
- name = xstrconcat (p, "gpg-XXXXXX", NULL);
- else
- name = xstrconcat (p, "/", "gpg-XXXXXX", NULL);
- if (!name || !gnupg_mkdtemp (name))
- {
- log_error (_("can't create temporary directory '%s': %s\n"),
- name?name:"", strerror (errno));
- return NULL;
- }
-
- return name;
-}
-
-
-/* Buffer size for I/O operations. */
-#define CONFUCIUS_BUFSIZE 4096
-
-/* Buffer size for output lines. */
-#define CONFUCIUS_LINESIZE 4096
-
-
-/* Copy the file IN to OUT, either of which may be "-". If PLAIN is
- true, and the copying fails, and OUT is not STDOUT, then shred the
- file instead unlinking it. */
-static int
-confucius_copy_file (char *infile, char *outfile, int plain)
-{
- FILE *in;
- int in_is_stdin = 0;
- FILE *out;
- int out_is_stdout = 0;
- char data[CONFUCIUS_BUFSIZE];
- ssize_t data_len;
-
- if (infile[0] == '-' && infile[1] == '\0')
- {
- /* FIXME: Is stdin in binary mode? */
- in = stdin;
- in_is_stdin = 1;
- }
- else
- {
- in = fopen (infile, "rb");
- if (!in)
- {
- log_error (_("could not open %s for writing: %s\n"),
- infile, strerror (errno));
- return 1;
- }
- }
-
- if (outfile[0] == '-' && outfile[1] == '\0')
- {
- /* FIXME: Is stdout in binary mode? */
- out = stdout;
- out_is_stdout = 1;
- }
- else
- {
- out = fopen (outfile, "wb");
- if (!out)
- {
- log_error (_("could not open %s for writing: %s\n"),
- infile, strerror (errno));
- return 1;
- }
- }
-
- /* Now copy the data. */
- while ((data_len = fread (data, 1, sizeof (data), in)) > 0)
- {
- if (fwrite (data, 1, data_len, out) != data_len)
- {
- log_error (_("error writing to %s: %s\n"), outfile,
- strerror (errno));
- goto copy_err;
- }
- }
- if (data_len < 0 || ferror (in))
- {
- log_error (_("error reading from %s: %s\n"), infile, strerror (errno));
- goto copy_err;
- }
-
- /* Close IN if appropriate. */
- if (!in_is_stdin && fclose (in) && ferror (in))
- {
- log_error (_("error closing %s: %s\n"), infile, strerror (errno));
- goto copy_err;
- }
-
- /* Close OUT if appropriate. */
- if (!out_is_stdout && fclose (out) && ferror (out))
- {
- log_error (_("error closing %s: %s\n"), infile, strerror (errno));
- goto copy_err;
- }
-
- return 0;
-
- copy_err:
- if (!out_is_stdout)
- remove_file (outfile, plain);
-
- return 1;
-}
-
-
-/* Get a passphrase in secure storage (if possible). If AGAIN is
- true, then this is a repeated attempt. If CANCELED is not a null
- pointer, it will be set to true or false, depending on if the user
- canceled the operation or not. On error (including cancellation), a
- null pointer is returned. The passphrase must be deallocated with
- confucius_drop_pass. CACHEID is the ID to be used for passphrase
- caching and can be NULL to disable caching. */
-char *
-confucius_get_pass (const char *cacheid, int again, int *canceled)
-{
- int err;
- char *pw;
- char *orig_codeset;
-
- if (canceled)
- *canceled = 0;
-
- orig_codeset = i18n_switchto_utf8 ();
- pw = simple_pwquery (cacheid,
- again ? _("does not match - try again"):NULL,
- _("Passphrase:"), NULL, 0, &err);
- i18n_switchback (orig_codeset);
-
- if (!pw)
- {
- if (err)
- log_error (_("error while asking for the passphrase: %s\n"),
- gpg_strerror (err));
- else
- {
- log_info (_("cancelled\n"));
- if (canceled)
- *canceled = 1;
- }
- }
-
- return pw;
-}
-
-
-/* Drop a passphrase retrieved with confucius_get_pass. */
-void
-confucius_drop_pass (char *pass)
-{
- if (pass)
- spwq_secure_free (pass);
-}
-
-
-/* Run a confucius crypto engine. If MODE is oEncrypt, encryption is
- requested. If it is oDecrypt, decryption is requested. INFILE and
- OUTFILE are the temporary files used in the process. */
-int
-confucius_process (int mode, char *infile, char *outfile,
- int argc, char *argv[])
-{
- char **args;
- int cstderr[2];
- int master;
- int slave;
- int res;
- pid_t pid;
- pid_t wpid;
- int tries = 0;
- char cacheid[40];
-
- signal (SIGPIPE, SIG_IGN);
-
- if (!opt.program)
- {
- log_error (_("no --program option provided\n"));
- return 1;
- }
-
- if (mode != oDecrypt && mode != oEncrypt)
- {
- log_error (_("only --decrypt and --encrypt are supported\n"));
- return 1;
- }
-
- if (!opt.keyfile)
- {
- log_error (_("no --keyfile option provided\n"));
- return 1;
- }
-
- /* Generate a hash from the keyfile name for caching. */
- snprintf (cacheid, sizeof (cacheid), "confucius:%lu",
- hash_string (opt.keyfile));
- cacheid[sizeof (cacheid) - 1] = '\0';
- args = malloc (sizeof (char *) * (10 + argc));
- if (!args)
- {
- log_error (_("cannot allocate args vector\n"));
- return 1;
- }
- args[0] = opt.program;
- args[1] = (mode == oEncrypt) ? "-m1" : "-m2";
- args[2] = "-q";
- args[3] = infile;
- args[4] = "-z";
- args[5] = outfile;
- args[6] = "-s";
- args[7] = opt.keyfile;
- args[8] = (mode == oEncrypt) ? "-af" : "-f";
- args[9 + argc] = NULL;
- while (argc--)
- args[9 + argc] = argv[argc];
-
- if (pipe (cstderr) < 0)
- {
- log_error (_("could not create pipe: %s\n"), strerror (errno));
- free (args);
- return 1;
- }
-
- if (openpty (&master, &slave, NULL, NULL, NULL) == -1)
- {
- log_error (_("could not create pty: %s\n"), strerror (errno));
- close (cstderr[0]);
- close (cstderr[1]);
- free (args);
- return -1;
- }
-
- /* We don't want to deal with the worst case scenarios. */
- assert (master > 2);
- assert (slave > 2);
- assert (cstderr[0] > 2);
- assert (cstderr[1] > 2);
-
- pid = fork ();
- if (pid < 0)
- {
- log_error (_("could not fork: %s\n"), strerror (errno));
- close (master);
- close (slave);
- close (cstderr[0]);
- close (cstderr[1]);
- free (args);
- return 1;
- }
- else if (pid == 0)
- {
- /* Child. */
-
- /* Close the parent ends. */
- close (master);
- close (cstderr[0]);
-
- /* Change controlling terminal. */
- if (login_tty (slave))
- {
- /* It's too early to output a debug message. */
- _exit (1);
- }
-
- dup2 (cstderr[1], 2);
- close (cstderr[1]);
-
- /* Now kick off the engine program. */
- execv (opt.program, args);
- log_error (_("execv failed: %s\n"), strerror (errno));
- _exit (1);
- }
- else
- {
- /* Parent. */
- char buffer[CONFUCIUS_LINESIZE];
- int buffer_len = 0;
- fd_set fds;
- int slave_closed = 0;
- int stderr_closed = 0;
-
- close (slave);
- close (cstderr[1]);
- free (args);
-
- /* Listen on the output FDs. */
- do
- {
- FD_ZERO (&fds);
-
- if (!slave_closed)
- FD_SET (master, &fds);
- if (!stderr_closed)
- FD_SET (cstderr[0], &fds);
-
- res = select (FD_SETSIZE, &fds, NULL, NULL, NULL);
- if (res < 0)
- {
- log_error (_("select failed: %s\n"), strerror (errno));
-
- kill (pid, SIGTERM);
- close (master);
- close (cstderr[0]);
- return 1;
- }
-
- if (FD_ISSET (cstderr[0], &fds))
- {
- /* We got some output on stderr. This is just passed
- through via the logging facility. */
-
- res = read (cstderr[0], &buffer[buffer_len],
- sizeof (buffer) - buffer_len - 1);
- if (res < 0)
- {
- log_error (_("read failed: %s\n"), strerror (errno));
-
- kill (pid, SIGTERM);
- close (master);
- close (cstderr[0]);
- return 1;
- }
- else
- {
- char *newline;
-
- buffer_len += res;
- for (;;)
- {
- buffer[buffer_len] = '\0';
- newline = strchr (buffer, '\n');
- if (newline)
- {
- *newline = '\0';
- log_error ("%s\n", buffer);
- buffer_len -= newline + 1 - buffer;
- memmove (buffer, newline + 1, buffer_len);
- }
- else if (buffer_len == sizeof (buffer) - 1)
- {
- /* Overflow. */
- log_error ("%s\n", buffer);
- buffer_len = 0;
- }
- else
- break;
- }
-
- if (res == 0)
- stderr_closed = 1;
- }
- }
- else if (FD_ISSET (master, &fds))
- {
- char data[512];
-
- res = read (master, data, sizeof (data));
- if (res < 0)
- {
- if (errno == EIO)
- {
- /* Slave-side close leads to readable fd and
- EIO. */
- slave_closed = 1;
- }
- else
- {
- log_error (_("pty read failed: %s\n"), strerror (errno));
-
- kill (pid, SIGTERM);
- close (master);
- close (cstderr[0]);
- return 1;
- }
- }
- else if (res == 0)
- /* This never seems to be what happens on slave-side
- close. */
- slave_closed = 1;
- else
- {
- /* Check for password prompt. */
- if (data[res - 1] == ':')
- {
- char *pass;
- int canceled;
-
- /* If this is not the first attempt, the
- passphrase seems to be wrong, so clear the
- cache. */
- if (tries)
- simple_pwclear (cacheid);
-
- pass = confucius_get_pass (cacheid,
- tries ? 1 : 0, &canceled);
- if (!pass)
- {
- kill (pid, SIGTERM);
- close (master);
- close (cstderr[0]);
- return canceled ? SYMC_CANCELED : 1;
- }
- write (master, pass, strlen (pass));
- write (master, "\n", 1);
- confucius_drop_pass (pass);
-
- tries++;
- }
- }
- }
- }
- while (!stderr_closed || !slave_closed);
-
- close (master);
- close (cstderr[0]);
-
- wpid = waitpid (pid, &res, 0);
- if (wpid < 0)
- {
- log_error (_("waitpid failed: %s\n"), strerror (errno));
-
- kill (pid, SIGTERM);
- /* State of cached password is unclear. Just remove it. */
- simple_pwclear (cacheid);
- return 1;
- }
- else
- {
- /* Shouldn't happen, as we don't use WNOHANG. */
- assert (wpid != 0);
-
- if (!WIFEXITED (res))
- {
- log_error (_("child aborted with status %i\n"), res);
-
- /* State of cached password is unclear. Just remove it. */
- simple_pwclear (cacheid);
-
- return 1;
- }
-
- if (WEXITSTATUS (res))
- {
- /* The passphrase was wrong. Remove it from the cache. */
- simple_pwclear (cacheid);
-
- /* We probably exceeded our number of attempts at guessing
- the password. */
- if (tries >= 3)
- return SYMC_BAD_PASSPHRASE;
- else
- return 1;
- }
-
- return 0;
- }
- }
-
- /* Not reached. */
-}
-
-
-/* Class confucius main program. If MODE is oEncrypt, encryption is
- requested. If it is oDecrypt, decryption is requested. The other
- parameters are taken from the global option data. */
-int
-confucius_main (int mode, int argc, char *argv[])
-{
- int res;
- char *tmpdir;
- char *infile;
- int infile_from_stdin = 0;
- char *outfile;
-
- tmpdir = confucius_mktmpdir ();
- if (!tmpdir)
- return 1;
-
- if (opt.input && !(opt.input[0] == '-' && opt.input[1] == '\0'))
- infile = xstrdup (opt.input);
- else
- {
- infile_from_stdin = 1;
-
- /* TMPDIR + "/" + "in" + "\0". */
- infile = malloc (strlen (tmpdir) + 1 + 2 + 1);
- if (!infile)
- {
- log_error (_("cannot allocate infile string: %s\n"),
- strerror (errno));
- rmdir (tmpdir);
- return 1;
- }
- strcpy (infile, tmpdir);
- strcat (infile, "/in");
- }
-
- /* TMPDIR + "/" + "out" + "\0". */
- outfile = malloc (strlen (tmpdir) + 1 + 3 + 1);
- if (!outfile)
- {
- log_error (_("cannot allocate outfile string: %s\n"), strerror (errno));
- free (infile);
- rmdir (tmpdir);
- return 1;
- }
- strcpy (outfile, tmpdir);
- strcat (outfile, "/out");
-
- if (infile_from_stdin)
- {
- /* Create INFILE and fill it with content. */
- res = confucius_copy_file ("-", infile, mode == oEncrypt);
- if (res)
- {
- free (outfile);
- free (infile);
- rmdir (tmpdir);
- return res;
- }
- }
-
- /* Run the engine and thus create the output file, handling
- passphrase retrieval. */
- res = confucius_process (mode, infile, outfile, argc, argv);
- if (res)
- {
- remove_file (outfile, mode == oDecrypt);
- if (infile_from_stdin)
- remove_file (infile, mode == oEncrypt);
- free (outfile);
- free (infile);
- rmdir (tmpdir);
- return res;
- }
-
- /* Dump the output file to stdout. */
- res = confucius_copy_file (outfile, "-", mode == oDecrypt);
- if (res)
- {
- remove_file (outfile, mode == oDecrypt);
- if (infile_from_stdin)
- remove_file (infile, mode == oEncrypt);
- free (outfile);
- free (infile);
- rmdir (tmpdir);
- return res;
- }
-
- remove_file (outfile, mode == oDecrypt);
- if (infile_from_stdin)
- remove_file (infile, mode == oEncrypt);
- free (outfile);
- free (infile);
- rmdir (tmpdir);
- return 0;
-}
-
-
-/* symcryptrun's entry point. */
-int
-main (int argc, char **argv)
-{
- gpgrt_argparse_t pargs;
- int orig_argc;
- char **orig_argv;
- char *last_configname = NULL;
- const char *configname = NULL;
- int mode = 0;
- int res;
- char *logfile = NULL;
-
- early_system_init ();
- gpgrt_set_strusage (my_strusage);
- log_set_prefix ("symcryptrun", GPGRT_LOG_WITH_PREFIX);
-
- /* Make sure that our subsystems are ready. */
- i18n_init();
- init_common_subsystems (&argc, &argv);
-
- /* Check whether we have a config file given on the commandline */
- orig_argc = argc;
- orig_argv = argv;
- pargs.argc = &argc;
- pargs.argv = &argv;
- pargs.flags= ARGPARSE_FLAG_KEEP|ARGPARSE_FLAG_NOVERSION;
- while (gpgrt_argparse (NULL, &pargs, opts))
- {
- if (pargs.r_opt == oHomedir)
- gnupg_set_homedir (pargs.r.ret_str);
- }
- /* Reset the flags. */
- pargs.flags &= ~(ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION);
-
- /* The configuraton directories for use by gpgrt_argparser. */
- gpgrt_set_confdir (GPGRT_CONFDIR_SYS, gnupg_sysconfdir ());
- gpgrt_set_confdir (GPGRT_CONFDIR_USER, gnupg_homedir ());
-
- argc = orig_argc;
- argv = orig_argv;
- pargs.argc = &argc;
- pargs.argv = &argv;
- /* We are re-using the struct, thus the reset flag. We OR the
- * flags so that the internal intialized flag won't be cleared. */
- pargs.flags |= (ARGPARSE_FLAG_RESET
- | ARGPARSE_FLAG_KEEP
- | ARGPARSE_FLAG_SYS
- | ARGPARSE_FLAG_USER);
-
- /* Parse the command line. */
- while (gpgrt_argparser (&pargs, opts, "symcryptrun.conf"))
- {
- switch (pargs.r_opt)
- {
- case ARGPARSE_CONFFILE:
- {
- if (pargs.r_type)
- {
- xfree (last_configname);
- last_configname = xstrdup (pargs.r.ret_str);
- configname = last_configname;
- }
- else
- configname = NULL;
- }
- break;
-
- case oDecrypt: mode = oDecrypt; break;
- case oEncrypt: mode = oEncrypt; break;
-
- case oQuiet: opt.quiet = 1; break;
- case oVerbose: opt.verbose++; break;
- case oNoVerbose: opt.verbose = 0; break;
-
- case oClass: opt.class = pargs.r.ret_str; break;
- case oProgram: opt.program = pargs.r.ret_str; break;
- case oKeyfile: opt.keyfile = pargs.r.ret_str; break;
- case oInput: opt.input = pargs.r.ret_str; break;
-
- case oLogFile: logfile = pargs.r.ret_str; break;
-
- case oHomedir: /* Ignore this option here. */; break;
-
- default:
- if (configname)
- pargs.err = ARGPARSE_PRINT_WARNING;
- else
- pargs.err = ARGPARSE_PRINT_ERROR;
- break;
- }
- }
- gpgrt_argparse (NULL, &pargs, NULL); /* Release internal state. */
-
- xfree (last_configname);
-
- if (!mode)
- log_error (_("either %s or %s must be given\n"),
- "--decrypt", "--encrypt");
-
- if (log_get_errorcount (0))
- exit (1);
-
- if (logfile)
- log_set_file (logfile);
-
- gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
- setup_libgcrypt_logging ();
- gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
-
- /* Tell simple-pwquery about the standard socket name. */
- {
- char *tmp = make_filename (gnupg_socketdir (), GPG_AGENT_SOCK_NAME, NULL);
- simple_pw_set_socket (tmp);
- xfree (tmp);
- }
-
- if (!opt.class)
- {
- log_error (_("no class provided\n"));
- res = 1;
- }
- else if (!strcmp (opt.class, "confucius"))
- {
- res = confucius_main (mode, argc, argv);
- }
- else
- {
- log_error (_("class %s is not supported\n"), opt.class);
- res = 1;
- }
-
- return res;
-}