mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-15 12:50:06 +01:00
Revert libcryptsetup_cli.
This reverts mostly these commits:42692418c2a985c12659The library was ment to export common functions shared by all cryptsetup tools and planned LUKS2 tokens plugins. It is no longer needed.
This commit is contained in:
@@ -6,7 +6,6 @@ DISTCLEAN_TARGETS =
|
|||||||
AM_CPPFLAGS = \
|
AM_CPPFLAGS = \
|
||||||
-include config.h \
|
-include config.h \
|
||||||
-I$(top_srcdir)/lib \
|
-I$(top_srcdir)/lib \
|
||||||
-I$(top_srcdir)/lib/cli \
|
|
||||||
-DDATADIR=\""$(datadir)"\" \
|
-DDATADIR=\""$(datadir)"\" \
|
||||||
-DLOCALEDIR=\""$(datadir)/locale"\" \
|
-DLOCALEDIR=\""$(datadir)/locale"\" \
|
||||||
-DLIBDIR=\""$(libdir)"\" \
|
-DLIBDIR=\""$(libdir)"\" \
|
||||||
@@ -37,7 +36,6 @@ include lib/crypto_backend/argon2/Makemodule.am
|
|||||||
endif
|
endif
|
||||||
include lib/crypto_backend/Makemodule.am
|
include lib/crypto_backend/Makemodule.am
|
||||||
include lib/Makemodule.am
|
include lib/Makemodule.am
|
||||||
include lib/cli/Makemodule.am
|
|
||||||
|
|
||||||
include src/Makemodule.am
|
include src/Makemodule.am
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,6 @@ dnl library version from <major>.<minor>.<release>[-<suffix>]
|
|||||||
LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
|
LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
|
||||||
LIBCRYPTSETUP_VERSION_INFO=18:0:6
|
LIBCRYPTSETUP_VERSION_INFO=18:0:6
|
||||||
|
|
||||||
LIBCRYPTSETUP_CLI_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
|
|
||||||
LIBCRYPTSETUP_CLI_VERSION_INFO=1:0:0
|
|
||||||
|
|
||||||
AM_SILENT_RULES([yes])
|
AM_SILENT_RULES([yes])
|
||||||
AC_CONFIG_SRCDIR(src/cryptsetup.c)
|
AC_CONFIG_SRCDIR(src/cryptsetup.c)
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
@@ -542,9 +539,6 @@ AC_SUBST([BLKID_LIBS])
|
|||||||
AC_SUBST([LIBCRYPTSETUP_VERSION])
|
AC_SUBST([LIBCRYPTSETUP_VERSION])
|
||||||
AC_SUBST([LIBCRYPTSETUP_VERSION_INFO])
|
AC_SUBST([LIBCRYPTSETUP_VERSION_INFO])
|
||||||
|
|
||||||
AC_SUBST([LIBCRYPTSETUP_CLI_VERSION])
|
|
||||||
AC_SUBST([LIBCRYPTSETUP_CLI_VERSION_INFO])
|
|
||||||
|
|
||||||
dnl ==========================================================================
|
dnl ==========================================================================
|
||||||
AC_ARG_ENABLE([dev-random],
|
AC_ARG_ENABLE([dev-random],
|
||||||
AS_HELP_STRING([--enable-dev-random], [use /dev/random by default for key generation (otherwise use /dev/urandom)]))
|
AS_HELP_STRING([--enable-dev-random], [use /dev/random by default for key generation (otherwise use /dev/urandom)]))
|
||||||
@@ -654,7 +648,6 @@ dnl ==========================================================================
|
|||||||
|
|
||||||
AC_CONFIG_FILES([ Makefile
|
AC_CONFIG_FILES([ Makefile
|
||||||
lib/libcryptsetup.pc
|
lib/libcryptsetup.pc
|
||||||
lib/cli/libcryptsetup_cli.pc
|
|
||||||
po/Makefile.in
|
po/Makefile.in
|
||||||
scripts/cryptsetup.conf
|
scripts/cryptsetup.conf
|
||||||
tests/Makefile
|
tests/Makefile
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
pkgconfig_DATA += lib/cli/libcryptsetup_cli.pc
|
|
||||||
|
|
||||||
lib_LTLIBRARIES += libcryptsetup_cli.la
|
|
||||||
|
|
||||||
include_HEADERS += lib/cli/libcryptsetup_cli.h
|
|
||||||
|
|
||||||
EXTRA_DIST += lib/cli/libcryptsetup_cli.pc.in lib/cli/libcryptsetup_cli.sym
|
|
||||||
|
|
||||||
# libcryptsetup_cli_la_CPPFLAGS = $(AM_CPPFLAGS)
|
|
||||||
|
|
||||||
libcryptsetup_cli_la_DEPENDENCIES = lib/cli/libcryptsetup_cli.sym libcryptsetup.la
|
|
||||||
|
|
||||||
libcryptsetup_cli_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined \
|
|
||||||
-Wl,--version-script=$(top_srcdir)/lib/cli/libcryptsetup_cli.sym \
|
|
||||||
-version-info @LIBCRYPTSETUP_CLI_VERSION_INFO@
|
|
||||||
|
|
||||||
libcryptsetup_cli_la_CFLAGS = $(AM_CFLAGS) \
|
|
||||||
-I $(top_srcdir)/src
|
|
||||||
|
|
||||||
libcryptsetup_cli_la_LIBADD = \
|
|
||||||
$(LTLIBICONV) \
|
|
||||||
@PWQUALITY_LIBS@ \
|
|
||||||
@PASSWDQC_LIBS@ \
|
|
||||||
libcryptsetup.la
|
|
||||||
|
|
||||||
libcryptsetup_cli_la_SOURCES = \
|
|
||||||
lib/utils_loop.c \
|
|
||||||
lib/utils_io.c \
|
|
||||||
lib/cli/cli.c \
|
|
||||||
lib/cli/libcryptsetup_cli.h \
|
|
||||||
lib/cli/cli_internal.h
|
|
||||||
417
lib/cli/cli.c
417
lib/cli/cli.c
@@ -1,417 +0,0 @@
|
|||||||
/*
|
|
||||||
* libcryptsetup_cli - cryptsetup command line tools library
|
|
||||||
*
|
|
||||||
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
|
|
||||||
* Copyright (C) 2012-2020 Milan Broz
|
|
||||||
* Copyright (C) 2020 Ondrej Kozina
|
|
||||||
*
|
|
||||||
* This file is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This file 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
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this file; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "nls.h"
|
|
||||||
#include "utils_loop.h"
|
|
||||||
#include "utils_io.h"
|
|
||||||
#include "libcryptsetup.h"
|
|
||||||
#include "libcryptsetup_cli.h"
|
|
||||||
#include "cli_internal.h"
|
|
||||||
|
|
||||||
/* Password reading helpers */
|
|
||||||
static int untimed_read(int fd, char *pass, size_t maxlen)
|
|
||||||
{
|
|
||||||
ssize_t i;
|
|
||||||
|
|
||||||
i = read(fd, pass, maxlen);
|
|
||||||
if (i > 0) {
|
|
||||||
pass[i-1] = '\0';
|
|
||||||
i = 0;
|
|
||||||
} else if (i == 0) { /* EOF */
|
|
||||||
*pass = 0;
|
|
||||||
i = -1;
|
|
||||||
}
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int timed_read(int fd, char *pass, size_t maxlen, long timeout)
|
|
||||||
{
|
|
||||||
struct timeval t;
|
|
||||||
fd_set fds = {}; /* Just to avoid scan-build false report for FD_SET */
|
|
||||||
int failed = -1;
|
|
||||||
|
|
||||||
FD_ZERO(&fds);
|
|
||||||
FD_SET(fd, &fds);
|
|
||||||
t.tv_sec = timeout;
|
|
||||||
t.tv_usec = 0;
|
|
||||||
|
|
||||||
if (select(fd+1, &fds, NULL, NULL, &t) > 0)
|
|
||||||
failed = untimed_read(fd, pass, maxlen);
|
|
||||||
|
|
||||||
return failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined ENABLE_PWQUALITY
|
|
||||||
#include <pwquality.h>
|
|
||||||
|
|
||||||
static int tools_check_pwquality(struct crypt_device *cd, const char *password)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
void *auxerror;
|
|
||||||
pwquality_settings_t *pwq;
|
|
||||||
|
|
||||||
crypt_logf(cd, CRYPT_LOG_DEBUG, "Checking new password using default pwquality settings.");
|
|
||||||
pwq = pwquality_default_settings();
|
|
||||||
if (!pwq)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
r = pwquality_read_config(pwq, NULL, &auxerror);
|
|
||||||
if (r) {
|
|
||||||
crypt_logf(cd, CRYPT_LOG_ERROR, _("Cannot check password quality: %s"),
|
|
||||||
pwquality_strerror(NULL, 0, r, auxerror));
|
|
||||||
pwquality_free_settings(pwq);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = pwquality_check(pwq, password, NULL, NULL, &auxerror);
|
|
||||||
if (r < 0) {
|
|
||||||
crypt_logf(cd, CRYPT_LOG_ERROR, _("Password quality check failed:\n %s"),
|
|
||||||
pwquality_strerror(NULL, 0, r, auxerror));
|
|
||||||
r = -EPERM;
|
|
||||||
} else {
|
|
||||||
crypt_logf(cd, CRYPT_LOG_DEBUG, "New password libpwquality score is %d.", r);
|
|
||||||
r = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pwquality_free_settings(pwq);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
#elif defined ENABLE_PASSWDQC
|
|
||||||
#include <passwdqc.h>
|
|
||||||
|
|
||||||
static int tools_check_pwquality(struct crypt_device *cd, const char *password)
|
|
||||||
{
|
|
||||||
passwdqc_params_t params;
|
|
||||||
char *parse_reason;
|
|
||||||
const char *check_reason;
|
|
||||||
const char *config = PASSWDQC_CONFIG_FILE;
|
|
||||||
|
|
||||||
passwdqc_params_reset(¶ms);
|
|
||||||
|
|
||||||
if (*config && passwdqc_params_load(¶ms, &parse_reason, config)) {
|
|
||||||
crypt_logf(cd, CRYPT_LOG_ERROR, _("Cannot check password quality: %s"),
|
|
||||||
(parse_reason ? parse_reason : "Out of memory"));
|
|
||||||
free(parse_reason);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
check_reason = passwdqc_check(¶ms.qc, password, NULL, NULL);
|
|
||||||
if (check_reason) {
|
|
||||||
crypt_logf(cd, CRYPT_LOG_ERROR, _("Password quality check failed: Bad passphrase (%s)"),
|
|
||||||
check_reason);
|
|
||||||
return -EPERM;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#else /* !(ENABLE_PWQUALITY || ENABLE_PASSWDQC) */
|
|
||||||
static int tools_check_pwquality(struct crypt_device *cd, const char *password)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* ENABLE_PWQUALITY || ENABLE_PASSWDQC */
|
|
||||||
|
|
||||||
static int interactive_pass(const char *prompt, char *pass, size_t maxlen,
|
|
||||||
long timeout)
|
|
||||||
{
|
|
||||||
struct termios orig, tmp;
|
|
||||||
int failed = -1;
|
|
||||||
int infd, outfd;
|
|
||||||
|
|
||||||
if (maxlen < 1)
|
|
||||||
return failed;
|
|
||||||
|
|
||||||
/* Read and write to /dev/tty if available */
|
|
||||||
infd = open("/dev/tty", O_RDWR);
|
|
||||||
if (infd == -1) {
|
|
||||||
infd = STDIN_FILENO;
|
|
||||||
outfd = STDERR_FILENO;
|
|
||||||
} else
|
|
||||||
outfd = infd;
|
|
||||||
|
|
||||||
if (tcgetattr(infd, &orig))
|
|
||||||
goto out_err;
|
|
||||||
|
|
||||||
memcpy(&tmp, &orig, sizeof(tmp));
|
|
||||||
tmp.c_lflag &= ~ECHO;
|
|
||||||
|
|
||||||
if (prompt && write(outfd, prompt, strlen(prompt)) < 0)
|
|
||||||
goto out_err;
|
|
||||||
|
|
||||||
tcsetattr(infd, TCSAFLUSH, &tmp);
|
|
||||||
if (timeout)
|
|
||||||
failed = timed_read(infd, pass, maxlen, timeout);
|
|
||||||
else
|
|
||||||
failed = untimed_read(infd, pass, maxlen);
|
|
||||||
tcsetattr(infd, TCSAFLUSH, &orig);
|
|
||||||
|
|
||||||
out_err:
|
|
||||||
if (!failed && write(outfd, "\n", 1)) {};
|
|
||||||
|
|
||||||
if (infd != STDIN_FILENO)
|
|
||||||
close(infd);
|
|
||||||
return failed;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int crypt_get_key_tty(const char *prompt,
|
|
||||||
char **key, size_t *key_size,
|
|
||||||
int timeout, int verify,
|
|
||||||
struct crypt_device *cd)
|
|
||||||
{
|
|
||||||
int key_size_max = DEFAULT_PASSPHRASE_SIZE_MAX;
|
|
||||||
int r = -EINVAL;
|
|
||||||
char *pass = NULL, *pass_verify = NULL;
|
|
||||||
|
|
||||||
*key = NULL;
|
|
||||||
*key_size = 0;
|
|
||||||
|
|
||||||
crypt_logf(cd, CRYPT_LOG_DEBUG, "Interactive passphrase entry requested.");
|
|
||||||
|
|
||||||
pass = crypt_safe_alloc(key_size_max + 1);
|
|
||||||
if (!pass) {
|
|
||||||
crypt_logf(cd, CRYPT_LOG_ERROR, _("Out of memory while reading passphrase."));
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interactive_pass(prompt, pass, key_size_max, timeout)) {
|
|
||||||
crypt_logf(cd, CRYPT_LOG_ERROR, _("Error reading passphrase from terminal."));
|
|
||||||
goto out_err;
|
|
||||||
}
|
|
||||||
pass[key_size_max] = '\0';
|
|
||||||
|
|
||||||
if (verify) {
|
|
||||||
pass_verify = crypt_safe_alloc(key_size_max);
|
|
||||||
if (!pass_verify) {
|
|
||||||
crypt_logf(cd, CRYPT_LOG_ERROR, _("Out of memory while reading passphrase."));
|
|
||||||
r = -ENOMEM;
|
|
||||||
goto out_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interactive_pass(_("Verify passphrase: "),
|
|
||||||
pass_verify, key_size_max, timeout)) {
|
|
||||||
crypt_logf(cd, CRYPT_LOG_ERROR, _("Error reading passphrase from terminal."));
|
|
||||||
goto out_err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strncmp(pass, pass_verify, key_size_max)) {
|
|
||||||
crypt_logf(cd, CRYPT_LOG_ERROR, _("Passphrases do not match."));
|
|
||||||
r = -EPERM;
|
|
||||||
goto out_err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*key = pass;
|
|
||||||
*key_size = strlen(pass);
|
|
||||||
r = 0;
|
|
||||||
out_err:
|
|
||||||
crypt_safe_free(pass_verify);
|
|
||||||
if (r)
|
|
||||||
crypt_safe_free(pass);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int tools_is_stdin(const char *key_file)
|
|
||||||
{
|
|
||||||
if (!key_file)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return strcmp(key_file, "-") ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Note: --key-file=- is interpreted as a read from a binary file (stdin)
|
|
||||||
* key_size_max == 0 means detect maximum according to input type (tty/file)
|
|
||||||
*/
|
|
||||||
int crypt_cli_get_key(const char *prompt,
|
|
||||||
char **key, size_t *key_size,
|
|
||||||
uint64_t keyfile_offset, size_t keyfile_size_max,
|
|
||||||
const char *key_file,
|
|
||||||
int timeout, int verify, int pwquality,
|
|
||||||
struct crypt_device *cd, struct crypt_cli *ctx __attribute__((unused)))
|
|
||||||
{
|
|
||||||
char tmp[PATH_MAX], *backing_file;
|
|
||||||
int r = -EINVAL;
|
|
||||||
|
|
||||||
if (tools_is_stdin(key_file)) {
|
|
||||||
if (isatty(STDIN_FILENO)) {
|
|
||||||
if (keyfile_offset) {
|
|
||||||
crypt_logf(cd, CRYPT_LOG_ERROR, _("Cannot use offset with terminal input."));
|
|
||||||
} else {
|
|
||||||
if (!prompt && !crypt_get_device_name(cd))
|
|
||||||
snprintf(tmp, sizeof(tmp), _("Enter passphrase: "));
|
|
||||||
else if (!prompt) {
|
|
||||||
backing_file = crypt_loop_backing_file(crypt_get_device_name(cd));
|
|
||||||
snprintf(tmp, sizeof(tmp), _("Enter passphrase for %s: "), backing_file ?: crypt_get_device_name(cd));
|
|
||||||
free(backing_file);
|
|
||||||
}
|
|
||||||
r = crypt_get_key_tty(prompt ?: tmp, key, key_size, timeout, verify, cd);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
crypt_logf(cd, CRYPT_LOG_DEBUG, "STDIN descriptor passphrase entry requested.");
|
|
||||||
/* No keyfile means STDIN with EOL handling (\n will end input)). */
|
|
||||||
r = crypt_keyfile_device_read(cd, NULL, key, key_size,
|
|
||||||
keyfile_offset, keyfile_size_max,
|
|
||||||
key_file ? 0 : CRYPT_KEYFILE_STOP_EOL);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
crypt_logf(cd, CRYPT_LOG_DEBUG, "File descriptor passphrase entry requested.");
|
|
||||||
r = crypt_keyfile_device_read(cd, key_file, key, key_size,
|
|
||||||
keyfile_offset, keyfile_size_max, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check pwquality for password (not keyfile) */
|
|
||||||
if (pwquality && !key_file && !r)
|
|
||||||
r = tools_check_pwquality(cd, *key);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
int crypt_cli_read_mk(struct crypt_device *cd, const char *file, char **key, size_t keysize)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
ssize_t ret;
|
|
||||||
|
|
||||||
if (!keysize || !key)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
*key = crypt_safe_alloc(keysize);
|
|
||||||
if (!*key)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
fd = open(file, O_RDONLY);
|
|
||||||
if (fd == -1) {
|
|
||||||
crypt_logf(cd, CRYPT_LOG_ERROR, _("Cannot read keyfile %s."), file);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = read_buffer(fd, *key, keysize);
|
|
||||||
if (ret < 0 || (size_t)ret != keysize) {
|
|
||||||
crypt_logf(cd, CRYPT_LOG_ERROR, _("Cannot read %d bytes from keyfile %s."), keysize, file);
|
|
||||||
close(fd);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
return 0;
|
|
||||||
fail:
|
|
||||||
crypt_safe_free(*key);
|
|
||||||
*key = NULL;
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct tools_arg *find_arg_in_args(const char *name, const struct tools_arg *args, size_t args_len)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (!args || !args_len)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < args_len; i++) {
|
|
||||||
if (args[i].name && !strcmp(name, args[i].name))
|
|
||||||
return args + i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct tools_arg *find_arg_by_name(struct crypt_cli *ctx, const char *name)
|
|
||||||
{
|
|
||||||
return find_arg_in_args(name, ctx->core_args, ctx->core_args_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
int crypt_cli_arg_value(struct crypt_cli *ctx, const char *name, void *value)
|
|
||||||
{
|
|
||||||
const struct tools_arg *arg;
|
|
||||||
|
|
||||||
if (!name || !ctx || !value)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
arg = find_arg_by_name(ctx, name);
|
|
||||||
if (!arg)
|
|
||||||
return -ENOENT;
|
|
||||||
|
|
||||||
switch (arg->type) {
|
|
||||||
case CRYPT_ARG_BOOL:
|
|
||||||
*((bool *)value) = arg->set;
|
|
||||||
break;
|
|
||||||
case CRYPT_ARG_STRING:
|
|
||||||
*((char **)value) = arg->u.str_value;
|
|
||||||
break;
|
|
||||||
case CRYPT_ARG_INT32:
|
|
||||||
*((int32_t *)value) = arg->u.i32_value;
|
|
||||||
break;
|
|
||||||
case CRYPT_ARG_UINT32:
|
|
||||||
*((uint32_t *)value) = arg->u.u32_value;
|
|
||||||
break;
|
|
||||||
case CRYPT_ARG_INT64:
|
|
||||||
*((int64_t *)value) = arg->u.i64_value;
|
|
||||||
break;
|
|
||||||
case CRYPT_ARG_UINT64:
|
|
||||||
*((uint64_t *)value) = arg->u.u64_value;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int crypt_cli_arg_type(struct crypt_cli *ctx, const char *name, crypt_arg_type_info *type)
|
|
||||||
{
|
|
||||||
const struct tools_arg *arg;
|
|
||||||
|
|
||||||
if (!name || !type || !ctx)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
arg = find_arg_by_name(ctx, name);
|
|
||||||
if (!arg)
|
|
||||||
return -ENOENT;
|
|
||||||
|
|
||||||
*type = arg->type;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool crypt_cli_arg_set(struct crypt_cli *ctx, const char *name)
|
|
||||||
{
|
|
||||||
const struct tools_arg *arg;
|
|
||||||
|
|
||||||
if (!name || !ctx)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
arg = find_arg_by_name(ctx, name);
|
|
||||||
if (!arg)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return arg->set;
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* libcryptsetup_cli - cryptsetup command line tools library
|
|
||||||
*
|
|
||||||
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
|
|
||||||
* Copyright (C) 2012-2020 Milan Broz
|
|
||||||
* Copyright (C) 2020 Ondrej Kozina
|
|
||||||
*
|
|
||||||
* This file is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This file 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
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this file; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef CLI_INTERNAL_H
|
|
||||||
#define CLI_INTERNAL_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#define MAX_ACTIONS 16
|
|
||||||
|
|
||||||
struct tools_arg {
|
|
||||||
const char *name;
|
|
||||||
bool set;
|
|
||||||
crypt_arg_type_info type;
|
|
||||||
union {
|
|
||||||
char *str_value;
|
|
||||||
uint64_t u64_value;
|
|
||||||
uint32_t u32_value;
|
|
||||||
int32_t i32_value;
|
|
||||||
int64_t i64_value;
|
|
||||||
} u;
|
|
||||||
const char *actions_array[MAX_ACTIONS];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct crypt_cli {
|
|
||||||
const struct tools_arg *core_args;
|
|
||||||
size_t core_args_count;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* libcryptsetup_cli - cryptsetup command line tools library
|
|
||||||
*
|
|
||||||
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
|
|
||||||
* Copyright (C) 2012-2020 Milan Broz
|
|
||||||
* Copyright (C) 2020 Ondrej Kozina
|
|
||||||
*
|
|
||||||
* This file is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This file 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
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this file; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _LIBCRYPTSETUP_CLI_H
|
|
||||||
#define _LIBCRYPTSETUP_CLI_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
struct crypt_cli;
|
|
||||||
struct crypt_device;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
CRYPT_ARG_BOOL = 0,
|
|
||||||
CRYPT_ARG_STRING,
|
|
||||||
CRYPT_ARG_INT32,
|
|
||||||
CRYPT_ARG_UINT32,
|
|
||||||
CRYPT_ARG_INT64,
|
|
||||||
CRYPT_ARG_UINT64
|
|
||||||
} crypt_arg_type_info;
|
|
||||||
|
|
||||||
int crypt_cli_get_key(const char *prompt,
|
|
||||||
char **key, size_t *key_size,
|
|
||||||
uint64_t keyfile_offset, size_t keyfile_size_max,
|
|
||||||
const char *key_file,
|
|
||||||
int timeout, int verify, int pwquality,
|
|
||||||
struct crypt_device *cd, struct crypt_cli *ctx);
|
|
||||||
|
|
||||||
int crypt_cli_read_mk(struct crypt_device *cd, const char *file, char **key, size_t keysize);
|
|
||||||
|
|
||||||
bool crypt_cli_arg_set(struct crypt_cli *ctx, const char *name);
|
|
||||||
|
|
||||||
int crypt_cli_arg_value(struct crypt_cli *ctx, const char *name, void *value);
|
|
||||||
|
|
||||||
int crypt_cli_arg_type(struct crypt_cli *ctx, const char *name, crypt_arg_type_info *type);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
prefix=@prefix@
|
|
||||||
exec_prefix=@exec_prefix@
|
|
||||||
libclidir=@libdir@
|
|
||||||
includedir=@includedir@
|
|
||||||
|
|
||||||
Name: cryptsetup-cli
|
|
||||||
Description: cryptsetup cli library
|
|
||||||
Version: @LIBCRYPTSETUP_VERSION@
|
|
||||||
Cflags: -I${includedir}
|
|
||||||
Libs: -L${libdir} -lcryptsetup_cli
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
CRYPTSETUP_CLI_1.0 {
|
|
||||||
global:
|
|
||||||
crypt_cli_get_key;
|
|
||||||
crypt_cli_read_mk;
|
|
||||||
crypt_cli_arg_set;
|
|
||||||
crypt_cli_arg_type;
|
|
||||||
crypt_cli_arg_value;
|
|
||||||
local:
|
|
||||||
*;
|
|
||||||
};
|
|
||||||
@@ -1,9 +1,6 @@
|
|||||||
# cryptsetup
|
# cryptsetup
|
||||||
if CRYPTSETUP
|
if CRYPTSETUP
|
||||||
|
|
||||||
# cryptsetup_CPPFLAGS = $(AM_CPPFLAGS) \
|
|
||||||
# -I $(top_srcdir)/lib/cli
|
|
||||||
|
|
||||||
cryptsetup_SOURCES = \
|
cryptsetup_SOURCES = \
|
||||||
lib/utils_crypt.c \
|
lib/utils_crypt.c \
|
||||||
lib/utils_loop.c \
|
lib/utils_loop.c \
|
||||||
@@ -23,8 +20,9 @@ cryptsetup_SOURCES = \
|
|||||||
|
|
||||||
cryptsetup_LDADD = $(LDADD) \
|
cryptsetup_LDADD = $(LDADD) \
|
||||||
libcryptsetup.la \
|
libcryptsetup.la \
|
||||||
libcryptsetup_cli.la \
|
|
||||||
@POPT_LIBS@ \
|
@POPT_LIBS@ \
|
||||||
|
@PWQUALITY_LIBS@ \
|
||||||
|
@PASSWDQC_LIBS@ \
|
||||||
@UUID_LIBS@ \
|
@UUID_LIBS@ \
|
||||||
@BLKID_LIBS@
|
@BLKID_LIBS@
|
||||||
|
|
||||||
@@ -62,8 +60,9 @@ veritysetup_SOURCES = \
|
|||||||
|
|
||||||
veritysetup_LDADD = $(LDADD) \
|
veritysetup_LDADD = $(LDADD) \
|
||||||
libcryptsetup.la \
|
libcryptsetup.la \
|
||||||
libcryptsetup_cli.la \
|
|
||||||
@POPT_LIBS@ \
|
@POPT_LIBS@ \
|
||||||
|
@PWQUALITY_LIBS@ \
|
||||||
|
@PASSWDQC_LIBS@ \
|
||||||
@BLKID_LIBS@
|
@BLKID_LIBS@
|
||||||
|
|
||||||
sbin_PROGRAMS += veritysetup
|
sbin_PROGRAMS += veritysetup
|
||||||
@@ -92,6 +91,7 @@ integritysetup_SOURCES = \
|
|||||||
src/utils_arg_names.h \
|
src/utils_arg_names.h \
|
||||||
src/utils_arg_macros.h \
|
src/utils_arg_macros.h \
|
||||||
src/utils_tools.c \
|
src/utils_tools.c \
|
||||||
|
src/utils_password.c \
|
||||||
src/utils_blockdev.c \
|
src/utils_blockdev.c \
|
||||||
src/integritysetup.c \
|
src/integritysetup.c \
|
||||||
src/integritysetup_args.h \
|
src/integritysetup_args.h \
|
||||||
@@ -100,8 +100,9 @@ integritysetup_SOURCES = \
|
|||||||
|
|
||||||
integritysetup_LDADD = $(LDADD) \
|
integritysetup_LDADD = $(LDADD) \
|
||||||
libcryptsetup.la \
|
libcryptsetup.la \
|
||||||
libcryptsetup_cli.la \
|
|
||||||
@POPT_LIBS@ \
|
@POPT_LIBS@ \
|
||||||
|
@PWQUALITY_LIBS@ \
|
||||||
|
@PASSWDQC_LIBS@ \
|
||||||
@UUID_LIBS@ \
|
@UUID_LIBS@ \
|
||||||
@BLKID_LIBS@
|
@BLKID_LIBS@
|
||||||
|
|
||||||
@@ -136,8 +137,9 @@ cryptsetup_reencrypt_SOURCES = \
|
|||||||
|
|
||||||
cryptsetup_reencrypt_LDADD = $(LDADD) \
|
cryptsetup_reencrypt_LDADD = $(LDADD) \
|
||||||
libcryptsetup.la \
|
libcryptsetup.la \
|
||||||
libcryptsetup_cli.la \
|
|
||||||
@POPT_LIBS@ \
|
@POPT_LIBS@ \
|
||||||
|
@PWQUALITY_LIBS@ \
|
||||||
|
@PASSWDQC_LIBS@ \
|
||||||
@UUID_LIBS@ \
|
@UUID_LIBS@ \
|
||||||
@BLKID_LIBS@
|
@BLKID_LIBS@
|
||||||
|
|
||||||
|
|||||||
@@ -167,25 +167,6 @@ static int _set_tries_tty(void)
|
|||||||
return (tools_is_stdin(ARG_STR(OPT_KEY_FILE_ID)) && isatty(STDIN_FILENO)) ? ARG_UINT32(OPT_TRIES_ID) : 1;
|
return (tools_is_stdin(ARG_STR(OPT_KEY_FILE_ID)) && isatty(STDIN_FILENO)) ? ARG_UINT32(OPT_TRIES_ID) : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tools_write_mk(const char *file, const char *key, int keysize)
|
|
||||||
{
|
|
||||||
int fd, r = -EINVAL;
|
|
||||||
|
|
||||||
fd = open(file, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR);
|
|
||||||
if (fd < 0) {
|
|
||||||
log_err(_("Cannot open keyfile %s for write."), file);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (write_buffer(fd, key, keysize) == keysize)
|
|
||||||
r = 0;
|
|
||||||
else
|
|
||||||
log_err(_("Cannot write to keyfile %s."), file);
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int action_open_plain(void)
|
static int action_open_plain(void)
|
||||||
{
|
{
|
||||||
struct crypt_device *cd = NULL, *cd1 = NULL;
|
struct crypt_device *cd = NULL, *cd1 = NULL;
|
||||||
@@ -515,7 +496,7 @@ static int action_open_bitlk(void)
|
|||||||
} else if (!keysize)
|
} else if (!keysize)
|
||||||
keysize = ARG_UINT32(OPT_KEY_SIZE_ID) / 8;
|
keysize = ARG_UINT32(OPT_KEY_SIZE_ID) / 8;
|
||||||
|
|
||||||
r = crypt_cli_read_mk(cd, ARG_STR(OPT_MASTER_KEY_FILE_ID), &key, keysize);
|
r = tools_read_mk(ARG_STR(OPT_MASTER_KEY_FILE_ID), &key, keysize);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
r = crypt_activate_by_volume_key(cd, activated_name,
|
r = crypt_activate_by_volume_key(cd, activated_name,
|
||||||
@@ -1411,7 +1392,7 @@ static int _luksFormat(struct crypt_device **r_cd, char **r_password, size_t *r_
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (ARG_SET(OPT_MASTER_KEY_FILE_ID)) {
|
if (ARG_SET(OPT_MASTER_KEY_FILE_ID)) {
|
||||||
r = crypt_cli_read_mk(cd, ARG_STR(OPT_MASTER_KEY_FILE_ID), &key, keysize);
|
r = tools_read_mk(ARG_STR(OPT_MASTER_KEY_FILE_ID), &key, keysize);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -1520,7 +1501,7 @@ static int action_open_luks(void)
|
|||||||
} else if (!keysize)
|
} else if (!keysize)
|
||||||
keysize = ARG_UINT32(OPT_KEY_SIZE_ID) / 8;
|
keysize = ARG_UINT32(OPT_KEY_SIZE_ID) / 8;
|
||||||
|
|
||||||
r = crypt_cli_read_mk(cd, ARG_STR(OPT_MASTER_KEY_FILE_ID), &key, keysize);
|
r = tools_read_mk(ARG_STR(OPT_MASTER_KEY_FILE_ID), &key, keysize);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
r = crypt_activate_by_volume_key(cd, activated_name,
|
r = crypt_activate_by_volume_key(cd, activated_name,
|
||||||
@@ -1764,7 +1745,7 @@ static int luksAddUnboundKey(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ARG_SET(OPT_MASTER_KEY_FILE_ID)) {
|
if (ARG_SET(OPT_MASTER_KEY_FILE_ID)) {
|
||||||
r = crypt_cli_read_mk(cd, ARG_STR(OPT_MASTER_KEY_FILE_ID), &key, keysize);
|
r = tools_read_mk(ARG_STR(OPT_MASTER_KEY_FILE_ID), &key, keysize);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@@ -1836,7 +1817,7 @@ static int action_luksAddKey(void)
|
|||||||
} else if (!keysize)
|
} else if (!keysize)
|
||||||
keysize = ARG_UINT32(OPT_KEY_SIZE_ID) / 8;
|
keysize = ARG_UINT32(OPT_KEY_SIZE_ID) / 8;
|
||||||
|
|
||||||
r = crypt_cli_read_mk(cd, ARG_STR(OPT_MASTER_KEY_FILE_ID), &key, keysize);
|
r = tools_read_mk(ARG_STR(OPT_MASTER_KEY_FILE_ID), &key, keysize);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@@ -3258,7 +3239,7 @@ static int action_reencrypt_luks2(struct crypt_device *cd)
|
|||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
if (ARG_SET(OPT_MASTER_KEY_FILE_ID)) {
|
if (ARG_SET(OPT_MASTER_KEY_FILE_ID)) {
|
||||||
r = crypt_cli_read_mk(cd, ARG_STR(OPT_MASTER_KEY_FILE_ID), &vk, key_size);
|
r = tools_read_mk(ARG_STR(OPT_MASTER_KEY_FILE_ID), &vk, key_size);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,8 +48,6 @@
|
|||||||
#include "lib/utils_blkid.h"
|
#include "lib/utils_blkid.h"
|
||||||
|
|
||||||
#include "libcryptsetup.h"
|
#include "libcryptsetup.h"
|
||||||
#include "libcryptsetup_cli.h"
|
|
||||||
#include "lib/cli/cli_internal.h"
|
|
||||||
|
|
||||||
#define CONST_CAST(x) (x)(uintptr_t)
|
#define CONST_CAST(x) (x)(uintptr_t)
|
||||||
#define DEFAULT_CIPHER(type) (DEFAULT_##type##_CIPHER "-" DEFAULT_##type##_MODE)
|
#define DEFAULT_CIPHER(type) (DEFAULT_##type##_CIPHER "-" DEFAULT_##type##_MODE)
|
||||||
@@ -109,6 +107,9 @@ struct tools_progress_params {
|
|||||||
int tools_wipe_progress(uint64_t size, uint64_t offset, void *usrptr);
|
int tools_wipe_progress(uint64_t size, uint64_t offset, void *usrptr);
|
||||||
int tools_reencrypt_progress(uint64_t size, uint64_t offset, void *usrptr);
|
int tools_reencrypt_progress(uint64_t size, uint64_t offset, void *usrptr);
|
||||||
|
|
||||||
|
int tools_read_mk(const char *file, char **key, int keysize);
|
||||||
|
int tools_write_mk(const char *file, const char *key, int keysize);
|
||||||
|
|
||||||
int tools_read_json_file(struct crypt_device *cd, const char *file, char **json, size_t *json_size, bool batch_mode);
|
int tools_read_json_file(struct crypt_device *cd, const char *file, char **json, size_t *json_size, bool batch_mode);
|
||||||
int tools_write_json_file(struct crypt_device *cd, const char *file, const char *json);
|
int tools_write_json_file(struct crypt_device *cd, const char *file, const char *json);
|
||||||
|
|
||||||
@@ -118,11 +119,6 @@ int tools_wipe_all_signatures(const char *path);
|
|||||||
int tools_lookup_crypt_device(struct crypt_device *cd, const char *type,
|
int tools_lookup_crypt_device(struct crypt_device *cd, const char *type,
|
||||||
const char *data_device_path, char *name, size_t name_length);
|
const char *data_device_path, char *name, size_t name_length);
|
||||||
|
|
||||||
void tools_parse_arg_value(poptContext popt_context, crypt_arg_type_info type, struct tools_arg *arg, const char *popt_arg, int popt_val, bool(*needs_size_conv_fn)(unsigned arg_id));
|
|
||||||
|
|
||||||
void tools_args_free(struct tools_arg *args, size_t args_count);
|
|
||||||
|
|
||||||
void tools_check_args(const char *action, const struct tools_arg *args, size_t args_size, poptContext popt_context);
|
|
||||||
|
|
||||||
/* each utility is required to implement it */
|
/* each utility is required to implement it */
|
||||||
void tools_cleanup(void);
|
void tools_cleanup(void);
|
||||||
@@ -135,6 +131,35 @@ void tools_cleanup(void);
|
|||||||
#define log_verbose(x...) crypt_logf(NULL, CRYPT_LOG_VERBOSE, x)
|
#define log_verbose(x...) crypt_logf(NULL, CRYPT_LOG_VERBOSE, x)
|
||||||
#define log_err(x...) crypt_logf(NULL, CRYPT_LOG_ERROR, x)
|
#define log_err(x...) crypt_logf(NULL, CRYPT_LOG_ERROR, x)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CRYPT_ARG_BOOL = 0,
|
||||||
|
CRYPT_ARG_STRING,
|
||||||
|
CRYPT_ARG_INT32,
|
||||||
|
CRYPT_ARG_UINT32,
|
||||||
|
CRYPT_ARG_INT64,
|
||||||
|
CRYPT_ARG_UINT64
|
||||||
|
} crypt_arg_type_info;
|
||||||
|
|
||||||
|
struct tools_arg {
|
||||||
|
const char *name;
|
||||||
|
bool set;
|
||||||
|
crypt_arg_type_info type;
|
||||||
|
union {
|
||||||
|
char *str_value;
|
||||||
|
uint64_t u64_value;
|
||||||
|
uint32_t u32_value;
|
||||||
|
int32_t i32_value;
|
||||||
|
int64_t i64_value;
|
||||||
|
} u;
|
||||||
|
const char *actions_array[MAX_ACTIONS];
|
||||||
|
};
|
||||||
|
|
||||||
|
void tools_parse_arg_value(poptContext popt_context, crypt_arg_type_info type, struct tools_arg *arg, const char *popt_arg, int popt_val, bool(*needs_size_conv_fn)(unsigned arg_id));
|
||||||
|
|
||||||
|
void tools_args_free(struct tools_arg *args, size_t args_count);
|
||||||
|
|
||||||
|
void tools_check_args(const char *action, const struct tools_arg *args, size_t args_size, poptContext popt_context);
|
||||||
|
|
||||||
struct tools_log_params {
|
struct tools_log_params {
|
||||||
bool verbose;
|
bool verbose;
|
||||||
bool debug;
|
bool debug;
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
|
|
||||||
#include "utils_arg_names.h"
|
#include "utils_arg_names.h"
|
||||||
#include "utils_arg_macros.h"
|
#include "utils_arg_macros.h"
|
||||||
#include "lib/cli/cli_internal.h"
|
|
||||||
|
|
||||||
#define BITLKDUMP_ACTION "bitlkDump"
|
#define BITLKDUMP_ACTION "bitlkDump"
|
||||||
#define BENCHMARK_ACTION "benchmark"
|
#define BENCHMARK_ACTION "benchmark"
|
||||||
|
|||||||
@@ -717,7 +717,7 @@ static int backup_luks_headers(struct reenc_ctx *rc)
|
|||||||
rc->p[rc->keyslot].password, rc->p[rc->keyslot].passwordLen);
|
rc->p[rc->keyslot].password, rc->p[rc->keyslot].passwordLen);
|
||||||
} else if (ARG_SET(OPT_MASTER_KEY_FILE_ID)) {
|
} else if (ARG_SET(OPT_MASTER_KEY_FILE_ID)) {
|
||||||
log_dbg("Loading new key from file.");
|
log_dbg("Loading new key from file.");
|
||||||
r = crypt_cli_read_mk(cd, ARG_STR(OPT_MASTER_KEY_FILE_ID), &key, key_size);
|
r = tools_read_mk(ARG_STR(OPT_MASTER_KEY_FILE_ID), &key, key_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
|||||||
@@ -46,14 +46,14 @@ static int _read_keys(char **integrity_key, struct crypt_params_integrity *param
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (integrity_key && ARG_SET(OPT_INTEGRITY_KEY_FILE_ID)) {
|
if (integrity_key && ARG_SET(OPT_INTEGRITY_KEY_FILE_ID)) {
|
||||||
r = crypt_cli_read_mk(NULL, ARG_STR(OPT_INTEGRITY_KEY_FILE_ID), &int_key, ARG_UINT32(OPT_INTEGRITY_KEY_SIZE_ID));
|
r = tools_read_mk(ARG_STR(OPT_INTEGRITY_KEY_FILE_ID), &int_key, ARG_UINT32(OPT_INTEGRITY_KEY_SIZE_ID));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
params->integrity_key_size = ARG_UINT32(OPT_INTEGRITY_KEY_SIZE_ID);
|
params->integrity_key_size = ARG_UINT32(OPT_INTEGRITY_KEY_SIZE_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ARG_SET(OPT_JOURNAL_INTEGRITY_KEY_FILE_ID)) {
|
if (ARG_SET(OPT_JOURNAL_INTEGRITY_KEY_FILE_ID)) {
|
||||||
r = crypt_cli_read_mk(NULL, ARG_STR(OPT_JOURNAL_INTEGRITY_KEY_FILE_ID), &journal_integrity_key, ARG_UINT32(OPT_JOURNAL_INTEGRITY_KEY_SIZE_ID));
|
r = tools_read_mk(ARG_STR(OPT_JOURNAL_INTEGRITY_KEY_FILE_ID), &journal_integrity_key, ARG_UINT32(OPT_JOURNAL_INTEGRITY_KEY_SIZE_ID));
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
crypt_safe_free(int_key);
|
crypt_safe_free(int_key);
|
||||||
return r;
|
return r;
|
||||||
@@ -63,7 +63,7 @@ static int _read_keys(char **integrity_key, struct crypt_params_integrity *param
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ARG_SET(OPT_JOURNAL_CRYPT_KEY_FILE_ID)) {
|
if (ARG_SET(OPT_JOURNAL_CRYPT_KEY_FILE_ID)) {
|
||||||
r = crypt_cli_read_mk(NULL, ARG_STR(OPT_JOURNAL_CRYPT_KEY_FILE_ID), &journal_crypt_key, ARG_UINT32(OPT_JOURNAL_CRYPT_KEY_SIZE_ID));
|
r = tools_read_mk(ARG_STR(OPT_JOURNAL_CRYPT_KEY_FILE_ID), &journal_crypt_key, ARG_UINT32(OPT_JOURNAL_CRYPT_KEY_SIZE_ID));
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
crypt_safe_free(int_key);
|
crypt_safe_free(int_key);
|
||||||
crypt_safe_free(journal_integrity_key);
|
crypt_safe_free(journal_integrity_key);
|
||||||
|
|||||||
@@ -20,6 +20,264 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cryptsetup.h"
|
#include "cryptsetup.h"
|
||||||
|
#include <termios.h>
|
||||||
|
|
||||||
|
#if defined ENABLE_PWQUALITY
|
||||||
|
#include <pwquality.h>
|
||||||
|
|
||||||
|
static int tools_check_pwquality(const char *password)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
void *auxerror;
|
||||||
|
pwquality_settings_t *pwq;
|
||||||
|
|
||||||
|
log_dbg("Checking new password using default pwquality settings.");
|
||||||
|
pwq = pwquality_default_settings();
|
||||||
|
if (!pwq)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
r = pwquality_read_config(pwq, NULL, &auxerror);
|
||||||
|
if (r) {
|
||||||
|
log_err(_("Cannot check password quality: %s"),
|
||||||
|
pwquality_strerror(NULL, 0, r, auxerror));
|
||||||
|
pwquality_free_settings(pwq);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = pwquality_check(pwq, password, NULL, NULL, &auxerror);
|
||||||
|
if (r < 0) {
|
||||||
|
log_err(_("Password quality check failed:\n %s"),
|
||||||
|
pwquality_strerror(NULL, 0, r, auxerror));
|
||||||
|
r = -EPERM;
|
||||||
|
} else {
|
||||||
|
log_dbg("New password libpwquality score is %d.", r);
|
||||||
|
r = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pwquality_free_settings(pwq);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
#elif defined ENABLE_PASSWDQC
|
||||||
|
#include <passwdqc.h>
|
||||||
|
|
||||||
|
static int tools_check_pwquality(const char *password)
|
||||||
|
{
|
||||||
|
passwdqc_params_t params;
|
||||||
|
char *parse_reason;
|
||||||
|
const char *check_reason;
|
||||||
|
const char *config = PASSWDQC_CONFIG_FILE;
|
||||||
|
|
||||||
|
passwdqc_params_reset(¶ms);
|
||||||
|
|
||||||
|
if (*config && passwdqc_params_load(¶ms, &parse_reason, config)) {
|
||||||
|
log_err(_("Cannot check password quality: %s"),
|
||||||
|
(parse_reason ? parse_reason : "Out of memory"));
|
||||||
|
free(parse_reason);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
check_reason = passwdqc_check(¶ms.qc, password, NULL, NULL);
|
||||||
|
if (check_reason) {
|
||||||
|
log_err(_("Password quality check failed: Bad passphrase (%s)"),
|
||||||
|
check_reason);
|
||||||
|
return -EPERM;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else /* !(ENABLE_PWQUALITY || ENABLE_PASSWDQC) */
|
||||||
|
static int tools_check_pwquality(const char *password)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* ENABLE_PWQUALITY || ENABLE_PASSWDQC */
|
||||||
|
|
||||||
|
/* Password reading helpers */
|
||||||
|
static int untimed_read(int fd, char *pass, size_t maxlen)
|
||||||
|
{
|
||||||
|
ssize_t i;
|
||||||
|
|
||||||
|
i = read(fd, pass, maxlen);
|
||||||
|
if (i > 0) {
|
||||||
|
pass[i-1] = '\0';
|
||||||
|
i = 0;
|
||||||
|
} else if (i == 0) { /* EOF */
|
||||||
|
*pass = 0;
|
||||||
|
i = -1;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int timed_read(int fd, char *pass, size_t maxlen, long timeout)
|
||||||
|
{
|
||||||
|
struct timeval t;
|
||||||
|
fd_set fds = {}; /* Just to avoid scan-build false report for FD_SET */
|
||||||
|
int failed = -1;
|
||||||
|
|
||||||
|
FD_ZERO(&fds);
|
||||||
|
FD_SET(fd, &fds);
|
||||||
|
t.tv_sec = timeout;
|
||||||
|
t.tv_usec = 0;
|
||||||
|
|
||||||
|
if (select(fd+1, &fds, NULL, NULL, &t) > 0)
|
||||||
|
failed = untimed_read(fd, pass, maxlen);
|
||||||
|
|
||||||
|
return failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int interactive_pass(const char *prompt, char *pass, size_t maxlen,
|
||||||
|
long timeout)
|
||||||
|
{
|
||||||
|
struct termios orig, tmp;
|
||||||
|
int failed = -1;
|
||||||
|
int infd, outfd;
|
||||||
|
|
||||||
|
if (maxlen < 1)
|
||||||
|
return failed;
|
||||||
|
|
||||||
|
/* Read and write to /dev/tty if available */
|
||||||
|
infd = open("/dev/tty", O_RDWR);
|
||||||
|
if (infd == -1) {
|
||||||
|
infd = STDIN_FILENO;
|
||||||
|
outfd = STDERR_FILENO;
|
||||||
|
} else
|
||||||
|
outfd = infd;
|
||||||
|
|
||||||
|
if (tcgetattr(infd, &orig))
|
||||||
|
goto out_err;
|
||||||
|
|
||||||
|
memcpy(&tmp, &orig, sizeof(tmp));
|
||||||
|
tmp.c_lflag &= ~ECHO;
|
||||||
|
|
||||||
|
if (prompt && write(outfd, prompt, strlen(prompt)) < 0)
|
||||||
|
goto out_err;
|
||||||
|
|
||||||
|
tcsetattr(infd, TCSAFLUSH, &tmp);
|
||||||
|
if (timeout)
|
||||||
|
failed = timed_read(infd, pass, maxlen, timeout);
|
||||||
|
else
|
||||||
|
failed = untimed_read(infd, pass, maxlen);
|
||||||
|
tcsetattr(infd, TCSAFLUSH, &orig);
|
||||||
|
|
||||||
|
out_err:
|
||||||
|
if (!failed && write(outfd, "\n", 1)) {};
|
||||||
|
|
||||||
|
if (infd != STDIN_FILENO)
|
||||||
|
close(infd);
|
||||||
|
return failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int crypt_get_key_tty(const char *prompt,
|
||||||
|
char **key, size_t *key_size,
|
||||||
|
int timeout, int verify,
|
||||||
|
struct crypt_device *cd)
|
||||||
|
{
|
||||||
|
int key_size_max = DEFAULT_PASSPHRASE_SIZE_MAX;
|
||||||
|
int r = -EINVAL;
|
||||||
|
char *pass = NULL, *pass_verify = NULL;
|
||||||
|
|
||||||
|
*key = NULL;
|
||||||
|
*key_size = 0;
|
||||||
|
|
||||||
|
log_dbg("Interactive passphrase entry requested.");
|
||||||
|
|
||||||
|
pass = crypt_safe_alloc(key_size_max + 1);
|
||||||
|
if (!pass) {
|
||||||
|
log_err( _("Out of memory while reading passphrase."));
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interactive_pass(prompt, pass, key_size_max, timeout)) {
|
||||||
|
log_err(_("Error reading passphrase from terminal."));
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
pass[key_size_max] = '\0';
|
||||||
|
|
||||||
|
if (verify) {
|
||||||
|
pass_verify = crypt_safe_alloc(key_size_max);
|
||||||
|
if (!pass_verify) {
|
||||||
|
log_err(_("Out of memory while reading passphrase."));
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interactive_pass(_("Verify passphrase: "),
|
||||||
|
pass_verify, key_size_max, timeout)) {
|
||||||
|
log_err(_("Error reading passphrase from terminal."));
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strncmp(pass, pass_verify, key_size_max)) {
|
||||||
|
log_err(_("Passphrases do not match."));
|
||||||
|
r = -EPERM;
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*key = pass;
|
||||||
|
*key_size = strlen(pass);
|
||||||
|
r = 0;
|
||||||
|
out_err:
|
||||||
|
crypt_safe_free(pass_verify);
|
||||||
|
if (r)
|
||||||
|
crypt_safe_free(pass);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note: --key-file=- is interpreted as a read from a binary file (stdin)
|
||||||
|
* key_size_max == 0 means detect maximum according to input type (tty/file)
|
||||||
|
*/
|
||||||
|
int tools_get_key(const char *prompt,
|
||||||
|
char **key, size_t *key_size,
|
||||||
|
uint64_t keyfile_offset, size_t keyfile_size_max,
|
||||||
|
const char *key_file,
|
||||||
|
int timeout, int verify, int pwquality,
|
||||||
|
struct crypt_device *cd)
|
||||||
|
{
|
||||||
|
char tmp[PATH_MAX], *backing_file;
|
||||||
|
int r = -EINVAL, block;
|
||||||
|
|
||||||
|
block = tools_signals_blocked();
|
||||||
|
if (block)
|
||||||
|
set_int_block(0);
|
||||||
|
|
||||||
|
if (tools_is_stdin(key_file)) {
|
||||||
|
if (isatty(STDIN_FILENO)) {
|
||||||
|
if (keyfile_offset) {
|
||||||
|
log_err(_("Cannot use offset with terminal input."));
|
||||||
|
} else {
|
||||||
|
if (!prompt && !crypt_get_device_name(cd))
|
||||||
|
snprintf(tmp, sizeof(tmp), _("Enter passphrase: "));
|
||||||
|
else if (!prompt) {
|
||||||
|
backing_file = crypt_loop_backing_file(crypt_get_device_name(cd));
|
||||||
|
snprintf(tmp, sizeof(tmp), _("Enter passphrase for %s: "), backing_file ?: crypt_get_device_name(cd));
|
||||||
|
free(backing_file);
|
||||||
|
}
|
||||||
|
r = crypt_get_key_tty(prompt ?: tmp, key, key_size, timeout, verify, cd);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log_dbg("STDIN descriptor passphrase entry requested.");
|
||||||
|
/* No keyfile means STDIN with EOL handling (\n will end input)). */
|
||||||
|
r = crypt_keyfile_device_read(cd, NULL, key, key_size,
|
||||||
|
keyfile_offset, keyfile_size_max,
|
||||||
|
key_file ? 0 : CRYPT_KEYFILE_STOP_EOL);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log_dbg("File descriptor passphrase entry requested.");
|
||||||
|
r = crypt_keyfile_device_read(cd, key_file, key, key_size,
|
||||||
|
keyfile_offset, keyfile_size_max, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block && !quit)
|
||||||
|
set_int_block(1);
|
||||||
|
|
||||||
|
/* Check pwquality for password (not keyfile) */
|
||||||
|
if (pwquality && !key_file && !r)
|
||||||
|
r = tools_check_pwquality(*key);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
void tools_passphrase_msg(int r)
|
void tools_passphrase_msg(int r)
|
||||||
{
|
{
|
||||||
@@ -29,29 +287,51 @@ void tools_passphrase_msg(int r)
|
|||||||
log_err(_("No usable keyslot is available."));
|
log_err(_("No usable keyslot is available."));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
int tools_read_mk(const char *file, char **key, int keysize)
|
||||||
* Only tool that currently blocks signals explicitly is cryptsetup-reencrypt.
|
|
||||||
* Leave the tools_get_key stub with signals handling here and remove it later
|
|
||||||
* only if we find signals blocking obsolete.
|
|
||||||
*/
|
|
||||||
int tools_get_key(const char *prompt,
|
|
||||||
char **key, size_t *key_size,
|
|
||||||
uint64_t keyfile_offset, size_t keyfile_size_max,
|
|
||||||
const char *key_file,
|
|
||||||
int timeout, int verify, int pwquality,
|
|
||||||
struct crypt_device *cd)
|
|
||||||
{
|
{
|
||||||
int r, block;
|
int fd;
|
||||||
|
|
||||||
block = tools_signals_blocked();
|
if (!keysize || !key)
|
||||||
if (block)
|
return -EINVAL;
|
||||||
set_int_block(0);
|
|
||||||
|
|
||||||
r = crypt_cli_get_key(prompt, key, key_size, keyfile_offset,
|
*key = crypt_safe_alloc(keysize);
|
||||||
keyfile_size_max, key_file, timeout, verify, pwquality, cd, NULL);
|
if (!*key)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
if (block && !quit)
|
fd = open(file, O_RDONLY);
|
||||||
set_int_block(1);
|
if (fd == -1) {
|
||||||
|
log_err(_("Cannot read keyfile %s."), file);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (read_buffer(fd, *key, keysize) != keysize) {
|
||||||
|
log_err(_("Cannot read %d bytes from keyfile %s."), keysize, file);
|
||||||
|
close(fd);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
return 0;
|
||||||
|
fail:
|
||||||
|
crypt_safe_free(*key);
|
||||||
|
*key = NULL;
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tools_write_mk(const char *file, const char *key, int keysize)
|
||||||
|
{
|
||||||
|
int fd, r = -EINVAL;
|
||||||
|
|
||||||
|
fd = open(file, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR);
|
||||||
|
if (fd < 0) {
|
||||||
|
log_err(_("Cannot open keyfile %s for write."), file);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (write_buffer(fd, key, keysize) == keysize)
|
||||||
|
r = 0;
|
||||||
|
else
|
||||||
|
log_err(_("Cannot write to keyfile %s."), file);
|
||||||
|
|
||||||
|
close(fd);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ static int _activate(const char *dm_device,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
signature_size = st.st_size;
|
signature_size = st.st_size;
|
||||||
r = crypt_cli_read_mk(cd, ARG_STR(OPT_ROOT_HASH_SIGNATURE_ID), &signature, signature_size);
|
r = tools_read_mk(ARG_STR(OPT_ROOT_HASH_SIGNATURE_ID), &signature, signature_size);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_err(_("Cannot read signature file %s."), ARG_STR(OPT_ROOT_HASH_SIGNATURE_ID));
|
log_err(_("Cannot read signature file %s."), ARG_STR(OPT_ROOT_HASH_SIGNATURE_ID));
|
||||||
goto out;
|
goto out;
|
||||||
|
|||||||
Reference in New Issue
Block a user