From 03b222dddab5c6c3101e8e61da7c1d36497e98a3 Mon Sep 17 00:00:00 2001 From: Michael Rash Date: Thu, 8 Nov 2012 22:22:04 -0500 Subject: [PATCH] [client] (Franck Joncourt) Fixed Ctrl-C problem where SPA packets were sent anyway [client] (Franck Joncourt) Contributed a patch to allow the fwknop client to be stopped during the password entry prompt with Ctrl-C before any SPA packet is sent on the wire. --- CREDITS | 2 + ChangeLog | 3 ++ client/getpasswd.c | 113 +++++++++++++++++++++++++++------------------ todo.org | 8 ++-- 4 files changed, 78 insertions(+), 48 deletions(-) diff --git a/CREDITS b/CREDITS index 1a37ae97..72e7eeca 100644 --- a/CREDITS +++ b/CREDITS @@ -41,6 +41,8 @@ Franck Joncourt appropriately via open(), and at the same time this patch fixes a potential race condition since the previous code used fopen() followed by chmod(). + - Contributed a patch to allow the fwknop client to be stopped with Ctrl-C + before sending an SPA packet on the wire. Jonathan Schulz - Submitted patches to change HTTP connection type to 'close' for -R mode diff --git a/ChangeLog b/ChangeLog index 46147748..df0453c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -29,6 +29,9 @@ fwknop-2.0.4 (11//2012): modes. - [libfko] Restricted usernames embedded in SPA packets to be alpha-numeric along with "-" chars. + - [client] (Franck Joncourt) Contributed a patch to allow the fwknop + client to be stopped during the password entry prompt with Ctrl-C before + any SPA packet is sent on the wire. - [client+server] Applied patch from Franck Joncourt to remove unnecessary chmod() call when creating client rc file and server replay cache file. The permissions are now set appropriately via open(), and at the same diff --git a/client/getpasswd.c b/client/getpasswd.c index f27ddbb5..54166f10 100644 --- a/client/getpasswd.c +++ b/client/getpasswd.c @@ -40,12 +40,25 @@ #include "fwknop_common.h" #include "getpasswd.h" -#define MAX_PASS_LEN 128 +#define MAX_PASS_LEN 128 ///< Maximum number of chars an encryption key or a password can contain -/* Function for accepting password input from users -*/ +#define PW_BREAK_CHAR 0x03 ///< Ascii code for the Ctrl-C char +#define PW_BS_CHAR 0x08 ///< Ascii code for the backspace char +#define PW_LF_CHAR 0x0A ///< Ascii code for the \n char +#define PW_CR_CHAR 0x0D ///< Ascii code for the \r char +#define PW_CLEAR_CHAR 0x15 ///< Ascii code for the Ctrl-U char + +/** + * Function for accepting password input from users + * + * The functions reads chars from the terminal and store them in a buffer of chars. + * + * @return NULL if a problem occured or the user killed the terminal (Ctrl-C)\n + * otherwise the password - empty password is accepted. + */ char* -getpasswd(const char *prompt) +getpasswd( + const char *prompt) ///< String displayed on the terminal to prompt the user for a password or an encryption key { static char pwbuf[MAX_PASS_LEN + 1] = {0}; char *ptr; @@ -63,18 +76,21 @@ getpasswd(const char *prompt) /* Setup blocks for SIGINT and SIGTSTP and save the original signal * mask. - */ + */ sigemptyset(&sig); sigaddset(&sig, SIGINT); sigaddset(&sig, SIGTSTP); sigprocmask(SIG_BLOCK, &sig, &old_sig); - /* Save current tty state for later restoration after we disable echo - * of characters to the tty. - */ + /* + * Save current tty state for later restoration after we : + * - disable echo of characters to the tty + * - disable signal generation + * - disable cannonical mode (input read line by line mode) + */ tcgetattr(fileno(fp), &ts); old_ts = ts; - ts.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); + ts.c_lflag &= ~(ECHO | ICANON | ISIG); tcsetattr(fileno(fp), TCSAFLUSH, &ts); fputs(prompt, fp); @@ -83,59 +99,66 @@ getpasswd(const char *prompt) /* Read in the password. */ ptr = pwbuf; + #ifdef WIN32 - _cputs(prompt); - while((c = _getch()) != '\r') - { - /* Handle a backspace without backing up too far. - */ - if(c == '\b') - { - if(ptr != pwbuf) - *ptr--; - - continue; - } - - /* Handle a Ctrl-U to clear the password entry and start over - * (like it works under Unix). - */ - if(c == 0x15) - { - ptr = pwbuf; - continue; - } + _cputs(prompt); + while((c = _getch()) != PW_CR_CHAR) #else - while((c = getc(fp)) != EOF && c != '\n') - { + while( ((c = getc(fp)) != EOF) && (c != PW_LF_CHAR) && (c != PW_BREAK_CHAR) ) #endif - if(ptr < &pwbuf[MAX_PASS_LEN]) - *ptr++ = c; - } + { + /* Handle a backspace without backing up too far. + */ + if (c == PW_BS_CHAR) + { + if (ptr != pwbuf) + ptr--; + } - /* Null terminate the password. - */ - *ptr = 0; + /* Handle a Ctrl-U to clear the password entry and start over + */ + else if (c == PW_CLEAR_CHAR) + ptr = pwbuf; + + /* Store data in the buffer and check for a possible overflow + */ + else if (ptr < &pwbuf[MAX_PASS_LEN]) + *ptr++ = c; + } + + /* If a Ctrl-C char has been detected we set an error + */ + if (c == PW_BREAK_CHAR) + ptr = NULL; + + /* Otherwise we make the password as a NULL terminated string and point + * to the start of the password in order to be returned by the function. + */ + else + { + *ptr = '\0'; + ptr = pwbuf; + } #ifndef WIN32 /* we can go ahead and echo out a newline. */ - putc('\n', fp); + putc(PW_LF_CHAR, fp); - /* Restore our tty state and signal handlers. + /* Restore our tty state and signal handlers. */ tcsetattr(fileno(fp), TCSAFLUSH, &old_ts); sigprocmask(SIG_BLOCK, &old_sig, NULL); fclose(fp); #else - /* In Windows, it would be a CR-LF - */ - _putch('\r'); - _putch('\n'); + /* In Windows, it would be a CR-LF + */ + _putch(PW_CR_CHAR); + _putch(PW_LF_CHAR); #endif - return(pwbuf); + return (ptr); } /* Function for accepting password input from from a file diff --git a/todo.org b/todo.org index 92525d62..5cc8c9cd 100644 --- a/todo.org +++ b/todo.org @@ -2,6 +2,11 @@ This is the main todo org mode file for the fwknop project ** COMPLETED This bucket is for completed tasks. +*** [client] Update to not send SPA packet if Ctrl-C is used + :CLOSED: <2012-11-08 Thu> + The client currently sends an SPA packet when an encryption key is + requested but the user tries to exit out with Ctrl-C. + - Completed by Franck Joncourt. *** [server] Add the ability to process pcap files offline :CLOSED: <2012-11-08 Thu> Leverage pcap_open_offline() to process pcap files from disk instead of @@ -126,9 +131,6 @@ ** Ruby bindings to libfko Perl and Python bindings already exist for libfko, so add Ruby to this list as well. -** [client] Update to not send SPA packet if Ctrl-C is used - The client currently sends an SPA packet when an encryption key is - requested but the user tries to exit out with Ctrl-C. ** [test suite] client/server only tests When only the client or server is being installed on a system, the test suite should be able to run only the relevant tests.