diff --git a/backport-Ncat-server-UDP-do-not-quit-after-EOF-on-STDIN.-Fixe.patch b/backport-Ncat-server-UDP-do-not-quit-after-EOF-on-STDIN.-Fixe.patch deleted file mode 100644 index 50cdc79243ca94d13b96b413a4ff197271ebb405..0000000000000000000000000000000000000000 --- a/backport-Ncat-server-UDP-do-not-quit-after-EOF-on-STDIN.-Fixe.patch +++ /dev/null @@ -1,31 +0,0 @@ -From d4e769197afccf425ec16dae5faeece72e8a5130 Mon Sep 17 00:00:00 2001 -From: dmiller -Date: Thu, 27 Jul 2023 17:31:48 +0000 -Subject: [PATCH] Ncat server UDP: do not quit after EOF on STDIN. Fixes #2685 - -Conflict: NA -Reference: https://github.com/nmap/nmap/commit/d4e769197afccf425ec16dae5faeece72e8a5130 - -diff --git a/ncat/ncat_listen.c b/ncat/ncat_listen.c -index 3cecb64f8..c307c68c4 100644 ---- a/ncat/ncat_listen.c -+++ b/ncat/ncat_listen.c -@@ -376,13 +376,13 @@ restart_fd_loop: - } else { - /* Read from stdin and write to all clients. */ - rc = read_stdin(); -- if (rc == 0) { -+ if (rc == 0 && type == SOCK_STREAM) { - if (o.proto != IPPROTO_TCP || (o.proto == IPPROTO_TCP && o.sendonly)) { - /* There will be nothing more to send. If we're not - receiving anything, we can quit here. */ - return 0; - } -- if (!o.noshutdown && type == SOCK_STREAM) shutdown_sockets(SHUT_WR); -+ if (!o.noshutdown) shutdown_sockets(SHUT_WR); - } - if (rc < 0) - return 1; --- -2.33.0 - diff --git a/backport-remove-nse_pcrelib-from-build.patch b/backport-remove-nse_pcrelib-from-build.patch deleted file mode 100644 index ed8933751bf9617b3ec4a40884ae5a613e023c6d..0000000000000000000000000000000000000000 --- a/backport-remove-nse_pcrelib-from-build.patch +++ /dev/null @@ -1,76 +0,0 @@ -From d131a096a869195be36ef7d4fa36739373346cb2 Mon Sep 17 00:00:00 2001 -From: dmiller -Date: Sat, 24 Jun 2023 01:53:09 +0000 -Subject: [PATCH] Remove nse_pcrelib from build. - -Conflict: NA -Reference: https://github.com/nmap/nmap/commit/d131a096a869195be36ef7d4fa36739373346cb2 ---- - Makefile.in | 6 +++--- - nse_main.cc | 2 -- - nse_main.lua | 2 +- - nselib/unittest.lua | 1 - - 4 files changed, 4 insertions(+), 7 deletions(-) - -diff --git a/Makefile.in b/Makefile.in -index 2b13e86..a924301 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -88,9 +88,9 @@ UNINSTALLNDIFF=@UNINSTALLNDIFF@ - UNINSTALLNPING=@UNINSTALLNPING@ - - ifneq (@NOLUA@,yes) --NSE_SRC=nse_main.cc nse_utility.cc nse_nsock.cc nse_db.cc nse_dnet.cc nse_fs.cc nse_nmaplib.cc nse_debug.cc nse_pcrelib.cc nse_lpeg.cc --NSE_HDRS=nse_main.h nse_utility.h nse_nsock.h nse_db.h nse_dnet.h nse_fs.h nse_nmaplib.h nse_debug.h nse_pcrelib.h nse_lpeg.h --NSE_OBJS=nse_main.o nse_utility.o nse_nsock.o nse_db.o nse_dnet.o nse_fs.o nse_nmaplib.o nse_debug.o nse_pcrelib.o nse_lpeg.o -+NSE_SRC=nse_main.cc nse_utility.cc nse_nsock.cc nse_db.cc nse_dnet.cc nse_fs.cc nse_nmaplib.cc nse_debug.cc nse_lpeg.cc -+NSE_HDRS=nse_main.h nse_utility.h nse_nsock.h nse_db.h nse_dnet.h nse_fs.h nse_nmaplib.h nse_debug.h nse_lpeg.h -+NSE_OBJS=nse_main.o nse_utility.o nse_nsock.o nse_db.o nse_dnet.o nse_fs.o nse_nmaplib.o nse_debug.o nse_lpeg.o - ifneq (@OPENSSL_LIBS@,) - NSE_SRC+=nse_openssl.cc nse_ssl_cert.cc - NSE_HDRS+=nse_openssl.h nse_ssl_cert.h -diff --git a/nse_main.cc b/nse_main.cc -index d5d460e..2382688 100644 ---- a/nse_main.cc -+++ b/nse_main.cc -@@ -15,7 +15,6 @@ - #include "nse_fs.h" - #include "nse_nsock.h" - #include "nse_nmaplib.h" --#include "nse_pcrelib.h" - #include "nse_openssl.h" - #include "nse_debug.h" - #include "nse_lpeg.h" -@@ -562,7 +561,6 @@ static int panic (lua_State *L) - static void set_nmap_libraries (lua_State *L) - { - static const luaL_Reg libs[] = { -- {NSE_PCRELIBNAME, luaopen_pcrelib}, - {NSE_NMAPLIBNAME, luaopen_nmap}, - {NSE_DBLIBNAME, luaopen_db}, - {LFSLIBNAME, luaopen_lfs}, -diff --git a/nse_main.lua b/nse_main.lua -index 24c9d2a..596aba9 100644 ---- a/nse_main.lua -+++ b/nse_main.lua -@@ -292,7 +292,7 @@ local REQUIRE_ERROR = {}; - rawset(stdnse, "silent_require", function (...) - local status, mod = pcall(require, ...); - if not status then -- print_debug(1, "%s", traceback(mod)); -+ print_debug(2, "%s", traceback(mod)); - error(REQUIRE_ERROR) - else - return mod; -diff --git a/nselib/unittest.lua b/nselib/unittest.lua -index b22de05..aaf5fce 100644 ---- a/nselib/unittest.lua -+++ b/nselib/unittest.lua -@@ -107,7 +107,6 @@ local libs = { - "ospf", - "outlib", - "packet", --"pcre", - "pgsql", - "pop3", - "pppoe", diff --git a/backport-upgrade-libpcre-to-PCRE2-10.42.patch b/backport-upgrade-libpcre-to-PCRE2-10.42.patch deleted file mode 100644 index fb6aac245737014fd6bdbc5d78306887a0bc2a53..0000000000000000000000000000000000000000 --- a/backport-upgrade-libpcre-to-PCRE2-10.42.patch +++ /dev/null @@ -1,1335 +0,0 @@ -From 828ab48764b82d0226e860c73c5dac5b11f77385 Mon Sep 17 00:00:00 2001 -From: dmiller -Date: Sat, 24 Jun 2023 01:53:07 +0000 -Subject: [PATCH] Upgrade libpcre to PCRE2 10.42. Windows/macOS builds not - completed. - -Conflict: Remove pcre2 source code modification, which can be replaced by pcre2-devel dependency -Reference: https://github.com/nmap/nmap/commit/828ab48764b82d0226e860c73c5dac5b11f77385 ---- - checklibs.sh | 10 +- - configure | 92 +++------ - configure.ac | 23 +-- - nmap.cc | 6 +- - nmap_config.h.in | 2 - - nping/nping_config.h.in | 2 - - nse_pcrelib.cc | 400 ---------------------------------------- - nse_pcrelib.h | 9 - - nselib/pcre.luadoc | 135 -------------- - service_scan.cc | 180 ++++++++++-------- - service_scan.h | 33 ++-- - 11 files changed, 156 insertions(+), 736 deletions(-) - delete mode 100644 nse_pcrelib.cc - delete mode 100644 nse_pcrelib.h - delete mode 100644 nselib/pcre.luadoc - -diff --git a/checklibs.sh b/checklibs.sh -index 2048e2a..26e9d8a 100644 ---- a/checklibs.sh -+++ b/checklibs.sh -@@ -11,13 +11,13 @@ trim_version() { - } - - check_libpcre() { -- PCRE_SOURCE="https://sourceforge.net/projects/pcre/files/latest/download" -+ PCRE_SOURCE="https://github.com/PCRE2Project/pcre2/releases/latest" - PCRE_MAJOR="" - PCRE_MINOR="" -- eval $(grep '^PCRE_MAJOR=' $NDIR/libpcre/configure) -- eval $(grep '^PCRE_MINOR=' $NDIR/libpcre/configure) -- PCRE_VERSION="$PCRE_MAJOR.$PCRE_MINOR" -- PCRE_LATEST=$(curl -s -I $PCRE_SOURCE | perl -lne 'if(/pcre-(\d+.\d+).zip/){print $1}' | newest) -+ eval $(grep '^PCRE2_MAJOR=' $NDIR/libpcre/configure) -+ eval $(grep '^PCRE2_MINOR=' $NDIR/libpcre/configure) -+ PCRE_VERSION="$PCRE2_MAJOR.$PCRE2_MINOR" -+ PCRE_LATEST=$(curl -s -I $PCRE_SOURCE | tee tmp.txt | perl -lne 'if(m|^Location:.*/tag/pcre2-(\d+.\d+)[\r\n]*$|){print $1;exit(0)}') - if [ "$PCRE_VERSION" != "$PCRE_LATEST" ]; then - echo "Newer version of libpcre available" - echo " Current:" $PCRE_VERSION -diff --git a/configure b/configure -index d1d2f19..12764ee 100755 ---- a/configure -+++ b/configure -@@ -1451,8 +1451,8 @@ Optional Packages: - [DIR]/lib/ and [DIR]/include/openssl/) - --with-libpcap=DIR Look for pcap in DIR/include and DIR/libs. - --with-libpcap=included Always use version included with Nmap -- --with-libpcre=DIR Use an existing (compiled) pcre lib from DIR/include -- and DIR/lib. -+ --with-libpcre=DIR Use an existing (compiled) pcre2 lib from -+ DIR/include and DIR/lib. - --with-libpcre=included Always use the version included with Nmap - --with-libz=DIR Use specific copy of libz - --with-libz=included Always use version included with Nmap -@@ -6437,58 +6437,19 @@ fi - - # If they didn't specify it, we try to find it - if test $have_pcre != yes -a $requested_included_pcre != yes ; then -- ac_fn_c_check_header_mongrel "$LINENO" "pcre.h" "ac_cv_header_pcre_h" "$ac_includes_default" --if test "x$ac_cv_header_pcre_h" = xyes; then : -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pcre_version in -lpcre" >&5 --$as_echo_n "checking for pcre_version in -lpcre... " >&6; } --if ${ac_cv_lib_pcre_pcre_version+:} false; then : -- $as_echo_n "(cached) " >&6 --else -- ac_check_lib_save_LIBS=$LIBS --LIBS="-lpcre $LIBS" --cat confdefs.h - <<_ACEOF >conftest.$ac_ext --/* end confdefs.h. */ -+ ac_fn_c_check_header_compile "$LINENO" "pcre2.h" "ac_cv_header_pcre2_h" " -+#define PCRE2_CODE_UNIT_WIDTH 8 - --/* Override any GCC internal prototype to avoid an error. -- Use char because int might match the return type of a GCC -- builtin and then its argument prototype would still apply. */ --#ifdef __cplusplus --extern "C" --#endif --char pcre_version (); --int --main () --{ --return pcre_version (); -- ; -- return 0; --} --_ACEOF --if ac_fn_c_try_link "$LINENO"; then : -- ac_cv_lib_pcre_pcre_version=yes --else -- ac_cv_lib_pcre_pcre_version=no --fi --rm -f core conftest.err conftest.$ac_objext \ -- conftest$ac_exeext conftest.$ac_ext --LIBS=$ac_check_lib_save_LIBS --fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pcre_pcre_version" >&5 --$as_echo "$ac_cv_lib_pcre_pcre_version" >&6; } --if test "x$ac_cv_lib_pcre_pcre_version" = xyes; then : -- have_pcre=yes --fi - --else -- ac_fn_c_check_header_mongrel "$LINENO" "pcre/pcre.h" "ac_cv_header_pcre_pcre_h" "$ac_includes_default" --if test "x$ac_cv_header_pcre_pcre_h" = xyes; then : -- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pcre_version in -lpcre" >&5 --$as_echo_n "checking for pcre_version in -lpcre... " >&6; } --if ${ac_cv_lib_pcre_pcre_version+:} false; then : -+" -+if test "x$ac_cv_header_pcre2_h" = xyes; then : -+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pcre2_compile_8 in -lpcre2-8" >&5 -+$as_echo_n "checking for pcre2_compile_8 in -lpcre2-8... " >&6; } -+if ${ac_cv_lib_pcre2_8_pcre2_compile_8+:} false; then : - $as_echo_n "(cached) " >&6 - else - ac_check_lib_save_LIBS=$LIBS --LIBS="-lpcre $LIBS" -+LIBS="-lpcre2-8 $LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext - /* end confdefs.h. */ - -@@ -6498,35 +6459,30 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext - #ifdef __cplusplus - extern "C" - #endif --char pcre_version (); -+char pcre2_compile_8 (); - int - main () - { --return pcre_version (); -+return pcre2_compile_8 (); - ; - return 0; - } - _ACEOF - if ac_fn_c_try_link "$LINENO"; then : -- ac_cv_lib_pcre_pcre_version=yes -+ ac_cv_lib_pcre2_8_pcre2_compile_8=yes - else -- ac_cv_lib_pcre_pcre_version=no -+ ac_cv_lib_pcre2_8_pcre2_compile_8=no - fi - rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LIBS=$ac_check_lib_save_LIBS - fi --{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pcre_pcre_version" >&5 --$as_echo "$ac_cv_lib_pcre_pcre_version" >&6; } --if test "x$ac_cv_lib_pcre_pcre_version" = xyes; then : -+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pcre2_8_pcre2_compile_8" >&5 -+$as_echo "$ac_cv_lib_pcre2_8_pcre2_compile_8" >&6; } -+if test "x$ac_cv_lib_pcre2_8_pcre2_compile_8" = xyes; then : - have_pcre=yes - fi - -- --fi -- -- -- - fi - - -@@ -6536,8 +6492,8 @@ fi - if test $have_pcre != yes ; then - subdirs="$subdirs libpcre" - -- CPPFLAGS="-I\$(top_srcdir)/$LIBPCREDIR $CPPFLAGS" -- LIBPCRE_LIBS="$LIBPCREDIR/libpcre.a" -+ CPPFLAGS="-I\$(top_srcdir)/$LIBPCREDIR/src $CPPFLAGS" -+ LIBPCRE_LIBS="$LIBPCREDIR/.libs/libpcre2-8.a" - PCRE_BUILD="build-pcre" - PCRE_CLEAN="clean-pcre" - PCRE_DIST_CLEAN="distclean-pcre" -@@ -6546,19 +6502,19 @@ $as_echo "#define PCRE_INCLUDED 1" >>confdefs.h - - else - # We only need to check for and use this if we are NOT using included pcre -- for ac_header in pcre/pcre.h -+ for ac_header in pcre2.h - do : -- ac_fn_c_check_header_mongrel "$LINENO" "pcre/pcre.h" "ac_cv_header_pcre_pcre_h" "$ac_includes_default" --if test "x$ac_cv_header_pcre_pcre_h" = xyes; then : -+ ac_fn_c_check_header_mongrel "$LINENO" "pcre2.h" "ac_cv_header_pcre2_h" "$ac_includes_default" -+if test "x$ac_cv_header_pcre2_h" = xyes; then : - cat >>confdefs.h <<_ACEOF --#define HAVE_PCRE_PCRE_H 1 -+#define HAVE_PCRE2_H 1 - _ACEOF - - fi - - done - -- LIBPCRE_LIBS="-lpcre" -+ LIBPCRE_LIBS="-lpcre2-8" - PCRE_BUILD="" - PCRE_CLEAN="" - PCRE_DIST_CLEAN="" -diff --git a/configure.ac b/configure.ac -index 7835d9b..c25fb04 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -510,7 +510,7 @@ LIBPCREDIR=libpcre - - # First we test whether they specified libpcre explicitly - AC_ARG_WITH(libpcre, --AC_HELP_STRING([--with-libpcre=DIR], [Use an existing (compiled) pcre lib from DIR/include and DIR/lib.]) -+AC_HELP_STRING([--with-libpcre=DIR], [Use an existing (compiled) pcre2 lib from DIR/include and DIR/lib.]) - AC_HELP_STRING([--with-libpcre=included], [Always use the version included with Nmap]), - [ case "$with_libpcre" in - yes) -@@ -528,27 +528,28 @@ AC_HELP_STRING([--with-libpcre=included], [Always use the version included with - - # If they didn't specify it, we try to find it - if test $have_pcre != yes -a $requested_included_pcre != yes ; then -- AC_CHECK_HEADER(pcre.h, -- AC_CHECK_LIB(pcre, pcre_version, [have_pcre=yes ]), -- [AC_CHECK_HEADER(pcre/pcre.h, -- [AC_CHECK_LIB(pcre, pcre_version, [have_pcre=yes])] -- )] -+ AC_CHECK_HEADER(pcre2.h, -+ AC_CHECK_LIB(pcre2-8, pcre2_compile_8, [have_pcre=yes ]), -+ [], -+ [ -+#define PCRE2_CODE_UNIT_WIDTH 8 -+ ] - ) - fi - - # If we still don't have it, we use our own - if test $have_pcre != yes ; then - AC_CONFIG_SUBDIRS( libpcre ) -- CPPFLAGS="-I\$(top_srcdir)/$LIBPCREDIR $CPPFLAGS" -- LIBPCRE_LIBS="$LIBPCREDIR/libpcre.a" -+ CPPFLAGS="-I\$(top_srcdir)/$LIBPCREDIR/src $CPPFLAGS" -+ LIBPCRE_LIBS="$LIBPCREDIR/.libs/libpcre2-8.a" - PCRE_BUILD="build-pcre" - PCRE_CLEAN="clean-pcre" - PCRE_DIST_CLEAN="distclean-pcre" -- AC_DEFINE(PCRE_INCLUDED, 1, [Using included libpcre]) -+ AC_DEFINE(PCRE_INCLUDED, 1, [Using included libpcre2]) - else - # We only need to check for and use this if we are NOT using included pcre -- AC_CHECK_HEADERS(pcre/pcre.h) -- LIBPCRE_LIBS="-lpcre" -+ AC_CHECK_HEADERS(pcre2.h) -+ LIBPCRE_LIBS="-lpcre2-8" - PCRE_BUILD="" - PCRE_CLEAN="" - PCRE_DIST_CLEAN="" -diff --git a/nmap.cc b/nmap.cc -index e4c65e7..96f0230 100644 ---- a/nmap.cc -+++ b/nmap.cc -@@ -2803,10 +2803,12 @@ static void display_nmap_version() { - without.push_back("libz"); - #endif - -+ char pcre2_version[255]; -+ pcre2_config(PCRE2_CONFIG_VERSION, pcre2_version); - #ifdef PCRE_INCLUDED -- with.push_back(std::string("nmap-libpcre-") + get_word_or_quote(pcre_version(), 0)); -+ with.push_back(std::string("nmap-libpcre2-") + get_word_or_quote(pcre2_version, 0)); - #else -- with.push_back(std::string("libpcre-") + get_word_or_quote(pcre_version(), 0)); -+ with.push_back(std::string("libpcre2-") + get_word_or_quote(pcre2_version, 0)); - #endif - - #ifdef WIN32 -diff --git a/nmap_config.h.in b/nmap_config.h.in -index 67dbeda..1dae65a 100644 ---- a/nmap_config.h.in -+++ b/nmap_config.h.in -@@ -103,8 +103,6 @@ - - #undef HAVE_TERMIOS_H - --#undef HAVE_PCRE_PCRE_H -- - #undef BSD_NETWORKING - - #undef IN_ADDR_DEEPSTRUCT -diff --git a/nping/nping_config.h.in b/nping/nping_config.h.in -index 98638cb..9b6f971 100644 ---- a/nping/nping_config.h.in -+++ b/nping/nping_config.h.in -@@ -101,8 +101,6 @@ - - #undef HAVE_TERMIOS_H - --#undef HAVE_PCRE_PCRE_H -- - #undef BSD_NETWORKING - - #undef IN_ADDR_DEEPSTRUCT -diff --git a/nse_pcrelib.cc b/nse_pcrelib.cc -deleted file mode 100644 -index 436697e..0000000 ---- a/nse_pcrelib.cc -+++ /dev/null -@@ -1,400 +0,0 @@ --/* lrexlib.c - PCRE regular expression library */ --/* Reuben Thomas nov00-18dec04 */ --/* Shmuel Zeigerman may04-18dec04 */ -- -- --#include --#include --#include -- --#include "nse_lua.h" -- --#include -- --#include -- --#ifdef HAVE_PCRE_PCRE_H --# include --#else --# include --#endif -- --#include "nse_pcrelib.h" -- --static int get_startoffset(lua_State *L, int stackpos, size_t len) --{ -- int startoffset = luaL_optinteger(L, stackpos, 1); -- if(startoffset > 0) -- startoffset--; -- else if(startoffset < 0) { -- startoffset += (int) len; -- if(startoffset < 0) -- startoffset = 0; -- } -- return startoffset; --} -- --static int udata_tostring (lua_State *L, const char* type_handle, -- const char* type_name) --{ -- char buf[256]; -- void *udata = luaL_checkudata(L, 1, type_handle); -- -- if(udata) { -- (void)Snprintf(buf, 255, "%s (%p)", type_name, udata); -- lua_pushstring(L, buf); -- } -- else { -- (void)Snprintf(buf, 255, "must be userdata of type '%s'", type_name); -- (void)luaL_argerror(L, 1, buf); -- } -- -- free(udata); -- return 1; --} -- --typedef struct { const char* key; lua_Integer val; } flags_pair; -- --static int get_flags (lua_State *L, const flags_pair *arr) --{ -- const flags_pair *p; -- lua_newtable(L); -- for(p=arr; p->key != NULL; p++) { -- lua_pushstring(L, p->key); -- lua_pushinteger(L, p->val); -- lua_rawset(L, -3); -- } -- return 1; --} -- --const char pcre_handle[] = "pcre_regex_handle"; --const char pcre_typename[] = "pcre_regex"; -- --typedef struct { -- pcre *pr; -- pcre_extra *extra; -- int *match; -- int ncapt; -- const unsigned char *tables; --} pcre2; /* a better name is needed */ -- --static const unsigned char *Lpcre_maketables(lua_State *L, int stackpos) --{ -- const unsigned char *tables; -- char old_locale[256]; -- char *locale = strdup(luaL_checkstring(L, stackpos)); -- -- if(locale == NULL) -- luaL_error(L, "cannot set locale"); -- -- strncpy(old_locale, setlocale(LC_CTYPE, NULL), 255); /* store the locale */ -- -- if(setlocale(LC_CTYPE, locale) == NULL) /* set new locale */ -- luaL_error(L, "cannot set locale"); -- -- tables = pcre_maketables(); /* make tables with new locale */ -- (void)setlocale(LC_CTYPE, old_locale); /* restore the old locale */ -- -- free(locale); -- return tables; --} -- --static int Lpcre_comp(lua_State *L) --{ -- char buf[256]; -- const char *error; -- int erroffset; -- pcre2 *ud; -- const char *pattern = luaL_checkstring(L, 1); -- int cflags = luaL_optinteger(L, 2, 0); -- const unsigned char *tables = NULL; -- -- if(lua_gettop(L) > 2 && !lua_isnil(L, 3)) -- tables = Lpcre_maketables(L, 3); -- if(tables == NULL) -- luaL_error(L, "PCRE compilation failed"); -- -- ud = (pcre2*)lua_newuserdata(L, sizeof(pcre2)); -- luaL_getmetatable(L, pcre_handle); -- (void)lua_setmetatable(L, -2); -- ud->match = NULL; -- ud->extra = NULL; -- ud->tables = tables; /* keep this for eventual freeing */ -- -- ud->pr = pcre_compile(pattern, cflags, &error, &erroffset, tables); -- if(!ud->pr) { -- (void)Snprintf(buf, 255, "%s (pattern offset: %d)", error, erroffset+1); -- /* show offset 1-based as it's common in Lua */ -- luaL_error(L, buf); -- } -- -- ud->extra = pcre_study(ud->pr, 0, &error); -- if(error) luaL_error(L, error); -- -- pcre_fullinfo(ud->pr, ud->extra, PCRE_INFO_CAPTURECOUNT, &ud->ncapt); -- /* need (2 ints per capture, plus one for substring match) * 3/2 */ -- ud->match = (int *) safe_malloc((ud->ncapt + 1) * 3 * sizeof(int)); -- -- return 1; --} -- --static void Lpcre_getargs(lua_State *L, pcre2 **pud, const char **text, -- size_t *text_len) --{ -- *pud = (pcre2 *)luaL_checkudata(L, 1, pcre_handle); -- if(*pud == NULL) -- (void)luaL_argerror(L, 1, ("compiled regexp expected")); -- *text = luaL_checklstring(L, 2, text_len); --} -- --typedef void (*Lpcre_push_matches) (lua_State *L, const char *text, pcre2 *ud); -- --static void Lpcre_push_substrings (lua_State *L, const char *text, pcre2 *ud) --{ -- unsigned int i, j; -- unsigned int namecount; -- unsigned char *name_table; -- int name_entry_size; -- unsigned char *tabptr; -- const int *match = ud->match; -- -- lua_newtable(L); -- for (i = 1; i <= (unsigned) ud->ncapt; i++) { -- j = i * 2; -- if (match[j] >= 0) -- lua_pushlstring(L, text + match[j], (size_t)(match[j + 1] - match[j])); -- else -- lua_pushboolean(L, 0); -- lua_rawseti(L, -2, i); -- } -- -- /* now do named subpatterns - NJG */ -- (void)pcre_fullinfo(ud->pr, ud->extra, PCRE_INFO_NAMECOUNT, &namecount); -- if (namecount <= 0) -- return; -- (void)pcre_fullinfo(ud->pr, ud->extra, PCRE_INFO_NAMETABLE, &name_table); -- (void)pcre_fullinfo(ud->pr, ud->extra, PCRE_INFO_NAMEENTRYSIZE, &name_entry_size); -- tabptr = name_table; -- for (i = 0; i < namecount; i++) { -- unsigned int n = (tabptr[0] << 8) | tabptr[1]; /* number of the capturing parenthesis */ -- if (n > 0 && n <= (unsigned) ud->ncapt) { /* check range */ -- unsigned int j = n * 2; -- lua_pushstring(L, (char*)tabptr + 2); /* name of the capture, zero terminated */ -- if (match[j] >= 0) -- lua_pushlstring(L, text + match[j], match[j + 1] - match[j]); -- else -- lua_pushboolean(L, 0); -- lua_rawset(L, -3); -- } -- tabptr += name_entry_size; -- } --} -- --static void Lpcre_push_offsets (lua_State *L, const char *text, pcre2 * ud) --{ -- unsigned int i, j, k; -- if(text) { -- /* suppress compiler warning */ -- } -- lua_newtable(L); -- for (i=1, j=1; i <= (unsigned) ud->ncapt; i++) { -- k = i * 2; -- if (ud->match[k] >= 0) { -- lua_pushinteger(L, ud->match[k] + 1); -- lua_rawseti(L, -2, j++); -- lua_pushinteger(L, ud->match[k+1]); -- lua_rawseti(L, -2, j++); -- } -- else { -- lua_pushboolean(L, 0); -- lua_rawseti(L, -2, j++); -- lua_pushboolean(L, 0); -- lua_rawseti(L, -2, j++); -- } -- } --} -- --static int Lpcre_match_generic(lua_State *L, Lpcre_push_matches push_matches) --{ -- int res; -- const char *text; -- pcre2 *ud; -- size_t elen; -- int startoffset; -- int eflags = luaL_optinteger(L, 4, 0); -- -- Lpcre_getargs(L, &ud, &text, &elen); -- startoffset = get_startoffset(L, 3, elen); -- -- res = pcre_exec(ud->pr, ud->extra, text, (int)elen, startoffset, eflags, -- ud->match, (ud->ncapt + 1) * 3); -- if (res >= 0) { -- lua_pushinteger(L, (lua_Number) ud->match[0] + 1); -- lua_pushinteger(L, (lua_Number) ud->match[1]); -- (*push_matches)(L, text, ud); -- return 3; -- } -- return 0; --} -- --static int Lpcre_match(lua_State *L) --{ -- return Lpcre_match_generic(L, Lpcre_push_substrings); --} -- --static int Lpcre_exec(lua_State *L) --{ -- return Lpcre_match_generic(L, Lpcre_push_offsets); --} -- --static int Lpcre_gmatch(lua_State *L) --{ -- int res; -- size_t len; -- int nmatch = 0, limit = 0; -- const char *text; -- pcre2 *ud; -- int maxmatch = luaL_optinteger(L, 4, 0); -- int eflags = luaL_optinteger(L, 5, 0); -- int startoffset = 0; -- Lpcre_getargs(L, &ud, &text, &len); -- luaL_checktype(L, 3, LUA_TFUNCTION); -- -- if(maxmatch > 0) /* this must be stated in the docs */ -- limit = 1; -- -- while (!limit || nmatch < maxmatch) { -- res = pcre_exec(ud->pr, ud->extra, text, (int)len, startoffset, eflags, -- ud->match, (ud->ncapt + 1) * 3); -- if (res >= 0) { -- nmatch++; -- lua_pushvalue(L, 3); -- lua_pushlstring(L, text + ud->match[0], ud->match[1] - ud->match[0]); -- Lpcre_push_substrings(L, text, ud); -- lua_call(L, 2, 1); -- if(lua_toboolean(L, -1)) -- break; -- lua_pop(L, 1); -- startoffset = ud->match[1]; -- } else -- break; -- } -- lua_pushinteger(L, nmatch); -- return 1; --} -- --static int Lpcre_gc (lua_State *L) --{ -- pcre2 *ud = (pcre2 *)luaL_checkudata(L, 1, pcre_handle); -- if (ud) { -- if(ud->pr) pcre_free(ud->pr); -- if(ud->extra) pcre_free(ud->extra); -- if(ud->tables) pcre_free((void *)ud->tables); -- if(ud->match) free(ud->match); -- } -- return 0; --} -- --static int Lpcre_tostring (lua_State *L) { -- return udata_tostring(L, pcre_handle, pcre_typename); --} -- --static int Lpcre_vers (lua_State *L) --{ -- lua_pushstring(L, pcre_version()); -- return 1; --} -- --static flags_pair pcre_flags[] = --{ -- { "CASELESS", PCRE_CASELESS }, -- { "MULTILINE", PCRE_MULTILINE }, -- { "DOTALL", PCRE_DOTALL }, -- { "EXTENDED", PCRE_EXTENDED }, -- { "ANCHORED", PCRE_ANCHORED }, -- { "DOLLAR_ENDONLY", PCRE_DOLLAR_ENDONLY }, -- { "EXTRA", PCRE_EXTRA }, -- { "NOTBOL", PCRE_NOTBOL }, -- { "NOTEOL", PCRE_NOTEOL }, -- { "UNGREEDY", PCRE_UNGREEDY }, -- { "NOTEMPTY", PCRE_NOTEMPTY }, -- { "UTF8", PCRE_UTF8 }, --#if PCRE_MAJOR >= 4 -- { "NO_AUTO_CAPTURE", PCRE_NO_AUTO_CAPTURE }, -- { "NO_UTF8_CHECK", PCRE_NO_UTF8_CHECK }, --#endif --#ifdef PCRE_AUTO_CALLOUT -- { "AUTO_CALLOUT", PCRE_AUTO_CALLOUT }, --#endif --#ifdef PCRE_PARTIAL -- { "PARTIAL", PCRE_PARTIAL }, --#endif --#ifdef PCRE_DFA_SHORTEST -- { "DFA_SHORTEST", PCRE_DFA_SHORTEST }, --#endif --#ifdef PCRE_DFA_RESTART -- { "DFA_RESTART", PCRE_DFA_RESTART }, --#endif --#ifdef PCRE_FIRSTLINE -- { "FIRSTLINE", PCRE_FIRSTLINE }, --#endif --#ifdef PCRE_DUPNAMES -- { "DUPNAMES", PCRE_DUPNAMES }, --#endif --#ifdef PCRE_NEWLINE_CR -- { "NEWLINE_CR", PCRE_NEWLINE_CR }, --#endif --#ifdef PCRE_NEWLINE_LF -- { "NEWLINE_LF", PCRE_NEWLINE_LF }, --#endif --#ifdef PCRE_NEWLINE_CRLF -- { "NEWLINE_CRLF", PCRE_NEWLINE_CRLF }, --#endif --#ifdef PCRE_NEWLINE_ANY -- { "NEWLINE_ANY", PCRE_NEWLINE_ANY }, --#endif --#ifdef PCRE_NEWLINE_ANYCRLF -- { "NEWLINE_ANYCRLF", PCRE_NEWLINE_ANYCRLF }, --#endif --#ifdef PCRE_BSR_ANYCRLF -- { "BSR_ANYCRLF", PCRE_BSR_ANYCRLF }, --#endif --#ifdef PCRE_BSR_UNICODE -- { "BSR_UNICODE", PCRE_BSR_UNICODE }, --#endif -- { NULL, 0 } --}; -- --static int Lpcre_get_flags (lua_State *L) { -- return get_flags(L, pcre_flags); --} -- --static const luaL_Reg pcremeta[] = { -- {"exec", Lpcre_exec}, -- {"match", Lpcre_match}, -- {"gmatch", Lpcre_gmatch}, -- {"__gc", Lpcre_gc}, -- {"__tostring", Lpcre_tostring}, -- {NULL, NULL} --}; -- --/* Open the library */ --static const luaL_Reg pcrelib[] = { -- {"new", Lpcre_comp}, -- {"flags", Lpcre_get_flags}, -- {"version", Lpcre_vers}, -- {NULL, NULL} --}; -- --LUALIB_API int luaopen_pcrelib(lua_State *L) --{ -- luaL_newmetatable(L, pcre_handle); -- lua_pushliteral(L, "__index"); -- luaL_newlib(L, pcremeta); -- lua_rawset(L, -3); -- lua_pop(L, 1); -- -- luaL_newlib(L, pcrelib); -- -- return 1; --} -diff --git a/nse_pcrelib.h b/nse_pcrelib.h -deleted file mode 100644 -index 512d2a8..0000000 ---- a/nse_pcrelib.h -+++ /dev/null -@@ -1,9 +0,0 @@ --#ifndef NSE_PCRELIB --#define NSE_PCRELIB -- --#define NSE_PCRELIBNAME "pcre" -- --LUALIB_API int luaopen_pcrelib (lua_State *L); -- --#endif -- -diff --git a/nselib/pcre.luadoc b/nselib/pcre.luadoc -deleted file mode 100644 -index c442a96..0000000 ---- a/nselib/pcre.luadoc -+++ /dev/null -@@ -1,135 +0,0 @@ ----- ---- Perl Compatible Regular Expressions. ---- ---- One of Lua's quirks is its string patterns. While they have great performance ---- and are tightly integrated into the Lua interpreter, they are very different ---- in syntax and not as powerful as standard regular expressions. So we have ---- integrated Perl compatible regular expressions into Lua using PCRE and a ---- modified version of the Lua PCRE library written by Reuben Thomas and Shmuel ---- Zeigerman. These are the same sort of regular expressions used by Nmap ---- version detection. The main modification to their library is that the NSE ---- version only supports PCRE expressions instead of both PCRE and POSIX ---- patterns. In order to maintain a high script execution speed, the library ---- interfacing with PCRE is kept very thin. It is not integrated as seamlessly ---- as the Lua string pattern API. This allows script authors to decide when to ---- use PCRE expressions versus Lua patterns. The use of PCRE involves a ---- separate pattern compilation step, which saves execution time when patterns ---- are reused. Compiled patterns can be cached in the NSE registry and reused ---- by other scripts. ---- ---- The documentation for this module is derived from that supplied by the PCRE ---- Lua lib. ---- ---- Warning: PCRE has a history of security vulnerabilities allowing attackers ---- who are able to compile arbitrary regular expressions to execute arbitrary ---- code. More such vulnerabilities may be discovered in the future. These have ---- never affected Nmap because it doesn't give attackers any control over the ---- regular expressions it uses. Similarly, NSE scripts should never build ---- regular expressions with untrusted network input. Matching hardcoded regular ---- expressions against the untrusted input is fine. ---- @author Reuben Thomas ---- @author Shmuel Zeigerman -- --module "pcre" -- ----- Returns a compiled regular expression. ---- ---- The resulting compiled regular expression is ready to be matched against ---- strings. Compiled regular expressions are subject to Lua's garbage ---- collection. ---- ---- The compilation flags are set bitwise. If you want to set the 3rd ---- (corresponding to the number 4) and the 1st (corresponding to 1) bit for ---- example you would pass the number 5 as a second argument. The compilation ---- flags accepted are those of the PCRE C library. These include flags for case ---- insensitive matching (1), matching line beginnings ---- (^) and endings ($) even in multiline strings ---- (i.e. strings containing newlines) (2) and a flag for matching ---- across line boundaries (4). No compilation flags yield a ---- default value of 0. ---- @param pattern a string describing the pattern, such as "^foo$". ---- @param flags a number describing which compilation flags are set. ---- @param locale a string describing the locale which should be used to compile ---- the regular expression (optional). The value is a string which is passed to ---- the C standard library function setlocale. For more ---- information on this argument refer to the documentation of ---- setlocale. ---- @usage local regex = pcre.new("pcre-pattern",0,"C") --function new(pattern, flags, locale) -- ----- Returns a table of the available PCRE option flags (numbers) keyed by their ---- names (strings). ---- ---- Possible names of the available strings can be retrieved from the ---- documentation of the PCRE library used to link against Nmap. The key is the ---- option name in the manual minus the PCRE_ prefix. ---- PCRE_CASELESS becomes CASELESS for example. --function flags() -- ----- Returns the version of the PCRE library in use as a string. ---- ---- For example "6.4 05-Sep-2005". --function version() -- ----- Matches a string against a compiled regular expression. ---- ---- Returns the start point and the end point of the first match of the compiled ---- regular expression in the string. ---- @param string the string to match against. ---- @param start where to start the match in the string (optional). ---- @param flags execution flags (optional). ---- @return nil if no match, otherwise the start point of the first ---- match. ---- @return the end point of the first match. ---- @return a table which contains false in the positions where the pattern did ---- not match. If named sub-patterns were used, the table also contains substring ---- matches keyed by their sub-pattern name. ---- @usage ---- i, j = regex:match("string to be searched", 0, 0) ---- if (i) then ... end --function match(string, start, flags) -- ----- Matches a string against a compiled regular expression, returning positions ---- of substring matches. ---- ---- This function is like match except that a table returned as a ---- third result contains offsets of substring matches rather than substring ---- matches themselves. That table will not contain string keys, even if named ---- sub-patterns are used. For example, if the whole match is at offsets 10, 20 ---- and substring matches are at offsets 12, 14 and 16, 19 then the function ---- returns 10, 20, {12,14,16,19}. ---- @param string the string to match against. ---- @param start where to start the match in the string (optional). ---- @param flags execution flags (optional). ---- @return nil if no match, otherwise the start point of the match ---- of the whole string. ---- @return the end point of the match of the whole string. ---- @return a table containing a list of substring match start and end positions. ---- @usage ---- i, j, substrings = regex:exec("string to be searched", 0, 0) ---- if (i) then ... end --function exec(string, start, flags) -- ----- Matches a string against a regular expression multiple times. ---- ---- Tries to match the regular expression pcre_obj against string up to ---- n times (or as many as possible if n is not given ---- or is not a positive number), subject to the execution flags ---- ef. Each time there is a match, func is called as ---- func(m, t), where m is the matched string and ---- t is a table of substring matches. This table contains false in ---- the positions where the corresponding sub-pattern did not match. If named ---- sub-patterns are used then the table also contains substring matches keyed ---- by their correspondent sub-pattern names (strings). If func ---- returns a true value, then gmatch immediately returns; ---- gmatch returns the number of matches made. ---- @param string the string to match against. ---- @param func the function to call for each match. ---- @param n the maximum number of matches to do (optional). ---- @param ef execution flags (optional). ---- @return the number of matches made. ---- @usage ---- local t = {} ---- local function match(m) t[#t + 1] = m end ---- local n = regex:gmatch("string to be searched", match) --function pcre_obj:gmatch(string, func, n, ef) -diff --git a/service_scan.cc b/service_scan.cc -index cf13d8b..473b3a6 100644 ---- a/service_scan.cc -+++ b/service_scan.cc -@@ -250,7 +250,7 @@ ServiceProbeMatch::ServiceProbeMatch() { - product_template = version_template = info_template = NULL; - hostname_template = ostype_template = devicetype_template = NULL; - regex_compiled = NULL; -- regex_extra = NULL; -+ match_data = NULL; - isInitialized = false; - matchops_ignorecase = false; - matchops_dotall = false; -@@ -269,8 +269,21 @@ ServiceProbeMatch::~ServiceProbeMatch() { - if (devicetype_template) free(devicetype_template); - for (it = cpe_templates.begin(); it != cpe_templates.end(); it++) - free(*it); -- if (regex_compiled) pcre_free(regex_compiled); -- if (regex_extra) pcre_free(regex_extra); -+ if (regex_compiled) -+ { -+ pcre2_code_free(regex_compiled); -+ regex_compiled=NULL; -+ } -+ if (match_data) -+ { -+ pcre2_match_data_free(match_data); -+ match_data=NULL; -+ } -+ if (match_context) -+ { -+ pcre2_match_context_free(match_context); -+ match_context=NULL; -+ } - isInitialized = false; - } - -@@ -350,9 +363,9 @@ void ServiceProbeMatch::InitMatch(const char *matchtext, int lineno) { - char *tmptemplate; - char modestr[4]; - char flags[4]; -- int pcre_compile_ops = 0; -- const char *pcre_errptr = NULL; -- int pcre_erroffset = 0; -+ int pcre2_compile_ops = 0; -+ int pcre2_errcode; -+ PCRE2_SIZE pcre2_erroffset; - char **curr_tmp = NULL; - - if (isInitialized) fatal("Sorry ... %s does not yet support reinitializion", __func__); -@@ -405,41 +418,42 @@ void ServiceProbeMatch::InitMatch(const char *matchtext, int lineno) { - - // Next we compile and study the regular expression to match - if (matchops_ignorecase) -- pcre_compile_ops |= PCRE_CASELESS; -+ pcre2_compile_ops |= PCRE2_CASELESS; - - if (matchops_dotall) -- pcre_compile_ops |= PCRE_DOTALL; -+ pcre2_compile_ops |= PCRE2_DOTALL; - -- regex_compiled = pcre_compile(matchstr, pcre_compile_ops, &pcre_errptr, -- &pcre_erroffset, NULL); -+ regex_compiled = pcre2_compile((PCRE2_SPTR)matchstr,PCRE2_ZERO_TERMINATED, pcre2_compile_ops, &pcre2_errcode, -+ &pcre2_erroffset, NULL); - - if (regex_compiled == NULL) -- fatal("%s: illegal regexp on line %d of nmap-service-probes (at regexp offset %d): %s\n", __func__, lineno, pcre_erroffset, pcre_errptr); -+ fatal("%s: illegal regexp on line %d of nmap-service-probes (at regexp offset %ld): %d\n", __func__, lineno, pcre2_erroffset, pcre2_errcode); - -- // Now study the regexp for greater efficiency -- regex_extra = pcre_study(regex_compiled, 0 --#ifdef PCRE_STUDY_EXTRA_NEEDED -- | PCRE_STUDY_EXTRA_NEEDED --#endif -- , &pcre_errptr); -- if (pcre_errptr != NULL) -- fatal("%s: failed to pcre_study regexp on line %d of nmap-service-probes: %s\n", __func__, lineno, pcre_errptr); -+ // creates a new match data block for holding the result of a match -+ match_data = pcre2_match_data_create_from_pattern( -+ regex_compiled,NULL -+ ); - -- if (!regex_extra) { -- regex_extra = (pcre_extra *) pcre_malloc(sizeof(pcre_extra)); -- memset(regex_extra, 0, sizeof(pcre_extra)); -+ if (!match_data) { -+ fatal("%s: failed to allocate match_data\n", __func__); - } - -+ match_context = pcre2_match_context_create(NULL); -+ -+ if (!match_context) { -+ fatal("%s: failed to allocate match_context\n", __func__); -+ } - // Set some limits to avoid evil match cases. - // These are flexible; if they cause problems, increase them. --#ifdef PCRE_ERROR_MATCHLIMIT -- regex_extra->match_limit = 100000; // 100K --#endif --#ifdef PCRE_ERROR_RECURSIONLIMIT -- regex_extra->match_limit_recursion = 10000; // 10K -+ pcre2_set_match_limit(match_context, 100000); -+#ifdef pcre2_set_depth_limit -+ // Changed name in PCRE2 10.30. PCRE2 uses macro definitions for function -+ // names, so we don't have to add this to configure.ac. -+ pcre2_set_depth_limit(match_context, 10000); -+#else -+ pcre2_set_recursion_limit(match_context, 10000); - #endif - -- - /* OK! Now we look for any templates of the form ?/.../ - * where ? is either p, v, i, h, o, or d. / is any - * delimiter character and ... is a template */ -@@ -509,34 +523,29 @@ const struct MatchDetails *ServiceProbeMatch::testMatch(const u8 *buf, int bufle - static char devicetype[32]; - static char cpe_a[80], cpe_h[80], cpe_o[80]; - char *bufc = (char *) buf; -- int ovector[150]; // allows 50 substring matches (including the overall match) - assert(isInitialized); - - // Clear out the output struct - memset(&MD_return, 0, sizeof(MD_return)); - MD_return.isSoft = isSoft; - -- rc = pcre_exec(regex_compiled, regex_extra, bufc, buflen, 0, 0, ovector, sizeof(ovector) / sizeof(*ovector)); -+ rc = pcre2_match(regex_compiled, (PCRE2_SPTR8)bufc, buflen, 0, 0, match_data, match_context); - if (rc < 0) { --#ifdef PCRE_ERROR_MATCHLIMIT // earlier PCRE versions lack this -- if (rc == PCRE_ERROR_MATCHLIMIT) { -+ if (rc == PCRE2_ERROR_MATCHLIMIT) { - if (o.debugging || o.verbose > 1) - error("Warning: Hit PCRE_ERROR_MATCHLIMIT when probing for service %s with the regex '%s'", servicename, matchstr); - } else --#endif // PCRE_ERROR_MATCHLIMIT --#ifdef PCRE_ERROR_RECURSIONLIMIT -- if (rc == PCRE_ERROR_RECURSIONLIMIT) { -+ if (rc == PCRE2_ERROR_RECURSIONLIMIT) { - if (o.debugging || o.verbose > 1) - error("Warning: Hit PCRE_ERROR_RECURSIONLIMIT when probing for service %s with the regex '%s'", servicename, matchstr); - } else --#endif // PCRE_ERROR_RECURSIONLIMIT -- if (rc != PCRE_ERROR_NOMATCH) { -+ if (rc != PCRE2_ERROR_NOMATCH) { - fatal("Unexpected PCRE error (%d) when probing for service %s with the regex '%s'", rc, servicename, matchstr); - } - } else { - // Yeah! Match apparently succeeded. - // Now lets get the version number if available -- getVersionStr(buf, buflen, ovector, rc, product, sizeof(product), version, sizeof(version), info, sizeof(info), -+ getVersionStr(buf, buflen, product, sizeof(product), version, sizeof(version), info, sizeof(info), - hostname, sizeof(hostname), ostype, sizeof(ostype), devicetype, sizeof(devicetype), - cpe_a, sizeof(cpe_a), cpe_h, sizeof(cpe_h), cpe_o, sizeof(cpe_o)); - if (*product) MD_return.product = product; -@@ -685,18 +694,17 @@ static char *transform_cpe(const char *s) { - // This function does the substitution of a placeholder like $2 or $P(4). It - // returns a newly allocated string, or NULL if it fails. tmplvar is a template - // variable, such as "$P(2)". We set *tmplvarend to the character after the --// variable. subject, subjectlen, ovector, and nummatches mean the same as in -+// variable. subject, subjectlen, and match_data mean the same as in - // dotmplsubst(). - static char *substvar(char *tmplvar, char **tmplvarend, -- const u8 *subject, int subjectlen, int *ovector, -- int nummatches) { -+ const u8 *subject, size_t subjectlen, pcre2_match_data *match_data -+ ) { - char substcommand[16]; - char *p = NULL; - char *p_end; -- int subnum = 0; -- int offstart, offend; -+ u8 subnum = 0; -+ PCRE2_SIZE offstart, offend; - int rc; -- int i; - struct substargs command_args; - char *result; - size_t n, len; -@@ -728,6 +736,8 @@ static char *substvar(char *tmplvar, char **tmplvarend, - } - - if (tmplvarend) *tmplvarend = tmplvar; -+ u32 nummatches = pcre2_get_ovector_count(match_data); -+ PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data); - - strbuf_init(&result, &n, &len); - if (!*substcommand) { -@@ -735,9 +745,10 @@ static char *substvar(char *tmplvar, char **tmplvarend, - if (subnum > 9 || subnum <= 0) return NULL; - if (subnum >= nummatches) return NULL; - offstart = ovector[subnum * 2]; -+ if (offstart == PCRE2_UNSET) return NULL; - offend = ovector[subnum * 2 + 1]; -- assert(offstart >= 0 && offstart <= subjectlen); -- assert(offend >= 0 && offend <= subjectlen); -+ assert(offstart <= subjectlen); -+ assert(offend != PCRE2_UNSET && offend <= subjectlen); - // A plain-jane copy - strbuf_append(&result, &n, &len, (const char *) subject + offstart, offend - offstart); - } else if (strcmp(substcommand, "P") == 0) { -@@ -749,13 +760,14 @@ static char *substvar(char *tmplvar, char **tmplvarend, - if (subnum > 9 || subnum <= 0) return NULL; - if (subnum >= nummatches) return NULL; - offstart = ovector[subnum * 2]; -+ if (offstart == PCRE2_UNSET) return NULL; - offend = ovector[subnum * 2 + 1]; -- assert(offstart >= 0 && offstart <= subjectlen); -- assert(offend >= 0 && offend <= subjectlen); -+ assert(offstart <= subjectlen); -+ assert(offend != PCRE2_UNSET && offend <= subjectlen); - // This filter only includes printable characters. It is particularly - // useful for collapsing unicode text that looks like - // "W\0O\0R\0K\0G\0R\0O\0U\0P\0" -- for(i=offstart; i < offend; i++) { -+ for(PCRE2_SIZE i=offstart; i < offend; i++) { - if (isprint((int) subject[i])) - strbuf_append(&result, &n, &len, (const char *) subject + i, 1); - } -@@ -772,14 +784,15 @@ static char *substvar(char *tmplvar, char **tmplvarend, - if (subnum > 9 || subnum <= 0) return NULL; - if (subnum >= nummatches) return NULL; - offstart = ovector[subnum * 2]; -+ if (offstart == PCRE2_UNSET) return NULL; - offend = ovector[subnum * 2 + 1]; -- assert(offstart >= 0 && offstart <= subjectlen); -- assert(offend >= 0 && offend <= subjectlen); -+ assert(offstart <= subjectlen); -+ assert(offend != PCRE2_UNSET && offend <= subjectlen); - findstr = command_args.str_args[1]; - findstrlen = command_args.str_args_len[1]; - replstr = command_args.str_args[2]; - replstrlen = command_args.str_args_len[2]; -- for(i=offstart; i < offend; ) { -+ for(PCRE2_SIZE i=offstart; i < offend; ) { - if (memcmp(subject + i, findstr, findstrlen) != 0) { - strbuf_append(&result, &n, &len, (const char *) subject + i, 1); // no match - i++; -@@ -805,8 +818,9 @@ static char *substvar(char *tmplvar, char **tmplvarend, - if (subnum > 9 || subnum <= 0) return NULL; - if (subnum >= nummatches) return NULL; - offstart = ovector[subnum * 2]; -+ if (offstart == PCRE2_UNSET) return NULL; - offend = ovector[subnum * 2 + 1]; -- assert(offstart >= 0 && offstart <= subjectlen); -+ assert(offend != PCRE2_UNSET && offstart <= subjectlen); - - // overflow - if (offend - offstart > 8) { -@@ -824,11 +838,11 @@ static char *substvar(char *tmplvar, char **tmplvarend, - break; - } - if (bigendian) { -- for(i=offstart; i < offend; i++) { -+ for(PCRE2_SIZE i=offstart; i < offend; i++) { - val = (val<<8) + subject[i]; - } - } else { -- for(i=offend - 1; i > offstart - 1; i--) { -+ for(PCRE2_SIZE i=offend - 1; i > offstart - 1; i--) { - val = (val<<8) + subject[i]; - } - } -@@ -847,16 +861,16 @@ static char *substvar(char *tmplvar, char **tmplvarend, - - // This function takes a template string (tmpl) which can have - // placeholders in it such as $1 for substring matches in a regexp --// that was run against subject, and subjectlen, with the 'nummatches' --// matches in ovector. The NUL-terminated newly composted string is -+// that was run against subject, and subjectlen, with the -+// matches in match_data. The NUL-terminated newly composted string is - // placed into 'newstr', as long as it doesn't exceed 'newstrlen' - // bytes. Trailing whitespace and commas are removed. Returns zero for success - // - // The transform argument is a function pointer. If not NULL, the given - // function is applied to all substitutions before they are inserted - // into the result string. --static int dotmplsubst(const u8 *subject, int subjectlen, -- int *ovector, int nummatches, char *tmpl, char *newstr, -+static int dotmplsubst(const u8 *subject, size_t subjectlen, -+ pcre2_match_data *match_data, char *tmpl, char *newstr, - int newstrlen, - char *(*transform)(const char *) = NULL) { - int newlen; -@@ -895,7 +909,7 @@ static int dotmplsubst(const u8 *subject, int subjectlen, - dst += newlen; - } - srcstart = srcend; -- subst = substvar(srcstart, &srcend, subject, subjectlen, ovector, nummatches); -+ subst = substvar(srcstart, &srcend, subject, subjectlen, match_data); - if (subst == NULL) - return -1; - /* Apply transformation if requested. */ -@@ -937,14 +951,14 @@ static int dotmplsubst(const u8 *subject, int subjectlen, - // for a string, that string will have zero length after the function - // call (assuming the corresponding length passed in is at least 1) - --int ServiceProbeMatch::getVersionStr(const u8 *subject, int subjectlen, -- int *ovector, int nummatches, char *product, int productlen, -- char *version, int versionlen, char *info, int infolen, -- char *hostname, int hostnamelen, char *ostype, int ostypelen, -- char *devicetype, int devicetypelen, -- char *cpe_a, int cpe_alen, -- char *cpe_h, int cpe_hlen, -- char *cpe_o, int cpe_olen) const { -+int ServiceProbeMatch::getVersionStr(const u8 *subject, size_t subjectlen, -+ char *product, size_t productlen, -+ char *version, size_t versionlen, char *info, size_t infolen, -+ char *hostname, size_t hostnamelen, char *ostype, size_t ostypelen, -+ char *devicetype, size_t devicetypelen, -+ char *cpe_a, size_t cpe_alen, -+ char *cpe_h, size_t cpe_hlen, -+ char *cpe_o, size_t cpe_olen) const { - - int rc; - assert(productlen >= 0 && versionlen >= 0 && infolen >= 0 && -@@ -963,9 +977,9 @@ int ServiceProbeMatch::getVersionStr(const u8 *subject, int subjectlen, - - // Now lets get this started! We begin with the product name - if (product_template) { -- rc = dotmplsubst(subject, subjectlen, ovector, nummatches, product_template, product, productlen); -+ rc = dotmplsubst(subject, subjectlen, match_data, product_template, product, productlen); - if (rc != 0) { -- error("Warning: Servicescan failed to fill product_template (subjectlen: %d, productlen: %d). Capture exceeds length? Match string was line %d: p/%s/%s/%s", subjectlen, productlen, deflineno, -+ error("Warning: Servicescan failed to fill product_template (subjectlen: %lu, productlen: %lu). Capture exceeds length? Match string was line %d: p/%s/%s/%s", subjectlen, productlen, deflineno, - (product_template)? product_template : "", - (version_template)? version_template : "", - (info_template)? info_template : ""); -@@ -975,9 +989,9 @@ int ServiceProbeMatch::getVersionStr(const u8 *subject, int subjectlen, - } - - if (version_template) { -- rc = dotmplsubst(subject, subjectlen, ovector, nummatches, version_template, version, versionlen); -+ rc = dotmplsubst(subject, subjectlen, match_data, version_template, version, versionlen); - if (rc != 0) { -- error("Warning: Servicescan failed to fill version_template (subjectlen: %d, versionlen: %d). Capture exceeds length? Match string was line %d: v/%s/%s/%s", subjectlen, versionlen, deflineno, -+ error("Warning: Servicescan failed to fill version_template (subjectlen: %lu, versionlen: %lu). Capture exceeds length? Match string was line %d: v/%s/%s/%s", subjectlen, versionlen, deflineno, - (product_template)? product_template : "", - (version_template)? version_template : "", - (info_template)? info_template : ""); -@@ -987,9 +1001,9 @@ int ServiceProbeMatch::getVersionStr(const u8 *subject, int subjectlen, - } - - if (info_template) { -- rc = dotmplsubst(subject, subjectlen, ovector, nummatches, info_template, info, infolen); -+ rc = dotmplsubst(subject, subjectlen, match_data, info_template, info, infolen); - if (rc != 0) { -- error("Warning: Servicescan failed to fill info_template (subjectlen: %d, infolen: %d). Capture exceeds length? Match string was line %d: i/%s/%s/%s", subjectlen, infolen, deflineno, -+ error("Warning: Servicescan failed to fill info_template (subjectlen: %lu, infolen: %lu). Capture exceeds length? Match string was line %d: i/%s/%s/%s", subjectlen, infolen, deflineno, - (product_template)? product_template : "", - (version_template)? version_template : "", - (info_template)? info_template : ""); -@@ -999,9 +1013,9 @@ int ServiceProbeMatch::getVersionStr(const u8 *subject, int subjectlen, - } - - if (hostname_template) { -- rc = dotmplsubst(subject, subjectlen, ovector, nummatches, hostname_template, hostname, hostnamelen); -+ rc = dotmplsubst(subject, subjectlen, match_data, hostname_template, hostname, hostnamelen); - if (rc != 0) { -- error("Warning: Servicescan failed to fill hostname_template (subjectlen: %d, hostnamelen: %d). Capture exceeds length? Match string was line %d: h/%s/", subjectlen, hostnamelen, deflineno, -+ error("Warning: Servicescan failed to fill hostname_template (subjectlen: %lu, hostnamelen: %lu). Capture exceeds length? Match string was line %d: h/%s/", subjectlen, hostnamelen, deflineno, - (hostname_template)? hostname_template : ""); - if (hostnamelen > 0) *hostname = '\0'; - retval = -1; -@@ -1009,9 +1023,9 @@ int ServiceProbeMatch::getVersionStr(const u8 *subject, int subjectlen, - } - - if (ostype_template) { -- rc = dotmplsubst(subject, subjectlen, ovector, nummatches, ostype_template, ostype, ostypelen); -+ rc = dotmplsubst(subject, subjectlen, match_data, ostype_template, ostype, ostypelen); - if (rc != 0) { -- error("Warning: Servicescan failed to fill ostype_template (subjectlen: %d, ostypelen: %d). Capture exceeds length? Match string was line %d: o/%s/", subjectlen, ostypelen, deflineno, -+ error("Warning: Servicescan failed to fill ostype_template (subjectlen: %lu, ostypelen: %lu). Capture exceeds length? Match string was line %d: o/%s/", subjectlen, ostypelen, deflineno, - (ostype_template)? ostype_template : ""); - if (ostypelen > 0) *ostype = '\0'; - retval = -1; -@@ -1019,9 +1033,9 @@ int ServiceProbeMatch::getVersionStr(const u8 *subject, int subjectlen, - } - - if (devicetype_template) { -- rc = dotmplsubst(subject, subjectlen, ovector, nummatches, devicetype_template, devicetype, devicetypelen); -+ rc = dotmplsubst(subject, subjectlen, match_data, devicetype_template, devicetype, devicetypelen); - if (rc != 0) { -- error("Warning: Servicescan failed to fill devicetype_template (subjectlen: %d, devicetypelen: %d). Too long? Match string was line %d: d/%s/", subjectlen, devicetypelen, deflineno, -+ error("Warning: Servicescan failed to fill devicetype_template (subjectlen: %lu, devicetypelen: %lu). Too long? Match string was line %d: d/%s/", subjectlen, devicetypelen, deflineno, - (devicetype_template)? devicetype_template : ""); - if (devicetypelen > 0) *devicetype = '\0'; - retval = -1; -@@ -1032,7 +1046,7 @@ int ServiceProbeMatch::getVersionStr(const u8 *subject, int subjectlen, - store in cpe_a, cpe_h, or cpe_o as appropriate. */ - for (unsigned int i = 0; i < cpe_templates.size(); i++) { - char *cpe; -- int cpelen; -+ size_t cpelen; - int part; - - part = cpe_get_part(cpe_templates[i]); -@@ -1055,9 +1069,9 @@ int ServiceProbeMatch::getVersionStr(const u8 *subject, int subjectlen, - continue; - break; - } -- rc = dotmplsubst(subject, subjectlen, ovector, nummatches, cpe_templates[i], cpe, cpelen, transform_cpe); -+ rc = dotmplsubst(subject, subjectlen, match_data, cpe_templates[i], cpe, cpelen, transform_cpe); - if (rc != 0) { -- error("Warning: Servicescan failed to fill cpe_%c (subjectlen: %d, cpelen: %d). Too long? Match string was line %d: %s", part, subjectlen, cpelen, deflineno, -+ error("Warning: Servicescan failed to fill cpe_%c (subjectlen: %lu, cpelen: %lu). Too long? Match string was line %d: %s", part, subjectlen, cpelen, deflineno, - (cpe_templates[i])? cpe_templates[i] : ""); - if (cpelen > 0) *cpe = '\0'; - retval = -1; -diff --git a/service_scan.h b/service_scan.h -index 7723d81..8ebdee7 100644 ---- a/service_scan.h -+++ b/service_scan.h -@@ -69,16 +69,8 @@ - - #include - --#ifdef HAVE_CONFIG_H --/* Needed for HAVE_PCRE_PCRE_H below */ --#include "nmap_config.h" --#endif /* HAVE_CONFIG_H */ -- --#ifdef HAVE_PCRE_PCRE_H --# include --#else --# include --#endif -+#define PCRE2_CODE_UNIT_WIDTH 8 -+#include - - #undef NDEBUG - #include -@@ -155,8 +147,9 @@ class ServiceProbeMatch { - bool isInitialized; // Has InitMatch yet been called? - const char *servicename; - char *matchstr; // Regular expression text -- pcre *regex_compiled; -- pcre_extra *regex_extra; -+ pcre2_code *regex_compiled; -+ pcre2_match_data *match_data; -+ pcre2_match_context *match_context; - bool matchops_ignorecase; - bool matchops_dotall; - bool isSoft; // is this a soft match? ("softmatch" keyword in nmap-service-probes) -@@ -179,14 +172,14 @@ class ServiceProbeMatch { - // are sufficient). Returns zero for success. If no template is available - // for a string, that string will have zero length after the function - // call (assuming the corresponding length passed in is at least 1) -- int getVersionStr(const u8 *subject, int subjectlen, int *ovector, -- int nummatches, char *product, int productlen, -- char *version, int versionlen, char *info, int infolen, -- char *hostname, int hostnamelen, char *ostype, int ostypelen, -- char *devicetype, int devicetypelen, -- char *cpe_a, int cpe_alen, -- char *cpe_h, int cpe_hlen, -- char *cpe_o, int cpe_olen) const; -+ int getVersionStr(const u8 *subject, size_t subjectlen, -+ char *product, size_t productlen, -+ char *version, size_t versionlen, char *info, size_t infolen, -+ char *hostname, size_t hostnamelen, char *ostype, size_t ostypelen, -+ char *devicetype, size_t devicetypelen, -+ char *cpe_a, size_t cpe_alen, -+ char *cpe_h, size_t cpe_hlen, -+ char *cpe_o, size_t cpe_olen) const; - }; - - diff --git a/nmap-7.94.tar.bz2 b/nmap-7.95.tar.bz2 similarity index 56% rename from nmap-7.94.tar.bz2 rename to nmap-7.95.tar.bz2 index 1ceb39c686520d04c496c8312c3528eda5c3353e..c4ea2d0665c942315cf6d4b446e03da48d797084 100644 Binary files a/nmap-7.94.tar.bz2 and b/nmap-7.95.tar.bz2 differ diff --git a/nmap.spec b/nmap.spec index e65ac8d0202f47fc84b1051a0f26264a495139c1..01609db10f11d887894b0443affa3c6bbc0313a2 100644 --- a/nmap.spec +++ b/nmap.spec @@ -2,8 +2,8 @@ Name: nmap Epoch: 2 -Version: 7.94 -Release: 6 +Version: 7.95 +Release: 1 License: GPL-2.0-or-later Summary: A tool for network discovery and security auditing. Requires: %{name}-ncat = %{epoch}:%{version}-%{release} @@ -19,11 +19,8 @@ Provides: nmap-frontend nmap-ndiff nmap-ncat nc nc6 Patch0001: backport-nmap-4.03-mktemp.patch Patch0002: backport-nmap_resolve_config.patch Patch0003: nmap-replace-sensitive-words.patch -Patch0004: backport-upgrade-libpcre-to-PCRE2-10.42.patch -Patch0005: backport-remove-nse_pcrelib-from-build.patch -Patch0006: backport-nping-fix-out-of-bounds-access.patch -Patch0007: backport-Ncat-server-UDP-do-not-quit-after-EOF-on-STDIN.-Fixe.patch -Patch0008: remove-password-printing.patch +Patch0004: backport-nping-fix-out-of-bounds-access.patch +Patch0005: remove-password-printing.patch %define pixmap_srcdir zenmap/share/pixmaps @@ -74,6 +71,12 @@ ln -s ncat %{buildroot}%{_bindir}/nc %{_mandir}/man1/*.1.gz %changelog +* Fri Jul 05 2024 liweigang - 2:7.95-1 +- Type: requirement +- ID: NA +- SUG: NA +- DESC: update nmap to 7.95 + * Fri Jun 14 2024 xinghe - 2:7.94-6 - Type:bugfix - CVE:NA