Fixed hostname resolution while spoof ip is used.
authorFranck Joncourt <franck@debian.org>
Sat, 27 Apr 2013 21:31:40 +0000 (23:31 +0200)
committerFranck Joncourt <franck@debian.org>
Sat, 27 Apr 2013 21:31:40 +0000 (23:31 +0200)
mrash/fwknop#64

client/fwknop.c
client/spa_comm.c
client/utils.c
client/utils.h
test/conf/client-gpg-no-pw/trustdb.gpg
test/conf/client-gpg/trustdb.gpg
test/conf/server-gpg-no-pw/trustdb.gpg
test/conf/server-gpg/trustdb.gpg
test/test-fwknop.pl
test/tests/rijndael.pl

index fe9a51c..fe7cea8 100644 (file)
@@ -57,8 +57,6 @@ static int get_rand_port(fko_ctx_t ctx);
 int resolve_ip_http(fko_cli_options_t *options);
 static void clean_exit(fko_ctx_t ctx, fko_cli_options_t *opts,
     unsigned int exit_status);
-static void *get_in_addr(struct sockaddr *sa);
-static int resolve_dest_adr(const char *dns_str, struct addrinfo *hints, char *ip_str, size_t ip_bufsize);
 static int is_hostname_str_with_port(const char *str, char *hostname, size_t hostname_bufsize, int *port);
 
 #define MAX_CMDLINE_ARGS            50                  /*!< should be way more than enough */
@@ -172,80 +170,6 @@ is_hostname_str_with_port(const char *str, char *hostname, size_t hostname_bufsi
     return valid;
 }
 
-/**
- * @brief Grab the sin address from the sockaddr structure.
- *
- * This function returns the sin address as a sockaddr_in or sockaddr_in6
- * structure according to the family set (ipv4 or ipv6) in the sockaddr
- * structure.
- *
- * @param sa sockaddr strcuture
- *
- * @return the sin addr if the sa family is AF_INET or the sin6_addr otherwise.
- */
-static void *
-get_in_addr(struct sockaddr *sa)
-{
-  if (sa->sa_family == AF_INET)
-  {
-    return &(((struct sockaddr_in*)sa)->sin_addr);
-  }
-
-  else
-  {
-    return &(((struct sockaddr_in6*)sa)->sin6_addr);
-  }
-}
-
-/**
- * @brief  Resolve a domain name as an ip adress.
- *
- * @param dns_str    Name of the host to resolve.
- * @param hints      Hints to reduce the number of result from getaddrinfo()
- * @param ip_str     String where to store the resolve ip address
- * @param ip_bufsize Number of bytes available in the ip_str buffer
- *
- * @return 0 if successful, 1 if an error occured.
- */
-static int
-resolve_dest_adr(const char *dns_str, struct addrinfo *hints, char *ip_str, size_t ip_bufsize)
-{
-    int                 error;      /* Function error return code */
-    struct addrinfo    *result;     /* Result of getaddrinfo() */
-    struct addrinfo    *rp;         /* Element of the linked list returned by getaddrinfo() */
-    struct sockaddr_in *sai_remote; /* Remote host information as a sockaddr_in structure */
-
-    /* Try to resolve the host name */
-    error = getaddrinfo(dns_str, NULL, hints, &result);
-    if (error != 0)
-        fprintf(stderr, "resolve_dest_adr() : %s\n", gai_strerror(error));
-
-    else
-    {
-        error = 1;
-
-        /* Go through the linked list of addrinfo structures */
-        for (rp = result; rp != NULL; rp = rp->ai_next)
-        {
-            sai_remote = (struct sockaddr_in *)get_in_addr((struct sockaddr *)(rp->ai_addr));
-
-            memset(ip_str, 0, ip_bufsize);
-            if (inet_ntop(rp->ai_family, sai_remote, ip_str, ip_bufsize) != NULL)
-            {
-                error = 0;
-                break;
-            }
-            else
-                fprintf(stderr, "resolve_dest_adr() : inet_ntop (%d) - %s\n", errno, strerror(errno));
-        }
-
-        /* Free our result from getaddrinfo() */
-        freeaddrinfo(result);
-    }
-
-    return error;
-}
-
 int
 main(int argc, char **argv)
 {
index 1f88b48..1090aac 100644 (file)
@@ -605,8 +605,12 @@ send_spa_packet(fko_ctx_t ctx, fko_cli_options_t *options)
 {
     int                 res, sd_len;
     char               *spa_data;
-
     struct sockaddr_in  saddr, daddr;
+    char                ip_str[INET_ADDRSTRLEN] = {0};  /* String used to contain the ip addres of an hostname */
+    struct addrinfo     hints;                          /* Structure used to set hints to reslove hostname */
+
+    /* Initialize the hint buffer */
+    memset(&hints, 0 , sizeof(hints));
 
 #ifdef WIN32
     WSADATA wsa_data;
@@ -679,16 +683,23 @@ send_spa_packet(fko_ctx_t ctx, fko_cli_options_t *options)
             exit(EXIT_FAILURE);
         }
 
-        /* Set destination address and port
+        /* Set destination port
         */
         daddr.sin_port = htons(options->spa_dst_port);
-        daddr.sin_addr.s_addr = inet_addr(options->spa_server_str);
 
-        if (daddr.sin_addr.s_addr == -1)
+        /* Set destination address. We use the default protocol to reslove
+         * the ip address */
+        hints.ai_family = AF_INET;
+
+        if (resolve_dest_adr(options->spa_server_str, &hints, ip_str, sizeof(ip_str)) != 0)
         {
-            fprintf(stderr, "Could not set destination IP.\n");
+            fprintf(stderr, "[*] Unable to resolve %s as an ip address\n",
+                    options->spa_server_str);
             exit(EXIT_FAILURE);
         }
+        else;
+
+        daddr.sin_addr.s_addr = inet_addr(ip_str);
 
         if (options->spa_proto == FKO_PROTO_TCP_RAW)
         {
index 28c32ce..4a6264c 100644 (file)
@@ -31,6 +31,9 @@
 #include "common.h"
 #include "fwknop_common.h"
 #include "utils.h"
+#include <arpa/inet.h>
+
+static void *get_in_addr(struct sockaddr *sa);
 
 /* Generic hex dump function.
 */
@@ -146,4 +149,78 @@ verify_file_perms_ownership(const char *file)
     return res;
 }
 
+/**
+ * @brief Grab the sin address from the sockaddr structure.
+ *
+ * This function returns the sin address as a sockaddr_in or sockaddr_in6
+ * structure according to the family set (ipv4 or ipv6) in the sockaddr
+ * structure.
+ *
+ * @param sa sockaddr strcuture
+ *
+ * @return the sin addr if the sa family is AF_INET or the sin6_addr otherwise.
+ */
+static void *
+get_in_addr(struct sockaddr *sa)
+{
+  if (sa->sa_family == AF_INET)
+  {
+    return &(((struct sockaddr_in*)sa)->sin_addr);
+  }
+
+  else
+  {
+    return &(((struct sockaddr_in6*)sa)->sin6_addr);
+  }
+}
+
+/**
+ * @brief  Resolve a domain name as an ip adress.
+ *
+ * @param dns_str    Name of the host to resolve.
+ * @param hints      Hints to reduce the number of result from getaddrinfo()
+ * @param ip_str     String where to store the resolve ip address
+ * @param ip_bufsize Number of bytes available in the ip_str buffer
+ *
+ * @return 0 if successful, 1 if an error occured.
+ */
+int
+resolve_dest_adr(const char *dns_str, struct addrinfo *hints, char *ip_str, size_t ip_bufsize)
+{
+    int                 error;      /* Function error return code */
+    struct addrinfo    *result;     /* Result of getaddrinfo() */
+    struct addrinfo    *rp;         /* Element of the linked list returned by getaddrinfo() */
+    struct sockaddr_in *sai_remote; /* Remote host information as a sockaddr_in structure */
+
+    /* Try to resolve the host name */
+    error = getaddrinfo(dns_str, NULL, hints, &result);
+    if (error != 0)
+        fprintf(stderr, "resolve_dest_adr() : %s\n", gai_strerror(error));
+
+    else
+    {
+        error = 1;
+
+        /* Go through the linked list of addrinfo structures */
+        for (rp = result; rp != NULL; rp = rp->ai_next)
+        {
+            sai_remote = (struct sockaddr_in *)get_in_addr((struct sockaddr *)(rp->ai_addr));
+
+            memset(ip_str, 0, ip_bufsize);
+            if (inet_ntop(rp->ai_family, sai_remote, ip_str, ip_bufsize) != NULL)
+            {
+                error = 0;
+                break;
+            }
+            else
+                fprintf(stderr, "resolve_dest_adr() : inet_ntop (%d) - %s\n", errno, strerror(errno));
+        }
+
+        /* Free our result from getaddrinfo() */
+        freeaddrinfo(result);
+    }
+
+    return error;
+}
+
 /***EOF***/
index b3156fe..450fcc9 100644 (file)
   #include "config.h"
 #endif
 
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
 /* Prototypes
 */
 void hex_dump(const unsigned char *data, const int size);
 int is_base64(const unsigned char *buf, const unsigned short int len);
 int set_file_perms(const char *file);
 int verify_file_perms_ownership(const char *file);
+int resolve_dest_adr(const char *dns_str, struct addrinfo *hints, char *ip_str, size_t ip_bufsize);
 
 #endif  /* UTILS_H */
index 58ec2d6..be93308 100644 (file)
Binary files a/test/conf/client-gpg-no-pw/trustdb.gpg and b/test/conf/client-gpg-no-pw/trustdb.gpg differ
index 58ec2d6..2c1093e 100644 (file)
Binary files a/test/conf/client-gpg/trustdb.gpg and b/test/conf/client-gpg/trustdb.gpg differ
index d5b5b60..0c29e43 100644 (file)
Binary files a/test/conf/server-gpg-no-pw/trustdb.gpg and b/test/conf/server-gpg-no-pw/trustdb.gpg differ
index d5b5b60..8090303 100644 (file)
Binary files a/test/conf/server-gpg/trustdb.gpg and b/test/conf/server-gpg/trustdb.gpg differ
index 4184dc1..9a5876b 100755 (executable)
@@ -144,12 +144,13 @@ our $libfko_bin = "$lib_dir/libfko.so";  ### this is usually a link
 our $gpg_server_key = '361BBAD4';
 our $gpg_client_key = '6A3FAD56';
 
-our $loopback_ip = '127.0.0.1';
-our $fake_ip     = '127.0.0.2';
+our $loopback_ip       = '127.0.0.1';
+our $fake_ip           = '127.0.0.2';
+our $fake_spoof_ip     = '1.2.3.4';
 our $internal_nat_host = '192.168.1.2';
-our $force_nat_host = '192.168.1.123';
-our $default_spa_port = 62201;
-our $non_std_spa_port = 12345;
+our $force_nat_host    = '192.168.1.123';
+our $default_spa_port  = 62201;
+our $non_std_spa_port  = 12345;
 
 our $spoof_user = 'testuser';
 
index d5d090e..2397ca0 100644 (file)
         'fw_rule_created' => $REQUIRE_NO_NEW_RULE,
         'fatal'    => $NO
     },
+    {
+        'category' => 'Rijndael',
+        'subcategory' => 'client+server',
+        'detail'   => 'localhost hostname->IP spoofed',
+        'function' => \&spa_cycle,
+        'cmdline'  => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
+            "$fwknopCmd -A tcp/22 -a $fake_ip -D localhost --get-key " .
+            "$local_key_file --no-save-args --verbose --verbose -Q $fake_spoof_ip",
+        'fwknopd_cmdline'  => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
+            "$fwknopdCmd $default_server_conf_args $intf_str",
+        'fw_rule_created' => $NEW_RULE_REQUIRED,
+        'fw_rule_removed' => $NEW_RULE_REMOVED,
+        'fatal'    => $NO
+    },
 );