Bug#782024: cryptsetup: [patch] fix remote unlock of encrypted root when plymouth is installed

2015-12-25 Thread Jonas Meurer
Hi Guilhem,

Am 24.12.2015 um 20:57 schrieb Guilhem Moulin:
> On Wed, 23 Dec 2015 at 23:11:29 +0100, Jonas Meurer wrote:
>> Guilhem, can you test the latest SVN version and verify that it works fo
>> you?
> 
> It works great, thanks!  Here is another patch to
>  - add an entry in d/copyright;
>  - change cryptroot-unlock's license from GPL3+ to GPL2+ to match other
>parts of the package; and
>  - add a lintian override regarding the “unusual shell interpreter”

applied :)

Cheers
 jonas




signature.asc
Description: OpenPGP digital signature


Bug#782024: cryptsetup: [patch] fix remote unlock of encrypted root when plymouth is installed

2015-12-24 Thread Guilhem Moulin
Hi Jonas,

On Wed, 23 Dec 2015 at 23:11:29 +0100, Jonas Meurer wrote:
> Guilhem, can you test the latest SVN version and verify that it works fo
> you?

It works great, thanks!  Here is another patch to
 - add an entry in d/copyright;
 - change cryptroot-unlock's license from GPL3+ to GPL2+ to match other
   parts of the package; and
 - add a lintian override regarding the “unusual shell interpreter”

Cheers,
-- 
Guilhem.
From f6f78b1cfd42d18d878c72b594e5474460f888a6 Mon Sep 17 00:00:00 2001
From: Guilhem Moulin 
Date: Thu, 24 Dec 2015 20:30:58 +0100
Subject: [PATCH] cryptroot-unlock: change license to GPL2+ and change the
 shebang to '/bin/busybox ash'.

---
 debian/copyright| 4 
 debian/cryptsetup.lintian-overrides | 2 ++
 debian/initramfs/cryptroot-unlock   | 4 ++--
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/debian/copyright b/debian/copyright
index 981b88c..435b11e 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -36,6 +36,10 @@ Files: debian/scripts/luksformat
 Copyright: © 2005 Canonical Ltd.
 License: GPL-2+
 
+Files: debian/initramfs/cryptroot-unlock
+Copyright: © 2015 Guilhem Moulin 
+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
diff --git a/debian/cryptsetup.lintian-overrides b/debian/cryptsetup.lintian-overrides
index 32d04bf..0d74b30 100644
--- a/debian/cryptsetup.lintian-overrides
+++ b/debian/cryptsetup.lintian-overrides
@@ -6,3 +6,5 @@ cryptsetup: init.d-script-does-not-source-init-functions etc/init.d/cryptdisks
 cryptsetup: init.d-script-does-not-source-init-functions etc/init.d/cryptdisks-early
 cryptsetup: init.d-script-not-included-in-package etc/init.d/cryptdisks-udev
 cryptsetup: no-debconf-config
+# `cryptroot-unlock` is meant to be run from the initramfs image, using busybox's /bin/ash
+unusual-interpreter usr/share/cryptsetup/initramfs/bin/cryptroot-unlock #!/bin/busybox
diff --git a/debian/initramfs/cryptroot-unlock b/debian/initramfs/cryptroot-unlock
index 575b7dc..4ae8810 100644
--- a/debian/initramfs/cryptroot-unlock
+++ b/debian/initramfs/cryptroot-unlock
@@ -1,4 +1,4 @@
-#!/bin/ash
+#!/bin/busybox ash
 
 # Remotely unlock encrypted volumes.
 #
@@ -6,7 +6,7 @@
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
+# the Free Software Foundation, either version 2 of the License, or
 # (at your option) any later version.
 #
 # This program is distributed in the hope that it will be useful,
-- 
2.6.4



signature.asc
Description: PGP signature


Bug#782024: /usr/share/initramfs-tools/bin directory in cryptsetup package? (was: [pkg-cryptsetup-devel] Bug#782024: cryptsetup: [patch] fix remote unlock of encrypted root when plymouth is installed)

2015-12-23 Thread Ben Hutchings
On Wed, 2015-12-23 at 23:19 +0100, Jonas Meurer wrote:
> Hi Ben,
> 
> a quick question to you as initramfs-tools maintainer: are you ok with
> us adding a directory '/usr/share/initramfs-tools/bin' to the cryptsetup
> package? We would like to place a script 'cryptroot-unlock' there which
> is installed into /bin/ in initramfs. Thus the directory
> '/usr/share/initramfs-tools/bin' seems most appropriate for us.
> 
> See the buglog[1] and below for further details.
[...]

Please don't create anything outside of the documented hook/script
directories under /usr/share/initramfs-tools.  Make your own directory
e.g. /usr/share/cryptsetup instead.

Ben.

-- 
Ben Hutchings
For every action, there is an equal and opposite criticism. - Harrison

signature.asc
Description: This is a digitally signed message part


Bug#782024: /usr/share/initramfs-tools/bin directory in cryptsetup package? (was: [pkg-cryptsetup-devel] Bug#782024: cryptsetup: [patch] fix remote unlock of encrypted root when plymouth is installed)

2015-12-23 Thread Jonas Meurer
Hi Ben,

a quick question to you as initramfs-tools maintainer: are you ok with
us adding a directory '/usr/share/initramfs-tools/bin' to the cryptsetup
package? We would like to place a script 'cryptroot-unlock' there which
is installed into /bin/ in initramfs. Thus the directory
'/usr/share/initramfs-tools/bin' seems most appropriate for us.

See the buglog[1] and below for further details.

Cheers
 jonas

[1] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=782024

Am 23.12.2015 um 23:11 schrieb Jonas Meurer:
> Am 19.12.2015 um 18:50 schrieb Guilhem Moulin:
>> On Fri, 18 Dec 2015 at 19:16:56 -0500, Richard Hansen wrote:
>>>  * why SIGKILL instead of SIGTERM?  seems too aggressive
>>>  * perhaps add a waitpid() after the kill() to ensure that a second
>>>plymouth won't be run before the first one exits
>>
>> Agreed, but unfortunately plymouth doesn't terminate on SIGTERM.
>>
>>>  * why does cryptroot-unlock use /bin/ash instead of /bin/sh?
>>>  * there are lots of BusyBox ashisms in the cryptroot-unlock script,
>>>many of which can be easily replaced with POSIX conformant code
>>
>> POSIX's read builtin doesn't support the -s flag.  Sure we can replace
>> with stty with a trap to restore echo, but since busybox is a dependency
>> anyway I don't think it's worth it :-P
>>
>> I've addressed the rest in the updated patch.  Thanks for your input!
> 
> I've incorporated the patch into SVN now, with some minor tweaks:
> 
> * bin/unlock in the initramfs is renamed to bin/cryptroot-unlock.
> * some minor coding style changes.
> 
> Also I don't really like that we create the directory
> '/usr/share/initramfs-tools/bin'. This place belongs to initramfs-tools
> package in my eyes and we should at least ask the maintainers before
> introducing it. I'll ask Ben in another ping mail to bug #807527 about
> his option.
> 
> Guilhem, can you test the latest SVN version and verify that it works fo
> you?
> 
> Cheers
>  jonas
> 
> 
> 




signature.asc
Description: OpenPGP digital signature


Bug#782024: [pkg-cryptsetup-devel] Bug#782024: Bug#782024: cryptsetup: [patch] fix remote unlock of encrypted root when plymouth is installed

2015-12-23 Thread Jonas Meurer
Am 19.12.2015 um 18:50 schrieb Guilhem Moulin:
> On Fri, 18 Dec 2015 at 19:16:56 -0500, Richard Hansen wrote:
>>  * why SIGKILL instead of SIGTERM?  seems too aggressive
>>  * perhaps add a waitpid() after the kill() to ensure that a second
>>plymouth won't be run before the first one exits
> 
> Agreed, but unfortunately plymouth doesn't terminate on SIGTERM.
> 
>>  * why does cryptroot-unlock use /bin/ash instead of /bin/sh?
>>  * there are lots of BusyBox ashisms in the cryptroot-unlock script,
>>many of which can be easily replaced with POSIX conformant code
> 
> POSIX's read builtin doesn't support the -s flag.  Sure we can replace
> with stty with a trap to restore echo, but since busybox is a dependency
> anyway I don't think it's worth it :-P
> 
> I've addressed the rest in the updated patch.  Thanks for your input!

I've incorporated the patch into SVN now, with some minor tweaks:

* bin/unlock in the initramfs is renamed to bin/cryptroot-unlock.
* some minor coding style changes.

Also I don't really like that we create the directory
'/usr/share/initramfs-tools/bin'. This place belongs to initramfs-tools
package in my eyes and we should at least ask the maintainers before
introducing it. I'll ask Ben in another ping mail to bug #807527 about
his option.

Guilhem, can you test the latest SVN version and verify that it works fo
you?

Cheers
 jonas





signature.asc
Description: OpenPGP digital signature


Bug#782024: [pkg-cryptsetup-devel] Bug#782024: cryptsetup: [patch] fix remote unlock of encrypted root when plymouth is installed

2015-12-19 Thread Guilhem Moulin
On Fri, 18 Dec 2015 at 19:16:56 -0500, Richard Hansen wrote:
>  * why SIGKILL instead of SIGTERM?  seems too aggressive
>  * perhaps add a waitpid() after the kill() to ensure that a second
>plymouth won't be run before the first one exits

Agreed, but unfortunately plymouth doesn't terminate on SIGTERM.

>  * why does cryptroot-unlock use /bin/ash instead of /bin/sh?
>  * there are lots of BusyBox ashisms in the cryptroot-unlock script,
>many of which can be easily replaced with POSIX conformant code

POSIX's read builtin doesn't support the -s flag.  Sure we can replace
with stty with a trap to restore echo, but since busybox is a dependency
anyway I don't think it's worth it :-P

I've addressed the rest in the updated patch.  Thanks for your input!

-- 
Guilhem.
diff --git a/debian/askpass.c b/debian/askpass.c
index d234879..6750385 100644
--- a/debian/askpass.c
+++ b/debian/askpass.c
@@ -38,11 +38,7 @@
 #include 
 #include 
 #include 
-#include 
-#include 
-#include 
 #include 
-#include 
 
 #define DEBUG 0
 
@@ -216,65 +212,76 @@ systemd_finish(int fd)
 }
 
 /*
- * splashy functions *
+ * plymouth 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;
+#define PLYMOUTH_PATH "/bin/plymouth"
+static pid_t plymouthpid;
+static size_t plymouthused = 0;
+static size_t plymouthsize = 0;
+static char *plymouthbuf = NULL;
 
 static int
-splashy_prepare(const char *prompt)
+plymouth_prepare(const char *prompt)
 {
-	int fd;
-	struct sockaddr addr = {AF_UNIX, SPLASHY_SOCK};
-	struct iovec iov[2];
+	int pipefds[2];
 
-	if ((fd = socket (PF_UNIX, SOCK_STREAM, 0)) == -1) {
+	if (access(PLYMOUTH_PATH, X_OK))
 		return -1;
-	}
 
-	if (connect (fd, , sizeof addr) == -1) {
-		close (fd);
+	if (system(PLYMOUTH_PATH" --ping"))
 		return -1;
-	}
 
-	iov[0].iov_base = "getpass ";
-	iov[0].iov_len = strlen ("getpass ");
-	iov[1].iov_base = (char *)prompt;
-	iov[1].iov_len = strlen (prompt) + 1;
+	/* Plymouth will add a ':' if it is a non-graphical prompt */
+	char *prompt2 = strdup(prompt);
+	int len = strlen(prompt2);
+	if (len > 1 && prompt2[len-2] == ':' && prompt2[len-1] == ' ')
+		prompt2[len-2] = '\0';
+	else if (len > 0 && prompt2[len-1] == ':')
+		prompt2[len-1] = '\0';
 
-	if (writev (fd, iov, 2) == -1) {
-		close (fd);
+	if (pipe(pipefds))
+		return -1;
+
+	plymouthpid = fork();
+	if (plymouthpid < 0) {
+		close(pipefds[0]);
+		close(pipefds[1]);
 		return -1;
 	}
 
-	/* Shutdown write? */
+	if (plymouthpid == 0) {
+		close(pipefds[0]);
+		if (dup2(pipefds[1], STDOUT_FILENO) < 0)
+			exit(EXIT_FAILURE);
+		execl(PLYMOUTH_PATH, PLYMOUTH_PATH,
+		  "ask-for-password", "--prompt", prompt2, (char*)NULL);
+		exit(EXIT_FAILURE);
+	}
+	free(prompt2);
 
-	return fd;
+	close(pipefds[1]);
+	return pipefds[0];
 }
 
 static bool
-splashy_read(int fd, char **buf, size_t *size)
+plymouth_read(int fd, char **buf, size_t *size)
 {
-	debug("In splashy_read\n");
-	if (fifo_common_read(fd, , , )) {
-		*buf = splashybuf;
-		*size = splashyused;
+	debug("In plymouth_read\n");
+	if (fifo_common_read(fd, , , )) {
+		*buf = plymouthbuf;
+		*size = plymouthused;
 		return true;
 	}
 
 	return false;
 }
 
-
 static void
-splashy_finish(int fd)
+plymouth_finish(int fd)
 {
-	fifo_common_finish (fd, , , );
+	kill(plymouthpid, SIGKILL);
+	fifo_common_finish(fd, , , );
 }
 
 /*
@@ -448,8 +455,8 @@ struct method {
 
 static struct method methods[] = {
 	{ "systemd", systemd_prepare, systemd_read, systemd_finish, true, false, true, -1 },
-	{ "splashy", splashy_prepare, splashy_read, splashy_finish, false, false, true, -1 },
 	{ "fifo", fifo_prepare, fifo_read, fifo_finish, false, false, true, -1 },
+	{ "plymouth", plymouth_prepare, plymouth_read, plymouth_finish, true, false, true, -1 },
 	{ "console", console_prepare, console_read, console_finish, false, false, true, -1 }
 };
 
diff --git a/debian/cryptsetup.dirs b/debian/cryptsetup.dirs
index 94c9a56..f4663f9 100644
--- a/debian/cryptsetup.dirs
+++ b/debian/cryptsetup.dirs
@@ -10,5 +10,6 @@
 /usr/share/initramfs-tools/scripts/local-bottom
 /usr/share/initramfs-tools/scripts/local-block
 /usr/share/initramfs-tools/conf-hooks.d
+/usr/share/initramfs-tools/bin
 /usr/share/man/man5
 /usr/share/man/man8
diff --git a/debian/initramfs/cryptroot-script b/debian/initramfs/cryptroot-script
index 3e8281a..1c313c1 100644
--- a/debian/initramfs/cryptroot-script
+++ b/debian/initramfs/cryptroot-script
@@ -292,14 +292,8 @@ setup_mapping()
 diskname="$cryptsource ($crypttarget)"
 			fi
 
-			if 

Bug#782024: cryptsetup: [patch] fix remote unlock of encrypted root when plymouth is installed

2015-12-18 Thread Guilhem Moulin
On Wed, 16 Dec 2015 at 23:37:31 -0500, Richard Hansen wrote:
> It should work on Debian, though I have not tested it.

The client part can't be shipped by cryptsetup; instead, it should have
its own ‘dropbear-initramfs-client’ package.  But IMHO this is not
really necessary: as explained in dropbear-initramfs' README.initramfs,
remote unlocking only boils down to

ssh -F ~/.luks/ssh.conf remote.system.com

when /root/.ssh/authorized_keys contains the command="/bin/unlock"
authorized_keys(5) restriction.

-- 
Guilhem.


signature.asc
Description: PGP signature


Bug#782024: cryptsetup: [patch] fix remote unlock of encrypted root when plymouth is installed

2015-12-18 Thread Richard Hansen
Apologies, I forgot to say that the script I linked is meant to be a
temporary workaround until proper remote unlocking support is added.  I
posted it as a reference for those who stumble across this bug report
looking for a way to get remote unlocking to work right away.

Regarding the original proposed patch:  I agree that it is probably not
a good idea to run /scripts/local-top/cryptroot a second time while
another instance is still running.  Aside from the benign but
scary/confusing error messages, issues can arise if cryptroot isn't
idempotent.

I prefer the approach in your latest patch.  I have a few questions,
comments, and suggestions for improvement (all minor):
  * use strdup() instead of strlen()+malloc()+strcpy()
  * sizeof(char) is always 1 (see C99 6.5.3.4p3)
  * add a free(prompt2) to keep static analyzers and valgrind happy
  * why SIGKILL instead of SIGTERM?  seems too aggressive
  * perhaps add a waitpid() after the kill() to ensure that a second
plymouth won't be run before the first one exits
  * why does cryptroot-unlock use /bin/ash instead of /bin/sh?
  * POSIX has deprecated test's -a and -o operators; the following is
safer:
[ -t 0 ] && [ -x "$ASKPASS" ]
  * can you use askpass itself to prompt for the password, or would the
multiple askpass instances cause problems?
  * echo might interpret backslashes or an initial dash in the password;
the following is safer:
printf %s "$REPLY" >$PASSFIFO
  * there are lots of BusyBox ashisms in the cryptroot-unlock script,
many of which can be easily replaced with POSIX conformant code

-Richard



Bug#782024: cryptsetup: [patch] fix remote unlock of encrypted root when plymouth is installed

2015-12-16 Thread Richard Hansen
This is the script I use to remotely unlock an encrypted root filesystem
on my Ubuntu machines:

https://github.com/rhansen/unlock-cryptroot

It should work on Debian, though I have not tested it.

It does not require any modifications to the target system's initramfs,
and works even if plymouth is installed.

-Richard



Bug#782024: cryptsetup: [patch] fix remote unlock of encrypted root when plymouth is installed

2015-10-13 Thread Guilhem Moulin
On Thu, 01 Oct 2015 at 12:24:58 +0200, Guilhem Moulin wrote:
> since I like Matthias' solution better

On second thought I take that back on second thought.  Aside from a typo
in my previous patch, init scripts such as /scripts/local-top/cryptroot
are intended to run sequentially, and running two of them in parallel
can yield some oddities such as “… not in dm-table” errors.
Furthermore, killing the existing cryptsetup prompt increases the
counter, hence the likeliness that init aborts by dropping a shell.

After some reflection, I came up with two solutions.

  1/ Replace the existing “$cryptkeyscript | $cryptopen” pipe by a named
 pipe (FIFO).  Then we can have another process dropping the
 passphrase into said FIFO.  It's a bit dirty because the reader
 ($cryptopen) will block until ALL writers are done, so upon success
 of a single writer we have to manually kill the other ones.

  2/ Patch askpass.c to make it work with Plymouth.  Actually there was
 some splashy code left (Plymouth's ancestor), although the
 changelog reads “remove usplash support from cryptroot initramfs
 script, askpass and keyscripts, add plymouth support to keyscripts.
 (closes: #620923)”.

Option 2/ was easy enough (one I made sure to load the method after the
FIFO one, and to set “no_more” to avoid starting the console method),
and the advantage of not messing around with the control flow.  Patch
attached (I also have a patch for 1/, but am not including it as I like
the other one better).

I've also included my own ‘unlock’ script.  I don't mind shipping it via
dropbear-initramfs instead (as I intended to originally), but it's
probably more suited for cryptsetup.

Cheers,
-- 
Guilhem.
diff --git a/debian/askpass.c b/debian/askpass.c
index d234879..6750385 100644
--- a/debian/askpass.c
+++ b/debian/askpass.c
@@ -38,11 +38,7 @@
 #include 
 #include 
 #include 
-#include 
-#include 
-#include 
 #include 
-#include 
 
 #define DEBUG 0
 
@@ -216,65 +212,76 @@ systemd_finish(int fd)
 }
 
 /*
- * splashy functions *
+ * plymouth 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;
+#define PLYMOUTH_PATH "/bin/plymouth"
+static pid_t plymouthpid;
+static size_t plymouthused = 0;
+static size_t plymouthsize = 0;
+static char *plymouthbuf = NULL;
 
 static int
-splashy_prepare(const char *prompt)
+plymouth_prepare(const char *prompt)
 {
-	int fd;
-	struct sockaddr addr = {AF_UNIX, SPLASHY_SOCK};
-	struct iovec iov[2];
+	int pipefds[2];
 
-	if ((fd = socket (PF_UNIX, SOCK_STREAM, 0)) == -1) {
+	if (access(PLYMOUTH_PATH, X_OK))
 		return -1;
-	}
 
-	if (connect (fd, , sizeof addr) == -1) {
-		close (fd);
+	if (system(PLYMOUTH_PATH" --ping"))
 		return -1;
-	}
 
-	iov[0].iov_base = "getpass ";
-	iov[0].iov_len = strlen ("getpass ");
-	iov[1].iov_base = (char *)prompt;
-	iov[1].iov_len = strlen (prompt) + 1;
+	/* Plymouth will add a ':' if it is a non-graphical prompt */
+	int len = strlen(prompt);
+	char *prompt2 = (char *)malloc(sizeof(char) * (len+1));
+	strcpy(prompt2, prompt);
+	if (len > 1 && prompt2[len-2] == ':' && prompt2[len-1] == ' ')
+		prompt2[len-2] = '\0';
+	else if (len > 0 && prompt2[len-1] == ':')
+		prompt2[len-1] = '\0';
 
-	if (writev (fd, iov, 2) == -1) {
-		close (fd);
+	if (pipe(pipefds))
+		return -1;
+
+	plymouthpid = fork();
+	if (plymouthpid < 0) {
+		close(pipefds[0]);
+		close(pipefds[1]);
 		return -1;
 	}
 
-	/* Shutdown write? */
+	if (plymouthpid == 0) {
+		close(pipefds[0]);
+		if (dup2(pipefds[1], STDOUT_FILENO) < 0)
+			exit(EXIT_FAILURE);
+		execl(PLYMOUTH_PATH, PLYMOUTH_PATH,
+		  "ask-for-password", "--prompt", prompt2, (char*)NULL);
+		exit(EXIT_FAILURE);
+	}
 
-	return fd;
+	close(pipefds[1]);
+	return pipefds[0];
 }
 
 static bool
-splashy_read(int fd, char **buf, size_t *size)
+plymouth_read(int fd, char **buf, size_t *size)
 {
-	debug("In splashy_read\n");
-	if (fifo_common_read(fd, , , )) {
-		*buf = splashybuf;
-		*size = splashyused;
+	debug("In plymouth_read\n");
+	if (fifo_common_read(fd, , , )) {
+		*buf = plymouthbuf;
+		*size = plymouthused;
 		return true;
 	}
 
 	return false;
 }
 
-
 static void
-splashy_finish(int fd)
+plymouth_finish(int fd)
 {
-	fifo_common_finish (fd, , , );
+	kill(plymouthpid, SIGKILL);
+	fifo_common_finish(fd, , , );
 }
 
 /*
@@ -448,8 +455,8 @@ struct method {
 
 static struct method methods[] = {
 	{ "systemd", systemd_prepare, systemd_read, systemd_finish, true, false, true, -1 },
-	{ "splashy", splashy_prepare, 

Bug#782024: cryptsetup: [patch] fix remote unlock of encrypted root when plymouth is installed

2015-10-01 Thread Guilhem Moulin
Hi there,

As a dropbear (in particular its remote unlocking feature) co-maintainer (see
#790125) I'd like to support this :-)

This bug has just been brought to my attention and it convinced me not
to make dropbear-initramfs conflict with plymouth.  Solving the problem
at the root seems like the way to go IMHO.

Furthermore I just removed my own ‘/bin/unlock’ hack from
dropbear-initramfs (never released, but enclosed here for completeness)
since I like Matthias' solution better and its proper place is probably
the cryptsetup package.

The presence of such a script is particularly interesting with SSH
since one can use ‘command=’ option of authorized_keys(5) to avoid users
poking around.

However I'd like to further patch ‘scripts/local-top/cryptroot’ to avoid
calling $cryptkeyscript if the standard input is not a TTY.  This would
allow my common use-case

  gpg -o - --decrypt /path/to/passphrase.gpg | ssh -F ~/.luks/ssh.conf host

(with ‘RequestTTY no’ in ‘~/.luks/ssh.conf’).  See the updated patch
enclosed.  I have also changed

> +   for PID in $(ps | grep -e '/lib/cryptsetup/askpass' -e 
> 'plymouth.*ask-for-password' | sed -n -e '/grep/! { 
> s#[[:space:]]*\([0-9]\+\)[[:space:]]*.*#\1#p ; }')
> +do
> +   kill -9 "${PID}"
> +   done

to

ps -eo pid,args | sed -nr 
"s#^\s*([0-9]+)\s+(/lib/cryptsetup/askpass|plymouth.*ask-for-password)\s+.*#\1#p"
 | xargs kill -9

although I'm too happy with the SIGKILL.  I wish there was a cleaner way
to tell these scripts to bail out, but SIGTERM doesn't seem enough for
askpass.

Also, I don't know what to think about hijacking the prereq to pass the
argument.  It might be better to use a ‘PLYMOUTH={yes/no}’ environment
variable and the following two-liner as unlock script:

  #!/bin/sh
  PLYMOUTH=no exec /scripts/local-top/cryptroot

Cheers,
-- 
Guilhem.
#!/bin/sh

# Remotely unlock encrypted volumes.
#
# Copyright © 2015 Guilhem Moulin 
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see .

set -ue
PATH=/sbin:/bin

TIMEOUT=10
PASSFIFO=/lib/cryptsetup/passfifo
ASKPASS=/lib/cryptsetup/askpass

# Return 0 if $pid has a file descriptor pointing to $name, and 1
# otherwise.
in_fds() {
local  pid="$1" name="$2" fd
for fd in $(find "/proc/$pid/fd" -type l); do
[ "$(readlink -f "$fd")" != "$name" ] || return 0
done
return 1
}

# Print the PID of the askpass process with a file descriptor opened to
# /lib/cryptsetup/passfifo.
get_askpass_pid() {
ps -eo pid,args | sed -nr "s#^\s*([0-9]+)\s+$ASKPASS\s+.*#\1#p" | while 
read pid; do
if in_fds "$pid" "$PASSFIFO"; then
echo "$pid"
break
fi
done
}

# Wait for askpass, then set $PID (resp. $BIRTH) to the PID (resp.
# birth date) of the cryptsetup process with same $CRYPTTAB_NAME.
wait_for_prompt() {
local pid=$(get_askpass_pid) timer=$(( 10 * $TIMEOUT ))

# wait for the fifo
until [ "$pid" ] && [ -p "$PASSFIFO" ]; do
sleep .1
pid=$(get_askpass_pid)
timer=$(( $timer - 1 ))
if [ $timer -le 0 ]; then
echo "Error: Timeout reached while waiting for askpass." >&2
exit 1
fi
done

# find the cryptsetup process with same $CRYPTTAB_NAME
eval $(grep -Ez '^CRYPTTAB_(NAME|TRIED|SOURCE)=' "/proc/$pid/environ" | tr 
'\0' '\n')
for pid in $(ps -eo pid,args | sed -nr 
's#^\s*([0-9]+)\s+/sbin/cryptsetup\s+.*#\1#p'); do
if grep -Fxqz "CRYPTTAB_NAME=$CRYPTTAB_NAME" "/proc/$pid/environ"; then
PID=$pid
BIRTH=$(stat -c'%Z' "/proc/$PID")
return 0;
fi
done

PID=
BIRTH=
}

# Wait until $PID no longer exists or has a birth date greater that
# $BIRTH (ie was reallocated).  Then return with exit value 0 if
# /dev/mapper/$CRYPTTAB_NAME exists, and with exit value 1 if the
# maximum number of tries exceeded.  Otherwise (if the unlocking
# failed), return with value 1.
wait_for_answer() {
local timer=$(( 10 * $TIMEOUT ))
until [ ! -d "/proc/$PID" ] || [ $(stat -c'%Z' "/proc/$PID") -gt $BIRTH ]; 
do
sleep .1
timer=$(( $timer - 1 ))
if [ $timer -le 0 ]; then
echo "Error: Timeout reached while waiting for PID $PID." >&2
exit 1
fi
done

if [ -e "/dev/mapper/$CRYPTTAB_NAME" ]; then
echo "cryptsetup: $CRYPTTAB_NAME set up successfully" >&2

Bug#782024: cryptsetup: [patch] fix remote unlock of encrypted root when plymouth is installed

2015-04-06 Thread Matthias Buecher / Germany
Package: cryptsetup
Version: 2:1.4.3-4
Severity: important
Tags: patch

Dear Maintainer,

The cryptroot script always uses plymouth if present (plymouth is
installed by default on Ubuntu).
Unfortunately this prevents to unlock an encrypted root from console
(e.g. via SSH).
Attached is a patch with a solution to this issue.


Changes in /usr/share/initramfs-tools/scripts/local-top/cryptroot
- new parameter noplymouth: possible to use during boot time to avoid
usage of plymouth even if present
- kill all processes which ask for the password after encrypted root is
available

New file /usr/share/initramfs-tools/hooks/cryptroot_unlock.sh
- creates /bin/unlock script in initramfs to define correct PATH and
call cryptroot script with correct parameter
- creates /etc/motd file in initramfs to inform user about unlock script


-- Package-specific info:
-- /proc/cmdline
BOOT_IMAGE=/vmlinuz-3.2.0-4-amd64 root=/dev/mapper/zulu1959-root ro quiet

-- /etc/crypttab
# target namesource devicekey fileoptions
md1_crypt UUID=033d63d6-3939-4908-803d-532ca73b77af none luks
md2_crypt UUID=305b4437-d583-497b-9b66-1cd118746982 md1_crypt
luks,keyscript=/lib/cryptsetup/scripts/decrypt_derived

-- /etc/fstab
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# file system mount point   type  options   dump  pass
# / was on /dev/mapper/zulu1959-root during installation
UUID=2294b0ce-084e-4999-b5ed-60fb23d62842 /   ext4
errors=remount-ro,usrquota 0   1
# /boot was on /dev/md0 during installation
UUID=683249e6-e34e-4beb-91b1-bd0ff6f46a20 /boot   ext2
defaults0   2
# swap was on /dev/mapper/zulu1959-swap_1 during installation
UUID=a4d49eb1-3697-4d43-a912-ff242b17e71b noneswap   sw
 0   0
/dev/mapper/zulu1959data-maddes_home /home/maddes ext4 defaults 0 0
/dev/mapper/zulu1959data-maddes_mail /home/maddes/mail ext4 defaults 0 0
/dev/mapper/zulu1959data-chrisse_home /home/chrisse ext4 defaults 0 0
/dev/mapper/zulu1959data-chrisse_mail /home/chrisse/mail ext4 defaults 0 0
/dev/mapper/zulu1959data-svn_home /home/svn ext4 defaults 0 0

-- lsmod
Module  Size  Used by
cpuid  12708  0
ip6t_REJECT12512  3
nf_conntrack_ipv6  13316  5
nf_defrag_ipv6 12832  1 nf_conntrack_ipv6
ip6table_filter12540  1
ip6table_raw   12528  1
ip6table_mangle12540  0
ip6_tables 22175  3 ip6table_mangle,ip6table_raw,ip6table_filter
xt_comment 12427  26
ipt_REJECT 12502  3
xt_tcpudp  12570  28
nf_conntrack_ipv4  14078  5
nf_defrag_ipv4 12483  1 nf_conntrack_ipv4
xt_conntrack   12681  10
nf_conntrack   52720  3
xt_conntrack,nf_conntrack_ipv4,nf_conntrack_ipv6
iptable_filter 12536  1
ip_tables  22042  1 iptable_filter
x_tables   19118  11
ip_tables,iptable_filter,xt_conntrack,xt_tcpudp,ipt_REJECT,xt_comment,ip6_tables,ip6table_mangle,ip6table_raw,ip6table_filter,ip6t_REJECT
nfsd  216181  2
nfs   308353  0
nfs_acl12511  2 nfs,nfsd
auth_rpcgss37143  2 nfs,nfsd
fscache36739  1 nfs
lockd  67306  2 nfs,nfsd
sunrpc173730  6 lockd,auth_rpcgss,nfs_acl,nfs,nfsd
ext2   59231  1
radeon722295  1
snd_hda_codec_hdmi 30824  1
ttm53664  1 radeon
drm_kms_helper 31370  1 radeon
snd_hda_intel  26259  0
snd_hda_codec  78031  2 snd_hda_intel,snd_hda_codec_hdmi
snd_hwdep  13186  1 snd_hda_codec
drm   183952  3 drm_kms_helper,ttm,radeon
power_supply   13475  1 radeon
snd_pcm68083  3
snd_hda_codec,snd_hda_intel,snd_hda_codec_hdmi
i2c_algo_bit   12841  1 radeon
fam15h_power   12677  0
sp5100_tco 12900  0
snd_page_alloc 13003  2 snd_pcm,snd_hda_intel
shpchp 31293  0
k10temp12611  0
i2c_piix4  12536  0
edac_mce_amd   17103  0
snd_timer  22917  1 snd_pcm
snd52893  6
snd_timer,snd_pcm,snd_hwdep,snd_hda_codec,snd_hda_intel,snd_hda_codec_hdmi
powernow_k817618  0
mperf  12453  1 powernow_k8
i2c_core   23876  5
i2c_piix4,i2c_algo_bit,drm,drm_kms_helper,radeon
soundcore  13065  1 snd
pcspkr 12579  0
edac_core  35258  0
psmouse69265  0
processor  28149  9 powernow_k8
evdev  17562  3
serio_raw  12931  0
button 12937  0
thermal_sys18040  1 processor
ext4  350804  6
crc16  12343  1 ext4
jbd2