added --save-args-file and corresponding tests to the fwknop client
authorMichael Rash <mbr@cipherdyne.org>
Fri, 15 Feb 2013 03:50:14 +0000 (22:50 -0500)
committerMichael Rash <mbr@cipherdyne.org>
Fri, 15 Feb 2013 03:50:14 +0000 (22:50 -0500)
client/cmd_opts.h
client/config_init.c
client/fwknop.c
client/fwknop_common.h
test/test-fwknop.pl

index 4ffa652..0a4854c 100644 (file)
@@ -60,7 +60,7 @@ enum {
 
 /* Our getopt_long options string.
 */
-#define GETOPTS_OPTION_STRING "a:A:bB:C:D:f:gG:hH:kK:lm:M:n:N:p:P:Q:rRsS:Tu:U:vV"
+#define GETOPTS_OPTION_STRING "a:A:bB:C:D:E:f:gG:hH:kK:lm:M:n:N:p:P:Q:rRsS:Tu:U:vV"
 
 /* Our program command-line options...
 */
@@ -74,6 +74,7 @@ static struct option cmd_opts[] =
     {"server-cmd",          1, NULL, 'C'},
     {"digest-type",         1, NULL, FKO_DIGEST_NAME},
     {"destination",         1, NULL, 'D'},
+    {"save-args-file",      1, NULL, 'E'},
     {"encryption-mode",     1, NULL, ENCRYPTION_MODE},
     {"fw-timeout",          1, NULL, 'f'},
     {"gpg-encryption",      0, NULL, 'g'},
index 74a35d4..8cc4388 100644 (file)
@@ -764,7 +764,7 @@ set_defaults(fko_cli_options_t *options)
 void
 config_init(fko_cli_options_t *options, int argc, char **argv)
 {
-    int                 cmd_arg, index;
+    int       cmd_arg, index;
 
     /* Zero out options and opts_track.
     */
@@ -787,6 +787,9 @@ config_init(fko_cli_options_t *options, int argc, char **argv)
                 options->no_save_args = 1;
                 strlcpy(options->use_rc_stanza, optarg, MAX_LINE_LEN);
                 break;
+            case 'E':
+                strlcpy(options->args_save_file, optarg, MAX_PATH_LEN);
+                break;
             case RC_FILE_PATH:
                 strlcpy(options->rc_file, optarg, MAX_PATH_LEN);
                 break;
@@ -826,6 +829,9 @@ config_init(fko_cli_options_t *options, int argc, char **argv)
             case 'D':
                 strlcpy(options->spa_server_str, optarg, MAX_SERVER_STR_LEN);
                 break;
+            case 'E':
+                strlcpy(options->args_save_file, optarg, MAX_PATH_LEN);
+                break;
             case 'f':
                 options->fw_timeout = atoi(optarg);
                 if (options->fw_timeout < 0) {
index ee4d117..ec3a4f7 100644 (file)
@@ -43,9 +43,12 @@ static void get_keys(fko_ctx_t ctx, fko_cli_options_t *options,
     int *hmac_key_len, const int crypt_op);
 static void display_ctx(fko_ctx_t ctx);
 static void errmsg(const char *msg, const int err);
-static void show_last_command(void);
-static void save_args(int argc, char **argv);
-static void run_last_args(fko_cli_options_t *options);
+static void prev_exec(fko_cli_options_t *options, int argc, char **argv);
+static int get_save_file(char *args_save_file);
+static void show_last_command(const char * const args_save_file);
+static void save_args(int argc, char **argv, const char * const args_save_file);
+static void run_last_args(fko_cli_options_t *options,
+        const char * const args_save_file);
 static int set_message_type(fko_ctx_t ctx, fko_cli_options_t *options);
 static int set_nat_access(fko_ctx_t ctx, fko_cli_options_t *options);
 static int get_rand_port(fko_ctx_t ctx);
@@ -73,14 +76,9 @@ main(int argc, char **argv)
     */
     config_init(&options, argc, argv);
 
-    /* Handle options that don't require a libfko context
+    /* Handle previous execution arguments if required
     */
-    if(options.run_last_command)
-        run_last_args(&options);
-    else if(options.show_last_command)
-        show_last_command();
-    else if (!options.no_save_args)
-        save_args(argc, argv);
+    prev_exec(&options, argc, argv);
 
     /* Generate Rijndael + HMAC keys from /dev/random (base64
      * encoded) and exit.
@@ -604,58 +602,63 @@ set_nat_access(fko_ctx_t ctx, fko_cli_options_t *options)
     return fko_set_spa_nat_access(ctx, nat_access_buf);
 }
 
-static int
-get_save_file(char *args_save_file)
+static void
+prev_exec(fko_cli_options_t *options, int argc, char **argv)
 {
-    char *homedir = NULL;
-    int rv = 0;
+    char       args_save_file[MAX_PATH_LEN] = {0};
 
-#ifdef WIN32
-    homedir = getenv("USERPROFILE");
-#else
-    homedir = getenv("HOME");
-#endif
-    if (homedir != NULL) {
-        snprintf(args_save_file, MAX_PATH_LEN, "%s%c%s",
-            homedir, PATH_SEP, ".fwknop.run");
-        rv = 1;
+    if(options->args_save_file != NULL && options->args_save_file[0] != 0x0)
+    {
+        strlcpy(args_save_file, options->args_save_file, MAX_PATH_LEN);
+    }
+    else
+    {
+        if (get_save_file(args_save_file) != 1)
+        {
+            fprintf(stderr, "Unable to determine args save file\n");
+            exit(EXIT_FAILURE);
+        }
     }
 
-    return rv;
+    if(options->run_last_command)
+        run_last_args(options, args_save_file);
+    else if(options->show_last_command)
+        show_last_command(args_save_file);
+    else if (!options->no_save_args)
+        save_args(argc, argv, args_save_file);
+
+    return;
 }
 
 /* Show the last command that was executed
 */
 static void
-show_last_command(void)
+show_last_command(const char * const args_save_file)
 {
-    char args_save_file[MAX_PATH_LEN];
     char args_str[MAX_LINE_LEN] = "";
     FILE *args_file_ptr = NULL;
 
-    if (get_save_file(args_save_file)) {
-        verify_file_perms_ownership(args_save_file);
-        if ((args_file_ptr = fopen(args_save_file, "r")) == NULL) {
-            fprintf(stderr, "Could not open args file: %s\n",
-                args_save_file);
-            exit(EXIT_FAILURE);
-        }
-        verify_file_perms_ownership(args_save_file);
-        if ((fgets(args_str, MAX_LINE_LEN, args_file_ptr)) != NULL) {
-            printf("Last fwknop client command line: %s", args_str);
-        } else {
-            printf("Could not read line from file: %s\n", args_save_file);
-        }
-        fclose(args_file_ptr);
+    verify_file_perms_ownership(args_save_file);
+    if ((args_file_ptr = fopen(args_save_file, "r")) == NULL) {
+        fprintf(stderr, "Could not open args file: %s\n",
+            args_save_file);
+        exit(EXIT_FAILURE);
     }
 
+    if ((fgets(args_str, MAX_LINE_LEN, args_file_ptr)) != NULL) {
+        printf("Last fwknop client command line: %s", args_str);
+    } else {
+        printf("Could not read line from file: %s\n", args_save_file);
+    }
+    fclose(args_file_ptr);
+
     exit(EXIT_SUCCESS);
 }
 
 /* Get the command line arguments from the previous invocation
 */
 static void
-run_last_args(fko_cli_options_t *options)
+run_last_args(fko_cli_options_t *options, const char * const args_save_file)
 {
     FILE           *args_file_ptr = NULL;
 
@@ -663,98 +666,121 @@ run_last_args(fko_cli_options_t *options)
     int             argc_new = 0;
     int             i = 0;
 
-    char            args_save_file[MAX_PATH_LEN] = {0};
     char            args_str[MAX_LINE_LEN] = {0};
     char            arg_tmp[MAX_LINE_LEN]  = {0};
     char           *argv_new[MAX_CMDLINE_ARGS];  /* should be way more than enough */
 
-    if (get_save_file(args_save_file))
+    verify_file_perms_ownership(args_save_file);
+    if ((args_file_ptr = fopen(args_save_file, "r")) == NULL)
     {
-        verify_file_perms_ownership(args_save_file);
-        if ((args_file_ptr = fopen(args_save_file, "r")) == NULL)
-        {
-            fprintf(stderr, "Could not open args file: %s\n",
+        fprintf(stderr, "Could not open args file: %s\n",
                 args_save_file);
-            exit(EXIT_FAILURE);
-        }
-        if ((fgets(args_str, MAX_LINE_LEN, args_file_ptr)) != NULL)
+        exit(EXIT_FAILURE);
+    }
+    if ((fgets(args_str, MAX_LINE_LEN, args_file_ptr)) != NULL)
+    {
+        args_str[MAX_LINE_LEN-1] = '\0';
+        if (options->verbose)
+            printf("Executing: %s\n", args_str);
+        for (i=0; i < (int)strlen(args_str); i++)
         {
-            args_str[MAX_LINE_LEN-1] = '\0';
-            if (options->verbose)
-                printf("Executing: %s\n", args_str);
-            for (i=0; i < (int)strlen(args_str); i++)
+            if (!isspace(args_str[i]))
+            {
+                arg_tmp[current_arg_ctr] = args_str[i];
+                current_arg_ctr++;
+            }
+            else
             {
-                if (!isspace(args_str[i]))
+                arg_tmp[current_arg_ctr] = '\0';
+                argv_new[argc_new] = malloc(strlen(arg_tmp)+1);
+                if (argv_new[argc_new] == NULL)
                 {
-                    arg_tmp[current_arg_ctr] = args_str[i];
-                    current_arg_ctr++;
+                    fprintf(stderr, "[*] malloc failure for cmd line arg.\n");
+                    exit(EXIT_FAILURE);
                 }
-                else
+                strlcpy(argv_new[argc_new], arg_tmp, strlen(arg_tmp)+1);
+                current_arg_ctr = 0;
+                argc_new++;
+                if(argc_new >= MAX_CMDLINE_ARGS)
                 {
-                    arg_tmp[current_arg_ctr] = '\0';
-                    argv_new[argc_new] = malloc(strlen(arg_tmp)+1);
-                    if (argv_new[argc_new] == NULL)
-                    {
-                        fprintf(stderr, "[*] malloc failure for cmd line arg.\n");
-                        exit(EXIT_FAILURE);
-                    }
-                    strlcpy(argv_new[argc_new], arg_tmp, strlen(arg_tmp)+1);
-                    current_arg_ctr = 0;
-                    argc_new++;
-                    if(argc_new >= MAX_CMDLINE_ARGS)
-                    {
-                        fprintf(stderr, "[*] max command line args exceeded.\n");
-                        exit(EXIT_FAILURE);
-                    }
+                    fprintf(stderr, "[*] max command line args exceeded.\n");
+                    exit(EXIT_FAILURE);
                 }
             }
         }
-        fclose(args_file_ptr);
+    }
+    fclose(args_file_ptr);
 
-        /* Reset the options index so we can run through them again.
-        */
-        optind = 0;
+    /* Reset the options index so we can run through them again.
+    */
+    optind = 0;
+
+    config_init(options, argc_new, argv_new);
 
-        config_init(options, argc_new, argv_new);
+    /* Since we passed in our own copies, free up malloc'd memory
+    */
+    for (i=0; i < argc_new; i++)
+    {
+        if(argv_new[i] == NULL)
+            break;
+        else
+            free(argv_new[i]);
     }
 
     return;
 }
 
+static int
+get_save_file(char *args_save_file)
+{
+    char *homedir = NULL;
+    int rv = 0;
+
+#ifdef WIN32
+    homedir = getenv("USERPROFILE");
+#else
+    homedir = getenv("HOME");
+#endif
+    if (homedir != NULL) {
+        snprintf(args_save_file, MAX_PATH_LEN, "%s%c%s",
+            homedir, PATH_SEP, ".fwknop.run");
+        rv = 1;
+    }
+
+    return rv;
+}
+
 /* Save our command line arguments
 */
 static void
-save_args(int argc, char **argv)
+save_args(int argc, char **argv, const char * const args_save_file)
 {
-    char args_save_file[MAX_PATH_LEN];
     char args_str[MAX_LINE_LEN] = "";
     int i = 0, args_str_len = 0, args_file_fd = -1;
 
-    if (get_save_file(args_save_file)) {
-        args_file_fd = open(args_save_file, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
-        if (args_file_fd == -1) {
-            fprintf(stderr, "Could not open args file: %s\n",
-                args_save_file);
-            exit(EXIT_FAILURE);
-        }
-        else {
-            for (i=0; i < argc; i++) {
-                args_str_len += strlen(argv[i]);
-                if (args_str_len >= MAX_PATH_LEN) {
-                    fprintf(stderr, "argument string too long, exiting.\n");
-                    exit(EXIT_FAILURE);
-                }
-                strlcat(args_str, argv[i], MAX_PATH_LEN);
-                strlcat(args_str, " ", MAX_PATH_LEN);
-            }
-            strlcat(args_str, "\n", MAX_PATH_LEN);
-            if(write(args_file_fd, args_str, strlen(args_str))
-                    != strlen(args_str)) {
-                fprintf(stderr,
-                "warning, did not write expected number of bytes to args save file\n");
+    args_file_fd = open(args_save_file, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
+    if (args_file_fd == -1) {
+        fprintf(stderr, "Could not open args file: %s\n",
+            args_save_file);
+        exit(EXIT_FAILURE);
+    }
+    else {
+        for (i=0; i < argc; i++) {
+            args_str_len += strlen(argv[i]);
+            if (args_str_len >= MAX_PATH_LEN) {
+                fprintf(stderr, "argument string too long, exiting.\n");
+                exit(EXIT_FAILURE);
             }
-            close(args_file_fd);
+            strlcat(args_str, argv[i], MAX_PATH_LEN);
+            strlcat(args_str, " ", MAX_PATH_LEN);
+        }
+        strlcat(args_str, "\n", MAX_PATH_LEN);
+        if(write(args_file_fd, args_str, strlen(args_str))
+                != strlen(args_str)) {
+            fprintf(stderr,
+            "warning, did not write expected number of bytes to args save file\n");
         }
+        close(args_file_fd);
     }
     return;
 }
index f4e8f02..01915f1 100644 (file)
@@ -87,6 +87,7 @@ typedef struct fko_cli_options
     int  save_packet_file_append;
     int  show_last_command;
     int  run_last_command;
+    char args_save_file[MAX_PATH_LEN];
     int  no_save_args;
     int  use_hmac;
     char spa_server_str[MAX_SERVER_STR_LEN];  /* may be a hostname */
index 2293ca7..32c40c1 100755 (executable)
@@ -85,6 +85,7 @@ my $default_digest_file = "$run_dir/digest.cache";
 my $default_pid_file    = "$run_dir/fwknopd.pid";
 my $tmp_rc_file         = "$run_dir/fwknoprc";
 my $tmp_pkt_file        = "$run_dir/tmp_spa.pkt";
+my $tmp_args_file       = "$run_dir/args.save";
 
 my $fwknopCmd   = '../client/.libs/fwknop';
 my $fwknopdCmd  = '../server/.libs/fwknopd';
@@ -781,8 +782,22 @@ my @tests = (
         'subcategory' => 'client',
         'detail'   => "--save-packet $tmp_pkt_file",
         'err_msg'  => 'could not run SPA client',
+        'function' => \&client_save_spa_pkt,
+        'cmdline'  => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
+            "$fwknopCmd -A tcp/22 -a $fake_ip -D $loopback_ip --get-key " .
+            "$local_key_file --save-args-file $tmp_args_file --verbose " .
+            "--verbose --save-packet $tmp_pkt_file",
+        'fatal'    => $NO
+    },
+    {
+        'category' => 'Rijndael SPA',
+        'subcategory' => 'client',
+        'detail'   => "--last-cmd",
+        'err_msg'  => 'could not run last args',
         'function' => \&generic_exec,
-        'cmdline'  => "$default_client_args --save-packet $tmp_pkt_file",
+        'cmdline'  => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
+            "$fwknopCmd --last-cmd --save-args-file $tmp_args_file " .
+            "--verbose --verbose",
         'fatal'    => $NO
     },
 
@@ -6570,7 +6585,8 @@ sub init() {
     }
 
     for my $file (glob("$output_dir/*.test"), "$output_dir/init",
-            $tmp_rc_file, $tmp_pkt_file, $logfile, $key_gen_file) {
+            $tmp_rc_file, $tmp_pkt_file, $tmp_args_file,
+            $logfile, $key_gen_file) {
         next unless -e $file;
         unlink $file or die "[*] Could not unlink($file)";
     }
@@ -6837,7 +6853,7 @@ sub parse_valgrind_flagged_functions() {
     mkdir "$output_dir/$valgrind_cov_dir"
         unless -d "$output_dir/$valgrind_cov_dir";
 
-    for my $file (glob("$output_dir/*.test")) {
+    FILE: for my $file (glob("$output_dir/*.test")) {
 
         my $type = 'server';
         $type = 'client' if $file =~ /\d\.test/;
@@ -6858,11 +6874,12 @@ sub parse_valgrind_flagged_functions() {
             } elsif (/TEST\:\s/) {
                 $test_title = $_;
                 chomp $test_title;
+                last if $test_title =~ /valgrind\soutput/;
             }
         }
         close F;
 
-        next if $test_title =~ /valgrind\soutput/;
+        next FILE if $test_title =~ /valgrind\soutput/;
 
         ### write out flagged fcns for this file
         if ($filename) {