[libfko] implemented shared utility function for ipv4 address checking
This commit implements a single shared utility function for checking the validaty of an IPv4 address, and both libfko and the fwknopd server use it now. The client will be updated as well.
This commit is contained in:
+3
-24
@@ -33,14 +33,6 @@
|
||||
#include "fko_message.h"
|
||||
#include "fko.h"
|
||||
|
||||
#ifndef WIN32
|
||||
/* for inet_aton() IP validation
|
||||
*/
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
static int
|
||||
have_allow_ip(const char *msg)
|
||||
{
|
||||
@@ -48,9 +40,6 @@ have_allow_ip(const char *msg)
|
||||
char ip_str[MAX_IPV4_STR_LEN];
|
||||
int dot_ctr = 0, char_ctr = 0;
|
||||
int res = FKO_SUCCESS;
|
||||
#if HAVE_SYS_SOCKET_H
|
||||
struct in_addr in;
|
||||
#endif
|
||||
|
||||
while(*ndx != ',' && *ndx != '\0')
|
||||
{
|
||||
@@ -76,19 +65,9 @@ have_allow_ip(const char *msg)
|
||||
else
|
||||
res = FKO_ERROR_INVALID_ALLOW_IP;
|
||||
|
||||
if ((res == FKO_SUCCESS) && (char_ctr < MIN_IPV4_STR_LEN))
|
||||
res = FKO_ERROR_INVALID_ALLOW_IP;
|
||||
|
||||
if((res == FKO_SUCCESS) && dot_ctr != 3)
|
||||
res = FKO_ERROR_INVALID_ALLOW_IP;
|
||||
|
||||
#if HAVE_SYS_SOCKET_H
|
||||
/* Stronger IP validation now that we have a candidate that looks
|
||||
* close enough
|
||||
*/
|
||||
if((res == FKO_SUCCESS) && (inet_aton(ip_str, &in) == 0))
|
||||
res = FKO_ERROR_INVALID_ALLOW_IP;
|
||||
#endif
|
||||
if(res == FKO_SUCCESS)
|
||||
if (! is_valid_ipv4_addr(ip_str))
|
||||
res = FKO_ERROR_INVALID_ALLOW_IP;
|
||||
|
||||
return(res);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,14 @@
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifndef WIN32
|
||||
/* for inet_aton() IP validation
|
||||
*/
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
/* Check for a FKO error returned by a function an return the error code */
|
||||
#define RETURN_ON_FKO_ERROR(e, f) do { if (((e)=(f)) != FKO_SUCCESS) { return (e); } } while(0);
|
||||
|
||||
@@ -104,6 +112,55 @@ is_valid_encoded_msg_len(const int len)
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* Validate an IPv4 address
|
||||
*/
|
||||
int
|
||||
is_valid_ipv4_addr(const char * const ip_str)
|
||||
{
|
||||
const char *ndx = ip_str;
|
||||
int dot_ctr = 0, char_ctr = 0;
|
||||
int res = 1;
|
||||
#if HAVE_SYS_SOCKET_H
|
||||
struct in_addr in;
|
||||
#endif
|
||||
|
||||
while(*ndx != '\0')
|
||||
{
|
||||
char_ctr++;
|
||||
if(char_ctr >= MAX_IPV4_STR_LEN)
|
||||
{
|
||||
res = 0;
|
||||
break;
|
||||
}
|
||||
if(*ndx == '.')
|
||||
dot_ctr++;
|
||||
else if(isdigit(*ndx) == 0)
|
||||
{
|
||||
res = 0;
|
||||
break;
|
||||
}
|
||||
ndx++;
|
||||
}
|
||||
if(char_ctr >= MAX_IPV4_STR_LEN)
|
||||
res = 0;
|
||||
|
||||
if ((res == 1) && (char_ctr < MIN_IPV4_STR_LEN))
|
||||
res = 0;
|
||||
|
||||
if((res == 1) && dot_ctr != 3)
|
||||
res = 0;
|
||||
|
||||
#if HAVE_SYS_SOCKET_H
|
||||
/* Stronger IP validation now that we have a candidate that looks
|
||||
* close enough
|
||||
*/
|
||||
if((res == 1) && (inet_aton(ip_str, &in) == 0))
|
||||
res = 0;
|
||||
#endif
|
||||
|
||||
return(res);
|
||||
}
|
||||
|
||||
/* Convert a digest_type string to its integer value.
|
||||
*/
|
||||
short
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
int is_valid_encoded_msg_len(const int len);
|
||||
int is_valid_pt_msg_len(const int len);
|
||||
int is_valid_digest_len(const int len);
|
||||
int is_valid_ipv4_addr(const char * const ip_str);
|
||||
int is_base64(const unsigned char * const buf, const unsigned short int len);
|
||||
int enc_mode_strtoint(const char *enc_mode_str);
|
||||
short enc_mode_inttostr(int enc_mode, char* enc_mode_str, size_t enc_mode_size);
|
||||
|
||||
@@ -180,6 +180,13 @@ add_acc_force_nat(fko_srv_options_t *opts, acc_stanza_t *curr_acc, const char *v
|
||||
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(! is_valid_ipv4_addr(ip_str))
|
||||
{
|
||||
log_msg(LOG_ERR,
|
||||
"[*] Fatal: invalid FORCE_NAT IP '%s'", ip_str);
|
||||
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
|
||||
}
|
||||
|
||||
curr_acc->force_nat = 1;
|
||||
add_acc_string(&(curr_acc->force_nat_ip), ip_str);
|
||||
|
||||
|
||||
@@ -444,6 +444,18 @@ validate_options(fko_srv_options_t *opts)
|
||||
set_config_entry(opts, CONF_ENABLE_IPT_SNAT,
|
||||
DEF_ENABLE_IPT_SNAT);
|
||||
|
||||
/* Make sure we have a valid IP if SNAT is enabled
|
||||
*/
|
||||
if(strncasecmp(opts->config[CONF_ENABLE_IPT_SNAT], "Y", 1) == 0)
|
||||
if(opts->config[CONF_SNAT_TRANSLATE_IP] != NULL)
|
||||
if(! is_valid_ipv4_addr(opts->config[CONF_SNAT_TRANSLATE_IP]))
|
||||
{
|
||||
log_msg(LOG_ERR,
|
||||
"Invalid IPv4 addr for SNAT_TRANSLATE_IP"
|
||||
);
|
||||
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Enable IPT OUTPUT.
|
||||
*/
|
||||
if(opts->config[CONF_ENABLE_IPT_OUTPUT] == NULL)
|
||||
|
||||
@@ -1110,11 +1110,19 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
if(ndx != NULL)
|
||||
{
|
||||
strlcpy(nat_ip, spadat->nat_access, (ndx-spadat->nat_access)+1);
|
||||
if (! is_valid_ipv4_addr(nat_ip))
|
||||
{
|
||||
log_msg(LOG_INFO, "Invalid NAT IP in SPA message");
|
||||
free_acc_port_list(port_list);
|
||||
return res;
|
||||
}
|
||||
|
||||
nat_port = strtol_wrapper(ndx+1, 0, MAX_PORT, NO_EXIT_UPON_ERR, &is_err);
|
||||
if(is_err != FKO_SUCCESS)
|
||||
{
|
||||
log_msg(LOG_INFO, "Invalid NAT port in SPA message");
|
||||
free_acc_port_list(port_list);
|
||||
res = is_err;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
+19
-2
@@ -643,11 +643,28 @@ incoming_spa(fko_srv_options_t *opts)
|
||||
continue;
|
||||
}
|
||||
|
||||
if((spa_ip_demark-spadat.spa_message) < MIN_IPV4_STR_LEN-1
|
||||
|| (spa_ip_demark-spadat.spa_message) > MAX_IPV4_STR_LEN)
|
||||
{
|
||||
log_msg(LOG_WARNING, "[%s] (stanza #%d) Invalid source IP in SPA message, ignoring SPA packet",
|
||||
spadat.pkt_source_ip, stanza_num, fko_errstr(res));
|
||||
|
||||
if(ctx != NULL)
|
||||
{
|
||||
if(fko_destroy(ctx) == FKO_ERROR_ZERO_OUT_DATA)
|
||||
log_msg(LOG_WARNING,
|
||||
"[%s] (stanza #%d) fko_destroy() could not zero out sensitive data buffer.",
|
||||
spadat.pkt_source_ip, stanza_num, fko_errstr(res)
|
||||
);
|
||||
ctx = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
strlcpy(spadat.spa_message_src_ip,
|
||||
spadat.spa_message, (spa_ip_demark-spadat.spa_message)+1);
|
||||
|
||||
if(strnlen(spadat.spa_message_src_ip,
|
||||
MIN_IPV4_STR_LEN) < MIN_IPV4_STR_LEN)
|
||||
if(! is_valid_ipv4_addr(spadat.spa_message_src_ip))
|
||||
{
|
||||
log_msg(LOG_WARNING, "[%s] (stanza #%d) Invalid source IP in SPA message, ignoring SPA packet",
|
||||
spadat.pkt_source_ip, stanza_num, fko_errstr(res));
|
||||
|
||||
Reference in New Issue
Block a user