From d1fae9bee1e0c9a8b2afa8c4a90b9a78e2e7b2d8 Mon Sep 17 00:00:00 2001 From: Michael Rash Date: Sat, 16 Jan 2010 01:05:41 +0000 Subject: [PATCH] * Added a new command line argument "--last-cmd" to run the fwknop client with the same command line arguments as the previous time it was executed. The previous arguments are parsed out of the ~/.fwknop.run file (if it exists). * Bug fix to not send any SPA packet out on the wire if a NULL password/key is provided to the fwknop client. This could happen if the user tried to abort fwknop execution by sending the process a SIGINT while being prompted to enter the password/key for SPA encryption. git-svn-id: file:///home/mbr/svn/fwknop/trunk@193 510a4753-2344-4c79-9c09-4d669213fbeb --- ChangeLog | 10 ++++ client/config_init.c | 13 ++++- client/config_init.h | 3 +- client/fwknop.c | 106 +++++++++++++++++++++++++++++++++++------ client/fwknop_common.h | 1 + 5 files changed, 116 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3c40350b..acbfc071 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2010-01-02 Michael Rash + * Added a new command line argument "--last-cmd" to run the fwknop client + with the same command line arguments as the previous time it was + executed. The previous arguments are parsed out of the ~/.fwknop.run + file (if it exists). + * Bug fix to not send any SPA packet out on the wire if a NULL password/key + is provided to the fwknop client. This could happen if the user tried to + abort fwknop execution by sending the process a SIGINT while being + prompted to enter the password/key for SPA encryption. + 2010-01-03 Damien Stuart * Added access.conf file, parsing, and processing. * Added a new acces.conf parameter, RESTRICT_PORTS for specifying 1 or more diff --git a/client/config_init.c b/client/config_init.c index 10bd526c..9d4b4165 100644 --- a/client/config_init.c +++ b/client/config_init.c @@ -203,7 +203,10 @@ validate_options(fko_cli_options_t *options) /* Gotta have a Destination unless we are just testing or getting the * the version, and must use one of [-s|-R|-a]. */ - if(!options->test && !options->version && !options->show_last_command) + if(!options->test + && !options->version + && !options->show_last_command + && !options->run_last_command) { if (options->spa_server_str[0] == 0x0) { @@ -312,6 +315,9 @@ config_init(fko_cli_options_t *options, int argc, char **argv) options->spa_proto = FKO_PROTO_HTTP; strlcpy(options->http_proxy, optarg, MAX_PATH_LEN); break; + case 'l': + options->run_last_command = 1; + break; case 'm': case FKO_DIGEST_NAME: if(strncasecmp(optarg, "md5", 3) == 0) @@ -500,6 +506,9 @@ usage(void) " SPA packet will be sent.\n" " -U, --spoof-user Set the username within outgoing SPA packet.\n" " -q, --quiet Perform fwknop functions quietly.\n" + " -l, --last-cmd Run the fwknop client with the same command\n" + " line args as the last time it was executed\n" + " (args are read from the ~/.fwknop.run file).\n" " -G, --get-key Load an encryption key/password from a file.\n" " -r, --rand-port Send the SPA packet over a randomly assigned\n" " port (requires a broader pcap filter on the\n" @@ -508,7 +517,7 @@ usage(void) " the network.\n" " -v, --verbose Set verbose mode.\n" " -V, --version Print version number.\n" - " -m, --digest-type Speciy the message digest algorithm to use.\n" + " -m, --digest-type Specify the message digest algorithm to use.\n" " (md5, sha1, or sha256 (default)).\n" " -f, --fw-timeout Specify SPA server firewall timeout from the\n" " client side.\n" diff --git a/client/config_init.h b/client/config_init.h index 2885acee..f520d6e3 100644 --- a/client/config_init.h +++ b/client/config_init.h @@ -51,7 +51,7 @@ enum { /* Our getopt_long options string. */ -#define GETOPTS_OPTION_STRING "a:A:bB:C:D:f:gG:hH:m:nN:p:P:qQ:rRsS:Tu:U:vV" +#define GETOPTS_OPTION_STRING "a:A:bB:C:D:f:gG:hH:lm:nN:p:P:qQ:rRsS:Tu:U:vV" /* Our program command-line options... */ @@ -74,6 +74,7 @@ static struct option cmd_opts[] = {"get-key", 1, NULL, 'G'}, {"help", 0, NULL, 'h'}, {"http-proxy", 1, NULL, 'H'}, + {"last-cmd", 0, NULL, 'l'}, {"nat-access", 1, NULL, 'N'}, {"nat-local", 0, NULL, NAT_LOCAL}, {"nat-port", 1, NULL, NAT_PORT}, diff --git a/client/fwknop.c b/client/fwknop.c index ca4db7e2..0deae9a8 100644 --- a/client/fwknop.c +++ b/client/fwknop.c @@ -36,6 +36,7 @@ static void display_ctx(fko_ctx_t ctx); void errmsg(char *msg, 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 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); @@ -44,7 +45,6 @@ static void dump_transmit_options(fko_cli_options_t *options); int resolve_ip_http(fko_cli_options_t *options); - int main(int argc, char **argv) { @@ -58,10 +58,11 @@ main(int argc, char **argv) /* Handle command line */ config_init(&options, argc, argv); - /* Handle options that don't require a libfko context */ - if(options.show_last_command) + 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); @@ -523,13 +524,13 @@ show_last_command(void) /* Not sure what the right thing is here on Win32, just exit * for now. */ - printf("[*] --show-last not implemented on Win32 yet."); + fprintf(stderr, "[*] --show-last not implemented on Win32 yet."); exit(EXIT_FAILURE); #endif if (get_save_file(args_save_file)) { if ((args_file_ptr = fopen(args_save_file, "r")) == NULL) { - printf("[*] Could not open args file: %s\n", + fprintf(stderr, "[*] Could not open args file: %s\n", args_save_file); exit(EXIT_FAILURE); } @@ -544,6 +545,73 @@ show_last_command(void) exit(EXIT_SUCCESS); } +/* Get the command line arguments from the previous invocation +*/ +static void +run_last_args(fko_cli_options_t *options) +{ + FILE *args_file_ptr = NULL; + + int current_arg_ctr = 0; + 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[200]; /* should be way more than enough */ + + +#ifdef WIN32 + /* Not sure what the right thing is here on Win32, just return + * for now. + */ + return; +#endif + + if (get_save_file(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) + { + args_str[MAX_LINE_LEN-1] = '\0'; + if (options->verbose) + printf("[+] Executing: %s\n", args_str); + for (i=0; i < strlen(args_str); i++) + { + if (!isspace(args_str[i])) + { + arg_tmp[current_arg_ctr] = args_str[i]; + current_arg_ctr++; + } + else + { + 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); + } + strcpy(argv_new[argc_new], arg_tmp); + current_arg_ctr = 0; + argc_new++; + } + } + } + fclose(args_file_ptr); + + config_init(options, argc_new, argv_new); + } + + return; +} + /* Save our command line arguments */ static void @@ -564,14 +632,14 @@ save_args(int argc, char **argv) if (get_save_file(args_save_file)) { if ((args_file_ptr = fopen(args_save_file, "w")) == NULL) { - printf("[*] Could not open args file: %s\n", + fprintf(stderr, "[*] Could not open args file: %s\n", args_save_file); exit(EXIT_FAILURE); } for (i=0; i < argc; i++) { args_str_len += strlen(argv[i]); if (args_str_len >= MAX_PATH_LEN) { - printf("[*] argument string too long, exiting.\n"); + fprintf(stderr, "[*] argument string too long, exiting.\n"); exit(EXIT_FAILURE); } strlcat(args_str, argv[i], MAX_PATH_LEN); @@ -627,25 +695,35 @@ set_message_type(fko_ctx_t ctx, fko_cli_options_t *options) char* get_user_pw(fko_cli_options_t *options, int crypt_op) { + char *pw_ptr = NULL; + if (options->get_key_file[0] != 0x0) { /* grab the key/password from the --get-key file */ - return(getpasswd_file(options->get_key_file, - options->spa_server_str)); + pw_ptr = getpasswd_file(options->get_key_file, + options->spa_server_str); } else if (options->use_gpg) { - return(options->use_gpg_agent ? "" - : getpasswd("Enter passphrase for secret key: ")); + pw_ptr = options->use_gpg_agent ? "" + : getpasswd("Enter passphrase for secret key: "); } else { if(crypt_op == CRYPT_OP_ENCRYPT) - return(getpasswd("Enter encryption password: ")); + pw_ptr = getpasswd("Enter encryption password: "); else if(crypt_op == CRYPT_OP_DECRYPT) - return(getpasswd("Enter decryption password: ")); + pw_ptr = getpasswd("Enter decryption password: "); else - return(getpasswd("Enter password: ")); + pw_ptr = getpasswd("Enter password: "); } + + if (pw_ptr == NULL || pw_ptr[0] == '\0') + { + fprintf(stderr, "[*] Received no password data, exiting.\n"); + exit(EXIT_FAILURE); + } + + return pw_ptr; } /* Display an FKO error message. diff --git a/client/fwknop_common.h b/client/fwknop_common.h index 5f88130f..ae5f43d7 100644 --- a/client/fwknop_common.h +++ b/client/fwknop_common.h @@ -70,6 +70,7 @@ typedef struct fko_cli_options char save_packet_file[MAX_PATH_LEN]; int save_packet_file_append; int show_last_command; + int run_last_command; int no_save_args; char spa_server_str[MAX_SERVER_STR_LEN]; /* may be a hostname */ char allow_ip_str[MAX_IP_STR_LEN];