Commit e030e3bd authored by Milan Broz's avatar Milan Broz

Add optional libpwquality support for new LUKS passwords.

If password is entered through terminal (no keyfile specified)
and cryptsetup is compiled with --enable-pwquality, default
system pwquality settings are used to check password quality.
parent c950cf26
......@@ -91,6 +91,20 @@ AC_DEFUN([NO_FIPS], [
fi
])
dnl ==========================================================================
dnl pwquality library (cryptsetup CLI only)
AC_ARG_ENABLE([pwquality], AS_HELP_STRING([--enable-pwquality],[enable password quality checking]),
[with_pwquality=$enableval],
[with_pwquality=no])
if test "x$with_pwquality" = "xyes"; then
AC_DEFINE(ENABLE_PWQUALITY, 1, [Enable password quality checking])
PKG_CHECK_MODULES([PWQUALITY], [pwquality >= 1.0.0],,
AC_MSG_ERROR([You need pwquality library.]))
PWQUALITY_STATIC_LIBS=$PWQUALITY_LIBS
fi
dnl ==========================================================================
dnl Crypto backend functions
......@@ -287,6 +301,9 @@ fi
AC_SUBST([DEVMAPPER_LIBS])
AC_SUBST([DEVMAPPER_STATIC_LIBS])
AC_SUBST([PWQUALITY_LIBS])
AC_SUBST([PWQUALITY_STATIC_LIBS])
AC_SUBST([CRYPTO_CFLAGS])
AC_SUBST([CRYPTO_LIBS])
AC_SUBST([CRYPTO_STATIC_LIBS])
......
......@@ -752,6 +752,16 @@ actually belongs to the header given. In fact you can specify an
arbitrary device as the ciphertext device for \fIopen\fR
with the \-\-header option. Use with care.
.TP
.B "\-\-force-password\fR"
Do not use password quality checking for new LUKS passwords.
This option applies only to \fIluksFormat\fR, \fIluksAddKey\fR and
\fIluksChangeKey\fR and is ignored if cryptsetup is built without
password quality checking support.
For more info about password quality check, see manual page
for \fBpwquality.conf(5)\fR.
.TP
.B "\-\-version"
Show the program version.
.TP
......
......@@ -15,13 +15,15 @@ cryptsetup_SOURCES = \
$(top_builddir)/lib/utils_loop.c \
$(top_builddir)/lib/utils_fips.c \
utils_tools.c \
utils_password.c \
cryptsetup.c \
cryptsetup.h
cryptsetup_LDADD = \
$(top_builddir)/lib/libcryptsetup.la \
@POPT_LIBS@ \
@FIPSCHECK_LIBS@
@FIPSCHECK_LIBS@ \
@PWQUALITY_LIBS@
cryptsetup_CFLAGS = -Wall
......@@ -34,6 +36,7 @@ cryptsetup_static_CFLAGS = $(cryptsetup_CFLAGS)
cryptsetup_static_LDFLAGS = -all-static
cryptsetup_static_LDADD = $(cryptsetup_LDADD) \
@CRYPTO_STATIC_LIBS@ \
@PWQUALITY_STATIC_LIBS@ \
@DEVMAPPER_STATIC_LIBS@ \
@UUID_LIBS@
endif
......
......@@ -1369,7 +1369,8 @@ int main(int argc, const char **argv)
{ "header", '\0', POPT_ARG_STRING, &opt_header_device, 0, N_("Device or file with separated LUKS header."), NULL },
{ "test-passphrase", '\0', POPT_ARG_NONE, &opt_test_passphrase, 0, N_("Do not activate device, just check passphrase."), NULL },
{ "hidden", '\0', POPT_ARG_NONE, &opt_hidden, 0, N_("Use hidden header (hidden TCRYPT device) ."), NULL },
{ "type", 'M', POPT_ARG_STRING, &opt_type, 0, N_("Type of device metadata: luks, plain, loopaes, tcrypt."), NULL },
{ "type", 'M', POPT_ARG_STRING, &opt_type, 0, N_("Type of device metadata: luks, plain, loopaes, tcrypt."), NULL },
{ "force-password", '\0', POPT_ARG_NONE, &opt_force_password, 0, N_("Disable password quality check (if enabled)."), NULL },
POPT_TABLEEND
};
poptContext popt_context;
......
......@@ -56,6 +56,7 @@
extern int opt_debug;
extern int opt_verbose;
extern int opt_batch_mode;
extern int opt_force_password;
/* Common tools */
void clogger(struct crypt_device *cd, int level, const char *file, int line,
......@@ -74,6 +75,7 @@ extern volatile int quit;
void set_int_block(int block);
void set_int_handler(int block);
void check_signal(int *r);
int tools_signals_blocked(void);
int tools_get_key(const char *prompt,
char **key, size_t *key_size,
......
/*
* Password quality check wrapper
*
* Copyright (C) 2012, Red Hat, Inc. All rights reserved.
* Copyright (C) 2012, Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "cryptsetup.h"
int opt_force_password = 0;
#if 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 passsword quality: %s\n"),
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\n"),
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;
}
#else /* ENABLE_PWQUALITY */
static int tools_check_pwquality(const char *password)
{
return 0;
}
#endif /* ENABLE_PWQUALITY */
int tools_get_key(const char *prompt,
char **key, size_t *key_size,
size_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;
block = tools_signals_blocked();
if (block)
set_int_block(0);
r = crypt_get_key(prompt, key, key_size, keyfile_offset,
keyfile_size_max, key_file, timeout, verify, cd);
if (block && !quit)
set_int_block(1);
/* Check pwquality for password (not keyfile) */
if (pwquality && !opt_force_password && !key_file && !r)
r = tools_check_pwquality(*key);
return r;
}
......@@ -35,6 +35,11 @@ static void int_handler(int sig __attribute__((__unused__)))
quit++;
}
int tools_signals_blocked(void)
{
return signals_blocked;
}
void set_int_block(int block)
{
sigset_t signals_open;
......@@ -67,28 +72,6 @@ void check_signal(int *r)
*r = -EINTR;
}
/* crypt_get_key() with signal handler */
int tools_get_key(const char *prompt,
char **key, size_t *key_size,
size_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;
block = signals_blocked;
if (block)
set_int_block(0);
r = crypt_get_key(prompt, key, key_size, keyfile_offset,
keyfile_size_max, key_file, timeout, verify, cd);
if (block && !quit)
set_int_block(1);
return r;
}
__attribute__((format(printf, 5, 6)))
void clogger(struct crypt_device *cd, int level, const char *file, int line,
const char *format, ...)
......@@ -151,7 +134,7 @@ int yesDialog(const char *msg, void *usrptr __attribute__((unused)))
size_t size = 0;
int r = 1, block;
block = signals_blocked;
block = tools_signals_blocked();
if (block)
set_int_block(0);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment