diff options
author | Justus Winter <justus@gnupg.org> | 2016-04-17 19:10:01 +0200 |
---|---|---|
committer | Justus Winter <justus@gnupg.org> | 2016-04-17 19:10:01 +0200 |
commit | 0a7383ee1ec041b7989a3e403c5b63a7ea478e2d (patch) | |
tree | 5995fb30b5141447e24666d268626b3ed88f1467 /debian/patches/gpg0005-trans-add-transparent-GnuPG-translator.patch | |
parent | ccd7e7529feeac77f053f9663d5f5256e6487627 (diff) |
drop old patch series
Diffstat (limited to 'debian/patches/gpg0005-trans-add-transparent-GnuPG-translator.patch')
-rw-r--r-- | debian/patches/gpg0005-trans-add-transparent-GnuPG-translator.patch | 890 |
1 files changed, 0 insertions, 890 deletions
diff --git a/debian/patches/gpg0005-trans-add-transparent-GnuPG-translator.patch b/debian/patches/gpg0005-trans-add-transparent-GnuPG-translator.patch deleted file mode 100644 index 09b1f317..00000000 --- a/debian/patches/gpg0005-trans-add-transparent-GnuPG-translator.patch +++ /dev/null @@ -1,890 +0,0 @@ -From f3dde907bc9bae67710eb47cb9d43748bbee278c Mon Sep 17 00:00:00 2001 -From: Justus Winter <justus@gnupg.org> -Date: Thu, 24 Mar 2016 22:55:54 +0100 -Subject: [PATCH hurd 5/5] trans: add transparent GnuPG translator - -* trans/Makefile: Add new file. -* trans/gpg.c: New file. -* utils/Makefile: Add new file. -* utils/gpg-env.sh: New file. ---- - trans/Makefile | 9 +- - trans/gpg.c | 682 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ - utils/Makefile | 6 +- - utils/gpg-env.sh | 122 ++++++++++ - 4 files changed, 812 insertions(+), 7 deletions(-) - create mode 100644 trans/gpg.c - create mode 100644 utils/gpg-env.sh - -diff --git a/trans/Makefile b/trans/Makefile -index e4eba0a..422d499 100644 ---- a/trans/Makefile -+++ b/trans/Makefile -@@ -21,10 +21,11 @@ makemode := servers - - targets = symlink firmlink ifsock magic null fifo new-fifo fwd crash \ - password hello hello-mt streamio fakeroot proxy-defpager remap \ -- mtab identity -+ mtab identity gpg - SRCS = ifsock.c symlink.c magic.c null.c fifo.c new-fifo.c fwd.c \ - crash.c firmlink.c password.c hello.c hello-mt.c streamio.c \ -- fakeroot.c proxy-defpager.c remap.c mtab.c chroot.c identity.c -+ fakeroot.c proxy-defpager.c remap.c mtab.c chroot.c identity.c \ -+ gpg.c - OBJS = $(SRCS:.c=.o) fsysServer.o ifsockServer.o passwordServer.o \ - crashServer.o crash_replyUser.o msgServer.o \ - default_pagerServer.o default_pagerUser.o \ -@@ -65,8 +66,8 @@ proxy-defpager: default_pagerServer.o default_pagerUser.o - streamio: device_replyServer.o - symlink: fsysServer.o - --identity: chroot.o --fakeroot identity: ../libnetfs/libnetfs.a -+identity gpg: chroot.o -+fakeroot identity gpg: ../libnetfs/libnetfs.a - fifo new-fifo: ../libpipe/libpipe.a - crash fifo firmlink hello hello-mt ifsock magic mtab new-fifo null password proxy-defpager remap streamio: ../libtrivfs/libtrivfs.a - $(targets): ../libfshelp/libfshelp.a \ -diff --git a/trans/gpg.c b/trans/gpg.c -new file mode 100644 -index 0000000..abdea7c ---- /dev/null -+++ b/trans/gpg.c -@@ -0,0 +1,682 @@ -+/* gpg -- a translator for encrypting, decrypting, and verifying files -+ Copyright (C) 2016 Free Software Foundation, Inc. -+ -+ This program is free software; you can redistribute it and/or -+ modify it under the terms of the GNU General Public License as -+ published by the Free Software Foundation; either version 2, or (at -+ your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, but -+ WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software -+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -+ -+#include <argz.h> -+#include <argp.h> -+#include <dirent.h> -+#include <error.h> -+#include <hurd/netfs.h> -+#include <stddef.h> -+#include <stdio.h> -+#include <stdlib.h> -+#include <string.h> -+#include <fcntl.h> -+#include <sys/mman.h> -+#include <sys/stat.h> -+#include <pthread.h> -+#include <hurd/ihash.h> -+#include <hurd/paths.h> -+#include <sys/types.h> -+#include <sys/wait.h> -+#include <unistd.h> -+ -+#include <version.h> -+ -+#include "chroot.h" -+ -+#include "libnetfs/fs_S.h" -+#include "libnetfs/io_S.h" -+#include "libnetfs/fsys_S.h" -+#include "libports/notify_S.h" -+#include "libports/interrupt_S.h" -+ -+const char *argp_program_version = STANDARD_HURD_VERSION (gpg); -+ -+char *netfs_server_name = "gpg"; -+char *netfs_server_version = HURD_VERSION; -+int netfs_maxsymlinks = 16; /* arbitrary */ -+ -+struct chroot_node -+{ -+ unsigned int encrypt:1; -+ file_t shadow_file; -+}; -+ -+#define GPG_DEFAULT_FILENAME "/usr/bin/gpg2" -+static char* gpg_filename = GPG_DEFAULT_FILENAME; -+static file_t gpg_file; -+ -+int symmetric; -+char *recipients; -+size_t recipients_len; -+ -+static error_t -+execute_gpg (mach_port_t in, mach_port_t out, mach_port_t extra, -+ char *argz, size_t argz_len, pid_t *pid) -+{ -+ error_t err; -+ task_t task; -+ process_t proc; -+ mach_port_t ports[INIT_PORT_MAX]; -+ mach_port_t fds[STDERR_FILENO + 2]; -+ int ints[INIT_INT_MAX]; -+ int i; -+ -+ for (i = 0; i < INIT_PORT_MAX; i++) -+ ports[i] = MACH_PORT_NULL; -+ for (i = 0; i < STDERR_FILENO + 2; i++) -+ fds[i] = MACH_PORT_NULL; -+ memset (ints, 0, INIT_INT_MAX * sizeof(int)); -+ -+ ports[INIT_PORT_CWDIR] = getcwdir (); -+ ports[INIT_PORT_CRDIR] = getcrdir (); -+ ports[INIT_PORT_AUTH] = getauth (); -+ fds[STDIN_FILENO] = in; -+ fds[STDOUT_FILENO] = out; -+ fds[STDERR_FILENO] = getdport (STDERR_FILENO); -+ fds[STDERR_FILENO+1] = extra; -+ -+ err = task_create (mach_task_self (), 0, &task); -+ if (err) -+ goto lose; -+ -+ proc = getproc (); -+ proc_child (proc, task); -+ -+ /* Try and exec GnuPG in TASK... */ -+ err = file_exec (gpg_file, task, EXEC_DEFAULTS, -+ argz, argz_len, 0, 0, -+ fds, MACH_MSG_TYPE_COPY_SEND, STDERR_FILENO + 2, -+ ports, MACH_MSG_TYPE_COPY_SEND, INIT_PORT_MAX, -+ ints, INIT_INT_MAX, 0, 0, 0, 0); -+ if (err) -+ goto lose; -+ -+ err = proc_task2pid (proc, task, pid); -+ -+ lose: -+ for (i = 0; i < INIT_PORT_MAX; i++) -+ mach_port_deallocate (mach_task_self (), ports[i]); -+ mach_port_deallocate (mach_task_self (), fds[STDERR_FILENO]); -+ return err; -+} -+ -+error_t -+clone_file (file_t file, file_t *new_file) -+{ -+ error_t err; -+ off_t newp; -+ retry_type do_retry; -+ string_t retry_name; -+ err = dir_lookup (file, "", O_RDONLY, 0, &do_retry, retry_name, new_file); -+ if (err) -+ return err; -+ return io_seek (*new_file, 0, SEEK_SET, &newp); -+} -+ -+static int -+gpg_verify (file_t sigfile, file_t orig_file) -+{ -+ error_t err; -+ file_t file; -+ pid_t pid; -+ char *argz = NULL; -+ size_t argz_len = 0; -+ err = clone_file (orig_file, &file); -+ if (err) -+ return 0; -+ -+ argz_add (&argz, &argz_len, "gpg2"); -+ argz_add (&argz, &argz_len, "--verify"); -+ argz_add (&argz, &argz_len, "/dev/fd/3"); -+ argz_add (&argz, &argz_len, "-"); -+ err = execute_gpg (file, getdport (STDERR_FILENO), sigfile, argz, argz_len, &pid); -+ mach_port_deallocate (mach_task_self (), file); -+ if (err) -+ { -+ error (0, err, "execute_gpg"); -+ return 0; -+ } -+ -+ int status; -+ while (waitpid (pid, &status, 0) == (pid_t)-1 && errno == EINTR) -+ { } -+ -+ return WIFEXITED (status) && WEXITSTATUS (status) == 0; -+} -+ -+static int -+gpg_decrypt (file_t cipherfile, file_t plainfile) -+{ -+ error_t err; -+ pid_t pid; -+ char *argz = NULL; -+ size_t argz_len = 0; -+ -+ argz_add (&argz, &argz_len, "gpg2"); -+ argz_add (&argz, &argz_len, "--output"); -+ argz_add (&argz, &argz_len, "-"); -+ err = execute_gpg (cipherfile, plainfile, MACH_PORT_NULL, -+ argz, argz_len, &pid); -+ if (err) -+ { -+ error (0, err, "execute_gpg"); -+ return 0; -+ } -+ -+ int status; -+ while (waitpid (pid, &status, 0) == (pid_t)-1 && errno == EINTR) -+ { } -+ -+ return WIFEXITED (status) && WEXITSTATUS (status) == 0; -+} -+ -+static int -+gpg_encrypt (file_t plainfile, file_t cipherfile) -+{ -+ error_t err; -+ pid_t pid; -+ char *argz = NULL; -+ size_t argz_len = 0; -+ -+ argz_add (&argz, &argz_len, "gpg2"); -+ argz_add (&argz, &argz_len, "--output"); -+ argz_add (&argz, &argz_len, "-"); -+ if (recipients) -+ { -+ char *recipient; -+ argz_add (&argz, &argz_len, "--encrypt"); -+ for (recipient = recipients; -+ recipient; -+ recipient = argz_next (recipients, recipients_len, recipient)) -+ { -+ argz_add (&argz, &argz_len, "--recipient"); -+ argz_add (&argz, &argz_len, recipient); -+ } -+ } -+ if (symmetric) -+ argz_add (&argz, &argz_len, "--symmetric"); -+ -+ err = execute_gpg (plainfile, cipherfile, MACH_PORT_NULL, -+ argz, argz_len, &pid); -+ if (err) -+ { -+ error (0, err, "execute_gpg"); -+ return 0; -+ } -+ -+ int status; -+ while (waitpid (pid, &status, 0) == (pid_t)-1 && errno == EINTR) -+ { } -+ -+ return WIFEXITED (status) && WEXITSTATUS (status) == 0; -+} -+ -+static error_t -+make_tmp_file (file_t *file) -+{ -+ char name[] = "/tmp/gpgtmp-XXXXXX"; -+ int fd; -+ -+ fd = mkstemp (name); -+ if (fd == -1) -+ return errno; -+ if (unlink (name) == -1) -+ return errno; -+ *file = getdport (fd); -+ close (fd); -+ return 0; -+} -+ -+error_t -+netfs_S_dir_lookup (struct protid *diruser, -+ char *filename, -+ int flags, -+ mode_t mode, -+ retry_type *do_retry, -+ char *retry_name, -+ mach_port_t *retry_port, -+ mach_msg_type_name_t *retry_port_type) -+{ -+ struct node *dnp, *np; -+ error_t err; -+ struct protid *newpi; -+ struct iouser *user; -+ file_t file; -+ file_t dir; -+ -+ if (! diruser) -+ return EOPNOTSUPP; -+ -+ dnp = diruser->po->np; -+ -+ dir = netfs_node_netnode (dnp)->file; -+ err = dir_lookup (dir, filename, -+ flags & (O_NOLINK|O_RDWR|O_EXEC|O_CREAT|O_EXCL|O_NONBLOCK), -+ mode, do_retry, retry_name, &file); -+ if (err == ENOENT) -+ { -+ file_t gpgfile; -+ char *gpgname; -+ asprintf (&gpgname, "%s.gpg", filename); -+ gpgfile = file_name_lookup_under (dir, gpgname, O_RDONLY, 0); -+ if (MACH_PORT_VALID (gpgfile)) -+ { -+ file_t tmpfile; -+ int ok; -+ off_t newp; -+ -+ err = make_tmp_file (&tmpfile); -+ if (err) -+ return err; -+ -+ ok = gpg_decrypt (gpgfile, tmpfile); -+ mach_port_deallocate (mach_task_self (), gpgfile); -+ if (! ok) -+ { -+ mach_port_deallocate (mach_task_self (), tmpfile); -+ return EIO; -+ } -+ -+ err = io_seek (tmpfile, 0, SEEK_SET, &newp); -+ if (err) -+ { -+ mach_port_deallocate (mach_task_self (), tmpfile); -+ return err; -+ } -+ -+ *do_retry = FS_RETRY_NORMAL; -+ retry_name[0] = 0; -+ *retry_port = tmpfile; -+ *retry_port_type = MACH_MSG_TYPE_MOVE_SEND; -+ return 0; -+ } -+ free (gpgname); -+ } -+ -+ if (err) -+ return err; -+ -+ switch (*do_retry) -+ { -+ case FS_RETRY_NORMAL: -+ break; -+ -+ case FS_RETRY_REAUTH: -+ error (0, 0, "FS_RETRY_REAUTH"); -+ /* Fallthrough. */ -+ -+ case FS_RETRY_MAGICAL: -+ *retry_port = file; -+ *retry_port_type = MACH_MSG_TYPE_MOVE_SEND; -+ return 0; -+ -+ default: -+ /* Invalid response to our dir_lookup request. */ -+ if (MACH_PORT_VALID (file)) -+ mach_port_deallocate (mach_task_self (), file); -+ *retry_port = MACH_PORT_NULL; -+ *retry_port_type = MACH_MSG_TYPE_COPY_SEND; -+ return EOPNOTSUPP; -+ } -+ -+ /* We have a new port to an underlying node. -+ Find or make our corresponding virtual node. */ -+ -+ np = 0; -+ -+ pthread_mutex_lock (&dnp->lock); -+ err = chroot_new_node (file, sizeof (struct chroot_node), &np); -+ pthread_mutex_unlock (&dnp->lock); -+ if (!err) -+ { -+ chroot_node (np)->encrypt = chroot_node (dnp)->encrypt; -+ chroot_node (np)->shadow_file = MACH_PORT_NULL; -+ err = netfs_validate_stat (np, diruser->user); -+ } -+ if (err) -+ goto lose; -+ -+ if (chroot_node (np)->encrypt && flags & O_WRITE -+ && strncmp (filename, "dev/", 4) != 0) -+ { -+ char *ciphname; -+ asprintf (&ciphname, "%s.gpg", filename); -+ if (ciphname == NULL) -+ { -+ err = errno; -+ goto lose; -+ } -+ -+ /* Fixup name. */ -+ err = dir_link (dir, file, ciphname, 0); -+ free (ciphname); -+ if (err) -+ return err; -+ -+ err = dir_unlink (dir, filename); -+ if (err) -+ return err; -+ -+ err = make_tmp_file (&chroot_node (np)->shadow_file); -+ if (err) -+ return err; -+ } -+ -+ if (retry_name[0] == 0) -+ { -+ file_t sig; -+ char *signame; -+ -+ asprintf (&signame, "%s.sig", filename); -+ if (signame == NULL) -+ { -+ err = errno; -+ goto lose; -+ } -+ -+ sig = file_name_lookup_under (dir, signame, O_RDONLY, 0); -+ if (MACH_PORT_VALID (sig)) -+ { -+ if (! gpg_verify (sig, file)) -+ err = EIO; -+ free (signame); -+ signame = NULL; -+ mach_port_deallocate (mach_task_self (), sig); -+ if (err) -+ goto lose; -+ } -+ free (signame); -+ } -+ -+ assert (*do_retry == FS_RETRY_NORMAL); -+ flags &= ~(O_CREAT|O_EXCL|O_NOLINK|O_NOTRANS|O_NONBLOCK); -+ -+ err = iohelp_dup_iouser (&user, diruser->user); -+ if (!err) -+ { -+ newpi = netfs_make_protid (netfs_make_peropen (np, flags, diruser->po), -+ user); -+ if (! newpi) -+ { -+ iohelp_free_iouser (user); -+ err = errno; -+ } -+ else -+ { -+ *retry_port = ports_get_right (newpi); -+ *retry_port_type = MACH_MSG_TYPE_MAKE_SEND; -+ ports_port_deref (newpi); -+ } -+ } -+ -+ lose: -+ if (dir != netfs_node_netnode (dnp)->file) -+ mach_port_deallocate (mach_task_self (), dir); -+ if (np != NULL) -+ netfs_nput (np); -+ return err; -+} -+ -+error_t -+netfs_attempt_mkfile (struct iouser *user, struct node *dir, -+ mode_t mode, struct node **np) -+{ -+ file_t newfile; -+ error_t err = dir_mkfile (netfs_node_netnode (dir)->file, O_RDWR|O_EXEC, -+ mode, &newfile); -+ pthread_mutex_unlock (&dir->lock); -+ if (err) -+ return err; -+ -+ err = chroot_new_node (newfile, sizeof (struct chroot_node), np); -+ if (err) -+ return err; -+ -+ if (chroot_node (dir)->encrypt) -+ { -+ err = make_tmp_file (&chroot_node (*np)->shadow_file); -+ if (err) -+ return err; -+ } -+ else -+ chroot_node (*np)->shadow_file = MACH_PORT_NULL; -+ -+ pthread_mutex_unlock (&(*np)->lock); -+ return err; -+} -+ -+error_t -+netfs_attempt_read (struct iouser *cred, struct node *np, -+ off_t offset, size_t *len, void *data) -+{ -+ struct chroot_node *n = chroot_node (np); -+ char *buf = data; -+ error_t err = io_read (n->shadow_file ?: netfs_node_netnode (np)->file, -+ &buf, len, offset, *len); -+ if (err == 0 && buf != data) -+ { -+ memcpy (data, buf, *len); -+ munmap (buf, *len); -+ } -+ return err; -+} -+ -+error_t -+netfs_attempt_write (struct iouser *cred, struct node *np, -+ off_t offset, size_t *len, void *data) -+{ -+ struct chroot_node *n = chroot_node (np); -+ return io_write (n->shadow_file ?: netfs_node_netnode (np)->file, -+ data, *len, offset, len); -+} -+ -+error_t -+netfs_attempt_sync (struct iouser *cred, struct node *np, int wait) -+{ -+ error_t err; -+ file_t gpg_file = netfs_node_netnode (np)->file; -+ struct chroot_node *n = chroot_node (np); -+ -+ err = file_sync (n->shadow_file ?: gpg_file, wait, 0); -+ if (err) -+ return err; -+ -+ if (wait && MACH_PORT_VALID (n->shadow_file)) -+ { -+ file_t shadow_file; -+ off_t newp; -+ -+ err = clone_file (n->shadow_file, &shadow_file); -+ if (err) -+ return err; -+ -+ err = io_seek (gpg_file, 0, SEEK_SET, &newp); -+ if (err) -+ return err; -+ -+ err = gpg_encrypt (shadow_file, gpg_file); -+ if (err) -+ return err; -+ -+ mach_port_deallocate (mach_task_self (), shadow_file); -+ err = file_sync (gpg_file, wait, 0); -+ } -+ -+ return err; -+} -+ -+ -+error_t -+netfs_attempt_link (struct iouser *user, struct node *dir, -+ struct node *file, char *name, int excl) -+{ -+ /* XXX translate name if file is encrypted. */ -+ return dir_link (netfs_node_netnode (dir)->file, -+ netfs_node_netnode (file)->file, name, excl); -+} -+ -+void -+chroot_node_norefs (struct node *np) -+{ -+ error_t err; -+ file_t gpg_file = netfs_node_netnode (np)->file; -+ struct chroot_node *n = chroot_node (np); -+ if (n->encrypt) -+ { -+ off_t newp; -+ -+ err = io_seek (n->shadow_file, 0, SEEK_SET, &newp); -+ if (err) -+ return; -+ -+ err = io_seek (gpg_file, 0, SEEK_SET, &newp); -+ if (err) -+ return; -+ -+ err = gpg_encrypt (n->shadow_file, gpg_file); -+ if (err) -+ return; -+ -+ mach_port_deallocate (mach_task_self (), n->shadow_file); -+ } -+} -+ -+ -+error_t -+netfs_get_dirents (struct iouser *cred, struct node *dir, -+ int entry, int nentries, char **data, -+ mach_msg_type_number_t *datacnt, -+ vm_size_t bufsize, int *amt) -+{ -+ error_t err; -+ char *ptr; -+ struct dirent *dent; -+ err = dir_readdir (netfs_node_netnode (dir)->file, data, datacnt, -+ entry, nentries, bufsize, amt); -+ if (err) -+ return err; -+ -+ for (ptr = *data, dent = (struct dirent *) ptr; -+ ptr - *data < *datacnt; -+ ptr += dent->d_reclen, dent = (struct dirent *) ptr) -+ { -+ size_t len = strlen (dent->d_name); -+ if (len > 4 && strcmp (&dent->d_name[len - 4], ".gpg") == 0) -+ memset (&dent->d_name[len - 4], 0, 4); -+ } -+ -+ return 0; -+} -+ -+#define OPT_GPG_PROGRAM -1 -+ -+static struct argp_option options[] = -+{ -+ {NULL, 0, NULL, 0, "How to encrypt:", 1}, -+ {"recipient", 'r', "NAME", 0, "Encrypt for user NAME. " -+ "Can be given multiple times.", 1}, -+ {"symmetric", 'c', NULL, 0, "Encrypt with a password.", 1}, -+ {NULL, 0, NULL, 0, "Advanced options:", 2}, -+ {"gpg-program", OPT_GPG_PROGRAM, "FILENAME", 0, -+ "Path to the GNU Privacy Guard executable ["GPG_DEFAULT_FILENAME"].", 2}, -+ {0} -+}; -+ -+static char *args_doc = ""; -+static char *doc = "Transparently encrypt, decrypt, and verify signatures" -+ " using GnuPG." -+ "\vFor everyday use, the commands 'encrypt', 'decrypt', and 'verify'" -+ " offer a simple and convenient frontend for this translator."; -+ -+static error_t -+parse_opt (int key, char *arg, struct argp_state *state) -+{ -+ error_t err; -+ switch (key) -+ { -+ case 'r': -+ err = argz_add (&recipients, &recipients_len, arg); -+ if (err) -+ error (1, err, "argz_add"); -+ break; -+ -+ case 'c': -+ symmetric = 1; -+ break; -+ -+ case OPT_GPG_PROGRAM: -+ gpg_filename = arg; -+ break; -+ -+ default: -+ return ARGP_ERR_UNKNOWN; -+ } -+ return 0; -+} -+ -+int -+main (int argc, char **argv) -+{ -+ error_t err; -+ mach_port_t bootstrap; -+ -+ struct argp argp = -+ { -+ .options = options, -+ .parser = parse_opt, -+ .args_doc = args_doc, -+ .doc = doc, -+ }; -+ -+ /* Parse our command line arguments (all none of them). */ -+ argp_parse (&argp, argc, argv, 0, 0, 0); -+ -+ task_get_bootstrap_port (mach_task_self (), &bootstrap); -+ if (! MACH_PORT_VALID (bootstrap)) -+ error (1, 0, "Must be started as a translator"); -+ -+ gpg_file = file_name_lookup (gpg_filename, O_EXEC, 0); -+ if (! MACH_PORT_VALID (gpg_file)) -+ error (1, errno, "%s", gpg_filename); -+ -+ netfs_init (); -+ chroot_init (); -+ -+ /* Get our underlying node (we presume it's a directory) and use -+ that to make the root node of the filesystem. */ -+ err = chroot_new_node (netfs_startup (bootstrap, O_READ), -+ sizeof (struct chroot_node), &netfs_root_node); -+ if (err) -+ error (5, err, "Cannot create root node"); -+ -+ err = netfs_validate_stat (netfs_root_node, 0); -+ if (err) -+ error (6, err, "Cannot stat underlying node"); -+ -+ netfs_root_node->nn_stat.st_mode &= ~(S_IPTRANS | S_IATRANS); -+ netfs_root_node->nn_stat.st_mode |= S_IROOT; -+ pthread_mutex_unlock (&netfs_root_node->lock); -+ -+ chroot_node (netfs_root_node)->encrypt = 1; -+ chroot_node (netfs_root_node)->shadow_file = MACH_PORT_NULL; -+ -+ netfs_server_loop (); /* Never returns. */ -+ -+ /*NOTREACHED*/ -+ return 0; -+} -diff --git a/utils/Makefile b/utils/Makefile -index d2ef9e8..aa6ff34 100644 ---- a/utils/Makefile -+++ b/utils/Makefile -@@ -22,16 +22,16 @@ targets = shd ps settrans showtrans syncfs fsysopts \ - storeinfo login w uptime ids loginpr sush vmstat portinfo \ - devprobe vminfo addauth rmauth unsu setauth ftpcp ftpdir storecat \ - storeread msgport rpctrace mount gcore fakeauth fakeroot remap \ -- umount nullauth rpcscan vmallocate -+ umount nullauth rpcscan vmallocate gpg-env - --special-targets = loginpr sush uptime fakeroot remap -+special-targets = loginpr sush uptime fakeroot remap gpg-env - SRCS = shd.c ps.c settrans.c syncfs.c showtrans.c addauth.c rmauth.c \ - fsysopts.c storeinfo.c login.c loginpr.sh sush.sh w.c \ - uptime.sh psout.c ids.c vmstat.c portinfo.c devprobe.c vminfo.c \ - parse.c frobauth.c frobauth-mod.c setauth.c pids.c nonsugid.c \ - unsu.c ftpcp.c ftpdir.c storeread.c storecat.c msgport.c \ - rpctrace.c mount.c gcore.c fakeauth.c fakeroot.sh remap.sh \ -- nullauth.c match-options.c msgids.c rpcscan.c -+ nullauth.c match-options.c msgids.c rpcscan.c gpg-env.sh - - OBJS = $(filter-out %.sh,$(SRCS:.c=.o)) - HURDLIBS = ps ihash store fshelp ports ftpconn shouldbeinlibc -diff --git a/utils/gpg-env.sh b/utils/gpg-env.sh -new file mode 100644 -index 0000000..cd3c9d5 ---- /dev/null -+++ b/utils/gpg-env.sh -@@ -0,0 +1,122 @@ -+#!/bin/sh -+# Execute a command in an environment which encrypts, decrypts, and -+# verifies files on demand. -+# -+# Copyright (C) 2016 Free Software Foundation, Inc. -+# -+# This file is part of the GNU Hurd. -+# -+# The GNU Hurd is free software; you can redistribute it and/or -+# modify it under the terms of the GNU General Public License as -+# published by the Free Software Foundation; either version 2, or (at -+# your option) any later version. -+# -+# The GNU Hurd is distributed in the hope that it will be useful, but -+# WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+# General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+# -+ -+USAGE="Usage: -+ [gpg-env] encrypt for RECIPIENT [RECIPIENT...] -- [OPTION...] [COMMAND...] -+ [gpg-env] encrypt with password [OPTION...] [COMMAND...] -+ [gpg-env] decrypt [OPTION...] [COMMAND...] -+ [gpg-env] decrypt with password [OPTION...] [COMMAND...] -+ [gpg-env] verify [OPTION...] [COMMAND...]" -+DOC="Execute COMMAND in an environment where files are automatically -+encrypted, decrypted and verified." -+ -+help() -+{ -+ [ "$1" ] && echo "$1 -+" -+ echo "$USAGE" -+ echo "" -+ echo "$DOC" -+ echo "" -+ echo " -?, --help Give this help list" -+ echo " --usage Give a short usage message" -+ echo " -V, --version Print program version" -+ [ "$1" ] && exit 1 || exit 0 -+} -+ -+if [ "$(basename $0)" = "gpg-env.sh" ] \ -+ || [ "$(basename $0)" = "gpg-env" ]; then -+ ACTION="$1" -+ if [ ! "$ACTION" ]; then -+ help "No action given." -+ fi -+ shift -+else -+ ACTION="$(basename $0)" -+fi -+ -+case "$ACTION" in -+ "encrypt") ;; -+ "decrypt") ;; -+ "verify") ;; -+ *) -+ help "Invalid action '$ACTION'." -+esac -+ -+ENCRYPT="" -+if [ "$ACTION" = "encrypt" ]; then -+ if [ "$1" = "with" ] && [ "$2" = "password" ]; then -+ ENCRYPT="--symmetric" -+ shift 2 -+ elif [ "$1" = "for" ]; then -+ shift -+ while [ "$#" -gt 0 ] && [ "x$1" != "x--" ]; do -+ ENCRYPT="$ENCRYPT --recipient $1" -+ shift -+ done -+ if [ "$ENCRYPT" = "" ]; then -+ echo "No recipients given." -+ exit 1 -+ fi -+ if [ "x$1" = "x--" ]; then -+ shift -+ elif [ "$#" -eq 0 ]; then -+ # it's ok if there are no more arguments -+ : -+ else -+ echo "Recipient list must be terminated using '--'." -+ exit 1 -+ fi -+ fi -+fi -+ -+while [ "$#" -gt 0 ]; do -+ case "$1" in -+ --help|"-?") -+ help -+ ;; -+ --usage) -+ echo "$USAGE" -+ echo "Options: [-V?] [--help] [--usage] [--version]" -+ exit 0;; -+ --version|-V) -+ echo "STANDARD_HURD_VERSION_gpg-env_"; exit 0;; -+ --) -+ shift -+ break -+ ;; -+ *) -+ break -+ esac -+done -+ -+if [ $# -eq 0 ]; then -+ set -- ${SHELL:-/bin/sh} -+fi -+ -+# We exec settrans, which execs the target command in the chroot -+# context provided by /hurd/gpg. -+exec /bin/settrans \ -+ --chroot-chdir "$PWD" \ -+ --chroot "$@" -- \ -+ / /hurd/gpg $ENCRYPT --- -2.1.4 - |