diff options
-rw-r--r-- | .github/workflows/cla-check.yml | 19 | ||||
-rw-r--r-- | .gitignore | 79 | ||||
-rw-r--r-- | Jenkinsfile | 23 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | debian/changelog | 9 | ||||
-rw-r--r-- | debian/control | 4 | ||||
-rw-r--r-- | src/Makefile.am | 6 | ||||
-rw-r--r-- | src/ipaddrcheck_functions.c | 61 | ||||
-rw-r--r-- | src/ipaddrcheck_functions.h | 4 | ||||
-rw-r--r-- | src/ipaddrcheck_functions.o | bin | 55552 -> 0 bytes | |||
-rw-r--r-- | tests/Makefile.am | 4 | ||||
-rwxr-xr-x | tests/integration_tests.sh | 3 |
12 files changed, 160 insertions, 54 deletions
diff --git a/.github/workflows/cla-check.yml b/.github/workflows/cla-check.yml new file mode 100644 index 0000000..3c1aeee --- /dev/null +++ b/.github/workflows/cla-check.yml @@ -0,0 +1,19 @@ +name: "CLA Check" + +permissions: + actions: write + contents: read + pull-requests: write + statuses: write + +on: + pull_request: + types: [opened, synchronize, closed] + issue_comment: + types: [created] + +jobs: + call-cla-assistant: + uses: vyos/vyos-cla-signatures/.github/workflows/cla-reusable.yml@current + secrets: + CLA_PAT: ${{ secrets.CLA_PAT }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6f267c1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,79 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Autotools-generated files + +Makefile +Makefile.in +aclocal.m4 +autom4te.cache/ +compile +config.status +configure +depcomp +install-sh +man/Makefile +man/Makefile.in +missing +src/.deps/ +src/.dirstamp +src/Makefile +src/Makefile.in +src/config.h +src/config.h.in +src/stamp-h1 +test-driver +tests/.deps/ +tests/Makefile +tests/Makefile.in + +# Misc + +*.log +*.trs + +# Build artifacts + +src/ipaddrcheck +tests/check_ipaddrcheck diff --git a/Jenkinsfile b/Jenkinsfile deleted file mode 100644 index 21a6829..0000000 --- a/Jenkinsfile +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (C) 2020-2021 VyOS maintainers and contributors -// -// This program is free software; you can redistribute it and/or modify -// in order to easy exprort images built to "external" world -// it under the terms of the GNU General Public License version 2 or later as -// published by the Free Software Foundation. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -@NonCPS - -// Using a version specifier library, use 'current' branch. The underscore (_) -// is not a typo! You need this underscore if the line immediately after the -// @Library annotation is not an import statement! -@Library('vyos-build@current')_ - -// Start package build using library function from https://github.com/vyos/vyos-build -buildPackage(null, null, null, true) diff --git a/configure.ac b/configure.ac index 567bfd9..482523c 100644 --- a/configure.ac +++ b/configure.ac @@ -4,7 +4,6 @@ AC_COPYRIGHT([Copyright (c) 2024 VyOS maintainers and contributors.]) #AC_PROG_CC AM_PROG_CC_C_O -AC_CHECK_HEADER([pcre.h], [], [AC_MSG_FAILURE([pcre.h is not found.])]) AC_CHECK_HEADER([libcidr.h], [], [AC_MSG_FAILURE([libcidr.h is not found.])]) AM_INIT_AUTOMAKE([gnu no-dist-gzip dist-bzip2 subdir-objects]) @@ -14,5 +13,6 @@ AC_CONFIG_FILES([Makefile src/Makefile tests/Makefile man/Makefile]) AC_CONFIG_HEADERS([src/config.h]) PKG_CHECK_MODULES([CHECK], [check >= 0.9.4]) +PKG_CHECK_MODULES([PCRE2], [libpcre2-8]) AC_OUTPUT diff --git a/debian/changelog b/debian/changelog index 6405fd7..e1c5d02 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +ipaddrcheck (1.3) unstable; urgency=medium + + * New option --range-prefix-length to require ranges to be within a subnet (Daniil Baturin). + * Options for checking IP ranges: --is-ipv4-range and --is-ipv6-range (Daniil Baturin). + * Fixed linker flags to build correctly on Debian Bullseye (John Eastabrook). + * Removed stale dependency on libcidr0-dev (Christian Breunig). + + -- Daniil Baturin <daniil@vyos.io> Tue, 25 Feb 2025 18:21:43 +0000 + ipaddrcheck (1.2) unstable; urgency=medium * Correct recognition of IPv4 /31 and IPv6 /127 as valid host addresses. diff --git a/debian/control b/debian/control index ac61240..bc6785a 100644 --- a/debian/control +++ b/debian/control @@ -2,11 +2,11 @@ Source: ipaddrcheck Section: contrib/net Priority: extra Maintainer: VyOS Package Maintainers <maintainers@vyos.net> -Build-Depends: autoconf, debhelper (>= 9), libpcre3-dev, libcidr-dev, check +Build-Depends: autoconf, debhelper (>= 9), libpcre2-dev, libcidr-dev, check Standards-Version: 3.9.6 Package: ipaddrcheck Architecture: any -Depends: libpcre3, libcidr0, ${shlibs:Depends}, ${misc:Depends} +Depends: libpcre2-8-0, libcidr0, ${shlibs:Depends}, ${misc:Depends} Description: IPv4 and IPv6 address validation utility A validation utility for IPv4 and IPv6 addresses. diff --git a/src/Makefile.am b/src/Makefile.am index 1c43bae..ce8ea59 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ -AM_CFLAGS = --pedantic -Wall -Werror -Wno-error=format-overflow= -std=c99 -O2 -AM_LDFLAGS = +AM_CFLAGS = --pedantic -Wall -Werror -std=c99 -O2 +AM_CPPFLAGS = $(PCRE2_CFLAGS) ipaddrcheck_SOURCES = ipaddrcheck.c ipaddrcheck_functions.c -ipaddrcheck_LDADD = -lcidr -lpcre +ipaddrcheck_LDADD = -lcidr $(PCRE2_LIBS) bin_PROGRAMS = ipaddrcheck diff --git a/src/ipaddrcheck_functions.c b/src/ipaddrcheck_functions.c index 2d2dff3..fb0e654 100644 --- a/src/ipaddrcheck_functions.c +++ b/src/ipaddrcheck_functions.c @@ -41,25 +41,31 @@ int regex_matches(const char* regex, const char* str) { - int offsets[1]; - pcre *re; + pcre2_code *re; int rc; - const char *error; - int erroffset; + int out; + int error; + PCRE2_SIZE erroffset; - re = pcre_compile(regex, 0, &error, &erroffset, NULL); + re = pcre2_compile((PCRE2_SPTR)regex, PCRE2_ZERO_TERMINATED, 0, &error, &erroffset, NULL); assert(re != NULL); - rc = pcre_exec(re, NULL, str, strlen(str), 0, 0, offsets, 1); + pcre2_match_data *match = pcre2_match_data_create_from_pattern(re, NULL); + + rc = pcre2_match(re, (PCRE2_SPTR)str, strlen(str), 0, 0, match, NULL); if( rc >= 0) { - return RESULT_SUCCESS; + out = RESULT_SUCCESS; } else { - return RESULT_FAILURE; + out = RESULT_FAILURE; } + + pcre2_match_data_free(match); + pcre2_code_free(re); + return out; } @@ -546,7 +552,10 @@ int is_ipv4_range(char* range_str, int prefix_length, int verbose) If the regex check succeeded, we know the hyphen is there. */ split_range(range_str, left, right); - if( !is_ipv4_single(left) ) + CIDR* left_addr = cidr_from_str(left); + CIDR* right_addr = cidr_from_str(right); + + if( !(is_ipv4_single(left) && is_valid_address(left_addr)) ) { if( verbose ) { @@ -554,7 +563,7 @@ int is_ipv4_range(char* range_str, int prefix_length, int verbose) } result = RESULT_FAILURE; } - else if( !is_ipv4_single(right) ) + else if( !(is_ipv4_single(right) && is_valid_address(right_addr)) ) { if( verbose ) { @@ -564,8 +573,6 @@ int is_ipv4_range(char* range_str, int prefix_length, int verbose) } else { - CIDR* left_addr = cidr_from_str(left); - CIDR* right_addr = cidr_from_str(right); struct in_addr* left_in_addr = cidr_to_inaddr(left_addr, NULL); struct in_addr* right_in_addr = cidr_to_inaddr(right_addr, NULL); @@ -577,10 +584,13 @@ int is_ipv4_range(char* range_str, int prefix_length, int verbose) { char left_pref_str[19]; - /* XXX: Prefix length size is checked elsewhere, so it can't be more than 2 characters (32) + /* XXX: Prefix length size is checked elsewhere with a regex, so it can't be more than 2 characters (32) and overflow cannot occur. */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wformat-overflow=" sprintf(left_pref_str, "%s/%u", left, prefix_length); + #pragma GCC diagnostic pop CIDR* left_addr_with_pref = cidr_from_str(left_pref_str); CIDR* left_net = cidr_addr_network(left_addr_with_pref); if( cidr_contains(left_net, right_addr) == 0 ) @@ -608,9 +618,9 @@ int is_ipv4_range(char* range_str, int prefix_length, int verbose) result = RESULT_FAILURE; } - cidr_free(left_addr); - cidr_free(right_addr); } + cidr_free(left_addr); + cidr_free(right_addr); } return(result); @@ -644,7 +654,11 @@ int is_ipv6_range(char* range_str, int prefix_length, int verbose) If the regex check succeeded, we know the hyphen is there. */ split_range(range_str, left, right); - if( !is_ipv6_single(left) ) + CIDR* left_addr = cidr_from_str(left); + CIDR* right_addr = cidr_from_str(right); + + if( !(is_ipv6_single(left) && + is_valid_address(left_addr) && !duplicate_double_colons(left)) ) { if( verbose ) { @@ -652,7 +666,8 @@ int is_ipv6_range(char* range_str, int prefix_length, int verbose) } result = RESULT_FAILURE; } - else if( !is_ipv6_single(right) ) + else if( !(is_ipv6_single(right) && + is_valid_address(right_addr) && !duplicate_double_colons(right)) ) { if( verbose ) { @@ -662,8 +677,6 @@ int is_ipv6_range(char* range_str, int prefix_length, int verbose) } else { - CIDR* left_addr = cidr_from_str(left); - CIDR* right_addr = cidr_from_str(right); struct in6_addr* left_in6_addr = cidr_to_in6addr(left_addr, NULL); struct in6_addr* right_in6_addr = cidr_to_in6addr(right_addr, NULL); @@ -675,10 +688,13 @@ int is_ipv6_range(char* range_str, int prefix_length, int verbose) { char left_pref_str[44]; - /* XXX: Prefix length size is checked elsewhere, so it can't be more than 3 characters (128) + /* XXX: Prefix length size is checked elsewhere with a regex, so it can't be more than 3 characters (128) and overflow cannot occur. */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wformat-overflow=" sprintf(left_pref_str, "%s/%u", left, prefix_length); + #pragma GCC diagnostic pop CIDR* left_addr_with_pref = cidr_from_str(left_pref_str); CIDR* left_net = cidr_addr_network(left_addr_with_pref); if( cidr_contains(left_net, right_addr) == 0 ) @@ -705,10 +721,9 @@ int is_ipv6_range(char* range_str, int prefix_length, int verbose) } result = RESULT_FAILURE; } - - cidr_free(left_addr); - cidr_free(right_addr); } + cidr_free(left_addr); + cidr_free(right_addr); } return(result); diff --git a/src/ipaddrcheck_functions.h b/src/ipaddrcheck_functions.h index 9b5e55f..b717d74 100644 --- a/src/ipaddrcheck_functions.h +++ b/src/ipaddrcheck_functions.h @@ -23,11 +23,13 @@ #ifndef IPADDRCHECK_FUNCTIONS_H #define IPADDRCHECK_FUNCTIONS_H +#define PCRE2_CODE_UNIT_WIDTH 8 + #include <stdio.h> #include <stdlib.h> #include <string.h> #include <getopt.h> -#include <pcre.h> +#include <pcre2.h> #include <libcidr.h> #define INVALID_PROTO -1 diff --git a/src/ipaddrcheck_functions.o b/src/ipaddrcheck_functions.o Binary files differdeleted file mode 100644 index a689dac..0000000 --- a/src/ipaddrcheck_functions.o +++ /dev/null diff --git a/tests/Makefile.am b/tests/Makefile.am index 5c0a09a..f7b824a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,3 +1,5 @@ +AM_CPPFLAGS = $(PCRE2_CFLAGS) + TESTS = check_ipaddrcheck integration_tests.sh TESTS_ENVIRONMENT = top_srcdir=$(top_srcdir) PATH=.:$(top_srcdir)/src:$$PATH @@ -5,4 +7,4 @@ TESTS_ENVIRONMENT = top_srcdir=$(top_srcdir) PATH=.:$(top_srcdir)/src:$$PATH check_PROGRAMS = check_ipaddrcheck check_ipaddrcheck_SOURCES = check_ipaddrcheck.c ../src/ipaddrcheck_functions.c check_ipaddrcheck_CFLAGS = @CHECK_CFLAGS@ -check_ipaddrcheck_LDADD = -lcidr -lpcre @CHECK_LIBS@ +check_ipaddrcheck_LDADD = -lcidr $(PCRE2_LIBS) @CHECK_LIBS@ diff --git a/tests/integration_tests.sh b/tests/integration_tests.sh index 3a1e4ea..2c2c72b 100755 --- a/tests/integration_tests.sh +++ b/tests/integration_tests.sh @@ -56,6 +56,7 @@ ipv4_range_negative=( 192.0.2.-192.0.2.100 192.0.2.0- 192.0.2.200-192.0.2.100 + 192.0.2.1-192.0.2.500 ) ipv6_range_positive=( @@ -66,6 +67,8 @@ ipv6_range_negative=( 2001:db8:xx-2001:db8::99 2001:db:- 2001:db8::99-2001:db8::1 + 2001::db8::1:1-2001::db8::1::10 + 2001:db8:pqrs::1-2001:db8:uvwx::100 ) ipv6_single_positive=( |