2009-09-30 17:28:38 +02:00
|
|
|
|
/* 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
|
2016-11-05 12:02:19 +01:00
|
|
|
|
* along with this program; if not, see <https://www.gnu.org/licenses/>.
|
2009-09-30 17:28:38 +02:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
#include <unistd.h>
|
2009-10-13 21:17:24 +02:00
|
|
|
|
#include <assert.h>
|
2009-09-30 17:28:38 +02:00
|
|
|
|
|
|
|
|
|
#include "g13.h"
|
2017-03-07 12:21:23 +01:00
|
|
|
|
#include "../common/i18n.h"
|
2009-09-30 17:28:38 +02:00
|
|
|
|
#include "keyblob.h"
|
|
|
|
|
#include "be-encfs.h"
|
2009-10-13 21:17:24 +02:00
|
|
|
|
#include "runner.h"
|
2014-11-11 15:14:31 +01:00
|
|
|
|
#include "../common/sysutils.h"
|
2009-10-13 21:17:24 +02:00
|
|
|
|
#include "../common/exechelp.h"
|
2009-09-30 17:28:38 +02:00
|
|
|
|
|
2009-10-13 21:17:24 +02:00
|
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
|
|
|
|
|
|
|
2011-02-04 12:57:53 +01:00
|
|
|
|
static gpg_error_t
|
2009-10-13 21:17:24 +02:00
|
|
|
|
send_cmd_bin (runner_t runner, const void *data, size_t datalen)
|
|
|
|
|
{
|
|
|
|
|
return runner_send_line (runner, data, datalen);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2011-02-04 12:57:53 +01:00
|
|
|
|
static gpg_error_t
|
2009-10-13 21:17:24 +02:00
|
|
|
|
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;
|
2009-10-20 16:30:35 +02:00
|
|
|
|
const char pgmname[] = FUSERMOUNT;
|
2009-10-13 21:17:24 +02:00
|
|
|
|
const char *args[3];
|
2011-02-04 12:57:53 +01:00
|
|
|
|
|
2009-10-13 21:17:24 +02:00
|
|
|
|
args[0] = "-u";
|
|
|
|
|
args[1] = mountpoint;
|
|
|
|
|
args[2] = NULL;
|
|
|
|
|
|
|
|
|
|
err = gnupg_spawn_process_detached (pgmname, args, NULL);
|
|
|
|
|
if (err)
|
2012-06-05 19:29:22 +02:00
|
|
|
|
log_error ("failed to run '%s': %s\n",
|
2009-10-13 21:17:24 +02:00
|
|
|
|
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++)
|
|
|
|
|
;
|
2012-06-05 19:29:22 +02:00
|
|
|
|
log_info ("got status '%s'\n", line);
|
2009-10-13 21:17:24 +02:00
|
|
|
|
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++)
|
|
|
|
|
;
|
2012-06-05 19:29:22 +02:00
|
|
|
|
log_info ("got prompt '%s'\n", line);
|
2009-10-13 21:17:24 +02:00
|
|
|
|
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;
|
2011-02-04 12:57:53 +01:00
|
|
|
|
|
2009-10-13 21:17:24 +02:00
|
|
|
|
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)))
|
|
|
|
|
{
|
2011-02-04 12:57:53 +01:00
|
|
|
|
if (gpg_err_code (err) == GPG_ERR_BUG
|
2009-10-13 21:17:24 +02:00
|
|
|
|
&& 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,
|
2009-10-15 19:20:41 +02:00
|
|
|
|
const char *rawdir, const char *mountpoint, tupledesc_t tuples,
|
|
|
|
|
unsigned int *r_id)
|
2009-10-13 21:17:24 +02:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2009-10-15 19:20:41 +02:00
|
|
|
|
err = runner_new (&runner, "encfs");
|
|
|
|
|
if (err)
|
|
|
|
|
goto leave;
|
2009-10-13 21:17:24 +02:00
|
|
|
|
|
2016-05-27 15:41:55 +02:00
|
|
|
|
err = gnupg_create_inbound_pipe (inbound, NULL, 0);
|
2009-10-13 21:17:24 +02:00
|
|
|
|
if (!err)
|
2016-05-27 15:41:55 +02:00
|
|
|
|
err = gnupg_create_outbound_pipe (outbound, NULL, 0);
|
2009-10-13 21:17:24 +02:00
|
|
|
|
if (err)
|
|
|
|
|
{
|
|
|
|
|
log_error (_("error creating a pipe: %s\n"), gpg_strerror (err));
|
|
|
|
|
goto leave;
|
|
|
|
|
}
|
|
|
|
|
|
2009-10-20 16:30:35 +02:00
|
|
|
|
pgmname = ENCFS;
|
2009-10-13 21:17:24 +02:00
|
|
|
|
idx = 0;
|
|
|
|
|
argv[idx++] = "-f";
|
2009-10-14 19:06:10 +02:00
|
|
|
|
if (opt.verbose)
|
|
|
|
|
argv[idx++] = "-v";
|
2009-10-13 21:17:24 +02:00
|
|
|
|
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)
|
|
|
|
|
{
|
2012-06-05 19:29:22 +02:00
|
|
|
|
log_error ("error spawning '%s': %s\n", pgmname, gpg_strerror (err));
|
2009-10-13 21:17:24 +02:00
|
|
|
|
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;
|
|
|
|
|
|
2009-10-15 19:20:41 +02:00
|
|
|
|
*r_id = runner_get_rid (runner);
|
2012-06-05 19:29:22 +02:00
|
|
|
|
log_info ("running '%s' in the background\n", pgmname);
|
2009-10-13 21:17:24 +02:00
|
|
|
|
|
|
|
|
|
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))
|
|
|
|
|
{
|
2010-06-24 12:51:30 +02:00
|
|
|
|
gnupg_wait_process (pgmname, pid, 1, NULL);
|
2010-06-09 18:53:51 +02:00
|
|
|
|
gnupg_release_process (pid);
|
2009-10-13 21:17:24 +02:00
|
|
|
|
}
|
|
|
|
|
runner_release (runner);
|
|
|
|
|
encfs_handler_cleanup (parm);
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2009-09-30 17:28:38 +02:00
|
|
|
|
/* 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2009-10-13 21:17:24 +02:00
|
|
|
|
/* Create a new session key and append it as a tuple to the memory
|
2011-02-04 12:57:53 +01:00
|
|
|
|
buffer MB.
|
2009-10-13 21:17:24 +02:00
|
|
|
|
|
|
|
|
|
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. */
|
2009-09-30 17:28:38 +02:00
|
|
|
|
gpg_error_t
|
|
|
|
|
be_encfs_create_new_keys (membuf_t *mb)
|
|
|
|
|
{
|
2009-10-13 21:17:24 +02:00
|
|
|
|
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
|
2011-02-04 12:57:53 +01:00
|
|
|
|
tool too much. */
|
2009-10-13 21:17:24 +02:00
|
|
|
|
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);
|
|
|
|
|
|
2009-09-30 17:28:38 +02:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2009-10-13 21:17:24 +02:00
|
|
|
|
/* Create the container described by the filename FNAME and the keyblob
|
|
|
|
|
information in TUPLES. */
|
|
|
|
|
gpg_error_t
|
2009-10-15 19:20:41 +02:00
|
|
|
|
be_encfs_create_container (ctrl_t ctrl, const char *fname, tupledesc_t tuples,
|
|
|
|
|
unsigned int *r_id)
|
2009-10-13 21:17:24 +02:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
2014-11-11 15:14:31 +01:00
|
|
|
|
if (!gnupg_mkdtemp (mountpoint))
|
2009-10-13 21:17:24 +02:00
|
|
|
|
{
|
|
|
|
|
err = gpg_error_from_syserror ();
|
2012-06-05 19:29:22 +02:00
|
|
|
|
log_error (_("can't create directory '%s': %s\n"),
|
2009-10-28 13:02:15 +01:00
|
|
|
|
"/tmp/.#g13_XXXXXX", gpg_strerror (err));
|
2009-10-13 21:17:24 +02:00
|
|
|
|
goto leave;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = run_encfs_tool (ctrl, ENCFS_CMD_CREATE, containername, mountpoint,
|
2009-10-15 19:20:41 +02:00
|
|
|
|
tuples, r_id);
|
2011-02-04 12:57:53 +01:00
|
|
|
|
|
2009-10-13 21:17:24 +02:00
|
|
|
|
/* In any case remove the temporary mount point. */
|
|
|
|
|
if (rmdir (mountpoint))
|
2012-06-05 19:29:22 +02:00
|
|
|
|
log_error ("error removing temporary mount point '%s': %s\n",
|
2009-10-13 21:17:24 +02:00
|
|
|
|
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
|
2009-10-15 19:20:41 +02:00
|
|
|
|
information in TUPLES. On success the runner id is stored at R_ID. */
|
2009-10-13 21:17:24 +02:00
|
|
|
|
gpg_error_t
|
2011-02-04 12:57:53 +01:00
|
|
|
|
be_encfs_mount_container (ctrl_t ctrl,
|
2009-10-13 21:17:24 +02:00
|
|
|
|
const char *fname, const char *mountpoint,
|
2009-10-15 19:20:41 +02:00
|
|
|
|
tupledesc_t tuples, unsigned int *r_id)
|
2009-10-13 21:17:24 +02:00
|
|
|
|
{
|
|
|
|
|
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,
|
2009-10-15 19:20:41 +02:00
|
|
|
|
tuples, r_id);
|
2011-02-04 12:57:53 +01:00
|
|
|
|
|
2009-10-13 21:17:24 +02:00
|
|
|
|
leave:
|
|
|
|
|
xfree (containername);
|
|
|
|
|
return err;
|
|
|
|
|
}
|