From 13477d60ee3913b84298039b2d42c7832c655775 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Sun, 26 Nov 2017 11:09:19 +0100 Subject: [PATCH] ipv4: add string validation function --- src/util-decode-mime.c | 37 +++++-------------------------- src/util-ip.c | 50 ++++++++++++++++++++++++++++++++++++++++++ src/util-ip.h | 1 + 3 files changed, 56 insertions(+), 32 deletions(-) diff --git a/src/util-decode-mime.c b/src/util-decode-mime.c index 12fac63a2f..2f5cbdfc1c 100644 --- a/src/util-decode-mime.c +++ b/src/util-decode-mime.c @@ -25,7 +25,7 @@ #include "suricata-common.h" #include "util-decode-mime.h" - +#include "util-ip.h" #include "util-spm-bs.h" #include "util-unittest.h" #include "util-memcmp.h" @@ -911,42 +911,12 @@ static int IsIpv4Host(const uint8_t *urlhost, uint32_t len) char tempIp[MAX_IP4_CHARS + 1]; /* Cut off at '/' */ - int alen = 0; - char addr[4][4]; - int dots = 0; uint32_t i = 0; - for (i = 0; i < len && urlhost[i] != 0; i++) { + for ( ; i < len && urlhost[i] != 0; i++) { if (urlhost[i] == '/') { break; } - - if (!(urlhost[i] == '.' || isdigit(urlhost[i]))) { - return 0; - } - if (urlhost[i] == '.') { - if (dots == 3) { - SCLogDebug("too many dots"); - return 0; - } - addr[dots][alen] = '\0'; - dots++; - alen = 0; - } else { - if (alen >= 4) { - SCLogDebug("too long"); - return 0; - } - addr[dots][alen++] = urlhost[i]; - } - } - addr[dots][alen] = '\0'; - for (int x = 0; x < 4; x++) { - int a = atoi(addr[x]); - if (a < 0 || a >= 256) { - SCLogDebug("out of range"); - return 0; - } } /* Too many chars */ @@ -958,6 +928,9 @@ static int IsIpv4Host(const uint8_t *urlhost, uint32_t len) memcpy(tempIp, urlhost, i); tempIp[i] = '\0'; + if (!IPv4AddressStringIsValid(tempIp)) + return 0; + return inet_pton(AF_INET, tempIp, &(sa.sin_addr)); } diff --git a/src/util-ip.c b/src/util-ip.c index b206197a4a..908a17d918 100644 --- a/src/util-ip.c +++ b/src/util-ip.c @@ -27,6 +27,53 @@ #include "suricata-common.h" #include "util-ip.h" +/** \brief determine if a string is a valid ipv4 address + * \retval bool is addr valid? + */ +bool IPv4AddressStringIsValid(const char *str) +{ + int alen = 0; + char addr[4][4]; + int dots = 0; + + memset(&addr, 0, sizeof(addr)); + + uint32_t len = strlen(str); + uint32_t i = 0; + for (i = 0; i < len; i++) { + if (!(str[i] == '.' || isdigit(str[i]))) { + return false; + } + if (str[i] == '.') { + if (dots == 3) { + SCLogDebug("too many dots"); + return false; + } + addr[dots][alen] = '\0'; + dots++; + alen = 0; + } else { + if (alen >= 4) { + SCLogDebug("too long"); + return false; + } + addr[dots][alen++] = str[i]; + } + } + if (dots != 3) + return false; + + addr[dots][alen] = '\0'; + for (int x = 0; x < 4; x++) { + int a = atoi(addr[x]); + if (a < 0 || a >= 256) { + SCLogDebug("out of range"); + return false; + } + } + return true; +} + /** * \brief Validates an IPV4 address and returns the network endian arranged * version of the IPV4 address @@ -43,6 +90,9 @@ struct in_addr *ValidateIPV4Address(const char *addr_str) { struct in_addr *addr = NULL; + if (!IPv4AddressStringIsValid(addr_str)) + return NULL; + if ( (addr = SCMalloc(sizeof(struct in_addr))) == NULL) { SCLogError(SC_ERR_FATAL, "Fatal error encountered in ValidateIPV4Address. Exiting..."); exit(EXIT_FAILURE); diff --git a/src/util-ip.h b/src/util-ip.h index 25ffe9ec5d..f92369ccb4 100644 --- a/src/util-ip.h +++ b/src/util-ip.h @@ -25,6 +25,7 @@ #ifndef __UTIL_IP_H__ #define __UTIL_IP_H__ +bool IPv4AddressStringIsValid(const char *str); struct in_addr *ValidateIPV4Address(const char *); struct in6_addr *ValidateIPV6Address(const char *); void MaskIPNetblock(uint8_t *, int, int);