Experimental and temporary patch to enable interactive prompt. It executes a program given to the ecryptfsd command-line.
Current prompt program may be one of the ssh program from: http://alon.barlev.googlepages.com/openssh-pkcs11 I already have kde, gnome and ncurses dialogs. The main issue is that the netlink socket is somehow affected from the fork(), the kernel believe that the user mode returned? Oct 13 21:50:13 alon1 decrypt_pki_encrypted_session_key: Failed to receive tag 65 packet from the user space daemon Oct 13 21:50:13 alon1 ecryptfs_parse_packet_set: Error decrypting the session key; rc = [-5] Oct 13 21:50:13 alon1 Error attempting to read the [user.ecryptfs] xattr from the lower file; return value = [4294967201] Can you please see if you can fix this? BTW: I removed the SIGCHLD mask, as waitpid will not work if it is masked. In order to make this kind of functionality the key module should receive a reference to ecryptfs context, so it may callback core functions. So basically we have several main issues to solve here: 1. netlink and fork(). 2. Modify the key module interface to be able to callback. 3. An API for user prompt. Best Regards, Alon Bar-Lev Note: this patch depends on: 0001-ecryptfs-utils-26-daemon.patch 0002-ecryptfs-utils-26-pkcs11.patch from: http://alon.barlev.googlepages.com/ecryptfs-utils-26-alon-patches.tar.bz2 --- diff -urNp ecryptfs-utils-26.a1/src/daemon/main.c ecryptfs-utils-26.a2/src/daemon/main.c --- ecryptfs-utils-26.a1/src/daemon/main.c 2007-10-13 22:40:39.000000000 +0200 +++ ecryptfs-utils-26.a2/src/daemon/main.c 2007-10-13 22:41:27.000000000 +0200 @@ -35,6 +35,120 @@ static int ecryptfs_socket = 0; static char *pidfile = NULL; +static char *prompt_prog = NULL; + +static +int +prompt_callback(char *prompt_type, char *prompt, char *input, int input_size) { + int status; + pid_t pid = -1; + int fds[2] = {-1, -1}; + int r = 0; + int rc; + + /* + * Make sure we don't reuse input + */ + if (input) { + memset (input, 0, input_size); + } + + if (prompt_prog == NULL) { + rc = -EINVAL; + goto out; + } + + if (pipe (fds) == -1) { + rc = -errno; + goto out; + } + + if ((pid = fork ()) == -1) { + rc = -errno; + goto out; + } + + if (pid == 0) { + close (fds[0]); + fds[0] = -1; + + if (dup2 (fds[1], 1) == -1) { + exit (1); + } + + close (fds[1]); + fds[1] = -1; + + execl ( + prompt_prog, + prompt_prog, + "-t", + prompt_type, + prompt, + NULL + ); + + exit (1); + } + + close (fds[1]); + fds[1] = -1; + + while ( + (r=waitpid (pid, &status, __WNOTHREAD)) == 0 || + (r == -1 && errno == EINTR) + ); + + if (r == -1) { + rc = -errno; + goto out; + } + + if (!WIFEXITED (status)) { + rc = -EFAULT; + goto out; + } + + if (WEXITSTATUS (status) != 0) { + rc = -EIO; + goto out; + } + + if (!strcmp (prompt_type, "password")) { + if ((r = read (fds[0], input, input_size)) == -1) { + rc = -errno; + goto out; + } + + input[r] = '\0'; + + if (strlen (input) > 0 && input[strlen (input)-1] == '\n') { + input[strlen (input)-1] = '\0'; + } + } + + rc = 0; + +out: + if (rc != 0) { + if (input) { + memset (input, 0, input_size); + } + } + + if (fds[0] != -1) { + close (fds[0]); + fds[0] = -1; + } + + if (fds[1] != -1) { + close (fds[1]); + fds[1] = -1; + } + + return rc; +} + static void ecryptfsd_exit(int retval) { @@ -161,11 +275,12 @@ int main(int argc, char **argv) { "pidfile\0\tSet pid file name", required_argument, NULL, 'p' }, { "foreground\0\t\tDon't fork into background", no_argument, NULL, 'f' }, { "chroot\0\t\tChroot to directory", required_argument, NULL, 'C' }, + { "prompt-prog\0Program to execute for user prompt", required_argument, NULL, 'R' }, { "version\0\t\t\tShow version information", no_argument, NULL, 'V' }, { "help\0\t\t\tShow usage information", no_argument, NULL, 'h' }, { NULL, 0, NULL, 0 } }; - static char * short_options = "p:f:C:Vh"; + static char * short_options = "p:f:C:R:Vh"; int long_options_ret; struct rlimit core = { 0, 0 }; int foreground = 0; @@ -186,6 +301,9 @@ int main(int argc, char **argv) case 'C': chrootdir=strdup(optarg); break; + case 'R': + prompt_prog = strdup(optarg); + break; case 'V': printf( ( @@ -268,6 +386,11 @@ int main(int argc, char **argv) goto daemon_out; } + /* TEMP TEMP TEMP - BEGIN + * Until we can affect ecryptfs context via daemon */ + cryptfs_get_ctx_opts ()->prompt = prompt_callback; + /* TEMP TEMP TEMP - END */ + rc = init_netlink_daemon(); if (rc) { syslog(LOG_ERR, "Error initializing netlink daemon; rc = [%d]\n", rc); diff -urNp ecryptfs-utils-26.a1/src/include/ecryptfs.h ecryptfs-utils-26.a2/src/include/ecryptfs.h --- ecryptfs-utils-26.a1/src/include/ecryptfs.h 2007-10-10 02:17:30.000000000 +0200 +++ ecryptfs-utils-26.a2/src/include/ecryptfs.h 2007-10-13 22:41:03.000000000 +0200 @@ -282,6 +282,11 @@ struct key_mod_param { #define ECRYPTFS_KEY_MOD_NO_SUCH_KEY 7 #define ECRYPTFS_KEY_MOD_HINT_INSUFFICIENT 8 +struct ecryptfs_ctx_ops { + int (*prompt)(char *prompt_type, char *prompt, char *input, + int input_size); +}; + /** * @init: Allocates memory on the heap and sets the alias into that * memory; callee will free @@ -472,4 +477,9 @@ int ecryptfs_generate_sig_from_key_data( int ecryptfs_fill_in_dummy_ops(struct ecryptfs_key_mod_ops *key_mod_ops); int ecryptfs_register_key_modules(struct ecryptfs_ctx* ctx); +/* TEMP TEMP TEMP - BEGIN + * until context will be forwarded into key modules */ +struct ecryptfs_ctx_ops *cryptfs_get_ctx_opts(void); +/* TEMP TEMP TEMP - END */ + #endif diff -urNp ecryptfs-utils-26.a1/src/key_mod/ecryptfs_key_mod_pkcs11_helper.c ecryptfs-utils-26.a2/src/key_mod/ecryptfs_key_mod_pkcs11_helper.c --- ecryptfs-utils-26.a1/src/key_mod/ecryptfs_key_mod_pkcs11_helper.c 2007-10-13 22:40:39.000000000 +0200 +++ ecryptfs-utils-26.a2/src/key_mod/ecryptfs_key_mod_pkcs11_helper.c 2007-10-13 22:41:03.000000000 +0200 @@ -125,7 +125,7 @@ static int ecryptfs_pkcs11h_serialize(un int rc = 0; (*blob_size) = 0; - if (!pkcs11h_data->serialized_id || !pkcs11h_data->passphrase) { + if (!pkcs11h_data->serialized_id) { rc = -EINVAL; syslog(LOG_ERR, "PKCS#11: pkcs11h_data internal structure not properly filled in\n"); goto out; @@ -184,17 +184,51 @@ pkcs11h_pin_prompt ( char * const pin, const size_t pin_max ) { + char *prompt = NULL; + int use_static_password = 0; + int rc; + (void)global_data; - if (retry == 0 && user_data != NULL) { - strncpy (pin, (char *)user_data, pin_max-1); - pin[pin_max-1] = '\x0'; + if (asprintf (&prompt, "Please enter PIN for token '%s'", token->display) == -1) { + rc = -ENOMEM; + goto out; + } - return 1; + /* TEMP TEMP TEMP - BEGIN + * Until we can affect ecryptfs context via daemon */ + if (cryptfs_get_ctx_opts ()->prompt) { + rc = cryptfs_get_ctx_opts ()->prompt ("password", prompt, pin, pin_max); + if (rc == -EINVAL) { + use_static_password = 1; + } + else { + goto out; + } } else { - return 0; + use_static_password = 1; } + + if (use_static_password) { + if (retry != 0 || user_data == NULL) { + rc = -EIO; + goto out; + } + strncpy (pin, (char *)user_data, pin_max-1); + pin[pin_max-1] = '\x0'; + } + + rc = 0; + + /* TEMP TEMP TEMP - END */ +out: + + if (prompt != NULL) { + free (prompt); + } + + return rc == 0; } /** @@ -1296,7 +1330,7 @@ static struct param_node pkcs11h_key_par .next_token = &pkcs11h_key_param_nodes[PKCS11H_KEY_TOK_PASS_STDIN], .trans_func = tf_pkcs11h_key_id}, {.val = "default", - .pretty_val = "Passphrase", + .pretty_val = "Passphrase (empty for interactive)", .next_token = &pkcs11h_key_param_nodes[PKCS11H_KEY_TOK_DEFAULT_PASS], .trans_func = tf_pkcs11h_key_id}}}, diff -urNp ecryptfs-utils-26.a1/src/libecryptfs/main.c ecryptfs-utils-26.a2/src/libecryptfs/main.c --- ecryptfs-utils-26.a1/src/libecryptfs/main.c 2007-10-13 22:40:39.000000000 +0200 +++ ecryptfs-utils-26.a2/src/libecryptfs/main.c 2007-10-13 22:41:03.000000000 +0200 @@ -879,3 +879,10 @@ int ecryptfs_list_zombie_session_placeho out: return rc; } + +static struct ecryptfs_ctx_ops ctx_ops; + +struct ecryptfs_ctx_ops *cryptfs_get_ctx_opts (void) +{ + return &ctx_ops; +} ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ eCryptfs-devel mailing list eCryptfs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ecryptfs-devel