diff options
-rw-r--r-- | main.c | 103 | ||||
-rw-r--r-- | ui.c | 50 | ||||
-rw-r--r-- | ui.h | 14 |
3 files changed, 131 insertions, 36 deletions
@@ -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); } @@ -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); +} + @@ -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 |