[client] added --get-hmac-key to mirror --get-key, closes #68
authorMichael Rash <mbr@cipherdyne.org>
Mon, 6 May 2013 01:54:07 +0000 (21:54 -0400)
committerMichael Rash <mbr@cipherdyne.org>
Mon, 6 May 2013 01:54:07 +0000 (21:54 -0400)
ChangeLog
Makefile.am
client/cmd_opts.h
client/config_init.c
client/fwknop.c
client/fwknop_common.h
client/getpasswd.c
client/getpasswd.h
doc/fwknop.man.asciidoc
test/test-fwknop.pl
test/tests/rijndael_hmac.pl

index 41d9c9c..7b15b44 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -60,6 +60,10 @@ fwknop-2.5 (//2013):
     - (Shawn Wilson) Added better SPA source IP logging for various fwknopd
       logging messages.  This helps to make it more clear why certain SPA
       packets are rejected from some systems.
+    - [client] Added --get-hmac-key to allow HMAC keys to be acquried from the
+      specified file similarly to the --get-key option.  This is a convenience
+      only, and the fwknop rc file feature should be used instead since it is
+      far more powerful.
 
 fwknop-2.0.4 (12/09/2012):
     - [client] Misc fixes and the addition of save_args and last command 
index bede97d..fa48c3d 100644 (file)
@@ -149,6 +149,7 @@ EXTRA_DIST = \
     test/conf/no_flush_exit_fwknopd.conf \
     test/conf/no_flush_init_or_exit_fwknopd.conf \
     test/conf/hmac_access.conf \
+    test/conf/hmac_get_key_access.conf \
     test/conf/hmac_no_b64_access.conf \
     test/conf/hmac_dual_key_usage_access.conf \
     test/conf/hmac_invalid_type_access.conf \
index ff71413..2c08b31 100644 (file)
@@ -52,6 +52,7 @@ enum {
     KEY_LEN,
     HMAC_DIGEST_TYPE,
     HMAC_KEY_LEN,
+    GET_HMAC_KEY,
     KEY_RIJNDAEL,
     KEY_RIJNDAEL_BASE64,
     KEY_HMAC_BASE64,
@@ -92,6 +93,7 @@ static struct option cmd_opts[] =
     {"gpg-home-dir",        1, NULL, GPG_HOME_DIR },
     {"gpg-agent",           0, NULL, GPG_AGENT },
     {"get-key",             1, NULL, 'G'},
+    {"get-hmac-key",        1, NULL, GET_HMAC_KEY },
     {"help",                0, NULL, 'h'},
     {"http-proxy",          1, NULL, 'H'},
     {"key-gen",             0, NULL, 'k'},
index e0cf501..653262a 100644 (file)
@@ -82,6 +82,7 @@ enum
     FWKNOP_CLI_ARG_KEY_HMAC,
     FWKNOP_CLI_ARG_USE_HMAC,
     FWKNOP_CLI_ARG_KEY_FILE,
+    FWKNOP_CLI_ARG_HMAC_KEY_FILE,
     FWKNOP_CLI_ARG_NAT_ACCESS,
     FWKNOP_CLI_ARG_HTTP_USER_AGENT,
     FWKNOP_CLI_ARG_RESOLVE_URL,
@@ -118,6 +119,7 @@ const char* fwknop_cli_key_tab[FWKNOP_CLI_ARG_NB] =
     "HMAC_KEY",
     "USE_HMAC",
     "KEY_FILE",
+    "HMAC_KEY_FILE",
     "NAT_ACCESS",
     "HTTP_USER_AGENT",
     "RESOLVE_URL",
@@ -700,6 +702,12 @@ parse_rc_param(fko_cli_options_t *options, const char *var, char * val)
     {
         strlcpy(options->get_key_file, val, sizeof(options->get_key_file));
     }
+    /* HMAC key file */
+    else if (conf_key_ndx == FWKNOP_CLI_ARG_HMAC_KEY_FILE)
+    {
+        strlcpy(options->get_key_file, val,
+            sizeof(options->get_hmac_key_file));
+    }
     /* NAT Access Request */
     else if (conf_key_ndx == FWKNOP_CLI_ARG_NAT_ACCESS)
     {
@@ -845,6 +853,9 @@ add_rc_param(FILE* fhandle, uint16_t arg_ndx, fko_cli_options_t *options)
         case FWKNOP_CLI_ARG_KEY_FILE :
             strlcpy(val, options->get_key_file, sizeof(val));
             break;
+        case FWKNOP_CLI_ARG_HMAC_KEY_FILE :
+            strlcpy(val, options->get_hmac_key_file, sizeof(val));
+            break;
         case FWKNOP_CLI_ARG_KEY_RIJNDAEL:
             strlcpy(val, options->key, sizeof(val));
             break;
@@ -1347,6 +1358,12 @@ config_init(fko_cli_options_t *options, int argc, char **argv)
                 strlcpy(options->get_key_file, optarg, sizeof(options->get_key_file));
                 cli_arg_bitmask |= FWKNOP_CLI_ARG_BM(FWKNOP_CLI_ARG_KEY_FILE);
                 break;
+            case GET_HMAC_KEY: 
+                strlcpy(options->get_hmac_key_file, optarg,
+                    sizeof(options->get_hmac_key_file));
+                options->use_hmac = 1;
+                cli_arg_bitmask |= FWKNOP_CLI_ARG_BM(FWKNOP_CLI_ARG_HMAC_KEY_FILE);
+                break;
             case 'h':
                 usage();
                 exit(EXIT_SUCCESS);
index 3b6d237..22ed7d9 100644 (file)
@@ -1134,8 +1134,7 @@ get_keys(fko_ctx_t ctx, fko_cli_options_t *options,
         */
         if (options->get_key_file[0] != 0x0)
         {
-            strlcpy(key, getpasswd_file(ctx, options), MAX_KEY_LEN+1);
-            *key_len = strlen(key);
+            get_key_file(key, key_len, options->get_key_file, ctx, options);
         }
         else if (options->use_gpg)
         {
@@ -1205,25 +1204,26 @@ get_keys(fko_ctx_t ctx, fko_cli_options_t *options,
     {
         /* If --get-key file was specified grab the key/password from it.
         */
-#if 0
-        if (options->get_key_file[0] != 0x0)
+        if(options->get_hmac_key_file[0] != 0x0)
         {
-            key = getpasswd_file(options->get_key_file, options->spa_server_str);
+            get_key_file(hmac_key, hmac_key_len,
+                options->get_hmac_key_file, ctx, options);
+            use_hmac = 1;
         }
         else
         {
-#endif
-        hmac_key_tmp = getpasswd("Enter HMAC key: ");
+            hmac_key_tmp = getpasswd("Enter HMAC key: ");
 
-        if(hmac_key_tmp == NULL)
-        {
-            log_msg(LOG_VERBOSITY_ERROR, "[*] getpasswd() key error.");
-            clean_exit(ctx, options, EXIT_FAILURE);
-        }
+            if(hmac_key_tmp == NULL)
+            {
+                log_msg(LOG_VERBOSITY_ERROR, "[*] getpasswd() key error.");
+                clean_exit(ctx, options, EXIT_FAILURE);
+            }
 
-        strlcpy(hmac_key, hmac_key_tmp, MAX_KEY_LEN+1);
-        *hmac_key_len = strlen(hmac_key);
-        use_hmac = 1;
+            strlcpy(hmac_key, hmac_key_tmp, MAX_KEY_LEN+1);
+            *hmac_key_len = strlen(hmac_key);
+            use_hmac = 1;
+        }
     }
 
     if (use_hmac)
index 0686899..e0221b8 100644 (file)
@@ -85,6 +85,7 @@ typedef struct fko_cli_options
     char key_gen_file[MAX_PATH_LEN];
     char server_command[MAX_LINE_LEN];
     char get_key_file[MAX_PATH_LEN];
+    char get_hmac_key_file[MAX_PATH_LEN];
     char save_packet_file[MAX_PATH_LEN];
     int  save_packet_file_append;
     int  show_last_command;
index daa8368..2a8f1b6 100644 (file)
@@ -163,20 +163,24 @@ getpasswd(
 
 /* Function for accepting password input from from a file
 */
-char*
-getpasswd_file(fko_ctx_t ctx, const fko_cli_options_t *options)
+void
+get_key_file(char *key, int *key_len, const char *key_file,
+    fko_ctx_t ctx, const fko_cli_options_t *options)
 {
     FILE           *pwfile_ptr;
     unsigned int    numLines = 0, i = 0, found_dst;
 
-    static char     pwbuf[MAX_KEY_LEN + 1]      = {0};
     char            conf_line_buf[MAX_LINE_LEN] = {0};
     char            tmp_char_buf[MAX_LINE_LEN]  = {0};
     char           *lptr;
 
-    if ((pwfile_ptr = fopen(options->get_key_file, "r")) == NULL)
+    memset(key, 0x00, MAX_KEY_LEN+1);
+    memset(conf_line_buf, 0x00, MAX_LINE_LEN);
+    memset(tmp_char_buf, 0x00, MAX_LINE_LEN);
+
+    if ((pwfile_ptr = fopen(key_file, "r")) == NULL)
     {
-        log_msg(LOG_VERBOSITY_ERROR, "Could not open config file: %s", options->get_key_file);
+        log_msg(LOG_VERBOSITY_ERROR, "Could not open config file: %s", key_file);
         fko_destroy(ctx);
         exit(EXIT_FAILURE);
     }
@@ -221,23 +225,25 @@ getpasswd_file(fko_ctx_t ctx, const fko_cli_options_t *options)
 
         i = 0;
         while (*lptr != '\0' && *lptr != '\n') {
-            pwbuf[i] = *lptr;
+            key[i] = *lptr;
             lptr++;
             i++;
         }
-        pwbuf[i] = '\0';
+        key[i] = '\0';
     }
 
     fclose(pwfile_ptr);
 
-    if (pwbuf[0] == '\0') {
-        log_msg(LOG_VERBOSITY_ERROR, "Could not get password for IP: %s from: %s",
-            options->spa_server_str, options->get_key_file);
+    if (key[0] == '\0') {
+        log_msg(LOG_VERBOSITY_ERROR, "Could not get key for IP: %s from: %s",
+            options->spa_server_str, key_file);
         fko_destroy(ctx);
         exit(EXIT_FAILURE);
     }
 
-    return pwbuf;
+    *key_len = strlen(key);
+
+    return;
 }
 
 /***EOF***/
index 5f571c6..dc4c7f8 100644 (file)
 /* Prototypes
 */
 char* getpasswd(const char *prompt);
-char* getpasswd_file(fko_ctx_t ctx, const fko_cli_options_t *options);
+
+/* This can be used to acquire an encryption key or HMAC key
+*/
+void get_key_file(char *key, int *key_len, const char *key_file,
+    fko_ctx_t ctx, const fko_cli_options_t *options);
 
 #endif  /* GETPASSWD_H */
index 21ddad9..ff2b725 100644 (file)
@@ -126,28 +126,49 @@ GENERAL OPTIONS
     contains a line for each destination hostname or IP address, a colon
     (":"), optional space and the password, followed by a newline.  Note
     that the last line has to have a terminating newline character.
-    Also note: though this is a convenience, have a file on your system with
-    cleartext passwords is not a good idea and is not recommended.
+    Also note: though this is a convenience, having a file on your system
+    with cleartext passwords is not a good idea and is not recommended.
+    Having the *fwknop* client prompt you for the key is generally more
+    secure.  Note also that if a key is stored on disk, the *fwknop* rc
+    file is a more powerful mechanism for specifying the key but other
+    options as well.
+
+*--get-hmac-key*='<file>'::
+    Load an HMAC key/password from the specified file.  Similarly to the
+    format for the *--get-key* option, the HMAC key file contains a line for
+    each destination hostname or IP address, a colon (":"), optional space
+    and the password, followed by a newline.  Note that the last line has
+    to have a terminating newline character.  Also note: though this is a
+    convenience, having a file on your system with cleartext passwords is
+    not a good idea and is not recommended.  Having the *fwknop* client
+    prompt you for the HMAC key is generally more secure.  Note also that
+    if a key is stored on disk, the *fwknop* rc file is a more powerful
+    mechanism for specifying the key but other options as well.
 
 *--key-rijndael*='<key>'::
-    Specify the Rijndael key. Since the password is visible to utilities
-    (like 'ps' under Unix) this form should only be used where security is
-    not important.
+    Specify the Rijndael key. Since the key may be visible to utilities
+    such as 'ps' under Unix, this form should only be used where security is
+    not critical.  Having the *fwknop* client prompt you for the key is
+    generally more secure.
 
 *--key-base64-rijndael*='<key>'::
-    Specify the base64 encoded Rijndael key. Since the password is visible
-    to utilities (like 'ps' under Unix) this form should only be used where
-    security is not important.
+    Specify the base64 encoded Rijndael key. Since the key may be visible
+    to utilities such as 'ps' under Unix, this form should only be used where
+    security is not critical.  Having the *fwknop* client prompt you for the
+    key is generally more secure.
 
 *--key-base64-hmac*='<key>'::
-    Specify the base64 encoded HMAC key. Since the password is visible to
-    utilities (like 'ps' under Unix) this form should only be used where
-    security is not important.
+    Specify the base64 encoded HMAC key. Since the key may be visible
+    to utilities such as 'ps' under Unix, this form should only be used where
+    security is not critical.  Having the *fwknop* client prompt you for the
+    key is generally more secure.
+
 
 *--key-hmac*='<key>'::
-    Specify the raw HMAC key (not base64 encoded). Since the password is
-    visible to utilities (like 'ps' under Unix) this form should only be used
-    where security is not important.
+    Specify the raw HMAC key (not base64 encoded). Since the key may be visible
+    to utilities such as 'ps' under Unix, this form should only be used where
+    security is not critical.  Having the *fwknop* client prompt you for the
+    key is generally more secure.
 
 *-l, --last-cmd*::
     Execute *fwknop* with the command-line arguments from the previous
index d82bfa2..3363278 100755 (executable)
@@ -16,6 +16,7 @@ use strict;
 #==================== config =====================
 my $logfile         = 'test.log';
 our $local_key_file = 'local_spa.key';
+our $local_hmac_key_file = 'local_hmac_spa.key';
 my $output_dir      = 'output';
 our $conf_dir       = 'conf';
 my $run_dir         = 'run';
@@ -38,6 +39,7 @@ our %cf = (
     'def'                          => "$conf_dir/default_fwknopd.conf",
     'def_access'                   => "$conf_dir/default_access.conf",
     'hmac_access'                  => "$conf_dir/hmac_access.conf",
+    'hmac_get_key_access'          => "$conf_dir/hmac_get_key_access.conf",
     'hmac_no_b64_access'           => "$conf_dir/hmac_no_b64_access.conf",
     'hmac_md5_access'              => "$conf_dir/hmac_md5_access.conf",
     'hmac_md5_short_key_access'    => "$conf_dir/hmac_md5_short_key_access.conf",
@@ -1187,7 +1189,19 @@ sub client_send_spa_packet() {
 
     my $rv = 1;
 
-    &write_key($default_key, $local_key_file);
+    if ($test_hr->{'get_key'}) {
+        &write_key($test_hr->{'get_key'}->{'key'},
+            $test_hr->{'get_key'}->{'file'});
+    } else {
+        &write_key($default_key, $local_key_file);
+    }
+
+    if ($test_hr->{'get_hmac_key'}) {
+        &write_key($test_hr->{'get_hmac_key'}->{'key'},
+            $test_hr->{'get_hmac_key'}->{'file'});
+    } else {
+        &write_key($default_key, $local_key_file);
+    }
 
     if (-e $server_cmd_tmp) {
         my $tries = 0;
@@ -4953,6 +4967,8 @@ sub validate_test_hashes() {
         'fuzzing_pkt'     => $OPTIONAL,
         'pkt_prefix'      => $OPTIONAL,
         'no_ip_check'     => $OPTIONAL,
+        'get_key'         => $OPTIONAL,
+        'get_hmac_key'    => $OPTIONAL,
         'set_legacy_iv'   => $OPTIONAL,
         'write_rc_file'   => $OPTIONAL,
         'save_rc_stanza'  => $OPTIONAL,
index 5fe0bce..71e70f6 100644 (file)
         'key_file' => $cf{'rc_hmac_b64_key'},
         'fatal'    => $NO
     },
+    {
+        'category' => 'Rijndael+HMAC',
+        'subcategory' => 'client+server',
+        'detail'   => '--get-hmac-key (tcp/22 ssh)',
+        'function' => \&spa_cycle,
+        'cmdline'  => $default_client_args .
+            " --get-hmac-key $local_hmac_key_file",
+        'fwknopd_cmdline'  => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
+            "$fwknopdCmd -c $cf{'def'} -a $cf{'hmac_get_key_access'} " .
+            "-d $default_digest_file -p $default_pid_file $intf_str",
+        'get_key' => {'file' => $local_key_file,
+            'key' => 'rijndaelkey'},
+        'get_hmac_key' => {'file' => $local_hmac_key_file,
+            'key' => 'hmackey'},
+        'fw_rule_created' => $NEW_RULE_REQUIRED,
+        'fw_rule_removed' => $NEW_RULE_REMOVED,
+        'fatal'    => $NO
+    },
 
     {
         'category' => 'Rijndael+HMAC',