[client] (Franck Joncourt) Fixed Ctrl-C problem where SPA packets were sent anyway
authorMichael Rash <mbr@cipherdyne.org>
Fri, 9 Nov 2012 03:22:04 +0000 (22:22 -0500)
committerMichael Rash <mbr@cipherdyne.org>
Fri, 9 Nov 2012 03:22:04 +0000 (22:22 -0500)
[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
ChangeLog
client/getpasswd.c
todo.org

diff --git a/CREDITS b/CREDITS
index 1a37ae9..72e7eec 100644 (file)
--- 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
index 4614774..df0453c 100644 (file)
--- 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
index f27ddbb..54166f1 100644 (file)
 #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])
+    {
+        /* Handle a backspace without backing up too far.
+         */
+        if (c == PW_BS_CHAR)
+        {
+            if (ptr != pwbuf)
+                ptr--;
+        }
+
+        /* 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;
-       }
+    }
 
-       /* Null terminate the password.
-    */
-    *ptr = 0;
+    /* 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
index 92525d6..5cc8c9c 100644 (file)
--- 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
 ** 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.