aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c103
-rw-r--r--ui.c50
-rw-r--r--ui.h14
3 files changed, 131 insertions, 36 deletions
diff --git a/main.c b/main.c
index a1fd090..f0c99d3 100644
--- a/main.c
+++ b/main.c
@@ -5,6 +5,8 @@
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
#include <fcntl.h>
#include "ui_ani.h"
@@ -22,6 +24,7 @@
#define VERSION "unknown"
#endif
+#define DEFAULT_FIFO "/lib/cryptsetup/passfifo"
#define SHTDWN_CMD "echo 'o' >/proc/sysrq-trigger"
@@ -32,7 +35,8 @@ usage(char *arg0)
fprintf(stderr, "%s (%s)\n %s\n", PKGNAME, VERSION, PKGDESC);
fprintf(stderr, " Written by %s (%s).\n", AUTHOR, AUTHOR_EMAIL);
fprintf(stderr, " License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.\n\n");
- fprintf(stderr, " Command: %s: [passfifo]\n", arg0);
+ fprintf(stderr, " Command:\n\t%s [args]\n", arg0);
+ fprintf(stderr, " Arguments:\n\t-h this\n\t-f [passfifo] default: %s\n\t-c [cryptcreate]\n", DEFAULT_FIFO);
}
static bool
@@ -58,38 +62,101 @@ check_fifo(char *fifo_path)
return (false);
}
-int main(int argc, char **argv)
+/* stolen from http://www.gnu.org/software/libc/manual/html_node/Waiting-for-I_002fO.html */
+static int
+input_timeout(int filedes, unsigned int seconds)
{
- int ffd;
- size_t plen;
+ fd_set set;
+ struct timeval timeout;
- if (argc != 2) {
+ /* Initialize the file descriptor set. */
+ FD_ZERO (&set);
+ FD_SET (filedes, &set);
+ /* Initialize the timeout data structure. */
+ timeout.tv_sec = seconds;
+ timeout.tv_usec = 0;
+ /* select returns 0 if timeout, 1 if input available, -1 if error. */
+ return TEMP_FAILURE_RETRY(select(FD_SETSIZE, &set, NULL, NULL, &timeout));
+}
+
+int
+run_cryptcreate(char *pass, char *crypt_cmd)
+{
+ int retval;
+ char *cmd;
+
+ if (crypt_cmd == NULL || pass != NULL) return (-1);
+ asprintf(&cmd, "echo '%s' | %s", pass, crypt_cmd);
+ retval = system(cmd);
+ return (retval);
+}
+
+int
+main(int argc, char **argv)
+{
+ int ffd, c_status, opt;
+ pid_t child;
+ char pbuf[MAX_PASSWD_LEN+1];
+ char *fifo_path = NULL;
+ char *crypt_cmd = NULL;
+
+ memset(pbuf, '\0', MAX_PASSWD_LEN+1);
+
+ while ((opt = getopt(argc, argv, "hf:c:")) != -1) {
+ switch (opt) {
+ case 'h':
+ usage(argv[0]);
+ exit(EXIT_SUCCESS);
+ case 'f':
+ fifo_path = strdup(optarg);
+ break;
+ case 'c':
+ crypt_cmd = strdup(optarg);
+ break;
+ default:
+ usage(argv[0]);
+ exit(EXIT_FAILURE);
+ }
+ }
+ if (optind < argc) {
+ fprintf(stderr, "%s: I dont understand you.\n\n", argv[0]);
usage(argv[0]);
exit(EXIT_FAILURE);
}
+ if (fifo_path == NULL) fifo_path = strdup(DEFAULT_FIFO);
- if (check_fifo(argv[1]) == false) {
+ if (check_fifo(fifo_path) == false) {
exit(EXIT_FAILURE);
}
- if ((ffd = open(argv[1], O_NONBLOCK | O_RDWR)) < 0) {
+ if ((ffd = open(fifo_path, O_NONBLOCK | O_RDWR)) < 0) {
+ fprintf(stderr, "fifo: %s\n", fifo_path);
perror("open");
exit(EXIT_FAILURE);
}
- do_ui();
- if (passwd != NULL) {
- plen = strlen(passwd);
- printf("Sending your password to the FIFO ..\n");
- if (write(ffd, (const void *)passwd, plen) != plen) {
- perror("write");
- } else {
- printf("Ok.\n");
+ if ((child = fork()) == 0) {
+ /* child */
+ do_ui(ffd);
+ } else if (child > 0) {
+ /* parent */
+ fclose(stdin);
+ while (input_timeout(ffd, 1) == 0) {
+ usleep(100000);
}
- memset(passwd, '\0', plen);
- plen = 0;
- free(passwd);
+ stop_ui();
+ wait(&c_status);
+ if (read(ffd, pbuf, MAX_PASSWD_LEN) > 0) {
+ run_cryptcreate(pbuf, crypt_cmd);
+ }
+ memset(pbuf, '\0', MAX_PASSWD_LEN+1);
+ } else {
+ /* fork error */
+ perror("fork");
+ exit(EXIT_FAILURE);
}
close(ffd);
+ if (crypt_cmd != NULL) free(crypt_cmd);
+ free(fifo_path);
return (EXIT_SUCCESS);
}
diff --git a/ui.c b/ui.c
index b5f7f0e..f598d62 100644
--- a/ui.c
+++ b/ui.c
@@ -28,13 +28,12 @@
#define STRLEN(s) (sizeof(s)/sizeof(s[0]))
-char *passwd = NULL;
-
+static int ffd;
static unsigned int max_x, max_y;
static WINDOW *wnd_main;
static struct nask_ui *nui = NULL;
static pthread_t thrd;
-static bool active;
+static bool active, passwd_from_ui;
static unsigned int atmout = APP_TIMEOUT;
static pthread_cond_t cnd_update = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t mtx_update = PTHREAD_MUTEX_INITIALIZER;
@@ -178,7 +177,7 @@ free_ui(void)
printf(" \033[2J\n");
}
-int
+static int
run_ui_thrd(void) {
pthread_mutex_lock(&mtx_busy);
active = true;
@@ -187,14 +186,33 @@ run_ui_thrd(void) {
return (pthread_create(&thrd, NULL, &ui_thrd, NULL));
}
-int
-stop_ui_thrd(void) {
+void
+stop_ui(void)
+{
pthread_mutex_lock(&mtx_busy);
active = false;
pthread_mutex_unlock(&mtx_busy);
+}
+
+static int
+stop_ui_thrd(void)
+{
+ stop_ui();
return (pthread_join(thrd, NULL));
}
+static int
+send_passwd(int fifo_fd, char *passwd, size_t len)
+{
+ if (write(fifo_fd, passwd, len) != len) {
+ memset(passwd, '\0', len);
+ return (errno);
+ } else {
+ memset(passwd, '\0', len);
+ return (0);
+ }
+}
+
static bool
process_key(wchar_t key, struct input *a, WINDOW *win)
{
@@ -203,9 +221,7 @@ process_key(wchar_t key, struct input *a, WINDOW *win)
atmout = APP_TIMEOUT;
switch (key) {
case UIKEY_ENTER:
- passwd = malloc((a->input_len + 1)*sizeof(char));
- strncpy(passwd, a->input, a->input_len);
- passwd[a->input_len] = '\0';
+ send_passwd(ffd, a->input, a->input_len);
retval = false;
break;
case UIKEY_BACKSPACE:
@@ -236,19 +252,20 @@ lower_statusbar_update(WINDOW *win, struct statusbar *bar)
}
int
-do_ui(void)
+do_ui(int fifo_fd)
{
struct input *pw_input;
struct anic *heartbeat;
struct statusbar *higher, *lower;
char key = '\0';
+ ffd = fifo_fd;
if (sem_init(&sem_rdy, 0, 0) == -1) {
perror("init semaphore");
return (DOUI_ERR);
}
init_ui();
- pw_input = init_input((unsigned int)(max_x / 2)-PASSWD_XRELPOS, (unsigned int)(max_y / 2)-PASSWD_YRELPOS, PASSWD_WIDTH, "PASSWORD: ", 128, COLOR_PAIR(3), COLOR_PAIR(2));
+ pw_input = init_input((unsigned int)(max_x / 2)-PASSWD_XRELPOS, (unsigned int)(max_y / 2)-PASSWD_YRELPOS, PASSWD_WIDTH, "PASSWORD: ", MAX_PASSWD_LEN, COLOR_PAIR(3), COLOR_PAIR(2));
heartbeat = init_anic(0, 0, A_BOLD | COLOR_PAIR(1), "[%c]");
higher = init_statusbar(0, max_x, A_BOLD | COLOR_PAIR(3), NULL);
lower = init_statusbar(max_y - 1, max_x, COLOR_PAIR(3), lower_statusbar_update);
@@ -288,3 +305,14 @@ do_ui(void)
free_ui();
return (DOUI_OK);
}
+
+bool
+is_passwd_from_ui(void)
+{
+ bool ret;
+ pthread_mutex_lock(&mtx_busy);
+ ret = passwd_from_ui;
+ pthread_mutex_unlock(&mtx_busy);
+ return (ret);
+}
+
diff --git a/ui.h b/ui.h
index 91e0b27..77a5bc9 100644
--- a/ui.h
+++ b/ui.h
@@ -4,6 +4,8 @@
#include <ncurses.h>
#include <stdint.h>
+#define MAX_PASSWD_LEN 128
+
#define UICB_OK 0
#define UICB_ERR_UNDEF 1
#define UICB_ERR_CB 2
@@ -25,8 +27,6 @@
#define UIKEY_RIGHT 5
-extern char *passwd;
-
typedef int (*ui_callback)(WINDOW *, void *, bool);
struct nask_ui {
@@ -52,12 +52,12 @@ void
free_ui(void);
int
-run_ui_thrd(void);
+do_ui(int fifo_fd);
-int
-stop_ui_thrd(void);
+void
+stop_ui(void);
-int
-do_ui(void);
+bool
+is_passwd_from_ui(void);
#endif