Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37726629
en ru br
Репозитории ALT
S:2.6.1-alt1
5.1: 1.0.6-alt2
4.1: 1.0.6-alt1
3.0: 0.1-alt1
www.altlinux.org/Changes

Группа :: Система/Ядро и оборудование
Пакет: cryptsetup

 Главная   Изменения   Спек   Патчи   Исходники   Загрузить   Gear   Bugs and FR  Repocop 

debian/000075500000000000000000000000001231257404500123015ustar00rootroot00000000000000debian/askpass.c000064400000000000000000000251421231257404500141160ustar00rootroot00000000000000/*
* askpass.c - prompts a user for a passphrase using any suitable method
* and prints the result to stdout.
*
* Copyright (C) 2008 David Hц╓rdeman <david@hardeman.nu>
*
* This package 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 of the License, or
* (at your option) any later version.
*
* This package 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 package; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/


#define _GNU_SOURCE
#define _BSD_SOURCE
#define _POSIX_C_SOURCE 1
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdlib.h>
#include <errno.h>
#include <stdbool.h>
#include <string.h>
#include <termios.h>
#include <sys/klog.h>
#include <sys/select.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <dirent.h>
#include <linux/vt.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/uio.h>

#define DEBUG 0

#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))

static bool disable_method(const char *method);

/*****************************************************************************
* Utility functions *
*****************************************************************************/
static void
debug(const char *fmt, ...)
{
va_list ap;
static bool first = true;
static FILE *dbgfile;

if (!DEBUG)
return;

if (first) {
first = false;
dbgfile = fopen("/tmp/askpass.debug", "a");
}

if (!dbgfile)
return;

va_start(ap, fmt);
vfprintf(dbgfile, fmt, ap);
va_end(ap);
}

static void
usage(const char *arg0, const char *errmsg)
{
if (errmsg)
fprintf(stderr, "Error: %s\nUsage: %s PROMPT\n", errmsg, arg0);
else
fprintf(stderr, "Usage: %s PROMPT\n", arg0);
exit(EXIT_FAILURE);
}

static void
fifo_common_finish(int fd, char **buf, size_t *used, size_t *size)
{
if (fd >= 0)
close(fd);

if (!*buf)
return;

memset(*buf, '\0', *size);
free(*buf);
*buf = NULL;
*used = 0;
*size = 0;
}

static bool
fifo_common_read(int fd, char **buf, size_t *used, size_t *size)
{
ssize_t result;

again:
if ((*size - *used) == 0) {
*size += 4096;
*buf = realloc(*buf, *size);
if (!*buf) {
*size = 0;
*used = 0;
debug("Failed to allocate memory for passphrase\n");
return false;
}
}

reread:
result = read(fd, *buf + *used, *size - *used);

if (result < 0) {
if (errno == EAGAIN)
return false;
if (errno == EINTR)
goto reread;
debug("Error when reading from fifo\n");
return false;
}

debug("Read %i bytes from fifo\n", (int)result);
*used += result;

if (result == 0)
return true;

goto again;
}


/*****************************************************************************
* splashy functions *
*****************************************************************************/

/* It might be better style to just do a popen of splashy_update ? */

#define SPLASHY_SOCK "\0/splashy"
static size_t splashyused = 0;
static size_t splashysize = 0;
static char *splashybuf = NULL;

static int
splashy_prepare(const char *prompt)
{
int fd;
struct sockaddr addr = {AF_UNIX, SPLASHY_SOCK};
struct iovec iov[2];

if ((fd = socket (PF_UNIX, SOCK_STREAM, 0)) == -1) {
return -1;
}

if (connect (fd, &addr, sizeof addr) == -1) {
close (fd);
return -1;
}

iov[0].iov_base = "getpass ";
iov[0].iov_len = strlen ("getpass ");
iov[1].iov_base = prompt;
iov[1].iov_len = strlen (prompt) + 1;

if (writev (fd, iov, 2) == -1) {
close (fd);
return -1;
}

/* Shutdown write? */

return fd;
}

static bool
splashy_read(int fd, char **buf, size_t *size)
{
debug("In splashy_read\n");
if (fifo_common_read(fd, &splashybuf, &splashyused, &splashysize)) {
*buf = splashybuf;
*size = splashyused;
return true;
}

return false;
}


static void
splashy_finish(int fd)
{
fifo_common_finish (fd, &splashybuf, &splashyused, &splashysize);
}

/*****************************************************************************
* fifo functions *
*****************************************************************************/
#define FIFO_PATH "/lib/cryptsetup/passfifo"
static size_t fifoused = 0;
static size_t fifosize = 0;
static char *fifobuf = NULL;

static void
fifo_finish(int fd)
{
fifo_common_finish(fd, &fifobuf, &fifoused, &fifosize);
}

static bool
fifo_read(int fd, char **buf, size_t *size)
{
debug("In fifo_read\n");
if (fifo_common_read(fd, &fifobuf, &fifoused, &fifosize)) {
*buf = fifobuf;
*size = fifoused;
return true;
}

return false;
}

static int
fifo_prepare(const char *prompt)
{
int ret;

ret = mkfifo(FIFO_PATH, 0600);
if (ret && errno != EEXIST)
return -1;

return open(FIFO_PATH, O_RDONLY | O_NONBLOCK);
}

/*****************************************************************************
* console functions *
*****************************************************************************/
#define CONSOLE_PATH "/dev/console"
static struct termios term_old;
static bool term_set = false;
static char *consolebuf = NULL;
static size_t consolebuflen = 0;

static void
console_finish(int fd)
{
if (consolebuf) {
memset(consolebuf, '\0', consolebuflen);
free(consolebuf);
consolebuf = NULL;
consolebuflen = 0;
}

if (!term_set || fd < 0)
return;

term_set = false;
tcsetattr(fd, TCSAFLUSH, &term_old);
fprintf(stderr, "\n");
klogctl(7, NULL, 0);
}

bool
console_read(int fd, char **buf, size_t *size)
{
ssize_t nread;

/* Console is in ICANON mode so we'll get entire lines */
nread = getline(&consolebuf, &consolebuflen, stdin);

if (nread < 0)
return NULL;

/* Strip trailing newline, if any */
if (nread > 0 && consolebuf[nread - 1] == '\n') {
nread--;
consolebuf[nread] = '\0';
}

*size = nread;
*buf = consolebuf;

return true;
}

static int
console_prepare(const char *prompt)
{
struct termios term_new;
char *prompt_ptr = prompt;
char *newline = NULL;

if (!isatty(STDIN_FILENO)) {
if (access(CONSOLE_PATH, R_OK | W_OK)) {
debug("No access to console device " CONSOLE_PATH "\n");
return -1;
}

if (!freopen(CONSOLE_PATH, "r", stdin) ||
!freopen(CONSOLE_PATH, "a", stdout) ||
!freopen(CONSOLE_PATH, "a", stderr) ||
!isatty(STDIN_FILENO)) {
debug("Failed to open console\n");
return -1;
}
}

if (tcgetattr(STDIN_FILENO, &term_old)) {
debug("Failed to get terminal settings\n");
return -1;
}

term_new = term_old;
term_new.c_lflag &= ~ECHO;
term_new.c_lflag |= ICANON;

if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &term_new)) {
debug("Failed to disable echoing\n");
return -1;
}

/* handle any non-literal embedded newlines in prompt */
while ( (newline = strstr(prompt_ptr,"\\n")) != NULL ) {
/* Calculate length of string leading up to newline. */
int line_len = newline - prompt_ptr;

/* Force trimming of prompt to location of newline. */
if (fwrite(prompt_ptr, line_len, 1, stderr) < 1 ||
fwrite("\n", 1, 1, stderr) < 1) {
debug("Failed to print prompt\n");
tcsetattr(STDIN_FILENO, TCSAFLUSH, &term_old);
return -1;
}

/* Skip over newline. */
prompt_ptr = newline + 2;
}
if (fputs(prompt_ptr, stderr) < 0) {
debug("Failed to print prompt\n");
tcsetattr(STDIN_FILENO, TCSAFLUSH, &term_old);
return -1;
}

/* Disable printk to console */
klogctl(6, NULL, 0);
term_set = true;
return STDIN_FILENO;
}

/*****************************************************************************
* main functions *
*****************************************************************************/

struct method {
const char *name;
int (*prepare)(const char *prompt);
bool (*read)(int fd, char **buf, size_t *size);
void (*finish)(int fd);
bool active;
bool enabled;
int fd;
};

static struct method methods[] = {
{ "splashy", splashy_prepare, splashy_read, splashy_finish, false, true, -1 },
{ "fifo", fifo_prepare, fifo_read, fifo_finish, false, true, -1 },
{ "console", console_prepare, console_read, console_finish, false, true, -1 }
};

static bool
disable_method(const char *method)
{
int i;
bool result = false;

debug("Disabling method %s\n", method ? method : "ALL");

for (i = 0; i < ARRAY_SIZE(methods); i++) {
/* A NULL method means all methods should be disabled */
if (method && strcmp(methods[i].name, method))
continue;
if (!methods[i].enabled)
continue;
if (methods[i].active)
methods[i].finish(methods[i].fd);

methods[i].active = false;
methods[i].fd = -1;
methods[i].enabled = false;
result = true;
}

return result;
}

int
main(int argc, char **argv, char **envp)
{
char *pass = NULL;
size_t passlen = 0;
int i;
int nfds;
fd_set fds;
int ret;
bool done = false;
sigset_t sigset;

if (argc != 2)
usage(argv[0], "incorrect number of arguments");

sigfillset(&sigset);
sigprocmask(SIG_BLOCK, &sigset, NULL);

for (i = 0; i < ARRAY_SIZE(methods); i++) {
if (!methods[i].enabled)
continue;
debug("Enabling method %s\n", methods[i].name);
methods[i].fd = methods[i].prepare(argv[1]);
if (methods[i].fd < 0)
methods[i].active = false;
else
methods[i].active = true;
}

while (!done) {
nfds = 0;
FD_ZERO(&fds);
for (i = 0; i < ARRAY_SIZE(methods); i++) {
if (!methods[i].enabled || methods[i].fd < 0)
continue;
debug("method %i has fd %i and name %s\n", i, methods[i].fd, methods[i].name);
FD_SET(methods[i].fd, &fds);
if (methods[i].fd + 1 > nfds)
nfds = methods[i].fd + 1;
}

if (nfds == 0) {
debug("All methods disabled\n");
exit(EXIT_FAILURE);
}

debug("Starting select with nfds %i\n", nfds);
ret = select(nfds, &fds, NULL, NULL, NULL);

if (ret <= 0) {
if (ret == 0 || errno == EINTR)
continue;
debug("Select failed\n");
disable_method(NULL);
exit(EXIT_FAILURE);
}

for (i = 0; i < ARRAY_SIZE(methods); i++) {
if (!methods[i].enabled || methods[i].fd < 0)
continue;
if (!FD_ISSET(methods[i].fd, &fds))
continue;
if (methods[i].read(methods[i].fd, &pass, &passlen) && pass) {
done = true;
break;
}
}
}

debug("Writing %i bytes to stdout\n", (int)passlen);
write(STDOUT_FILENO, pass, passlen);
disable_method(NULL);
exit(EXIT_SUCCESS);
}

debian/checks/000075500000000000000000000000001231257404500135415ustar00rootroot00000000000000debian/checks/blkid000064400000000000000000000020201231257404500145430ustar00rootroot00000000000000#!/bin/sh
# this script depends on /sbin/blkid from the util-linux package

# usage: blkid <device> <fs_type>
# <device> may be any device that should be checked.
# if no <fs_type> is given, the check fails if no valid filesystem is found.
# if <fs_type> is given, the check fails when no filesystem type <fs_type>
# is found on the device. if <fs_type> is 'none', the check fails if any
# know filesystem is found.

if test ! -x "/sbin/blkid"; then
echo " - WARNING: blkid from util-linux is not available, impossible to run checks."
exit 1
fi

dev="$1"
fs="$2"

blkid="$(/sbin/blkid -o value -s TYPE -p $dev)"

# blkid output is empty if $dev has an unknown filesystem
if [ -z "$blkid" ] && [ -z "$fs" ]; then
echo " - The device $dev does not contain a known filesystem."
exit 1
elif [ -n "$blkid" ] && [ "$fs" = "none" ]; then
echo " - The device $dev contains a filesystem type $blkid."
exit 1
elif [ -n "$fs" ] && [ "$blkid" != "$fs" ]; then
echo " - The device $dev does not contain a filesystem type $fs."
exit 1
fi
debian/checks/un_blkid000064400000000000000000000014731231257404500152600ustar00rootroot00000000000000#!/bin/sh
# this script depends on /sbin/blkid from the util-linux package

# usage: un_blkid <device> <fs_type>
# <device> may be any device that should be checked.
# if no <fs_type> is given, the check fails for any valid filesystem
# if <fs_type> is given, the check fails when a filesystem type <fs_type>
# is found on the device.

if test ! -x "/sbin/blkid"; then
echo " - WARNING: blkid from util-linux is not available, impossible to run checks."
exit 1
fi

dev="$1"
fs="$2"

blkid="$(/sbin/blkid -o value -s TYPE -p $dev)"

# blkid output is empty if $dev has an unknown filesystem
if [ -n "$blkid" ] && [ -z "$fs" ]; then
echo " - The device $dev contains a filesystem type $blkid."
exit 1
elif [ -n "$fs" ] && [ "$blkid" = "$fs" ]; then
echo " - The device $dev contains a filesystem type $fs."
exit 1
fi
debian/copyright000064400000000000000000000035421231257404500142400ustar00rootroot00000000000000Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Contact: Milan Broz <mbroz@redhat.com>
Source: http://code.google.com/p/cryptsetup

Files: debian/*
Copyright: б╘ 2004-2005 Wesley W. Terpstra <terpstra@debian.org>
б╘ 2005-2006 Michael Gebetsroither <michael.geb@gmx.at>
б╘ 2006-2008 David Hц╓rdeman <david@hardeman.nu>
б╘ 2005-2010 Jonas Meurer <jonas@freesources.org>
License: GPL-2+

Files: debian/askpass.c debian/passdev.c
Copyright: б╘ 2008 David Hц╓rdeman <david@hardeman.nu>
License: GPL-2+

Files: debian/README.openct
Copyright: б╘ 2008 Daniel Baumann <baumann@swiss-it.ch>
License: GPL-2+

Files: debian/README.opensc
Copyright: б╘ 2008 Benjamin Kiessling <benjaminkiessling@bttec.org>
License: GPL-2+

Files: debian/README.remote
Copyright: б╘ 2009 <debian@x.ray.net>
License: GPL-2+

Files: debian/scripts/cryptdisks_start
Copyright: б╘ 2007 Jon Dowland <jon@alcopop.org>
License: GPL-2+

Files: debian/scripts/luksformat
Copyright: б╘ 2005 Canonical Ltd.
License: GPL-2+

License: GPL-2+
This package 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 of the License, or
(at your option) any later version.
.
This package 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 package; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
.
On Debian systems, the complete text of the GNU General Public
License v2 can be found in `/usr/share/common-licenses/GPL-2'.
debian/cryptdisks-early.init000064400000000000000000000015711231257404500165030ustar00rootroot00000000000000#! /bin/sh
### BEGIN INIT INFO
# Provides: cryptdisks-early
# Required-Start: checkroot
# Required-Stop: umountroot
# Should-Start: udev mdadm-raid
# Should-Stop: udev mdadm-raid
# X-Start-Before: lvm2
# X-Stop-After: lvm2
# X-Interactive: true
# Default-Start: S
# Default-Stop: 0 6
# Short-Description: Setup early encrypted block devices.
# Description:
### END INIT INFO

set -e

if [ -r /etc/rc.d/init.d/cryptdisks.functions ]; then
. /etc/rc.d/init.d/cryptdisks.functions
else
exit 0
fi

INITSTATE="early"
DEFAULT_LOUD=""

case "$CRYPTDISKS_ENABLE" in
[Nn]*)
exit 0
;;
esac

case "$1" in
start)
do_start
;;
stop)
do_stop
;;
restart|reload|force-reload)
do_stop
do_start
;;
force-start)
FORCE_START="yes"
do_start
;;
*)
echo "Usage: cryptdisks-early {start|stop|restart|reload|force-reload|force-start}"
exit 1
;;
esac
debian/cryptdisks.default000064400000000000000000000012141231257404500160440ustar00rootroot00000000000000# Run cryptdisks initscripts at startup? Default is Yes.
CRYPTDISKS_ENABLE=Yes

# Mountpoints to mount, before cryptsetup is invoked at initscripts. Takes
# mountpoins which are configured in /etc/fstab as arguments. Separate
# mountpoints by space.
# This is useful for keyfiles on removable media. Default is unset.
CRYPTDISKS_MOUNT=""

# Default check script. Takes effect, if the 'check' option is set in crypttab
# without a value.
CRYPTDISKS_CHECK=blkid

# Default precheck script. Takes effect, if the 'precheck' option is set in
# crypttab without a value.
# Default is 'un_blkid' for plain dm-crypt devices if unset here.
CRYPTDISKS_PRECHECK=
debian/cryptdisks.functions000064400000000000000000000362011231257404500164340ustar00rootroot00000000000000#
# This file is for inclusion with
# . /lib/cryptsetup/cryptdisks.functions
# and should not be executed directly.

PATH="/usr/sbin:/usr/bin:/sbin:/bin"
TABFILE=${TABFILE-"/etc/crypttab"}
CRYPTDISKS_ENABLE="Yes"

#set -x

# Sanity check #1
[ -x /sbin/cryptsetup ] || exit 0

WITHOUT_RC_COMPAT=1

# Source function library
. /etc/init.d/functions

if [ -r /etc/sysconfig/cryptdisks ]; then
. /etc/sysconfig/cryptdisks
fi

# Sanity check #2
[ -f "$TABFILE" ] || exit 0

MOUNT="$CRYPTDISKS_MOUNT"

# Parses the option field from the crypttab file
parse_opts () {
local opts opt IFS PARAM VALUE

# Strip comments - https://bugs.launchpad.net/bugs/185380
opts=$(echo -n $1 | sed 's/ *#.*//')
PARAMS=""
PLAINPARAMS=""
CHECK=""
CHECKARGS=""
PRECHECK=""
TRIES="3"
TMPFS=""
MAKESWAP=""
USELUKS=""
KEYSCRIPT=""
IGNORE=""
CRYPTTAB_OPTIONS=""
LOUD="$DEFAULT_LOUD"

# Parse the options field, convert to cryptsetup parameters
# and construct the command line
IFS=','
for opt in $opts; do
PARAM=$(echo "$opt" | sed 's/=.*//')
VALUE=$(echo "$opt" | sed '/=/!d;s/^.*=//')

case "$PARAM" in
readonly)
PARAMS="$PARAMS -r"
;;
cipher)
if [ -z "$VALUE" ]; then
echo "$dst: no value for cipher option, skipping"
return 1
fi
PLAINPARAMS="$PLAINPARAMS -c $VALUE"
;;
size)
if [ -z "$VALUE" ] || echo "$VALUE" | grep -q "^[[:digit:]]\+$" && [ "$VALUE" -gt 0 ]; then
PLAINPARAMS="$PLAINPARAMS -s $VALUE"
else
echo "$dst: option size used with an incorrect argument, skipping"
return 1
fi
;;
hash)
if [ -z "$VALUE" ]; then
echo "$dst: no value for hash option, skipping"
return 1
fi
PLAINPARAMS="$PLAINPARAMS -h $VALUE"
;;
offset)
if [ -z "$VALUE" ]; then
echo "$dst: no value for offset option, skipping"
return 1
fi
PLAINPARAMS="$PLAINPARAMS -o $VALUE"
;;
skip)
if [ -z "$VALUE" ]; then
echo "$dst: no value for skip option, skipping"
return 1
fi
PLAINPARAMS="$PLAINPARAMS -p $VALUE"
;;
verify)
PARAMS="$PARAMS -y"
;;
check)
if [ -z "$VALUE" ]; then
VALUE="$CRYPTDISKS_CHECK"
fi
if [ -x "$VALUE" ]; then
CHECK="$VALUE"
elif [ -x "/lib/cryptsetup/checks/$VALUE" ]; then
CHECK="/lib/cryptsetup/checks/$VALUE"
else
echo "check $VALUE is not an executable script, skipping"
return 1
fi
;;
checkargs)
if [ -n "$VALUE" ]; then
CHECKARGS="$VALUE"
fi
;;
precheck)
if [ -z "$VALUE" ]; then
VALUE="$CRYPTDISKS_PRECHECK"
fi
if [ -x "$VALUE" ]; then
PRECHECK="$VALUE"
elif [ -x "/lib/cryptsetup/checks/$VALUE" ]; then
PRECHECK="/lib/cryptsetup/checks/$VALUE"
else
echo "precheck $VALUE is not an executable script, skipping"
return 1
fi
;;
tries)
if echo "$VALUE" | grep -q "^[[:digit:]]\+$" && [ "$VALUE" -ge 0 ]; then
TRIES="$VALUE"
else
echo "$dst: option tries used with an incorrect argument - forced to $TRIES"
fi
;;
discard)
PARAMS="$PARAMS --allow-discards"
;;
swap)
MAKESWAP="yes"
;;
tmp)
if [ -z "$VALUE" ]; then
TMPFS="ext4"
else
TMPFS="$VALUE"
fi
;;
luks)
USELUKS="yes"
;;
noearly)
if [ "$INITSTATE" = "early" ]; then
IGNORE="yes"
fi
;;
noauto)
if [ "$INITSTATE" != "manual" ]; then
IGNORE="yes"
fi
;;
loud)
LOUD="yes"
;;
quiet)
LOUD=""
;;
keyscript)
if [ -n "$KEYSCRIPT" ]; then
echo "$dst: multiple key decryption options are not allowed together, skipping"
return 1
elif [ -z "$VALUE" ]; then
echo "$dst: no value for keyscript option, skipping"
return 1
elif [ -x "$VALUE" ]; then
KEYSCRIPT="$VALUE"
elif [ -x "/lib/cryptsetup/scripts/$VALUE" ]; then
KEYSCRIPT="/lib/cryptsetup/scripts/$VALUE"
elif type "$VALUE" >/dev/null 2>&1; then
KEYSCRIPT="$VALUE"
else
echo "script $VALUE is not an executable script, skipping"
return 1
fi
;;
esac

CRYPTTAB_OPTIONS="$CRYPTTAB_OPTIONS $PARAM"
[ -z "$VALUE" ] && VALUE="yes"
eval export CRYPTTAB_OPTION_$PARAM="\"$VALUE\""
done
export CRYPTTAB_OPTIONS

return 0
}

# Sanity check for keys
check_key () {
local GMODE OMODE OWNER GROUP

# If the keyscript option is set, the "key" is just an argument to
# the keyscript and not necessarily a file
if [ -n "$KEYSCRIPT" ]; then
return 0
fi

if [ -z "$key" ] || [ "$key" = "none" ]; then
key=""
return 0
fi

if [ ! -e "$key" ]; then
echo "$dst: keyfile not found"
return 1
fi

# LUKS requires a persistent key, /dev/*random is not supported
if [ "$USELUKS" = "yes" ] && [ "$key" != "${key%random}" ]; then
echo "$dst: LUKS does not work with random data as key"
return 1
fi

# Check ownership of $key
OWNER="$(ls -l "$key" | sed 's/^.\{10\}[+\.]\?.[^[:space:]]* \([^[:space:]]*\).*/\1/')"
if [ "$OWNER" != "root" ]; then
echo "$dst: INSECURE OWNER FOR $key, see /usr/share/doc/cryptsetup/README.Debian."
fi

# If key is random, we're done
if [ "$key" != "${key%random}" ]; then
return 0
fi

# Check owner group of $key
GROUP="$(ls -l "$key" | sed 's/^.\{10\}[+\.]\?.[^[:space:]]* \([^[:space:]]*\).*/\1/')"
if [ "$GROUP" != "root" ]; then
echo "$dst: INSECURE OWNER GROUP FOR $key, see /usr/share/doc/cryptsetup/README.Debian."
fi

# Check group and other permissions
GMODE="$(ls -l "$key" | sed 's/[[:space:]].*//;s/^.\{4\}\(.\{3\}\).*/\1/')"
OMODE="$(ls -l "$key" | sed 's/[[:space:]].*//;s/^.\{7\}\(.\{3\}\).*/\1/')"
if [ "$GMODE" != "---" ] && [ "$OMODE" != "---" ]; then
echo "$dst: INSECURE MODE FOR $key, see /usr/share/doc/cryptsetup/README.Debian."
fi

return 0
}

# Setup a luks mapping
do_luks () {
local tried keyscriptarg
tried=0
keyscriptarg=""

if ! cryptsetup isLuks "$src" >/dev/null 2>&1; then
echo "$dst: device '$src' is not a LUKS partition, skipping"
return 1
fi

if [ -n "$KEYSCRIPT" ]; then
# keyscript => "key" is just an argument to the keyscript
keyscriptarg="$key"
key="-"
elif [ -z "$key" ]; then
# no keyscript, no key => password
keyscriptarg="Unlocking the disk $src ($dst)\nEnter passphrase: "
key="-"
if [ -x /bin/plymouth ] && plymouth --ping; then
KEYSCRIPT="plymouth ask-for-password --prompt"
keyscriptarg=$(printf "$keyscriptarg")
else
KEYSCRIPT="/lib/cryptsetup/askpass"
fi
elif [ "$key" != "${key%/dev/*}" ]; then
# no keyscript, device key => special treatment
keyscriptarg=""
key="$key"
KEYSCRIPT=""
else
# no keyscript, key => file input
keyscriptarg="$key"
key="-"
KEYSCRIPT="cat"
fi

PARAMS="$PARAMS --key-file=$key"

while [ "$tried" -lt "$TRIES" ] || [ "$TRIES" -eq "0" ]; do
if [ -n "$KEYSCRIPT" ]; then
if $KEYSCRIPT "$keyscriptarg" | cryptsetup $PARAMS luksOpen "$src" "${dst}_unformatted"; then
break
fi
else
if cryptsetup $PARAMS luksOpen "$src" "${dst}_unformatted"; then
break
fi
fi

tried=$(( $tried + 1 ))
if [ "$tried" -ge "$TRIES" ] && [ "$TRIES" -ne "0" ]; then
return 1
fi
done

if [ -n "$CHECK" ] && ! "$CHECK" "/dev/mapper/${dst}_unformatted" $CHECKARGS; then
echo "$dst: the check for '/dev/mapper/$dst' failed"
cryptsetup luksClose "${dst}_unformatted"
return 1
fi

return 0
}

# Setup a regular mapping
do_noluks () {
local pre_out tried keyscriptarg
tried=0
keyscriptarg=""

if [ -z "$PRECHECK" ]; then
PRECHECK="/lib/cryptsetup/checks/un_blkid"
fi

if ! pre_out="$($PRECHECK "$src" 2>/dev/null)" && \
! /lib/cryptsetup/checks/blkid "$src" swap >/dev/null; then
echo "$dst: the precheck for '$src' failed: $pre_out"
return 1
fi

if [ -n "$KEYSCRIPT" ]; then
# keyscript => "key" is just an argument to the keyscript
keyscriptarg="$key"
key="-"
elif [ -z "$key" ]; then
# no keyscript, no key => password
keyscriptarg="Unlocking the disk $src ($dst)\nEnter passphrase: "
key="-"
if [ -x /bin/plymouth ] && plymouth --ping; then
KEYSCRIPT="plymouth ask-for-password --prompt"
keyscriptarg=$(printf "$keyscriptarg")
else
KEYSCRIPT="/lib/cryptsetup/askpass"
fi
else
# no keyscript, key => file input
keyscriptarg=""
key="$key"
KEYSCRIPT=""
fi

PARAMS="$PARAMS --key-file=$key"

while [ "$tried" -lt "$TRIES" ]; do
if [ -n "$KEYSCRIPT" ]; then
$KEYSCRIPT "$keyscriptarg" | cryptsetup $PLAINPARAMS $PARAMS create "${dst}_unformatted" "$src"
else
cryptsetup $PLAINPARAMS $PARAMS create "${dst}_unformatted" "$src"
fi

if [ -z "$CHECK" ] || "$CHECK" "/dev/mapper/${dst}_unformatted" $CHECKARGS; then
break
else
echo "$dst: the check for '/dev/mapper/$dst' failed - maybe the password is wrong"
cryptsetup remove "${dst}_unformatted"
fi

tried=$(( $tried + 1 ))
if [ "$tried" -ge "$TRIES" ]; then
return 1
fi
done

return 0
}

# Premounts file systems
mount_fs () {
local point
MOUNTED=""

for point in $MOUNT; do
if mount "$point" >/dev/null; then
MOUNTED="$MOUNTED $point"
fi
done
}

# Postunmounts file systems
umount_fs () {
local point

for point in $MOUNTED; do
umount "$point" >/dev/null
done
}

# Prepares swap partitions using random keys
do_swap () {
local swap_out

if [ "$MAKESWAP" != "yes" ] || [ ! -b "/dev/mapper/${dst}_unformatted" ]; then
return 0
fi

if swap_out="$(/lib/cryptsetup/checks/un_blkid "/dev/mapper/${dst}_unformatted" 2>/dev/null)" || \
/lib/cryptsetup/checks/blkid "/dev/mapper/${dst}_unformatted" swap >/dev/null 2>&1; then
mkswap "/dev/mapper/${dst}_unformatted" >/dev/null 2>&1
else
echo "$dst: the check for '/dev/mapper/$dst' failed. /dev/mapper/$dst contains data: $swap_out"
do_close
return 1
fi

return 0
}

# Prepares tmp partitions using random keys
do_tmp () {
if [ "x$TMPFS" = "x" ] || [ ! -b "/dev/mapper/${dst}_unformatted" ]; then
return 0
fi

mkfs -t $TMPFS -q "/dev/mapper/${dst}_unformatted" >/dev/null 2>&1 || return 1
mkdir -p "/var/run/cryptsetup/$dst"
mount -t $TMPFS "/dev/mapper/${dst}_unformatted" "/var/run/cryptsetup/$dst" || return 1
chmod 1777 "/var/run/cryptsetup/$dst"
umount "/var/run/cryptsetup/$dst"
return 0
}

# Rename the device from its temp name to its final name, which will
# trigger mountall
finalize_device () {
if [ -x /sbin/udevadm ]; then
udevadm settle
fi
dmsetup rename "${dst}_unformatted" "$dst"
}

# Removes a mapping
do_close () {
local found IFS opt

found="no"
IFS=','
for opt in $opts; do
if [ "$opt" = "luks" ]; then
found="yes"
break
fi
done

if [ "$found" = "yes" ]; then
cryptsetup luksClose "$dst"
else
cryptsetup remove "$dst"
fi
return $?
}

load_optimized_module () {
local module optmodule
module="$1"

optmodule=$(find "/lib/modules/$(uname -r)/kernel/arch" -name "${module}*.ko" 2>/dev/null)
if [ -n "$optmodule" ] && [ "$(echo -n "$optmodule" | wc -l)" -eq 1 ]; then
modprobe "$optmodule" 2>/dev/null && return 0
fi

modprobe "$module" 2>/dev/null || return 1
return 0
}

# Sets up all entries in crypttab
handle_crypttab_line_start () {
dst=$1
src=$2
key=$3
opts=$4

# Make sure that all fields are present
if [ -z "$dst" ]; then
return 1
elif [ -z "$src" ] || [ -z "$key" ] || [ -z "$opts" ]; then
return 1
fi

# parse UUID= symlinks
if [ "${src#UUID=}" != "$src" ]; then
src="/dev/disk/by-uuid/${src#UUID=}"
elif [ "${src#LABEL=}" != "$src" ]; then
src="/dev/disk/by-label/${src#LABEL=}"
fi

# Do the preparatory steps
if ! parse_opts "$opts"; then
return 1
fi

# Ignore noauto devices
if [ "$IGNORE" = "yes" ] && [ -z "$FORCE_START" ]; then
return 0
fi

if ! check_key; then
return 1
fi

# Export crypttab fields as environment variables
export CRYPTTAB_NAME="$dst"
export CRYPTTAB_SOURCE="$src"
export CRYPTTAB_KEY="$key"

# Make sure source device exists
if [ ! -r "$src" ]; then
if [ "$LOUD" = "yes" ]; then
return 1
fi
return 2
fi

# Make sure that target device doesn't exist
if [ -b "/dev/mapper/${dst}_unformatted" ] || [ -b "/dev/mapper/$dst" ]; then
return 2
fi

# All checks passed, do the real setup
result="ok"
if [ "$USELUKS" = "yes" ]; then
do_luks || result="fail"
else
do_noluks || result="fail"
fi

# Finish up
if [ "$result" != "ok" ]; then
return 1
else
do_swap
do_tmp
finalize_device
fi

return 0
}

handle_crypttab_line_stop () {
dst=$1
src=$2
key=$3
opts=$4

if [ ! -b "/dev/mapper/$dst" ]; then
return 2
fi

opencount=$(dmsetup info -c --noheadings -o open "$dst" 2>/dev/null || true)
if [ -z "$opencount" ]; then
return 1
elif [ "$opencount" != "0" ]; then
if [ "$INITSTATE" = "early" ] || [ "$INITSTATE" = "manual" ]; then
return 1
fi
return 2
fi

#major=$(dmsetup info -c --noheadings -o major "$dst" 2>/dev/null || true)
#minor=$(dmsetup info -c --noheadings -o minor "$dst" 2>/dev/null || true)
src_major="$(dmsetup deps "$dst" 2>/dev/null | sed -e 's/^.*(\([0-9]*\), [0-9]*)$/\1/g' || true)"
src_minor="$(dmsetup deps "$dst" 2>/dev/null | sed -e 's/^.*([0-9]*, \([0-9]*\))$/\1/g' || true)"

if [ -z "$src_major" ] || [ -z "$src_minor" ]; then
return 1
fi

do_close || return $?

return 0
}

crypttab_start_one_disk () {
local dst src key opts result
local ret=0

egrep -v "^[[:space:]]*(#|$)" "$TABFILE" | while read dst src key opts; do
if [ "xUUID=$ID_FS_UUID" = "x$src" ]; then
src="/dev/disk/by-uuid/${src#UUID=}"
elif [ "xLABEL=$ID_FS_LABEL_ENC" = "x$src" ]; then
src="/dev/disk/by-label/${src#LABEL=}"
elif [ "x$1" != "x$src" ]; then
found=
for link in $DEVLINKS; do
if [ "x$link" = "x$src" ]; then
found=1
break
fi
done
if [ -z "$found" ]; then
continue
fi
fi
modprobe -qb dm-mod || true
modprobe -qb dm-crypt || true
dmsetup mknodes > /dev/null 2>&1 || true
# FIXME: no locking
mount_fs
handle_crypttab_line_start "$dst" "$src" "$key" "$opts" || ret=$?
umount_fs
done
return $ret
}

do_start () {
local dst src key opts result rc

modprobe -qb dm-mod || true
modprobe -qb dm-crypt || true
dmsetup mknodes >/dev/null 2>&1 || true
mount_fs

egrep -v "^[[:space:]]*(#|$)" "$TABFILE" | while read dst src key opts; do
rc=0
dev_match="$src"
if [ "${dev_match#UUID=}" != "$dev_match" ]; then
dev_match="$(readlink -f /dev/disk/by-uuid/${dev_match#UUID=})"
elif [ "${dev_match#LABEL=}" != "$dev_match" ]; then
dev_match="$(readlink -f /dev/disk/by-label/${dev_match#LABEL=})"
fi
# if there's already a udev-triggered job running for this
# device, wait for it to finish, then re-process to confirm
# that it's started successfully. In the general case this
# will just be a no-op, but we don't want to defer to the
# other job entirely because this is the fallback for fixing
# up any ordering-dependent decrypting.
while status cryptdisks-udev DEVNAME="$dev_match" 2>&1 | grep -q 'start'
do
sleep 1
done
handle_crypttab_line_start "$dst" "$src" "$key" "$opts" <&3 || rc=$?
msg_starting "$INITSTATE crypto disks ($dst)"
if [ $rc -eq 0 ]; then
success ||:
elif [ $rc -eq 2 ]; then
passed ||:
else
failure ||:
fi
echo
done 3<&1
umount_fs
}

# Removes all mappings in crypttab
do_stop () {
local dst src key opts opencount major minor rc

dmsetup mknodes

egrep -v "^[[:space:]]*(#|$)" "$TABFILE" | while read dst src key opts; do
rc=0
handle_crypttab_line_stop "$dst" "$src" "$key" "$opts" <&3 || rc=$?
msg_starting "$INITSTATE crypto disks ($dst)"
if [ $rc -eq 0 ]; then
success ||:
elif [ $rc -eq 2 ]; then
passed ||:
else
failure ||:
fi
echo
done 3<&1
}
debian/cryptdisks.init000064400000000000000000000016541231257404500153730ustar00rootroot00000000000000#! /bin/sh
### BEGIN INIT INFO
# Provides: cryptdisks
# Required-Start: checkroot cryptdisks-early
# Required-Stop: umountroot cryptdisks-early
# Should-Start: udev mdadm-raid lvm2
# Should-Stop: udev mdadm-raid lvm2
# X-Start-Before: checkfs
# X-Stop-After: umountfs
# X-Interactive: true
# Default-Start: S
# Default-Stop: 0 6
# Short-Description: Setup remaining encrypted block devices.
# Description:
### END INIT INFO

set -e

if [ -r /etc/rc.d/init.d/cryptdisks.functions ]; then
. /etc/rc.d/init.d/cryptdisks.functions
else
exit 0
fi

INITSTATE="remaining"
DEFAULT_LOUD="yes"

case "$CRYPTDISKS_ENABLE" in
[Nn]*)
exit 0
;;
esac

case "$1" in
start)
do_start
;;
stop)
do_stop
;;
restart|reload|force-reload)
do_stop
do_start
;;
force-start)
FORCE_START="yes"
do_start
;;
*)
echo "Usage: cryptdisks {start|stop|restart|reload|force-reload|force-start}"
exit 1
;;
esac
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin