* [dm-crypt] [PATCH] Network passphrase reading
@ 2010-01-18 3:36 Bryan Kadzban
2010-01-18 4:31 ` Dennis Furey
0 siblings, 1 reply; 9+ messages in thread
From: Bryan Kadzban @ 2010-01-18 3:36 UTC (permalink / raw)
To: dm-crypt
[-- Attachment #1: Type: text/plain, Size: 1402 bytes --]
I have a machine with a rootfs on dm-crypt, so the initramfs runs
cryptsetup to unlock it at boot time. A couple of weeks ago, I remote
booted it (wake-on-LAN magic packet), and afterward realized that the
reason it wasn't showing up on the network was that it was waiting on
the passphrase. :-)
So with a couple of changes to the initramfs, and the attached patch
(against current SVN), I could send the passphrase over the network
instead of typing it in.
It's cleartext, which is crappy, but pulling in OpenSSL and requiring
certs would be hard, it's disabled by default, and I trust my local
network. If I didn't care about doing both network and terminal, I'd
just "openssl s_server -quiet" and pipe the result into cryptsetup. But
most of the time I'm sitting at the keyboard; I only need the network
support when I'm trying to look at something remotely and the machine is
off.
...Although after writing this patch, it occurs to me that it might be
better to add a general --secondary-fd=X argument (with X any number),
which would make cryptsetup read from X as well, in the select loop.
That would get rid of some of the network eccentricities in the loop,
though making it general-purpose enough might be hard. It would also
remove the ability to preempt an existing connection (and throw away any
data it has sent).
Comments? Would people prefer the secondary-FD approach instead?
[-- Attachment #2: cryptsetup-network.patch --]
[-- Type: text/plain, Size: 17896 bytes --]
Index: src/cryptsetup.c
===================================================================
--- src/cryptsetup.c (revision 188)
+++ src/cryptsetup.c (working copy)
@@ -37,6 +37,8 @@
static int opt_tries = 3;
static int opt_align_payload = 0;
static int opt_non_exclusive = 0;
+static int opt_network_password = 0;
+static int opt_network_port = 4994;
static const char **action_argv;
static int action_argc;
@@ -412,6 +414,7 @@
.key_size = opt_key_file ? (opt_key_size / 8) : 0, /* limit bytes read from keyfile */
.timeout = opt_timeout,
.tries = opt_key_file ? 1 : opt_tries, /* verify is usefull only for tty */
+ .network_port = opt_network_password ? opt_network_port : 0,
.icb = &cmd_icb,
};
@@ -561,6 +564,9 @@
if ((r = crypt_load(cd, CRYPT_LUKS1, NULL)))
goto out;
+ if ((r = crypt_set_network_port(cd, opt_network_password ? opt_network_port : 0)))
+ goto out;
+
if (opt_key_file)
r = crypt_resume_by_keyfile(cd, action_argv[0], CRYPT_ANY_SLOT,
opt_key_file, opt_key_size / 8);
@@ -721,6 +727,8 @@
{ "align-payload", '\0', POPT_ARG_INT, &opt_align_payload, 0, N_("Align payload at <n> sector boundaries - for luksFormat"), N_("SECTORS") },
{ "non-exclusive", '\0', POPT_ARG_NONE, &opt_non_exclusive, 0, N_("(Obsoleted, see man page.)"), NULL },
{ "header-backup-file",'\0', POPT_ARG_STRING, &opt_header_backup_file, 0, N_("File with LUKS header and keyslots backup."), NULL },
+ { "network-password", '\0', POPT_ARG_NONE, &opt_network_password, 0, N_("Whether to accept a passphrase over the network"), NULL },
+ { "password-port", '\0', POPT_ARG_INT, &opt_network_port, 0, N_("TCP port to listen on for a passphrase"), N_("PORT") },
POPT_TABLEEND
};
poptContext popt_context;
Index: lib/libcryptsetup.h
===================================================================
--- lib/libcryptsetup.h (revision 188)
+++ lib/libcryptsetup.h (working copy)
@@ -102,11 +102,13 @@
* @password_retry - number of tries for password if not verified
* @iteration_time - iteration time for LUKS header in miliseconds
* @password_verify - for compiled-in password query always verify passwords twice
+ * @network_port - for compiled-in password query, port to listen on for network password, or -1 to disable
*/
void crypt_set_timeout(struct crypt_device *cd, uint64_t timeout_sec);
void crypt_set_password_retry(struct crypt_device *cd, int tries);
void crypt_set_iterarion_time(struct crypt_device *cd, uint64_t iteration_time_ms);
void crypt_set_password_verify(struct crypt_device *cd, int password_verify);
+void crypt_set_network_port(struct crypt_device *cd, int network_port);
/**
* Helper to lock/unlock memory to avoid swap sensitive data to disk
@@ -552,6 +554,8 @@
uint64_t align_payload;
int tries;
+ int network_port;
+
struct interface_callbacks *icb;
};
Index: lib/utils.c
===================================================================
--- lib/utils.c (revision 188)
+++ lib/utils.c (working copy)
@@ -14,6 +14,9 @@
#include <termios.h>
#include <sys/mman.h>
#include <sys/resource.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
#include "libcryptsetup.h"
#include "internal.h"
@@ -304,42 +307,215 @@
return write_blockwise(fd, buf, count) + innerCount;
}
+/* Networking helper */
+
+static int setup_socket(struct crypt_device *cd, int network_port)
+{
+ int sockfd;
+ struct sockaddr_in addr;
+ int one = 1;
+
+ if(network_port <= 0)
+ return -1;
+
+ sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+ if(sockfd < 0) {
+ log_std(cd, _("socket() failed: skipping network.\n"));
+ return -1;
+ } else {
+ log_dbg(_("socket() succeeded."));
+ }
+
+ if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) {
+ log_std(cd, _("setsockopt(SO_REUSEADDR) failed; bind may fail next.\n"));
+ } else {
+ log_dbg(_("setsockopt(SO_REUSEADDR) succeeded."));
+ }
+
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons((uint16_t)network_port);
+ addr.sin_addr.s_addr = INADDR_ANY;
+
+ if(bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ log_std(cd, _("bind() failed: skipping network.\n"));
+ close(sockfd);
+ return -1;
+ } else {
+ log_dbg(_("bind() succeeded."));
+ }
+
+ if(listen(sockfd, 1) < 0) {
+ log_std(cd, _("listen() failed: skipping network.\n"));
+ close(sockfd);
+ return -1;
+ } else {
+ log_dbg(_("listen() succeeded, socket OK."));
+ }
+
+ return sockfd;
+}
+
/* Password reading helpers */
-static int untimed_read(int fd, char *pass, size_t maxlen)
+static int single_read(int fd, int kill_newline, char *pass, size_t maxlen)
{
ssize_t i;
i = read(fd, pass, maxlen);
if (i > 0) {
- pass[i-1] = '\0';
- i = 0;
+ if (kill_newline)
+ pass[i-1] = '\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)
+static int multi_read(int fd, int sockfd, char *pass, size_t maxlen,
+ long timeout, struct crypt_device *cd)
{
struct timeval t;
fd_set fds;
int failed = -1;
+ int maxfd, clientfd = -1;
+ int rv;
+ char *netbuf = NULL, *ptr;
+ size_t curmaxlen;
- FD_ZERO(&fds);
- FD_SET(fd, &fds);
- t.tv_sec = timeout;
- t.tv_usec = 0;
+ /* Luckily, Linux modifies the struct timeval in select()... */
+ if (timeout) {
+ t.tv_sec = timeout;
+ t.tv_usec = 0;
+ }
- if (select(fd+1, &fds, NULL, NULL, &t) > 0)
- failed = untimed_read(fd, pass, maxlen);
+ if (sockfd >= 0) {
+ netbuf = malloc(maxlen);
+ if (!netbuf) {
+ log_err(cd, _("Out of memory.\n"));
+ return -1;
+ }
+ }
- return failed;
+ while(1) {
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+ maxfd = fd;
+
+ if (sockfd >= 0) {
+ FD_SET(sockfd, &fds);
+
+ if (sockfd > maxfd)
+ maxfd = sockfd;
+ }
+
+ if (clientfd >= 0) {
+ FD_SET(clientfd, &fds);
+
+ if (clientfd > maxfd)
+ maxfd = clientfd;
+ }
+
+ rv = select(maxfd+1, &fds, NULL, NULL, timeout ? &t : NULL);
+
+ if (rv < 0 && errno == EINTR)
+ continue;
+
+ if (rv < 0) {
+ log_err(cd, _("select() failed.\n"));
+ failed = -1;
+ break;
+ }
+
+ if (rv == 0) {
+ /* timeout */
+ failed = -1;
+ break;
+ }
+
+ /* terminal input preempts network input */
+ if (FD_ISSET(fd, &fds)) {
+ failed = single_read(fd, 1, pass, maxlen);
+ if (failed == 0) /* EOF */
+ failed = -1;
+ break;
+ }
+
+ /* check the client first since the sockfd check might reset this FD */
+ if (clientfd >= 0 && FD_ISSET(clientfd, &fds)) {
+ /* Don't kill the newline in this call. Network passwords
+ * might come in over multiple read() calls, since TCP is a
+ * stream, with no defined packet boundaries. */
+ rv = single_read(clientfd, 0, ptr, curmaxlen);
+
+ if (rv < 0) {
+ failed = -1;
+ } else if (rv == 0) {
+ /* client closed connection, no \n received: ignore */
+ shutdown(clientfd, SHUT_RDWR);
+ close(clientfd);
+ clientfd = -1;
+
+ if (!failed)
+ break;
+ } else {
+ char *tmp = memchr(ptr, '\n', curmaxlen);
+
+ if (tmp) {
+ /* success */
+
+ *tmp = '\0';
+ /* telnet sends \r\n, not just \n: kill the \r too */
+ if (tmp > netbuf && *(tmp-1) == '\r')
+ *(tmp-1) = '\0';
+ failed = 0;
+
+ memcpy(pass, netbuf, maxlen);
+ memset(netbuf, 0, maxlen);
+
+ shutdown(clientfd, SHUT_RDWR);
+
+ /* but keep going, so we read to EOF. setting failed = 0
+ * above makes the EOF handler exit. */
+ } else if (curmaxlen - rv == 0) {
+ /* end of buffer hit, no \n received: ignore */
+ shutdown(clientfd, SHUT_RDWR);
+ close(clientfd);
+ clientfd = -1;
+ } else {
+ /* keep reading... */
+ ptr += rv;
+ curmaxlen -= rv;
+ }
+ }
+ }
+
+ if (sockfd >= 0 && FD_ISSET(sockfd, &fds)) {
+ /* new connections kill older ones */
+ if (clientfd >= 0) {
+ shutdown(clientfd, SHUT_RDWR);
+ close(clientfd);
+ }
+
+ clientfd = accept(sockfd, NULL, NULL);
+ ptr = netbuf;
+ curmaxlen = maxlen;
+ }
+ }
+
+ if (clientfd >= 0) {
+ shutdown(clientfd, SHUT_RDWR);
+ close(clientfd);
+ }
+
+ if (netbuf)
+ free(netbuf);
+
+ return failed < 0 ? -1 : 0;
}
static int interactive_pass(const char *prompt, char *pass, size_t maxlen,
- long timeout)
+ long timeout, int sockfd, struct crypt_device *cd)
{
struct termios orig, tmp;
int failed = -1;
@@ -364,10 +540,7 @@
goto out_err;
tcsetattr(infd, TCSAFLUSH, &tmp);
- if (timeout)
- failed = timed_read(infd, pass, maxlen, timeout);
- else
- failed = untimed_read(infd, pass, maxlen);
+ failed = multi_read(infd, sockfd, pass, maxlen, timeout, cd);
tcsetattr(infd, TCSAFLUSH, &orig);
out_err:
@@ -393,10 +566,11 @@
*/
void get_key(char *prompt, char **key, unsigned int *passLen, int key_size,
- const char *key_file, int timeout, int how2verify,
+ const char *key_file, int timeout, int how2verify, int network_port,
struct crypt_device *cd)
{
int fd = -1;
+ int sockfd = -1;
const int verify = how2verify & CRYPT_FLAG_VERIFY;
const int verify_if_possible = how2verify & CRYPT_FLAG_VERIFY_IF_POSSIBLE;
char *pass = NULL;
@@ -425,6 +599,8 @@
fd = STDIN_FILENO;
newline_stop = 1;
read_horizon = 0; /* Infinite, if read from terminal or fd */
+
+ sockfd = setup_socket(cd, network_port);
}
/* Interactive case */
@@ -432,13 +608,13 @@
int i;
pass = safe_alloc(MAX_TTY_PASSWORD_LEN);
- if (!pass || (i = interactive_pass(prompt, pass, MAX_TTY_PASSWORD_LEN, timeout))) {
+ if (!pass || (i = interactive_pass(prompt, pass, MAX_TTY_PASSWORD_LEN, timeout, sockfd, cd))) {
log_err(cd, _("Error reading passphrase from terminal.\n"));
goto out_err;
}
if (verify || verify_if_possible) {
char pass_verify[MAX_TTY_PASSWORD_LEN];
- i = interactive_pass(_("Verify passphrase: "), pass_verify, sizeof(pass_verify), timeout);
+ i = interactive_pass(_("Verify passphrase: "), pass_verify, sizeof(pass_verify), timeout, -1, cd);
if (i || strcmp(pass, pass_verify) != 0) {
log_err(cd, _("Passphrases do not match.\n"));
goto out_err;
@@ -509,11 +685,15 @@
}
if(fd != STDIN_FILENO)
close(fd);
+ if(sockfd >= 0)
+ close(sockfd);
return;
out_err:
if(fd >= 0 && fd != STDIN_FILENO)
close(fd);
+ if(sockfd >= 0)
+ close(sockfd);
if(pass)
safe_free(pass);
*key = NULL;
Index: lib/setup.c
===================================================================
--- lib/setup.c (revision 188)
+++ lib/setup.c (working copy)
@@ -18,6 +18,7 @@
uint64_t iteration_time;
int tries;
int password_verify;
+ int network_port;
/* used in CRYPT_LUKS1 */
struct luks_phdr hdr;
@@ -199,7 +200,7 @@
unsigned int passwordLen;
get_key(_("Enter any remaining LUKS passphrase: "), &password,
- &passwordLen, 0, key_file, cd->timeout, flags, cd);
+ &passwordLen, 0, key_file, cd->timeout, flags, 0, cd);
if(!password)
return -EINVAL;
@@ -234,7 +235,7 @@
int keyIndex;
get_key(message,&password,&passwordLen, 0, key_file,
- cd->timeout, flags, cd);
+ cd->timeout, flags, 0, cd);
if(!password)
return -EINVAL;
@@ -457,7 +458,7 @@
} else {
if (force_verify || cd->password_verify)
flags |= CRYPT_FLAG_VERIFY_IF_POSSIBLE;
- get_key(msg, key, key_len, 0, NULL, cd->timeout, flags, cd);
+ get_key(msg, key, key_len, 0, NULL, cd->timeout, flags, cd->network_port, cd);
}
}
@@ -504,7 +505,7 @@
char **key, unsigned int *key_len,
const char *key_file, size_t key_size)
{
- get_key(msg, key, key_len, key_size, key_file, cd->timeout, 0, cd);
+ get_key(msg, key, key_len, key_size, key_file, cd->timeout, 0, 0, cd);
}
static int _crypt_init(struct crypt_device **cd,
@@ -539,6 +540,7 @@
crypt_set_password_retry(*cd, options->tries);
crypt_set_iterarion_time(*cd, options->iteration_time ?: 1000);
crypt_set_password_verify(*cd, options->flags & CRYPT_FLAG_VERIFY);
+ crypt_set_network_port(*cd, options->network_port);
if (load && !init_by_name)
r = crypt_load(*cd, type, NULL);
@@ -598,7 +600,7 @@
return r;
get_key(_("Enter passphrase: "), &key, &keyLen, options->key_size,
- options->key_file, cd->timeout, options->flags, cd);
+ options->key_file, cd->timeout, options->flags, 0, cd);
if (!key)
r = -ENOENT;
else
@@ -626,7 +628,7 @@
return r;
get_key(_("Enter passphrase: "), &key, &keyLen, options->key_size,
- options->key_file, cd->timeout, options->flags, cd);
+ options->key_file, cd->timeout, options->flags, 0, cd);
if (!key)
r = -ENOENT;
else
@@ -782,7 +784,7 @@
}
get_key(_("Enter LUKS passphrase: "), &password, &passwordLen, 0,
- options->new_key_file, options->timeout, options->flags, cd);
+ options->new_key_file, options->timeout, options->flags, 0, cd);
if(!password) {
r = -EINVAL;
@@ -803,7 +805,7 @@
return (r < 0) ? r : 0;
}
-/* OPTIONS: name, device, key_size, key_file, timeout, tries, flags, icb */
+/* OPTIONS: name, device, key_size, key_file, timeout, tries, flags, network_port, icb */
int crypt_luksOpen(struct crypt_options *options)
{
struct crypt_device *cd = NULL;
@@ -1918,6 +1920,12 @@
cd->password_verify = password_verify ? 1 : 0;
}
+void crypt_set_network_port(struct crypt_device *cd, int network_port)
+{
+ log_dbg("Network port set to %d.", network_port);
+ cd->network_port = network_port;
+}
+
int crypt_memory_lock(struct crypt_device *cd, int lock)
{
return lock ? crypt_memlock_inc(cd) : crypt_memlock_dec(cd);
Index: lib/internal.h
===================================================================
--- lib/internal.h (revision 188)
+++ lib/internal.h (working copy)
@@ -102,7 +102,7 @@
int wipe_device_header(const char *device, int sectors);
void get_key(char *prompt, char **key, unsigned int *passLen, int key_size,
- const char *key_file, int timeout, int how2verify,
+ const char *key_file, int timeout, int how2verify, int network_port,
struct crypt_device *cd);
int parse_into_name_and_mode(const char *nameAndMode, char *name, char *mode);
Index: man/cryptsetup.8
===================================================================
--- man/cryptsetup.8 (revision 188)
+++ man/cryptsetup.8 (working copy)
@@ -46,7 +46,7 @@
\fIluksOpen\fR <device> <name>
.IP
opens the LUKS partition <device> and sets up a mapping <name> after successful verification of the supplied key material (either via key file by \-\-key-file, or via prompting).
-<options> can be [\-\-key-file, \-\-readonly].
+<options> can be [\-\-key-file, \-\-readonly, \-\-network-password, \-\-password-port].
.PP
\fIluksClose\fR <name>
.IP
@@ -200,11 +200,21 @@
useful to align the filesystem at full stripe boundaries so it can take advantage of the RAID's geometry. See for instance the sunit and swidth options
in the mkfs.xfs manual page. By default, the payload is aligned at an 8 sector (4096 byte) boundary.
.TP
+.B "\-\-network-password"
+Enable reading a passphrase from a TCP connection, as well as the current terminal. This option allows remote booting a machine that would normally require a human to enter the passphrase at boot time. Network passphrase support is disabled by default. This option has no effect (network passphrase support remains disabled) if used in conjunction with \-\-key-file, or with any \fB<action>\fR other than \fIluksOpen\fR and \fIluksResume\fR.
+
+Note that the passphrase must currently be transmitted in cleartext, so this is \fInot\fR safe over any untrusted network link. Note also that a newline (or, to support telnet as a client, a carriage return followed by a newline) is required just before the end of the TCP stream, and is discarded from the passphrase. See \fBNOTES ON PASSWORD PROCESSING\fR below.
+
+A suitable invocation to send the passphrase to this program would be "echo 'passphrase' >/dev/tcp/\fIa.b.c.d\fR/\fIport\fR", where \fIa.b.c.d\fR is the IP address of this machine, and \fIport\fR is the TCP port this program listens on (4994 by default, but see \fB\-\-password-port\fR below). The above invocation assumes your shell is bash, and it was configured with \-\-enable-net-redirections when it was built; if either of these assumptions is false, then you can also use tools like \fInc(1)\fR, or \fItelnet(1)\fR. No data is returned over the connection.
+.TP
+.B "\-\-password-port=\fIport\fR"
+Listen on TCP port \fIport\fR for a passphrase, instead of the default 4994.
+.TP
.B "\-\-version"
Show the version.
.SH NOTES ON PASSWORD PROCESSING
-\fIFrom a file descriptor or a terminal\fR: Password processing is new-line sensitive, meaning the reading will stop after encountering \\n. It will process the read material (without newline) with the default hash or the hash given by \-\-hash. After hashing, it will be cropped to the key size given by \-s.
+\fIFrom a file descriptor, network connection, or a terminal\fR: Password processing is new-line sensitive, meaning the reading will stop after encountering \\n. It will process the read material (without the trailing newline -- or carriage-return-newline sequence, if the data came from the network) with the default hash or the hash given by \-\-hash. After hashing, it will be cropped to the key size given by \-s.
\fIFrom stdin\fR: Reading will continue until EOF (so using e.g. /dev/random as stdin will not work), with the trailing newline stripped. After that the read data will be hashed with the default hash or the hash given by \-\-hash and the result will be cropped to the keysize given by \-s. If "plain" is used as an argument to the hash option, the input data will not be hashed.
Instead, it will be zero padded (if shorter than the keysize) or truncated (if longer than the keysize) and used directly as the key. No warning will be given if the amount of data read from stdin is less than the keysize.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [dm-crypt] [PATCH] Network passphrase reading
2010-01-18 3:36 [dm-crypt] [PATCH] Network passphrase reading Bryan Kadzban
@ 2010-01-18 4:31 ` Dennis Furey
2010-01-18 5:14 ` Bryan Kadzban
0 siblings, 1 reply; 9+ messages in thread
From: Dennis Furey @ 2010-01-18 4:31 UTC (permalink / raw)
To: Bryan Kadzban; +Cc: dm-crypt
On Sun, Jan 17, 2010 at 07:36:33PM -0800, Bryan Kadzban wrote:
>
> So with a couple of changes to the initramfs, and the attached patch
> (against current SVN), I could send the passphrase over the network
> instead of typing it in.
...
> Comments?
Apologies if this is well known already, but have a look at
http://www.debian-administration.org/articles/579, which claims to
solve this problem by embedding a lightweight ssh server in the
initramfs, and allows either local or remote booting without sending
the passphrase in clear text. It doesn't appear to require any source
code modifications to cryptsetup.
I for one would be very interested in a standard solution that would
be applicable to remotely hosted dedicated servers.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [dm-crypt] [PATCH] Network passphrase reading
2010-01-18 4:31 ` Dennis Furey
@ 2010-01-18 5:14 ` Bryan Kadzban
2010-01-18 9:02 ` Mario 'BitKoenig' Holbe
0 siblings, 1 reply; 9+ messages in thread
From: Bryan Kadzban @ 2010-01-18 5:14 UTC (permalink / raw)
To: Dennis Furey; +Cc: dm-crypt
Dennis Furey wrote:
> On Sun, Jan 17, 2010 at 07:36:33PM -0800, Bryan Kadzban wrote:
>> So with a couple of changes to the initramfs, and the attached
>> patch (against current SVN), I could send the passphrase over the
>> network instead of typing it in.
> ...
>> Comments?
>
> Apologies if this is well known already,
It was not; thanks!
> but have a look at http://www.debian-administration.org/articles/579,
> which claims to solve this problem by embedding a lightweight ssh
> server in the initramfs,
Hmm.
That's definitely a hack and a half. :-P Especially the way it kills
the cryptroot_block script, and requires two separate inputs at runtime
if you are present. Making this choice for you is exactly what select()
is for... :-)
But yeah; an alternate generic select()able FD (in addition to /dev/tty)
would allow this to work mostly-unmodified; you could log into SSH and
just echo the passphrase into the write end of a named pipe, or
configure sshd to dump the data it receives into the pipe (similar to
what it does with sftp-server, with a different subsystem -- though that
may not work with dropbear). Then provide the read end of that pipe to
cryptsetup on the secondary FD.
Here it looks like you have to log in and run the "unlock" script (which
runs cryptsetup and then kills the _block script). I was hoping for a
one-liner. ...Although actually, "ssh root@<ip> unlock" is a one-liner;
hmm.
(Though I don't use Debian, I could hack this approach into the
initramfs setup I do have.)
> I for one would be very interested in a standard solution that would
> be applicable to remotely hosted dedicated servers.
Yeah, or any box that you don't happen to have physical access to, but
need to (re)boot.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [dm-crypt] [PATCH] Network passphrase reading
2010-01-18 5:14 ` Bryan Kadzban
@ 2010-01-18 9:02 ` Mario 'BitKoenig' Holbe
2010-01-18 21:08 ` Bryan Kadzban
0 siblings, 1 reply; 9+ messages in thread
From: Mario 'BitKoenig' Holbe @ 2010-01-18 9:02 UTC (permalink / raw)
To: dm-crypt
Bryan Kadzban <cryptsetup@kdzbn.homelinux.net> wrote:
> But yeah; an alternate generic select()able FD (in addition to /dev/tty)
> would allow this to work mostly-unmodified; you could log into SSH and
> just echo the passphrase into the write end of a named pipe, or
This is exactly what askpass does - shipped with the Debian cryptsetup
package and used in the initramfs.
regards
Mario
--
<snupidity> bjmg: ja, logik ist mein fachgebiet. das liegt im gen
<uepsie> in welchem?
<snupidity> im zweiten X
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [dm-crypt] [PATCH] Network passphrase reading
2010-01-18 9:02 ` Mario 'BitKoenig' Holbe
@ 2010-01-18 21:08 ` Bryan Kadzban
2010-01-19 0:39 ` Mario 'BitKoenig' Holbe
0 siblings, 1 reply; 9+ messages in thread
From: Bryan Kadzban @ 2010-01-18 21:08 UTC (permalink / raw)
To: Mario 'BitKoenig' Holbe; +Cc: dm-crypt
Mario 'BitKoenig' Holbe wrote:
> Bryan Kadzban <cryptsetup@kdzbn.homelinux.net> wrote:
>> But yeah; an alternate generic select()able FD (in addition to
>> /dev/tty) would allow this to work mostly-unmodified; you could log
>> into SSH and just echo the passphrase into the write end of a named
>> pipe, or
>
> This is exactly what askpass does - shipped with the Debian
> cryptsetup package and used in the initramfs.
Hmm. Indeed, askpass listens on several file descriptors, including
/dev/console and a specific named pipe. (Also on some sort of pipe or
socket or something to splashy, whatever that is, and another pipe or
socket or something to usplash, whatever *that* is. Presumably those
things are "infrastructure in Debian initramfs or boot scripts".) It
wouldn't be terribly difficult to make askpass listen on a socket
directly as well (although again, you'd really want to build in some
kind of encryption; sshd is probably easier).
Looks like the way to get this all to fit together is to pipe askpass
into cryptsetup, and move the select() multiplexing out of cryptsetup
itself. I suppose that works.
Would it be possible to drop askpass into the cryptsetup package here?
Or move it into a different package? That would make this easier on a
distro that doesn't include the Debian patches to cryptsetup...
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [dm-crypt] [PATCH] Network passphrase reading
2010-01-18 21:08 ` Bryan Kadzban
@ 2010-01-19 0:39 ` Mario 'BitKoenig' Holbe
2010-01-19 4:08 ` Bryan Kadzban
0 siblings, 1 reply; 9+ messages in thread
From: Mario 'BitKoenig' Holbe @ 2010-01-19 0:39 UTC (permalink / raw)
To: dm-crypt
Bryan Kadzban <cryptsetup@kdzbn.homelinux.net> wrote:
> Hmm. Indeed, askpass listens on several file descriptors, including
> /dev/console and a specific named pipe. (Also on some sort of pipe or
> socket or something to splashy, whatever that is, and another pipe or
> socket or something to usplash, whatever *that* is. Presumably those
> things are "infrastructure in Debian initramfs or boot scripts".) It
> wouldn't be terribly difficult to make askpass listen on a socket
> directly as well (although again, you'd really want to build in some
> kind of encryption; sshd is probably easier).
It listens on /lib/cryptsetup/passfifo. This one you are able to reach
via ssh (dropbear in initramfs) and piping some passphrase into it in a
more or less secure manner (i.e. network traffic crypted via ssh).
I'm not aware of any generic socket it listens on. I personally wouldn't
feel well with a generic network socket for generic use (independent on
how far you personally would trust your local network) unless you'd use
some sort of public/private key authentication over it (smartcard
interaction or whatever).
> Looks like the way to get this all to fit together is to pipe askpass
> into cryptsetup, and move the select() multiplexing out of cryptsetup
> itself. I suppose that works.
This is what Debian's initramfs does.
cryptcreate="/sbin/cryptsetup -T 1 ...
cryptkeyscript="/lib/cryptsetup/askpass"
$cryptkeyscript "$cryptkey" | $cryptcreate --key-file=-
> Would it be possible to drop askpass into the cryptsetup package here?
IMHO, the best way would be to provide askpass as cryptsetup/contrib
content.
regards
Mario
--
Oh Du mein Koenig ... Eine Netzgroesse schrieb mal sinngemaess:
Du musst es so lesen wie ich es meine, nicht so wie ich es schreibe.
Ich meine es natuerlich so, wie Du es schreibst 8--)
O.G. Schwenk - de.comm.chatsystems
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [dm-crypt] [PATCH] Network passphrase reading
2010-01-19 0:39 ` Mario 'BitKoenig' Holbe
@ 2010-01-19 4:08 ` Bryan Kadzban
2010-01-19 9:44 ` Milan Broz
0 siblings, 1 reply; 9+ messages in thread
From: Bryan Kadzban @ 2010-01-19 4:08 UTC (permalink / raw)
To: Mario 'BitKoenig' Holbe; +Cc: dm-crypt
Mario 'BitKoenig' Holbe wrote:
> Bryan Kadzban <cryptsetup@kdzbn.homelinux.net> wrote:
>> It
>> wouldn't be terribly difficult to make askpass listen on a socket
>> directly as well (although again, you'd really want to build in some
>> kind of encryption; sshd is probably easier).
>
> I'm not aware of any generic socket it listens on.
From the code (assuming I read the debian patch correctly), there isn't
one. It's doing lots of stuff with pipes, but I never saw it call
socket (except with PF_UNIX, to talk to splashy, and that was a client
socket, not a server).
> I personally wouldn't
> feel well with a generic network socket for generic use (independent on
> how far you personally would trust your local network) unless you'd use
> some sort of public/private key authentication over it (smartcard
> interaction or whatever).
Probably a good point. Even listening on localhost only (on an ipv4
socket) could be too much, I suppose. Well, either way. :-)
> This is what Debian's initramfs does.
> cryptcreate="/sbin/cryptsetup -T 1 ...
> cryptkeyscript="/lib/cryptsetup/askpass"
> $cryptkeyscript "$cryptkey" | $cryptcreate --key-file=-
Yeah; --key-file=- is the important bit there. (Though I'm not sure
what $cryptkey is. Maybe it comes from crypttab? Actually, never mind;
it doesn't matter all that much.)
>> Would it be possible to drop askpass into the cryptsetup package here?
>
> IMHO, the best way would be to provide askpass as cryptsetup/contrib
> content.
Yeah, stuffing it into a contrib/ directory would work for me. What do
the cryptsetup maintainers say? (If you aren't one of them, that is.)
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [dm-crypt] [PATCH] Network passphrase reading
2010-01-19 4:08 ` Bryan Kadzban
@ 2010-01-19 9:44 ` Milan Broz
2010-05-03 14:41 ` Jonas Meurer
0 siblings, 1 reply; 9+ messages in thread
From: Milan Broz @ 2010-01-19 9:44 UTC (permalink / raw)
To: Bryan Kadzban; +Cc: dm-crypt, Mario 'BitKoenig' Holbe, Jonas Meurer
On 01/19/2010 05:08 AM, Bryan Kadzban wrote:
>>> Would it be possible to drop askpass into the cryptsetup package here?
>>
>> IMHO, the best way would be to provide askpass as cryptsetup/contrib
>> content.
>
> Yeah, stuffing it into a contrib/ directory would work for me. What do
> the cryptsetup maintainers say? (If you aren't one of them, that is.)
If you mean upstream cryptsetup, I would be happy if we can commit these
Debian additional programs upstream and not patch distro later.
Just send patches to me or create new issue requesting it on project pages
http://code.google.com/p/cryptsetup/
Just a few notes:
- license must be compatible with GPL2
- I do not want anything working with network/sockets etc. in base cryptsetup
or libcryptsetup. No problem with specialized programs/wrappers.
- but please, if possible, use new libcryptsetup and not pipe passphrase
to cryptsetup binary, libcryptsetup should provide all needed callbacks now,
including optional locking of memory to avoid swapping some buffer with passphrase
(but maybe this is not possible because wrapper is used even for other
purposes)
Milan
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [dm-crypt] [PATCH] Network passphrase reading
2010-01-19 9:44 ` Milan Broz
@ 2010-05-03 14:41 ` Jonas Meurer
0 siblings, 0 replies; 9+ messages in thread
From: Jonas Meurer @ 2010-05-03 14:41 UTC (permalink / raw)
To: Milan Broz; +Cc: dm-crypt
[-- Attachment #1: Type: text/plain, Size: 1824 bytes --]
hey milan,
sorry for the late reply.
On 19/01/2010 Milan Broz wrote:
> On 01/19/2010 05:08 AM, Bryan Kadzban wrote:
>
> >>> Would it be possible to drop askpass into the cryptsetup package here?
> >>
> >> IMHO, the best way would be to provide askpass as cryptsetup/contrib
> >> content.
> >
> > Yeah, stuffing it into a contrib/ directory would work for me. What do
> > the cryptsetup maintainers say? (If you aren't one of them, that is.)
>
> If you mean upstream cryptsetup, I would be happy if we can commit these
> Debian additional programs upstream and not patch distro later.
>
> Just send patches to me or create new issue requesting it on project pages
> http://code.google.com/p/cryptsetup/
>
> Just a few notes:
> - license must be compatible with GPL2
>
> - I do not want anything working with network/sockets etc. in base cryptsetup
> or libcryptsetup. No problem with specialized programs/wrappers.
>
> - but please, if possible, use new libcryptsetup and not pipe passphrase
> to cryptsetup binary, libcryptsetup should provide all needed callbacks now,
> including optional locking of memory to avoid swapping some buffer with passphrase
> (but maybe this is not possible because wrapper is used even for other
> purposes)
i like the idea to incorporate passdev and askpass into upstream
cryptsetup, but i don't have resources to rewrite them for
libcryptsetup. if you intend to do it on your own, please keep the
possibility to use both utils without cryptsetup, in order to support
custom keyscripts which do further processing of the keyfile/passphrase.
ideally, even /etc/crypttab handling would be supported upstream. the
cryptdisks_start and cryptdisks_stop scripts could be reimplemented in
c, using the libcryptsetup api.
greetings,
jonas
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 490 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2010-05-03 14:41 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-18 3:36 [dm-crypt] [PATCH] Network passphrase reading Bryan Kadzban
2010-01-18 4:31 ` Dennis Furey
2010-01-18 5:14 ` Bryan Kadzban
2010-01-18 9:02 ` Mario 'BitKoenig' Holbe
2010-01-18 21:08 ` Bryan Kadzban
2010-01-19 0:39 ` Mario 'BitKoenig' Holbe
2010-01-19 4:08 ` Bryan Kadzban
2010-01-19 9:44 ` Milan Broz
2010-05-03 14:41 ` Jonas Meurer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox