added icmp type/code blurb
authorMichael Rash <mbr@cipherdyne.org>
Fri, 12 Oct 2012 03:40:04 +0000 (23:40 -0400)
committerMichael Rash <mbr@cipherdyne.org>
Fri, 12 Oct 2012 03:40:04 +0000 (23:40 -0400)
ChangeLog
client/cmd_opts.h
client/config_init.c
client/fwknop_common.h
client/spa_comm.c
common/common.h
doc/fwknop.man.asciidoc
lib/fko_encryption.c
test/test-fwknop.pl
todo.org

index 0ae097e..e679258 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -23,6 +23,11 @@ fwknop-2.0.4 (09/20/2012):
       against libfko in the local directory (if it exists) so that it doesn't
       have to have libfko completely installed in /usr/lib/.  This allows the
       test suite to run FKO tests without installing libfko.
+    - [client] Added --icmp-type and --icmp-code arguments so the user can
+      control the icmp type/code combination for spoofed SPA packets ('-P
+      icmp') mode.
+    - [client] Updated default TTL value to 64 for spoofed SPA packets.  This
+      closer to more OS default TTL values than the previous 255.
 
 fwknop-2.0.3 (09/03/2012):
     - [server] Fernando Arnaboldi from IOActive found several DoS/code
index cd042c1..27d5373 100644 (file)
@@ -49,6 +49,8 @@ enum {
     GPG_SIGNER_KEY,
     GPG_HOME_DIR,
     GPG_AGENT,
+    SPA_ICMP_TYPE,
+    SPA_ICMP_CODE,
     NOOP /* Just to be a marker for the end */
 };
 
@@ -78,6 +80,8 @@ static struct option cmd_opts[] =
     {"get-key",             1, NULL, 'G'},
     {"help",                0, NULL, 'h'},
     {"http-proxy",          1, NULL, 'H'},
+    {"icmp-type",           1, NULL, SPA_ICMP_TYPE },
+    {"icmp-code",           1, NULL, SPA_ICMP_CODE },
     {"last-cmd",            0, NULL, 'l'},
     {"nat-access",          1, NULL, 'N'},
     {"named-config",        1, NULL, 'n'},
index fb9c46a..5f97560 100644 (file)
@@ -29,6 +29,7 @@
  ******************************************************************************
 */
 #include "fwknop_common.h"
+#include "netinet_common.h"
 #include "config_init.h"
 #include "cmd_opts.h"
 #include "utils.h"
@@ -644,6 +645,8 @@ set_defaults(fko_cli_options_t *options)
     options->spa_dst_port = FKO_DEFAULT_PORT;
     options->fw_timeout   = -1;
 
+    options->spa_icmp_type = ICMP_ECHOREPLY;  /* only used in '-P icmp' mode */
+    options->spa_icmp_code = 0;               /* only used in '-P icmp' mode */
     return;
 }
 
@@ -733,6 +736,22 @@ 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 SPA_ICMP_TYPE:
+                options->spa_icmp_type = atoi(optarg);
+                if (options->spa_icmp_type < 0 || options->spa_icmp_type > MAX_ICMP_TYPE)
+                {
+                    fprintf(stderr, "Unrecognized icmp type value: %s\n", optarg);
+                    exit(EXIT_FAILURE);
+                }
+                break;
+            case SPA_ICMP_CODE:
+                options->spa_icmp_code = atoi(optarg);
+                if (options->spa_icmp_code < 0 || options->spa_icmp_code > MAX_ICMP_CODE)
+                {
+                    fprintf(stderr, "Unrecognized icmp code value: %s\n", optarg);
+                    exit(EXIT_FAILURE);
+                }
+                break;
             case 'l':
                 options->run_last_command = 1;
                 break;
index bdbe5b9..212a825 100644 (file)
@@ -117,6 +117,9 @@ typedef struct fko_cli_options
     unsigned int spa_dst_port;
     unsigned int spa_src_port; /* only used with --source-port */
 
+    int spa_icmp_type;  /* only used in '-P icmp' mode */
+    int spa_icmp_code;  /* only used in '-P icmp' mode */
+
     unsigned int digest_type;
 
     /* Various command-line flags */
index 1d914ac..f592fa1 100644 (file)
@@ -257,7 +257,7 @@ send_spa_packet_tcp_raw(const char *spa_data, const int sd_len,
     /* The value here does not matter */
     iph->id         = random() & 0xffff;
     iph->frag_off   = 0;
-    iph->ttl        = 255;
+    iph->ttl        = RAW_SPA_TTL;
     iph->protocol   = IPPROTO_TCP;
     iph->check      = 0;
     iph->saddr      = saddr->sin_addr.s_addr;
@@ -370,7 +370,7 @@ send_spa_packet_udp_raw(const char *spa_data, const int sd_len,
     /* The value here does not matter */
     iph->id         = random() & 0xffff;
     iph->frag_off   = 0;
-    iph->ttl        = 255;
+    iph->ttl        = RAW_SPA_TTL;
     iph->protocol   = IPPROTO_UDP;
     iph->check      = 0;
     iph->saddr      = saddr->sin_addr.s_addr;
@@ -469,7 +469,7 @@ send_spa_packet_icmp(const char *spa_data, const int sd_len,
     /* The value here does not matter */
     iph->id         = random() & 0xffff;
     iph->frag_off   = 0;
-    iph->ttl        = 255;
+    iph->ttl        = RAW_SPA_TTL;
     iph->protocol   = IPPROTO_ICMP;
     iph->check      = 0;
     iph->saddr      = saddr->sin_addr.s_addr;
@@ -477,10 +477,16 @@ send_spa_packet_icmp(const char *spa_data, const int sd_len,
 
     /* Now the ICMP header values.
     */
-    icmph->type     = ICMP_ECHOREPLY; /* Make it an echo reply */
-    icmph->code     = 0;
+    icmph->type     = options->spa_icmp_type;
+    icmph->code     = options->spa_icmp_code;
     icmph->checksum = 0;
 
+    if(icmph->type == ICMP_ECHO && icmph->code == 0)
+    {
+        icmph->un.echo.id       = htons(random() & 0xffff);
+        icmph->un.echo.sequence = htons(1);
+    }
+
     /* No we can compute our checksum.
     */
     iph->check = chksum((unsigned short *)pkt_data, iph->tot_len);
index 47902f0..4daa3b8 100644 (file)
@@ -104,6 +104,9 @@ enum {
 #define MIN_HIGH_PORT       10000  /* sensible minimum for SPA dest port */
 #define MAX_PORT            65535
 #define MAX_SERVER_STR_LEN  50
+#define MAX_ICMP_TYPE       40
+#define MAX_ICMP_CODE       15
+#define RAW_SPA_TTL         255
 
 #define MAX_LINE_LEN        1024
 #define MAX_PATH_LEN        1024
index eee79fa..2c7fe4f 100644 (file)
@@ -316,6 +316,14 @@ SPA OPTIONS
     on the fwknopd server (*--spoof-src* mode requires that the *fwknop*
     client is executed as root).
 
+*--icmp-type*='<type>'::
+    In *-P icmp* mode, specify the ICMP type value that will be set in the
+    SPA packet ICMP header.  The default is echo reply.
+
+*--icmp-code*='<code>'::
+    In *-P icmp* mode, specify the ICMP code value that will be set in the
+    SPA packet ICMP header.  The default is zero.
+
 
 GPG-RELATED OPTIONS
 -------------------
index e75a222..fb742dc 100644 (file)
@@ -53,11 +53,11 @@ _rijndael_encrypt(fko_ctx_t ctx, const char *enc_key)
     /* Make a bucket big enough to hold the enc msg + digest (plaintext)
      * and populate it appropriately.
     */
-    plain = malloc(strlen(ctx->encoded_msg) + strlen(ctx->digest) + 2);
+    plain = malloc(strlen(ctx->encoded_msg) + strlen(ctx->digest) + 4);
     if(plain == NULL)
         return(FKO_ERROR_MEMORY_ALLOCATION);
 
-    snprintf(plain, strlen(ctx->encoded_msg) + strlen(ctx->digest) + 2,
+    snprintf(plain, strlen(ctx->encoded_msg) + strlen(ctx->digest) + 4,
             "%s:%s", ctx->encoded_msg, ctx->digest);
 
     /* Make a bucket for the encrypted version and populate it.
index a29d215..259d635 100755 (executable)
@@ -868,6 +868,21 @@ my @tests = (
         'server_positive_output_matches' => [qr/SPA\sPacket\sfrom\sIP\:\s$spoof_ip\s/],
         'fatal'    => $NO
     },
+    {
+        'category' => 'Rijndael SPA',
+        'subcategory' => 'client+server',
+        'detail'   => "icmp type/code 8/0 spoof src IP ",
+        'err_msg'  => "could not spoof source IP",
+        'function' => \&spa_cycle,
+        'cmdline'  => "$default_client_args -P icmp --icmp-type 8 --icmp-code 0 -Q $spoof_ip",
+        'fwknopd_cmdline'  => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
+            "$fwknopdCmd -c $cf{'icmp_pcap_filter'} -a $cf{'def_access'} " .
+            "-d $default_digest_file -p $default_pid_file $intf_str",
+        'fw_rule_created' => $NEW_RULE_REQUIRED,
+        'fw_rule_removed' => $NEW_RULE_REMOVED,
+        'server_positive_output_matches' => [qr/SPA\sPacket\sfrom\sIP\:\s$spoof_ip\s/],
+        'fatal'    => $NO
+    },
 
     ### SPA over TCP (not really "single" packet auth since a TCP connection
     ### is established)
index 8118a7c..ac91808 100644 (file)
--- a/todo.org
+++ b/todo.org
 ** [server] Add access variable to require particular IP's even when REQUIRE_SOURCE is used
    The SOURCE variable only applies to the IP header.  Add analogous filtering
    for the allow IP that is encrypted within an SPA payload.
+** [client] Add --icmp-type and --icmp-code args
+   For SPA packets sent over ICMP via raw socket, allow the user to specify
+   the ICMP type and code.
+** [client] Fix 'Could not set destination IP.' in hostname resolution in '-P icmp' mode
+   It seems that hostname resolution is not working when SPA packets are 
+   spoofed.  Here is the command line to trigger the problem:
+   # fwknop -A tcp/22 -a 127.0.0.2 -D <host> --verbose --verbose -P icmp --icmp-type 8 --icmp-code 0 -Q 1.2.3.4