From 56be13b3f67a4abf2cb307cf366a6450c0bbc8a9 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Fri, 25 Dec 2015 11:20:00 -0600 Subject: [PATCH 1/5] Add dns resolution for nat access --- common/fko_util.c | 95 ++++++++++++++++++++++++++++++++++++++ common/fko_util.h | 14 +++++- lib/fko_message.c | 3 +- server/fw_util_firewalld.c | 22 +++++++-- server/fw_util_iptables.c | 23 +++++++-- 5 files changed, 145 insertions(+), 12 deletions(-) diff --git a/common/fko_util.c b/common/fko_util.c index 7095c54c..586abce1 100644 --- a/common/fko_util.c +++ b/common/fko_util.c @@ -958,4 +958,99 @@ dump_ctx_to_buffer(fko_ctx_t ctx, char *dump_buf, size_t dump_buf_len) return (err); } +/** + * @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 address. + * + * @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 + * @param opts Client command line options + * + * @return 0 if successful, 1 if an error occured. + */ +int +ipv4_resolve(const char *dns_str, char *ip_str) +{ + int error; /* Function error return code */ + size_t ip_bufsize = MAX_IPV4_STR_LEN; + struct addrinfo hints; + struct addrinfo *result; /* Result of getaddrinfo() */ + struct addrinfo *rp; /* Element of the linked list returned by getaddrinfo() */ +#if WIN32 && WINVER <= 0x0600 + struct sockaddr_in *in; + char *win_ip; +#else + struct sockaddr_in *sai_remote; /* Remote host information as a sockaddr_in structure */ +#endif + + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + /* Try to resolve the host name */ + error = getaddrinfo(dns_str, NULL, &hints, &result); + if (error != 0) + fprintf(stderr, "resolve_dst_addr() : %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) + { + memset(ip_str, 0, ip_bufsize); + +#if WIN32 && WINVER <= 0x0600 + /* On older Windows systems (anything before Vista?), + * we use inet_ntoa for now. + */ + in = (struct sockaddr_in*)(rp->ai_addr); + win_ip = inet_ntoa(in->sin_addr); + + if (win_ip != NULL && (strlcpy(ip_str, win_ip, ip_bufsize) > 0)) +#else + sai_remote = (struct sockaddr_in *)get_in_addr((struct sockaddr *)(rp->ai_addr)); + if (inet_ntop(rp->ai_family, sai_remote, ip_str, ip_bufsize) != NULL) +#endif + { + error = 0; + break; + } + } + + /* Free our result from getaddrinfo() */ + freeaddrinfo(result); + } + + return error; +} + + /***EOF***/ diff --git a/common/fko_util.h b/common/fko_util.h index bbece991..da45e786 100644 --- a/common/fko_util.h +++ b/common/fko_util.h @@ -35,7 +35,6 @@ #define MAX_CMDLINE_ARGS 30 /*!< should be way more than enough */ #define MAX_ARGS_LINE_LEN 1024 - /* Function prototypes */ int is_valid_encoded_msg_len(const int len); @@ -65,6 +64,8 @@ void chop_spaces(char *str); int strtoargv(const char * const args_str, char **argv_new, int *argc_new); void free_argv(char **argv_new, int *argc_new); +int ipv4_resolve(const char *dns_str, char *ip_str); + #if !HAVE_STRLCAT size_t strlcat(char *dst, const char *src, size_t siz); #endif @@ -79,6 +80,17 @@ char * strndup( const char * s, size_t len ); int dump_ctx_to_buffer(fko_ctx_t ctx, char *dump_buf, size_t dump_buf_len); +#include +#ifdef WIN32 + #include + #include +#else + #if HAVE_SYS_SOCKET_H + #include + #endif + #include +#endif + #endif /* FKO_UTIL_H */ /***EOF***/ diff --git a/lib/fko_message.c b/lib/fko_message.c index c1273117..de3d1b9e 100644 --- a/lib/fko_message.c +++ b/lib/fko_message.c @@ -311,9 +311,10 @@ validate_nat_access_msg(const char *msg) return(FKO_ERROR_INVALID_DATA_MESSAGE_NAT_MISSING); /* Should always have a valid allow IP regardless of message type - */ + * if((res = have_allow_ip(msg)) != FKO_SUCCESS) return(FKO_ERROR_INVALID_SPA_NAT_ACCESS_MSG); + */ /* Position ourselves beyond the allow IP and make sure we have * a single port value diff --git a/server/fw_util_firewalld.c b/server/fw_util_firewalld.c index f8d5ae1b..0f13ff8f 100644 --- a/server/fw_util_firewalld.c +++ b/server/fw_util_firewalld.c @@ -1319,6 +1319,7 @@ process_spa_request(const fko_srv_options_t * const opts, const acc_stanza_t * const acc, spa_data_t * const spadat) { char nat_ip[MAX_IPV4_STR_LEN] = {0}; + char nat_dst[64] = {0}; //not finding a MAX_HOSTNAME_LEN #define unsigned int nat_port = 0; unsigned int fst_proto; unsigned int fst_port; @@ -1381,12 +1382,23 @@ process_spa_request(const fko_srv_options_t * const opts, ndx = strchr(spadat->nat_access, ','); if(ndx != NULL) { - strlcpy(nat_ip, spadat->nat_access, (ndx-spadat->nat_access)+1); - if (! is_valid_ipv4_addr(nat_ip)) + strlcpy(nat_dst, spadat->nat_access, (ndx-spadat->nat_access)+1); + if (! is_valid_ipv4_addr(nat_dst)) { - log_msg(LOG_INFO, "Invalid NAT IP in SPA message"); - free_acc_port_list(port_list); - return res; + if (ipv4_resolve(nat_dst, nat_ip) == 0) + { + log_msg(LOG_INFO, "Resolved NAT IP in SPA message"); + } + else + { + log_msg(LOG_INFO, "Invalid NAT IP in SPA message"); + free_acc_port_list(port_list); + return res; + } + } + else + { + strlcpy(nat_ip, nat_dst, MAX_IPV4_STR_LEN); } nat_port = strtol_wrapper(ndx+1, 0, MAX_PORT, diff --git a/server/fw_util_iptables.c b/server/fw_util_iptables.c index ef9dabf5..d54101ec 100644 --- a/server/fw_util_iptables.c +++ b/server/fw_util_iptables.c @@ -1305,6 +1305,8 @@ process_spa_request(const fko_srv_options_t * const opts, const acc_stanza_t * const acc, spa_data_t * const spadat) { char nat_ip[MAX_IPV4_STR_LEN] = {0}; + char nat_dst[64] = {0}; //not finding a MAX_HOSTNAME_LEN #define + unsigned int nat_port = 0; unsigned int fst_proto; unsigned int fst_port; @@ -1367,12 +1369,23 @@ process_spa_request(const fko_srv_options_t * const opts, ndx = strchr(spadat->nat_access, ','); if(ndx != NULL) { - strlcpy(nat_ip, spadat->nat_access, (ndx-spadat->nat_access)+1); - if (! is_valid_ipv4_addr(nat_ip)) + strlcpy(nat_dst, spadat->nat_access, (ndx-spadat->nat_access)+1); + if (! is_valid_ipv4_addr(nat_dst)) { - log_msg(LOG_INFO, "Invalid NAT IP in SPA message"); - free_acc_port_list(port_list); - return res; + if (ipv4_resolve(nat_dst, nat_ip) == 0) + { + log_msg(LOG_INFO, "Resolved NAT IP in SPA message"); + } + else + { + log_msg(LOG_INFO, "Invalid NAT IP in SPA message"); + free_acc_port_list(port_list); + return res; + } + } + else + { + strlcpy(nat_ip, nat_dst, MAX_IPV4_STR_LEN); } nat_port = strtol_wrapper(ndx+1, 0, MAX_PORT, From bc55f0f21f4afee930f2c233699b38d01d9bdabe Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Thu, 31 Dec 2015 02:12:08 +0000 Subject: [PATCH 2/5] Add count_characters and a CUnit test series for it. --- client/fwknop_common.h | 1 - common/fko_util.c | 43 ++++++++++++++++++++++++++++++++++++++ common/fko_util.h | 13 ++++++++++-- lib/fko.h | 2 +- lib/fko_utests.c | 2 ++ server/fw_util_firewalld.c | 2 +- server/fw_util_iptables.c | 2 +- 7 files changed, 59 insertions(+), 6 deletions(-) diff --git a/client/fwknop_common.h b/client/fwknop_common.h index e7daef7e..4469c718 100644 --- a/client/fwknop_common.h +++ b/client/fwknop_common.h @@ -66,7 +66,6 @@ #define HTTP_MAX_REQUEST_LEN 2000 #define HTTP_MAX_RESPONSE_LEN 2000 #define HTTP_MAX_USER_AGENT_LEN 100 -#define MAX_HOSTNAME_LEN 70 #define MAX_URL_HOST_LEN 256 #define MAX_URL_PATH_LEN 1024 diff --git a/common/fko_util.c b/common/fko_util.c index 586abce1..fc2d8231 100644 --- a/common/fko_util.c +++ b/common/fko_util.c @@ -50,6 +50,11 @@ #define NULL_STRING "" /*!< String which represents a NULL buffer */ +#ifdef HAVE_C_UNIT_TESTS +#include "cunit_common.h" +DECLARE_TEST_SUITE(utils_test, "Utility functions test suite"); +#endif + /** * Structure to handle an encryption mode string string and its associated integer value */ @@ -1052,5 +1057,43 @@ ipv4_resolve(const char *dns_str, char *ip_str) return error; } +int +count_characters(const char *str, const char match, int len) +{ + int i, count = 0; + for (i=0; i < len; i++) { + if (str[i] == match) + count++; + if (str[i] == '\0') + return count; + } + return count; +} + +#ifdef HAVE_C_UNIT_TESTS + +DECLARE_UTEST(test_count_characters, "test the count_characters function") +{ + char test_str[32]; + strcpy(test_str, "abcd"); + CU_ASSERT(count_characters(test_str, 'a', 4) == 1); + strcpy(test_str, "aacd"); + CU_ASSERT(count_characters(test_str, 'a', 4) == 2); + strcpy(test_str, "a,b,c,d,"); + CU_ASSERT(count_characters(test_str, ',', 4) == 2); + strcpy(test_str, "a,b,c,d,"); + CU_ASSERT(count_characters(test_str, ',', 8) == 4); + strcpy(test_str, "aaaa"); + CU_ASSERT(count_characters(test_str, 'a', 3) == 3); +} + +int register_utils_test(void) +{ + ts_init(&TEST_SUITE(utils_test), TEST_SUITE_DESCR(utils_test), NULL, NULL); + ts_add_utest(&TEST_SUITE(utils_test), UTEST_FCT(test_count_characters), UTEST_DESCR(test_count_characters)); + + return register_ts(&TEST_SUITE(utils_test)); +} +#endif /***EOF***/ diff --git a/common/fko_util.h b/common/fko_util.h index da45e786..af8d31fe 100644 --- a/common/fko_util.h +++ b/common/fko_util.h @@ -35,6 +35,8 @@ #define MAX_CMDLINE_ARGS 30 /*!< should be way more than enough */ #define MAX_ARGS_LINE_LEN 1024 +#define MAX_HOSTNAME_LEN 64 + /* Function prototypes */ int is_valid_encoded_msg_len(const int len); @@ -61,11 +63,18 @@ void chop_newline(char *str); void chop_char(char *str, const char chop); void chop_spaces(char *str); +/** + * + * \brief counts the occurences of a character + * + * \return returns the number of chars found + */ +int count_characters(const char *str, const char match, int len); + int strtoargv(const char * const args_str, char **argv_new, int *argc_new); void free_argv(char **argv_new, int *argc_new); -int ipv4_resolve(const char *dns_str, char *ip_str); - +int ipv4_resolve(const char *dns_str, char *ip_str); #if !HAVE_STRLCAT size_t strlcat(char *dst, const char *src, size_t siz); #endif diff --git a/lib/fko.h b/lib/fko.h index 8824b2d4..98cf4ab2 100644 --- a/lib/fko.h +++ b/lib/fko.h @@ -1401,7 +1401,7 @@ int register_ts_fko_decode(void); int register_ts_hmac_test(void); int register_ts_digest_test(void); int register_ts_aes_test(void); - +int register_utils_test(void); #endif #endif /* FKO_H */ diff --git a/lib/fko_utests.c b/lib/fko_utests.c index 22b8b339..d5b85882 100755 --- a/lib/fko_utests.c +++ b/lib/fko_utests.c @@ -2,6 +2,7 @@ #include "fko.h" +#include "fko_util.h" /** * Register test suites from FKO files. * @@ -14,6 +15,7 @@ static void register_test_suites(void) register_ts_hmac_test(); register_ts_digest_test(); register_ts_aes_test(); + register_utils_test(); } /* The main() function for setting up and running the tests. diff --git a/server/fw_util_firewalld.c b/server/fw_util_firewalld.c index 0f13ff8f..4047b5c2 100644 --- a/server/fw_util_firewalld.c +++ b/server/fw_util_firewalld.c @@ -1319,7 +1319,7 @@ process_spa_request(const fko_srv_options_t * const opts, const acc_stanza_t * const acc, spa_data_t * const spadat) { char nat_ip[MAX_IPV4_STR_LEN] = {0}; - char nat_dst[64] = {0}; //not finding a MAX_HOSTNAME_LEN #define + char nat_dst[MAX_HOSTNAME_LEN] = {0}; unsigned int nat_port = 0; unsigned int fst_proto; unsigned int fst_port; diff --git a/server/fw_util_iptables.c b/server/fw_util_iptables.c index d54101ec..74faf5e7 100644 --- a/server/fw_util_iptables.c +++ b/server/fw_util_iptables.c @@ -1305,7 +1305,7 @@ process_spa_request(const fko_srv_options_t * const opts, const acc_stanza_t * const acc, spa_data_t * const spadat) { char nat_ip[MAX_IPV4_STR_LEN] = {0}; - char nat_dst[64] = {0}; //not finding a MAX_HOSTNAME_LEN #define + char nat_dst[MAX_HOSTNAME_LEN] = {0}; unsigned int nat_port = 0; unsigned int fst_proto; From 748803aef746c5ef551161e9f37e238e6886a508 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Thu, 31 Dec 2015 03:38:27 +0000 Subject: [PATCH 3/5] Add length checks for nat_access messages --- common/fko_util.h | 2 +- lib/fko_message.c | 19 +++++++++++++++---- server/fw_util_firewalld.c | 6 ++++-- server/fw_util_iptables.c | 6 ++++-- server/fwknopd_common.h | 1 - 5 files changed, 24 insertions(+), 10 deletions(-) diff --git a/common/fko_util.h b/common/fko_util.h index af8d31fe..100d9982 100644 --- a/common/fko_util.h +++ b/common/fko_util.h @@ -35,7 +35,7 @@ #define MAX_CMDLINE_ARGS 30 /*!< should be way more than enough */ #define MAX_ARGS_LINE_LEN 1024 -#define MAX_HOSTNAME_LEN 64 +#define MAX_HOSTNAME_LEN 70 /* Function prototypes */ diff --git a/lib/fko_message.c b/lib/fko_message.c index de3d1b9e..1ce55680 100644 --- a/lib/fko_message.c +++ b/lib/fko_message.c @@ -304,17 +304,28 @@ int validate_nat_access_msg(const char *msg) { const char *ndx; + int host_len; int res = FKO_SUCCESS; int startlen = strnlen(msg, MAX_SPA_MESSAGE_SIZE); if(startlen == MAX_SPA_MESSAGE_SIZE) return(FKO_ERROR_INVALID_DATA_MESSAGE_NAT_MISSING); - /* Should always have a valid allow IP regardless of message type - * - if((res = have_allow_ip(msg)) != FKO_SUCCESS) - return(FKO_ERROR_INVALID_SPA_NAT_ACCESS_MSG); + /* must have exactly one comma here */ + if(count_characters(msg, ',', startlen) != 1) + return(FKO_ERROR_INVALID_SPA_NAT_ACCESS_MSG); + + /* Must not be longer than the max hostname length + */ + host_len = strcspn(msg, ","); + if(host_len > MAX_HOSTNAME_LEN) + return(FKO_ERROR_INVALID_SPA_NAT_ACCESS_MSG); + + /* Check for some invalid characters + */ + if(strcspn(msg, " /?\"\'\\") < host_len) + return(FKO_ERROR_INVALID_SPA_NAT_ACCESS_MSG); /* Position ourselves beyond the allow IP and make sure we have * a single port value diff --git a/server/fw_util_firewalld.c b/server/fw_util_firewalld.c index 4047b5c2..3afd8ecb 100644 --- a/server/fw_util_firewalld.c +++ b/server/fw_util_firewalld.c @@ -1334,6 +1334,7 @@ process_spa_request(const fko_srv_options_t * const opts, char *ndx = NULL; int res = 0, is_err; + int str_len; time_t now; unsigned int exp_ts; @@ -1380,9 +1381,10 @@ process_spa_request(const fko_srv_options_t * const opts, else { ndx = strchr(spadat->nat_access, ','); - if(ndx != NULL) + str_len = strcspn(spadat->nat_access, ","); + if((ndx != NULL) && (str_len <= MAX_HOSTNAME_LEN)) { - strlcpy(nat_dst, spadat->nat_access, (ndx-spadat->nat_access)+1); + strlcpy(nat_dst, spadat->nat_access, str_len+1); if (! is_valid_ipv4_addr(nat_dst)) { if (ipv4_resolve(nat_dst, nat_ip) == 0) diff --git a/server/fw_util_iptables.c b/server/fw_util_iptables.c index 74faf5e7..6ce25572 100644 --- a/server/fw_util_iptables.c +++ b/server/fw_util_iptables.c @@ -1321,6 +1321,7 @@ process_spa_request(const fko_srv_options_t * const opts, char *ndx = NULL; int res = 0, is_err; + int str_len; time_t now; unsigned int exp_ts; @@ -1367,9 +1368,10 @@ process_spa_request(const fko_srv_options_t * const opts, else { ndx = strchr(spadat->nat_access, ','); - if(ndx != NULL) + str_len = strcspn(spadat->nat_access, ","); + if((ndx != NULL) && (str_len <= MAX_HOSTNAME_LEN)) { - strlcpy(nat_dst, spadat->nat_access, (ndx-spadat->nat_access)+1); + strlcpy(nat_dst, spadat->nat_access, str_len+1); if (! is_valid_ipv4_addr(nat_dst)) { if (ipv4_resolve(nat_dst, nat_ip) == 0) diff --git a/server/fwknopd_common.h b/server/fwknopd_common.h index a8624be5..b60a154d 100644 --- a/server/fwknopd_common.h +++ b/server/fwknopd_common.h @@ -211,7 +211,6 @@ #define MAX_PCAP_FILTER_LEN 1024 #define MAX_IFNAME_LEN 128 #define MAX_SPA_PACKET_LEN 1500 /* --DSS check this? */ -#define MAX_HOSTNAME_LEN 64 #define MAX_DECRYPTED_SPA_LEN 1024 /* The minimum possible valid SPA data size. From 669e448db5dfceaf7ec161d4236212b5e8dc22dd Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Thu, 31 Dec 2015 18:05:55 +0000 Subject: [PATCH 4/5] Add ENABLE_NAT_DNS config option --- server/cmd_opts.h | 1 + server/config_init.c | 4 ++++ server/fw_util_firewalld.c | 27 +++++++++++++++++++++++---- server/fw_util_iptables.c | 27 +++++++++++++++++++++++---- server/fwknopd.conf | 3 +++ server/fwknopd_common.h | 2 ++ 6 files changed, 56 insertions(+), 8 deletions(-) diff --git a/server/cmd_opts.h b/server/cmd_opts.h index 8e30bc24..a04c479d 100644 --- a/server/cmd_opts.h +++ b/server/cmd_opts.h @@ -72,6 +72,7 @@ static char *config_map[NUMBER_OF_CONFIG_ENTRIES] = { //"ENABLE_EXT_CMD_PREFIX", //"EXT_CMD_PREFIX", "ENABLE_DESTINATION_RULE", + "ENABLE_NAT_DNS", #if FIREWALL_FIREWALLD "ENABLE_FIREWD_FORWARDING", "ENABLE_FIREWD_LOCAL_NAT", diff --git a/server/config_init.c b/server/config_init.c index bafc4a3d..bf90cd8e 100644 --- a/server/config_init.c +++ b/server/config_init.c @@ -880,6 +880,10 @@ validate_options(fko_srv_options_t *opts) #endif /* FIREWALL type */ + /* NAT DNS enabled*/ + if(opts->config[CONF_ENABLE_NAT_DNS] == NULL) + set_config_entry(opts, CONF_ENABLE_NAT_DNS, DEF_ENABLE_NAT_DNS); + /* GPG Home dir. */ if(opts->config[CONF_GPG_HOME_DIR] == NULL) diff --git a/server/fw_util_firewalld.c b/server/fw_util_firewalld.c index 3afd8ecb..998d607c 100644 --- a/server/fw_util_firewalld.c +++ b/server/fw_util_firewalld.c @@ -1385,17 +1385,29 @@ process_spa_request(const fko_srv_options_t * const opts, if((ndx != NULL) && (str_len <= MAX_HOSTNAME_LEN)) { strlcpy(nat_dst, spadat->nat_access, str_len+1); - if (! is_valid_ipv4_addr(nat_dst)) + if((! is_valid_ipv4_addr(nat_dst))) { - if (ipv4_resolve(nat_dst, nat_ip) == 0) + if(strncasecmp(opts->config[CONF_ENABLE_NAT_DNS], "Y", 1)==0) { - log_msg(LOG_INFO, "Resolved NAT IP in SPA message"); + if (ipv4_resolve(nat_dst, nat_ip) == 0) + { + log_msg(LOG_INFO, "Resolved NAT IP in SPA message"); + } + else + { + log_msg(LOG_INFO, "Unable to resolve Hostname in NAT SPA message"); + free_acc_port_list(port_list); + res = is_err; + return res; + } } else { - log_msg(LOG_INFO, "Invalid NAT IP in SPA message"); + log_msg(LOG_INFO, "Received Hostname in NAT SPA message, but hostname is disabled."); free_acc_port_list(port_list); + res = is_err; return res; + } } else @@ -1413,6 +1425,13 @@ process_spa_request(const fko_srv_options_t * const opts, return res; } } + else + { + log_msg(LOG_INFO, "Invalid NAT IP in SPA message"); + free_acc_port_list(port_list); + res = is_err; + return res; + } } if(spadat->message_type == FKO_LOCAL_NAT_ACCESS_MSG diff --git a/server/fw_util_iptables.c b/server/fw_util_iptables.c index 6ce25572..a280d9c1 100644 --- a/server/fw_util_iptables.c +++ b/server/fw_util_iptables.c @@ -1372,17 +1372,29 @@ process_spa_request(const fko_srv_options_t * const opts, if((ndx != NULL) && (str_len <= MAX_HOSTNAME_LEN)) { strlcpy(nat_dst, spadat->nat_access, str_len+1); - if (! is_valid_ipv4_addr(nat_dst)) + if((! is_valid_ipv4_addr(nat_dst))) { - if (ipv4_resolve(nat_dst, nat_ip) == 0) + if(strncasecmp(opts->config[CONF_ENABLE_NAT_DNS], "Y", 1)==0) { - log_msg(LOG_INFO, "Resolved NAT IP in SPA message"); + if (ipv4_resolve(nat_dst, nat_ip) == 0) + { + log_msg(LOG_INFO, "Resolved NAT IP in SPA message"); + } + else + { + log_msg(LOG_INFO, "Unable to resolve Hostname in NAT SPA message"); + free_acc_port_list(port_list); + res = is_err; + return res; + } } else { - log_msg(LOG_INFO, "Invalid NAT IP in SPA message"); + log_msg(LOG_INFO, "Received Hostname in NAT SPA message, but hostname is disabled."); free_acc_port_list(port_list); + res = is_err; return res; + } } else @@ -1400,6 +1412,13 @@ process_spa_request(const fko_srv_options_t * const opts, return res; } } + else + { + log_msg(LOG_INFO, "Invalid NAT IP in SPA message"); + free_acc_port_list(port_list); + res = is_err; + return res; + } } if(spadat->message_type == FKO_LOCAL_NAT_ACCESS_MSG diff --git a/server/fwknopd.conf b/server/fwknopd.conf index ed2afeb1..d6b31374 100644 --- a/server/fwknopd.conf +++ b/server/fwknopd.conf @@ -109,6 +109,9 @@ # #ENABLE_SPA_OVER_HTTP N; +# Allow fwknopd to resolve hostnames in NAT access messages +#ENABLE_NAT_DNS Y; + # Enable the fwknopd TCP server. This is a "dummy" TCP server that will # accept TCP connection requests on the specified TCPSERV_PORT. # If set to "Y", fwknopd will fork off a child process to listen for and diff --git a/server/fwknopd_common.h b/server/fwknopd_common.h index b60a154d..3fcc175f 100644 --- a/server/fwknopd_common.h +++ b/server/fwknopd_common.h @@ -95,6 +95,7 @@ #define DEF_RULES_CHECK_THRESHOLD "20" #define DEF_MAX_SNIFF_BYTES "1500" #define DEF_GPG_HOME_DIR "/root/.gnupg" +#define DEF_ENABLE_NAT_DNS "Y" #ifdef GPG_EXE #define DEF_GPG_EXE GPG_EXE #else @@ -260,6 +261,7 @@ enum { //CONF_ENABLE_EXT_CMD_PREFIX, //CONF_EXT_CMD_PREFIX, CONF_ENABLE_DESTINATION_RULE, + CONF_ENABLE_NAT_DNS, #if FIREWALL_FIREWALLD CONF_ENABLE_FIREWD_FORWARDING, CONF_ENABLE_FIREWD_LOCAL_NAT, From dda7fa39c195fe0d3c470617d6a98598ce174c10 Mon Sep 17 00:00:00 2001 From: Jonathan Bennett Date: Thu, 31 Dec 2015 19:24:45 +0000 Subject: [PATCH 5/5] Disable client side nat_dns --- client/fwknop.c | 27 ++++++++++----------------- common/fko_util.c | 3 ++- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/client/fwknop.c b/client/fwknop.c index 6931ba2a..30293d7f 100644 --- a/client/fwknop.c +++ b/client/fwknop.c @@ -893,26 +893,19 @@ set_nat_access(fko_ctx_t ctx, fko_cli_options_t *options, const char * const acc /* Check if there is a hostname to resolve as an ip address in the NAT access buffer */ if (is_hostname_str_with_port(nat_access_buf, hostname, sizeof(hostname), &port)) { - /* Speed up the name resolution by forcing ipv4 (AF_INET). - * A NULL pointer could be used instead if there is no constraint. - * Maybe when ipv6 support will be enable the structure could initialize the - * family to either AF_INET or AF_INET6 */ - hints.ai_family = AF_INET; - if (resolve_dst_addr(hostname, &hints, - dst_ip_str, sizeof(dst_ip_str), options) != 0) - { - log_msg(LOG_VERBOSITY_ERROR, "[*] Unable to resolve %s as an ip address", - hostname); - return FKO_ERROR_INVALID_DATA; - } - - snprintf(nat_access_buf, MAX_LINE_LEN, NAT_ACCESS_STR_TEMPLATE, - dst_ip_str, port); + /* We now send the hostname, and resolve it server side */ + snprintf(nat_access_buf, MAX_LINE_LEN, "%s", + options->nat_access_str); } - /* Nothing to resolve */ - else; + /* assume just hostname */ + else + { + snprintf(nat_access_buf, MAX_LINE_LEN, NAT_ACCESS_STR_TEMPLATE, + options->nat_access_str, access_port); + + } if(options->nat_rand_port) { diff --git a/common/fko_util.c b/common/fko_util.c index fc2d8231..fc29c7d9 100644 --- a/common/fko_util.c +++ b/common/fko_util.c @@ -1014,6 +1014,7 @@ ipv4_resolve(const char *dns_str, char *ip_str) struct sockaddr_in *sai_remote; /* Remote host information as a sockaddr_in structure */ #endif + memset(&hints, 0 , sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; @@ -1021,7 +1022,7 @@ ipv4_resolve(const char *dns_str, char *ip_str) /* Try to resolve the host name */ error = getaddrinfo(dns_str, NULL, &hints, &result); if (error != 0) - fprintf(stderr, "resolve_dst_addr() : %s\n", gai_strerror(error)); + fprintf(stderr, "ipv4_resolve() : %s\n", gai_strerror(error)); else {