1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 04:31:29 +00:00

Copy nping, nsock, nbase, zenmap, ncat from their homes in /.

If you have trouble updating after this revision you need to follow
these instructions. You have probably just seen an error like this:

svn: URL 'svn://svn.insecure.org/nping' of existing directory 'nping'
does not match expected URL 'svn://svn.insecure.org/nmap/nping'

This is caused by the replacement of SVN externals.

Here's what you need to do. First, save any local changes you might have
in the nping, nsock, nbase, ncat, and zenmap directories. (For example
by running "cd nping; svn diff > ../nping.diff".) If you don't have any
local changes you can skip this step.

Then run these commands:

rm -rf nping/ nsock/ nbase/ ncat/ zenmap/
svn update
svn cleanup

If all else fails, you can just delete your whole working directory and
check out anew:

svn co --username guest --password "" svn://svn.insecure.org/nmap

There may be further discussion in the mailing list thread at
http://seclists.org/nmap-dev/2011/q4/303.
This commit is contained in:
david
2011-11-16 21:49:44 +00:00
parent 4dabecf3b8
commit ed2ba4e168
619 changed files with 351133 additions and 0 deletions

5
nbase/CHANGELOG Normal file
View File

@@ -0,0 +1,5 @@
-- Added snprintf.c, inet_aton.c, inet_pton.c, and inet_ntop.c from
tcpdump-2000.09.17 ( www.tcpdump.org)
-- Nbase library initially created (9/17/00)

64
nbase/Makefile.in Normal file
View File

@@ -0,0 +1,64 @@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
mandir = @mandir@
srcdir = @srcdir@
CC = @CC@
AR = ar
RANLIB = @RANLIB@
CCOPT =
DEFS = @DEFS@
# With GCC, add extra security checks to source code.
DEFS += -D_FORTIFY_SOURCE=2
CPPFLAGS = @CPPFLAGS@
CFLAGS = @CFLAGS@ $(CCOPT) $(GLIB_CFLAGS) $(DEFS) $(INCLS)
STATIC =
LDFLAGS = @LDFLAGS@ $(STATIC)
LIBS = @LIBS@
SHTOOL = ./shtool
INSTALL = $(SHTOOL) install
MAKEDEPEND = @MAKEDEPEND@
TARGET = libnbase.a
DEPS = getopt.h nbase.h nbase_winconfig.h nbase_config.h nbase_ipv6.h nbase_winunix.h nbase_crc32ct.h nbase_addrset.h
OBJS = @LIBOBJS@
all: $(TARGET)
$(TARGET): $(DEPS) $(OBJS)
rm -f $@
$(AR) cr $@ $(OBJS)
$(RANLIB) $@
clean:
rm -f $(OBJS) $(TARGET)
distclean: clean
rm -f Makefile config.cache config.log config.status nbase_config.h
depend:
$(MAKEDEPEND) $(INCLS) -s "# DO NOT DELETE" -- $(DEFS) -- $(SRCS)
configure: configure.ac
autoconf
Makefile: Makefile.in config.status
./config.status
config.status: configure
./config.status --recheck
.cc.o:
$(CC) -c $(CFLAGS) $*.cc
# DO NOT DELETE -- Needed by makedepend

301
nbase/aclocal.m4 vendored Normal file
View File

@@ -0,0 +1,301 @@
dnl aclocal.m4 generated automatically by aclocal 1.4
dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl This program is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
dnl PARTICULAR PURPOSE.
# Do all the work for Automake. This macro actually does too much --
# some checks are only needed if your package does certain things.
# But this isn't really a big deal.
# serial 1
dnl Usage:
dnl AM_INIT_AUTOMAKE(package,version, [no-define])
AC_DEFUN(AM_INIT_AUTOMAKE,
[AC_REQUIRE([AC_PROG_INSTALL])
PACKAGE=[$1]
AC_SUBST(PACKAGE)
VERSION=[$2]
AC_SUBST(VERSION)
dnl test to see if srcdir already configured
if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
fi
ifelse([$3],,
AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
AC_REQUIRE([AM_SANITY_CHECK])
AC_REQUIRE([AC_ARG_PROGRAM])
dnl FIXME This is truly gross.
missing_dir=`cd $ac_aux_dir && pwd`
AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
AC_REQUIRE([AC_PROG_MAKE_SET])])
#
# Check to make sure that the build environment is sane.
#
AC_DEFUN(AM_SANITY_CHECK,
[AC_MSG_CHECKING([whether build environment is sane])
# Just in case
sleep 1
echo timestamp > conftestfile
# Do `set' in a subshell so we don't clobber the current shell's
# arguments. Must try -L first in case configure is actually a
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
if (
set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
if test "[$]*" = "X"; then
# -L didn't work.
set X `ls -t $srcdir/configure conftestfile`
fi
if test "[$]*" != "X $srcdir/configure conftestfile" \
&& test "[$]*" != "X conftestfile $srcdir/configure"; then
# If neither matched, then we have a broken ls. This can happen
# if, for instance, CONFIG_SHELL is bash and it inherits a
# broken ls alias from the environment. This has actually
# happened. Such a system could not be considered "sane".
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
alias in your environment])
fi
test "[$]2" = conftestfile
)
then
# Ok.
:
else
AC_MSG_ERROR([newly created file is older than distributed files!
Check your system clock])
fi
rm -f conftest*
AC_MSG_RESULT(yes)])
dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
dnl The program must properly implement --version.
AC_DEFUN(AM_MISSING_PROG,
[AC_MSG_CHECKING(for working $2)
# Run test in a subshell; some versions of sh will print an error if
# an executable is not found, even if stderr is redirected.
# Redirect stdin to placate older versions of autoconf. Sigh.
if ($2 --version) < /dev/null > /dev/null 2>&1; then
$1=$2
AC_MSG_RESULT(found)
else
$1="$3/missing $2"
AC_MSG_RESULT(missing)
fi
AC_SUBST($1)])
# Configure paths for GLIB
# Owen Taylor 97-11-3
dnl AM_PATH_GLIB([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, MODULES]]]])
dnl Test for GLIB, and define GLIB_CFLAGS and GLIB_LIBS, if "gmodule" or
dnl gthread is specified in MODULES, pass to glib-config
dnl
AC_DEFUN(AM_PATH_GLIB,
[dnl
dnl Get the cflags and libraries from the glib-config script
dnl
AC_ARG_WITH(glib-prefix,[ --with-glib-prefix=PFX Prefix where GLIB is installed (optional)],
glib_config_prefix="$withval", glib_config_prefix="")
AC_ARG_WITH(glib-exec-prefix,[ --with-glib-exec-prefix=PFX Exec prefix where GLIB is installed (optional)],
glib_config_exec_prefix="$withval", glib_config_exec_prefix="")
AC_ARG_ENABLE(glibtest, [ --disable-glibtest Do not try to compile and run a test GLIB program],
, enable_glibtest=yes)
if test x$glib_config_exec_prefix != x ; then
glib_config_args="$glib_config_args --exec-prefix=$glib_config_exec_prefix"
if test x${GLIB_CONFIG+set} != xset ; then
GLIB_CONFIG=$glib_config_exec_prefix/bin/glib-config
fi
fi
if test x$glib_config_prefix != x ; then
glib_config_args="$glib_config_args --prefix=$glib_config_prefix"
if test x${GLIB_CONFIG+set} != xset ; then
GLIB_CONFIG=$glib_config_prefix/bin/glib-config
fi
fi
for module in . $4
do
case "$module" in
gmodule)
glib_config_args="$glib_config_args gmodule"
;;
gthread)
glib_config_args="$glib_config_args gthread"
;;
esac
done
AC_PATH_PROG(GLIB_CONFIG, glib-config, no)
min_glib_version=ifelse([$1], ,0.99.7,$1)
AC_MSG_CHECKING(for GLIB - version >= $min_glib_version)
no_glib=""
if test "$GLIB_CONFIG" = "no" ; then
no_glib=yes
else
GLIB_CFLAGS=`$GLIB_CONFIG $glib_config_args --cflags`
GLIB_LIBS=`$GLIB_CONFIG $glib_config_args --libs`
glib_config_major_version=`$GLIB_CONFIG $glib_config_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
glib_config_minor_version=`$GLIB_CONFIG $glib_config_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
glib_config_micro_version=`$GLIB_CONFIG $glib_config_args --version | \
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
if test "x$enable_glibtest" = "xyes" ; then
ac_save_CFLAGS="$CFLAGS"
ac_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $GLIB_CFLAGS"
LIBS="$GLIB_LIBS $LIBS"
dnl
dnl Now check if the installed GLIB is sufficiently new. (Also sanity
dnl checks the results of glib-config to some extent
dnl
rm -f conf.glibtest
AC_TRY_RUN([
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
int
main ()
{
int major, minor, micro;
char *tmp_version;
system ("touch conf.glibtest");
/* HP/UX 9 (%@#!) writes to sscanf strings */
tmp_version = g_strdup("$min_glib_version");
if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &micro) != 3) {
printf("%s, bad version string\n", "$min_glib_version");
exit(1);
}
if ((glib_major_version != $glib_config_major_version) ||
(glib_minor_version != $glib_config_minor_version) ||
(glib_micro_version != $glib_config_micro_version))
{
printf("\n*** 'glib-config --version' returned %d.%d.%d, but GLIB (%d.%d.%d)\n",
$glib_config_major_version, $glib_config_minor_version, $glib_config_micro_version,
glib_major_version, glib_minor_version, glib_micro_version);
printf ("*** was found! If glib-config was correct, then it is best\n");
printf ("*** to remove the old version of GLIB. You may also be able to fix the error\n");
printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n");
printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n");
printf("*** required on your system.\n");
printf("*** If glib-config was wrong, set the environment variable GLIB_CONFIG\n");
printf("*** to point to the correct copy of glib-config, and remove the file config.cache\n");
printf("*** before re-running configure\n");
}
else if ((glib_major_version != GLIB_MAJOR_VERSION) ||
(glib_minor_version != GLIB_MINOR_VERSION) ||
(glib_micro_version != GLIB_MICRO_VERSION))
{
printf("*** GLIB header files (version %d.%d.%d) do not match\n",
GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION);
printf("*** library (version %d.%d.%d)\n",
glib_major_version, glib_minor_version, glib_micro_version);
}
else
{
if ((glib_major_version > major) ||
((glib_major_version == major) && (glib_minor_version > minor)) ||
((glib_major_version == major) && (glib_minor_version == minor) && (glib_micro_version >= micro)))
{
return 0;
}
else
{
printf("\n*** An old version of GLIB (%d.%d.%d) was found.\n",
glib_major_version, glib_minor_version, glib_micro_version);
printf("*** You need a version of GLIB newer than %d.%d.%d. The latest version of\n",
major, minor, micro);
printf("*** GLIB is always available from ftp://ftp.gtk.org.\n");
printf("***\n");
printf("*** If you have already installed a sufficiently new version, this error\n");
printf("*** probably means that the wrong copy of the glib-config shell script is\n");
printf("*** being found. The easiest way to fix this is to remove the old version\n");
printf("*** of GLIB, but you can also set the GLIB_CONFIG environment to point to the\n");
printf("*** correct copy of glib-config. (In this case, you will have to\n");
printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
printf("*** so that the correct libraries are found at run-time))\n");
}
}
return 1;
}
],, no_glib=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
fi
fi
if test "x$no_glib" = x ; then
AC_MSG_RESULT(yes)
ifelse([$2], , :, [$2])
else
AC_MSG_RESULT(no)
if test "$GLIB_CONFIG" = "no" ; then
echo "*** The glib-config script installed by GLIB could not be found"
echo "*** If GLIB was installed in PREFIX, make sure PREFIX/bin is in"
echo "*** your path, or set the GLIB_CONFIG environment variable to the"
echo "*** full path to glib-config."
else
if test -f conf.glibtest ; then
:
else
echo "*** Could not run GLIB test program, checking why..."
CFLAGS="$CFLAGS $GLIB_CFLAGS"
LIBS="$LIBS $GLIB_LIBS"
AC_TRY_LINK([
#include <glib.h>
#include <stdio.h>
], [ return ((glib_major_version) || (glib_minor_version) || (glib_micro_version)); ],
[ echo "*** The test program compiled, but did not run. This usually means"
echo "*** that the run-time linker is not finding GLIB or finding the wrong"
echo "*** version of GLIB. If it is not finding GLIB, you'll need to set your"
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
echo "*** to the installed location Also, make sure you have run ldconfig if that"
echo "*** is required on your system"
echo "***"
echo "*** If you have an old version installed, it is best to remove it, although"
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"
echo "***"
echo "*** If you have a RedHat 5.0 system, you should remove the GTK package that"
echo "*** came with the system with the command"
echo "***"
echo "*** rpm --erase --nodeps gtk gtk-devel" ],
[ echo "*** The test program failed to compile or link. See the file config.log for the"
echo "*** exact error that occured. This usually means GLIB was incorrectly installed"
echo "*** or that you have moved GLIB since it was installed. In the latter case, you"
echo "*** may want to edit the glib-config script: $GLIB_CONFIG" ])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
fi
fi
GLIB_CFLAGS=""
GLIB_LIBS=""
ifelse([$3], , :, [$3])
fi
AC_SUBST(GLIB_CFLAGS)
AC_SUBST(GLIB_LIBS)
rm -f conf.glibtest
])

213
nbase/configlocal.m4 Normal file
View File

@@ -0,0 +1,213 @@
dnl -----------------------------------------------------------------
dnl Nbase local macros
dnl $Id$
dnl -----------------------------------------------------------------
dnl
dnl check for working getaddrinfo(). This check is from
dnl Apache 2.0.40
dnl
dnl Note that if the system doesn't have gai_strerror(), we
dnl can't use getaddrinfo() because we can't get strings
dnl describing the error codes.
dnl
AC_DEFUN(APR_CHECK_WORKING_GETADDRINFO,[
AC_CACHE_CHECK(for working getaddrinfo, ac_cv_working_getaddrinfo,[
AC_TRY_RUN( [
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
int main(void) {
struct addrinfo hints, *ai;
int error;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo("127.0.0.1", NULL, &hints, &ai);
if (error) {
exit(1);
}
if (ai->ai_addr->sa_family != AF_INET) {
exit(1);
}
exit(0);
}
],[
ac_cv_working_getaddrinfo="yes"
],[
ac_cv_working_getaddrinfo="no"
],[
ac_cv_working_getaddrinfo="yes"
])])
if test "$ac_cv_working_getaddrinfo" = "yes"; then
if test "$ac_cv_func_gai_strerror" != "yes"; then
ac_cv_working_getaddrinfo="no"
else
AC_DEFINE(HAVE_GETADDRINFO, 1, [Define if getaddrinfo exists and works well enough for APR])
fi
fi
])
dnl
dnl check for working getnameinfo() -- from Apache 2.0.40
dnl
AC_DEFUN(APR_CHECK_WORKING_GETNAMEINFO,[
AC_CACHE_CHECK(for working getnameinfo, ac_cv_working_getnameinfo,[
AC_TRY_RUN( [
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
int main(void) {
struct sockaddr_in sa;
char hbuf[256];
int error;
sa.sin_family = AF_INET;
sa.sin_port = 0;
sa.sin_addr.s_addr = inet_addr("127.0.0.1");
#ifdef SIN6_LEN
sa.sin_len = sizeof(sa);
#endif
error = getnameinfo((const struct sockaddr *)&sa, sizeof(sa),
hbuf, 256, NULL, 0,
NI_NUMERICHOST);
if (error) {
exit(1);
} else {
exit(0);
}
}
],[
ac_cv_working_getnameinfo="yes"
],[
ac_cv_working_getnameinfo="no"
],[
ac_cv_working_getnameinfo="yes"
])])
if test "$ac_cv_working_getnameinfo" = "yes"; then
AC_DEFINE(HAVE_GETNAMEINFO, 1, [Define if getnameinfo exists])
fi
])
AC_DEFUN(APR_CHECK_SOCKADDR_IN6,[
AC_CACHE_CHECK(for sockaddr_in6, ac_cv_define_sockaddr_in6,[
AC_TRY_COMPILE([
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
],[
struct sockaddr_in6 sa;
],[
ac_cv_define_sockaddr_in6=yes
],[
ac_cv_define_sockaddr_in6=no
])
])
if test "$ac_cv_define_sockaddr_in6" = "yes"; then
have_sockaddr_in6=1
AC_DEFINE(HAVE_SOCKADDR_IN6)
else
have_sockaddr_in6=0
fi
])
AC_DEFUN(CHECK_AF_INET6_DEFINE,[
AC_CACHE_CHECK(for AF_INET6 definition, ac_cv_define_af_inet6,[
AC_TRY_COMPILE([
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
],[
int af = AF_INET6;
],[
ac_cv_define_af_inet6=yes
],[
ac_cv_define_af_inet6=no
])
])
if test "$ac_cv_define_af_inet6" = "yes"; then
have_af_inet6=1
AC_DEFINE(HAVE_AF_INET6)
else
have_af_inet6=0
fi
])
AC_DEFUN(APR_CHECK_SOCKADDR_STORAGE,[
AC_CACHE_CHECK(for sockaddr_storage, ac_cv_define_sockaddr_storage,[
AC_TRY_COMPILE([
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
],[
struct sockaddr_storage sa;
],[
ac_cv_define_sockaddr_storage=yes
],[
ac_cv_define_sockaddr_storage=no
])
])
if test "$ac_cv_define_sockaddr_storage" = "yes"; then
have_sockaddr_storage=1
AC_DEFINE(HAVE_SOCKADDR_STORAGE)
else
have_sockaddr_storage=0
fi
])
dnl This test taken from GCC libjava.
AC_DEFUN(CHECK_PROC_SELF_EXE,[
if test x"$cross_compiling" = x"no"; then
AC_CHECK_FILES(/proc/self/exe, [
AC_DEFINE(HAVE_PROC_SELF_EXE, 1, [Define if you have /proc/self/exe])])
else
case $host in
*-linux*)
AC_DEFINE(HAVE_PROC_SELF_EXE, 1, [Define if you have /proc/self/exe])
;;
esac
fi
])

6449
nbase/configure vendored Executable file

File diff suppressed because it is too large Load Diff

298
nbase/configure.ac Normal file
View File

@@ -0,0 +1,298 @@
dnl # -*- mode: fundamental; -*-
dnl # Autoconf configuration file for Nbase
dnl #
dnl # Process this file with autoconf to produce a configure script.
dnl # $Id$
# Because nbase is usually distributed with Nmap, the necessary files
# config.guess, config.guess, and install-sh are not distributed with
# nbase. Rather they are gotten from Nmap.
# Require autoconf 2.13
AC_PREREQ(2.13)
# Include my own macros
sinclude(configlocal.m4)
AC_INIT(nbase.h)
AC_ARG_WITH(localdirs,
[ --with-localdirs Explicitly ask compiler to use /usr/local/{include,libs} if they exist ],
[ case "$with_localdirs" in
yes)
user_localdirs=1
;;
no)
user_localdirs=0
;;
esac
],
[ user_localdirs=0 ] )
if test "$user_localdirs" = 1; then
if test -d /usr/local/lib; then
LDFLAGS="$LDFLAGS -L/usr/local/lib"
fi
if test -d /usr/local/include; then
CFLAGS="$CFLAGS -I/usr/local/include"
fi
fi
dnl use config.h instad of -D macros
AC_CONFIG_HEADER(nbase_config.h)
dnl Checks for programs.
AC_PROG_CC
if test -n "$GCC"; then
CFLAGS="$CFLAGS -Wall "
fi
AC_PROG_RANLIB
dnl AC_PROG_INSTALL
dnl AC_PATH_PROG(MAKEDEPEND, makedepend)
AC_SUBST(COMPAT_OBJS)
AC_SUBST(COMPAT_SRCS)
dnl Host specific hacks
AC_CANONICAL_HOST
dnl equiv to '#define inline' to 'inline', '__inline__', '__inline' or ''
AC_C_INLINE
case "$host" in
*-sgi-irix5* | *-sgi-irix6*)
if test -z "$GCC"; then
AC_DEFINE(inline, )
fi
;;
esac
dnl Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS( string.h getopt.h strings.h sys/param.h sys/time.h unistd.h errno.h sys/types.h sys/socket.h netinet/in.h arpa/inet.h sys/stat.h netdb.h sys/wait.h fcntl.h sys/resource.h inttypes.h mach-o/dyld.h)
AC_HEADER_TIME
dnl A special check required for <net/if.h> on Darwin. See
dnl http://www.gnu.org/software/autoconf/manual/html_node/Header-Portability.html.
AC_CHECK_HEADERS([sys/socket.h])
AC_CHECK_HEADERS([net/if.h], [], [],
[#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
])
AC_MSG_CHECKING(for __attribute__)
AC_CACHE_VAL(ac_cv___attribute__, [
AC_TRY_COMPILE(
[
#include <stdlib.h>
static void foo(void) __attribute__ ((noreturn));
static void
foo(void)
{
exit(1);
}
],
[
foo();
],
ac_cv___attribute__=yes,
ac_cv___attribute__=no
)
])
if test "$ac_cv___attribute__" = "yes"; then
AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__])
fi
AC_MSG_RESULT($ac_cv___attribute__)
AC_SUBST(CFLAGS)
dnl This test is from the configure.in of Unix Network Programming second
dnl edition example code by W. Richard Stevens
dnl ##################################################################
dnl Check if sockaddr{} has sa_len member.
dnl
AC_CACHE_CHECK(if sockaddr{} has sa_len member, ac_cv_sockaddr_has_sa_len,
AC_TRY_COMPILE([
#include <sys/types.h>
#include <sys/socket.h>],
[unsigned int i = sizeof(((struct sockaddr *)0)->sa_len)],
ac_cv_sockaddr_has_sa_len=yes,
ac_cv_sockaddr_has_sa_len=no))
if test $ac_cv_sockaddr_has_sa_len = yes ; then
AC_DEFINE(HAVE_SOCKADDR_SA_LEN)
fi
dnl check endedness
AC_C_BIGENDIAN
dnl determine types so nbase can export u32, u16, etc.
AC_TYPE_INT8_T
AC_TYPE_INT16_T
AC_TYPE_INT32_T
AC_TYPE_INT64_T
AC_TYPE_UINT8_T
AC_TYPE_UINT16_T
AC_TYPE_UINT32_T
AC_TYPE_UINT64_T
dnl Checks for library functions.
AC_CHECK_FUNCS( snprintf vsnprintf nanosleep strerror strcasestr strcasecmp strncasecmp signal )
needsnprintf=no
AC_CHECK_FUNCS(vsnprintf snprintf asprintf asnprintf vasprintf vasnprintf,,
[needsnprintf=yes])
if test $needsnprintf = yes; then
AC_LIBOBJ([snprintf])
fi
AC_CHECK_FUNCS( getopt getopt_long_only)
AC_CHECK_FUNCS(usleep gettimeofday sleep, ,
[ AC_LIBOBJ([nbase_time]) ])
AC_CHECK_FUNC(getopt_long_only, ,
[ AC_LIBOBJ([getopt]) ])
AC_CHECK_FUNCS(strcasecmp strncasecmp, ,
[ AC_LIBOBJ([strcasecmp]) ])
dnl We always want some of our files
AC_LIBOBJ([nbase_str])
AC_LIBOBJ([nbase_misc])
AC_LIBOBJ([nbase_memalloc])
AC_LIBOBJ([nbase_rnd])
AC_LIBOBJ([nbase_addrset])
# Check for IPv6 support -- modified from Apache 2.0.40:
AC_ARG_ENABLE(ipv6,
[ --disable-ipv6 Disable IPv6 support ],
[ if test "$enableval" = "no"; then
user_disabled_ipv6=1
fi ],
[ user_disabled_ipv6=0 ] )
AC_SEARCH_LIBS(getaddrinfo, [inet6 socket])
AC_SEARCH_LIBS(gai_strerror, [inet6 socket])
AC_SEARCH_LIBS(getnameinfo, [inet6 socket])
AC_CHECK_FUNCS(gai_strerror)
AC_REPLACE_FUNCS(inet_ntop inet_pton)
APR_CHECK_WORKING_GETADDRINFO
# The inet_addr function is used by APR_CHECK_WORKING_GETNAMEINFO.
AC_SEARCH_LIBS(inet_addr, [nsl])
APR_CHECK_WORKING_GETNAMEINFO
APR_CHECK_SOCKADDR_IN6
APR_CHECK_SOCKADDR_STORAGE
CHECK_AF_INET6_DEFINE
AC_MSG_CHECKING(for IPv6 support)
have_ipv6="0"
if test "$user_disabled_ipv6" = 1; then
AC_MSG_RESULT("no -- disabled by user")
else
if test "x$have_sockaddr_in6" = "x1"; then
if test "x$ac_cv_working_getaddrinfo" = "xyes"; then
if test "x$ac_cv_working_getnameinfo" = "xyes"; then
have_ipv6="1"
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT("no -- no working getnameinfo")
fi
else
AC_MSG_RESULT("no -- no working getaddrinfo")
fi
else
AC_MSG_RESULT("no -- no sockaddr_in6");
fi
fi
if test "x$ac_cv_working_getaddrinfo" != "xyes"; then
AC_LIBOBJ([getaddrinfo])
fi
if test "x$ac_cv_working_getnameinfo" != "xyes"; then
AC_LIBOBJ([getnameinfo])
fi
if test "$have_ipv6" = "1"; then
AC_DEFINE(HAVE_IPV6)
fi
# First we test whether they specified openssl desires explicitly
use_openssl="yes"
specialssldir=""
AC_ARG_WITH(openssl,
[ --with-openssl=DIR Use optional openssl libs and includes from [DIR]/lib/
and [DIR]/include/openssl/)],
[ case "$with_openssl" in
yes)
;;
no)
use_openssl="no"
;;
*)
specialssldir="$with_openssl"
;;
esac]
)
# If they didn't specify it, we try to find it
if test "$use_openssl" = "yes" -a -z "$specialssldir"; then
AC_CHECK_HEADER(openssl/ssl.h,,
[ use_openssl="no"
AC_MSG_WARN([Failed to find openssl/ssl.h so OpenSSL will not be used. If it
is installed you can try the --with-openssl=DIR argument]) ])
if test "$use_openssl" = "yes"; then
AC_CHECK_HEADER(openssl/err.h,,
[ use_openssl="no"
AC_MSG_WARN([Failed to find openssl/err.h so OpenSSL will not be used. If it
is installed you can try the --with-openssl=DIR argument]) ])
fi
if test "$use_openssl" = "yes"; then
AC_CHECK_HEADER(openssl/rand.h,,
[ use_openssl="no"
AC_MSG_WARN([Failed to find openssl/rand.h so OpenSSL will not be used. If i
t is installed you can try the --with-openssl=DIR argument]) ])
fi
if test "$use_openssl" = "yes"; then
AC_CHECK_LIB(crypto, BIO_int_ctrl,
[],
[ use_openssl="no"
AC_MSG_WARN([Failed to find libcrypto so OpenSSL will not be used. If it is installed you can try the --with-openssl=DIR argument]) ])
fi
if test "$use_openssl" = "yes"; then
AC_CHECK_LIB(ssl, SSL_new,
[],
[ use_openssl="no"
AC_MSG_WARN([Failed to find libssl so OpenSSL will not be used. If it is ins
talled you can try the --with-openssl=DIR argument]) ])
fi
fi
if test "$use_openssl" = "yes"; then
AC_DEFINE(HAVE_OPENSSL)
fi
CHECK_PROC_SELF_EXE
AC_OUTPUT(Makefile)

221
nbase/getaddrinfo.c Normal file
View File

@@ -0,0 +1,221 @@
/***************************************************************************
* getaddrinfo.c -- A **PARTIAL** implementation of the getaddrinfo(3) *
* hostname resolution call. In particular, IPv6 is not supported and *
* neither are some of the flags. Service "names" are always returned as *
* port numbers. *
* *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include "nbase.h"
#include <stdio.h>
#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#if HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#if HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#if HAVE_NETDB_H
#include <netdb.h>
#endif
#include <assert.h>
#if !defined(HAVE_GAI_STRERROR) || defined(__MINGW32__)
#ifdef __MINGW32__
#undef gai_strerror
#endif
const char *gai_strerror(int errcode) {
static char customerr[64];
switch (errcode) {
case EAI_FAMILY:
return "ai_family not supported";
case EAI_NODATA:
return "no address associated with hostname";
case EAI_NONAME:
return "hostname nor servname provided, or not known";
default:
Snprintf(customerr, sizeof(customerr), "unknown error (%d)", errcode);
return "unknown error.";
}
return NULL; /* unreached */
}
#endif
#ifdef __MINGW32__
char* WSAAPI gai_strerrorA (int errcode)
{
return gai_strerror(errcode);
}
#endif
#ifndef HAVE_GETADDRINFO
void freeaddrinfo(struct addrinfo *res) {
struct addrinfo *next;
do {
next = res->ai_next;
free(res);
} while ((res = next) != NULL);
}
/* Allocates and initializes a new AI structure with the port and IPv4
address specified in network byte order */
static struct addrinfo *new_ai(unsigned short portno, u32 addr)
{
struct addrinfo *ai;
ai = (struct addrinfo *) safe_malloc(sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
ai->ai_family = AF_INET;
ai->ai_addrlen = sizeof(struct sockaddr_in);
ai->ai_addr = (struct sockaddr *)(ai + 1);
ai->ai_addr->sa_family = AF_INET;
#if HAVE_SOCKADDR_SA_LEN
ai->ai_addr->sa_len = ai->ai_addrlen;
#endif
((struct sockaddr_in *)(ai)->ai_addr)->sin_port = portno;
((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
return(ai);
}
int getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints, struct addrinfo **res) {
struct addrinfo *cur, *prev = NULL;
struct hostent *he;
struct in_addr ip;
unsigned short portno;
int i;
if (service)
portno = htons(atoi(service));
else
portno = 0;
if (hints && hints->ai_flags & AI_PASSIVE) {
*res = new_ai(portno, htonl(0x00000000));
return 0;
}
if (!node) {
*res = new_ai(portno, htonl(0x7f000001));
return 0;
}
if (inet_pton(AF_INET, node, &ip)) {
*res = new_ai(portno, ip.s_addr);
return 0;
}
he = gethostbyname(node);
if (he && he->h_addr_list[0]) {
for (i = 0; he->h_addr_list[i]; i++) {
cur = new_ai(portno, ((struct in_addr *)he->h_addr_list[i])->s_addr);
if (prev)
prev->ai_next = cur;
else
*res = cur;
prev = cur;
}
return 0;
}
return EAI_NODATA;
}
#endif /* HAVE_GETADDRINFO */

146
nbase/getnameinfo.c Normal file
View File

@@ -0,0 +1,146 @@
/***************************************************************************
* getnameinfo.c -- A **PARTIAL** implementation of the getnameinfo(3) *
* host resolution call. In particular, IPv6 is not supported and neither *
* are some of the flags. Service "names" are always returned as decimal *
* port numbers. *
* *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include "nbase.h"
#if HAVE_NETDB_H
#include <netdb.h>
#endif
#include <assert.h>
#include <stdio.h>
#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#if HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#if HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
int getnameinfo(const struct sockaddr *sa, size_t salen,
char *host, size_t hostlen,
char *serv, size_t servlen, int flags) {
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
struct hostent *he;
if (sin->sin_family != AF_INET || salen != sizeof(struct sockaddr_in))
return EAI_FAMILY;
if (serv != NULL) {
Snprintf(serv, servlen, "%d", ntohs(sin->sin_port));
return 0;
}
if (host) {
if (flags & NI_NUMERICHOST) {
Strncpy(host, inet_ntoa(sin->sin_addr), hostlen);
return 0;
} else {
he = gethostbyaddr((char *)&sin->sin_addr, sizeof(struct in_addr),
AF_INET);
if (he == NULL) {
if (flags & NI_NAMEREQD)
return EAI_NONAME;
Strncpy(host, inet_ntoa(sin->sin_addr), hostlen);
return 0;
}
assert(he->h_name);
Strncpy(host, he->h_name, hostlen);
return 0;
}
}
return 0;
}

302
nbase/getopt.c Normal file
View File

@@ -0,0 +1,302 @@
/*
* my_getopt.c - my re-implementation of getopt.
* Copyright 1997, 2000, 2001, 2002, 2006, Benjamin Sittler
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "getopt.h"
#if HAVE_CONFIG_H
#include "nbase_config.h"
#else
#ifdef WIN32
#include "nbase_winconfig.h" /* mainly for _CRT_SECURE_NO_DEPRECATE */
#endif /* WIN32 */
#endif /* HAVE_CONFIG_H */
int optind=1, opterr=1, optopt=0;
char *optarg=0;
/* reset argument parser to start-up values */
int getopt_reset(void)
{
optind = 1;
opterr = 1;
optopt = 0;
optarg = 0;
return 0;
}
/* this is the plain old UNIX getopt, with GNU-style extensions. */
/* if you're porting some piece of UNIX software, this is all you need. */
/* this supports GNU-style permution and optional arguments */
static int _getopt(int argc, char * argv[], const char *opts)
{
static int charind=0;
const char *s;
char mode, colon_mode;
int off = 0, opt = -1;
if(getenv("POSIXLY_CORRECT")) colon_mode = mode = '+';
else {
if((colon_mode = *opts) == ':') off ++;
if(((mode = opts[off]) == '+') || (mode == '-')) {
off++;
if((colon_mode != ':') && ((colon_mode = opts[off]) == ':'))
off ++;
}
}
optarg = 0;
if(charind) {
optopt = argv[optind][charind];
for(s=opts+off; *s; s++) if(optopt == *s) {
charind++;
if((*(++s) == ':') || ((optopt == 'W') && (*s == ';'))) {
if(argv[optind][charind]) {
optarg = &(argv[optind++][charind]);
charind = 0;
} else if(*(++s) != ':') {
charind = 0;
if(++optind >= argc) {
if(opterr) fprintf(stderr,
"%s: option requires an argument -- %c\n",
argv[0], optopt);
opt = (colon_mode == ':') ? ':' : '?';
goto my_getopt_ok;
}
optarg = argv[optind++];
}
}
opt = optopt;
goto my_getopt_ok;
}
if(opterr) fprintf(stderr,
"%s: illegal option -- %c\n",
argv[0], optopt);
opt = '?';
if(argv[optind][++charind] == '\0') {
optind++;
charind = 0;
}
my_getopt_ok:
if(charind && ! argv[optind][charind]) {
optind++;
charind = 0;
}
} else if((optind >= argc) ||
((argv[optind][0] == '-') &&
(argv[optind][1] == '-') &&
(argv[optind][2] == '\0'))) {
optind++;
opt = -1;
} else if((argv[optind][0] != '-') ||
(argv[optind][1] == '\0')) {
char *tmp;
int i, j, k;
if(mode == '+') opt = -1;
else if(mode == '-') {
optarg = argv[optind++];
charind = 0;
opt = 1;
} else {
for(i=j=optind; i<argc; i++) if((argv[i][0] == '-') &&
(argv[i][1] != '\0')) {
optind=i;
opt=_getopt(argc, argv, opts);
while(i > j) {
tmp=argv[--i];
for(k=i; k+1<optind; k++) argv[k]=argv[k+1];
argv[--optind]=tmp;
}
break;
}
if(i == argc) opt = -1;
}
} else {
charind++;
opt = _getopt(argc, argv, opts);
}
if (optind > argc) optind = argc;
return opt;
}
/* this is the extended getopt_long{,_only}, with some GNU-like
* extensions. Implements _getopt_internal in case any programs
* expecting GNU libc getopt call it.
*/
int _getopt_internal(int argc, char * argv[], const char *shortopts,
const struct option *longopts, int *longind,
int long_only)
{
char mode, colon_mode = *shortopts;
int shortoff = 0, opt = -1;
if(getenv("POSIXLY_CORRECT")) colon_mode = mode = '+';
else {
if((colon_mode = *shortopts) == ':') shortoff ++;
if(((mode = shortopts[shortoff]) == '+') || (mode == '-')) {
shortoff++;
if((colon_mode != ':') && ((colon_mode = shortopts[shortoff]) == ':'))
shortoff ++;
}
}
optarg = 0;
if((optind >= argc) ||
((argv[optind][0] == '-') &&
(argv[optind][1] == '-') &&
(argv[optind][2] == '\0'))) {
optind++;
opt = -1;
} else if((argv[optind][0] != '-') ||
(argv[optind][1] == '\0')) {
char *tmp;
int i, j, k;
opt = -1;
if(mode == '+') return -1;
else if(mode == '-') {
optarg = argv[optind++];
return 1;
}
for(i=j=optind; i<argc; i++) if((argv[i][0] == '-') &&
(argv[i][1] != '\0')) {
optind=i;
opt=_getopt_internal(argc, argv, shortopts,
longopts, longind,
long_only);
while(i > j) {
tmp=argv[--i];
for(k=i; k+1<optind; k++)
argv[k]=argv[k+1];
argv[--optind]=tmp;
}
break;
}
} else if((!long_only) && (argv[optind][1] != '-'))
opt = _getopt(argc, argv, shortopts);
else {
int charind, offset;
int found = 0, ind, hits = 0;
if(((optopt = argv[optind][1]) != '-') && ! argv[optind][2]) {
int c;
ind = shortoff;
while((c = shortopts[ind++])) {
if(((shortopts[ind] == ':') ||
((c == 'W') && (shortopts[ind] == ';'))) &&
(shortopts[++ind] == ':'))
ind ++;
if(optopt == c) return _getopt(argc, argv, shortopts);
}
}
offset = 2 - (argv[optind][1] != '-');
for(charind = offset;
(argv[optind][charind] != '\0') &&
(argv[optind][charind] != '=');
charind++);
for(ind = 0; longopts[ind].name && !hits; ind++)
if((strlen(longopts[ind].name) == (size_t) (charind - offset)) &&
(strncmp(longopts[ind].name,
argv[optind] + offset, charind - offset) == 0))
found = ind, hits++;
if(!hits) for(ind = 0; longopts[ind].name; ind++)
if(strncmp(longopts[ind].name,
argv[optind] + offset, charind - offset) == 0)
found = ind, hits++;
if(hits == 1) {
opt = 0;
if(argv[optind][charind] == '=') {
if(longopts[found].has_arg == 0) {
opt = '?';
if(opterr) fprintf(stderr,
"%s: option `--%s' doesn't allow an argument\n",
argv[0], longopts[found].name);
} else {
optarg = argv[optind] + ++charind;
charind = 0;
}
} else if(longopts[found].has_arg == 1) {
if(++optind >= argc) {
opt = (colon_mode == ':') ? ':' : '?';
if(opterr) fprintf(stderr,
"%s: option `--%s' requires an argument\n",
argv[0], longopts[found].name);
} else optarg = argv[optind];
}
if(!opt) {
if (longind) *longind = found;
if(!longopts[found].flag) opt = longopts[found].val;
else *(longopts[found].flag) = longopts[found].val;
}
optind++;
} else if(!hits) {
if(offset == 1) opt = _getopt(argc, argv, shortopts);
else {
opt = '?';
if(opterr) fprintf(stderr,
"%s: unrecognized option `%s'\n",
argv[0], argv[optind++]);
}
} else {
opt = '?';
if(opterr) fprintf(stderr,
"%s: option `%s' is ambiguous\n",
argv[0], argv[optind++]);
}
}
if (optind > argc) optind = argc;
return opt;
}
/* This function is kinda problematic because most getopt() nowadays
seem to use char * const argv[] (they DON'T permute the options list),
but this one does. So we remove it as long as HAVE_GETOPT is define, so
people can use the version from their platform instead */
#ifndef HAVE_GETOPT
int getopt(int argc, char * argv[], const char *opts)
{
return _getopt(argc, argv, opts);
}
#endif /* HAVE_GETOPT */
int getopt_long(int argc, char * argv[], const char *shortopts,
const struct option *longopts, int *longind)
{
return _getopt_internal(argc, argv, shortopts, longopts, longind, 0);
}
int getopt_long_only(int argc, char * argv[], const char *shortopts,
const struct option *longopts, int *longind)
{
return _getopt_internal(argc, argv, shortopts, longopts, longind, 1);
}

82
nbase/getopt.h Normal file
View File

@@ -0,0 +1,82 @@
/*
* my_getopt.h - interface to my re-implementation of getopt.
* Copyright 1997, 2000, 2001, 2002, 2006, Benjamin Sittler
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef MY_GETOPT_H_INCLUDED
#define MY_GETOPT_H_INCLUDED
#if HAVE_CONFIG_H
#include "nbase_config.h"
#else
#ifdef WIN32
#include "nbase_winconfig.h"
#endif /* WIN32 */
#endif /* HAVE_CONFIG_H */
#ifdef __cplusplus
extern "C" {
#endif
/* reset argument parser to start-up values */
extern int getopt_reset(void);
#ifndef HAVE_GETOPT
/* UNIX-style short-argument parser */
extern int getopt(int argc, char * argv[], const char *opts);
#endif /* HAVE_GETOPT */
extern int optind, opterr, optopt;
extern char *optarg;
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
/* human-readable values for has_arg */
#undef no_argument
#define no_argument 0
#undef required_argument
#define required_argument 1
#undef optional_argument
#define optional_argument 2
/* GNU-style long-argument parsers */
extern int getopt_long(int argc, char * argv[], const char *shortopts,
const struct option *longopts, int *longind);
extern int getopt_long_only(int argc, char * argv[], const char *shortopts,
const struct option *longopts, int *longind);
extern int _getopt_internal(int argc, char * argv[], const char *shortopts,
const struct option *longopts, int *longind,
int long_only);
#ifdef __cplusplus
}
#endif
#endif /* MY_GETOPT_H_INCLUDED */

251
nbase/inet_ntop.c Normal file
View File

@@ -0,0 +1,251 @@
/* Copyright (c) 1996 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/* Modified by Fyodor (fyodor@insecure.org) for inclusion in the Nmap
* Security Scanner.
*
* $Id$
*/
#include "nbase.h"
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#if HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#if HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include <string.h>
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#include <stdio.h>
#ifndef IN6ADDRSZ
#define IN6ADDRSZ 16
#endif
#ifndef INT16SZ
#define INT16SZ sizeof(u16)
#endif
#if !defined(EAFNOSUPPORT) && defined(WSAEAFNOSUPPORT)
#define EAFNOSUPPORT WSAEAFNOSUPPORT
#endif
/*
* WARNING: Don't even consider trying to compile this on a system where
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
*/
static const char *inet_ntop4(const unsigned char *src, char *dst, size_t size);
#if HAVE_IPV6
static const char *inet_ntop6(const unsigned char *src, char *dst, size_t size);
#endif
/* char *
* inet_ntop(af, src, dst, size)
* convert a network format address to presentation format.
* return:
* pointer to presentation format address (`dst'), or NULL (see errno).
* author:
* Paul Vixie, 1996.
*/
const char *
inet_ntop(int af, const void *src, char *dst, size_t size)
{
switch (af) {
case AF_INET:
return (inet_ntop4((const unsigned char *) src, dst, size));
#if HAVE_IPV6
case AF_INET6:
return (inet_ntop6((const unsigned char *) src, dst, size));
#endif
default:
#ifndef WIN32
errno = EAFNOSUPPORT;
#endif
return (NULL);
}
/* NOTREACHED */
}
/* const char *
* inet_ntop4(src, dst, size)
* format an IPv4 address, more or less like inet_ntoa()
* return:
* `dst' (as a const)
* notes:
* (1) uses no statics
* (2) takes a u_char* not an in_addr as input
* author:
* Paul Vixie, 1996.
*/
static const char *
inet_ntop4(const unsigned char *src, char *dst, size_t size)
{
const size_t MIN_SIZE = 16; /* space for 255.255.255.255\0 */
int n = 0;
char *next = dst;
if (size < MIN_SIZE) {
#ifndef WIN32
errno = ENOSPC;
#endif
return NULL;
}
do {
unsigned char u = *src++;
if (u > 99) {
*next++ = '0' + u/100;
u %= 100;
*next++ = '0' + u/10;
u %= 10;
}
else if (u > 9) {
*next++ = '0' + u/10;
u %= 10;
}
*next++ = '0' + u;
*next++ = '.';
n++;
} while (n < 4);
*--next = 0;
return dst;
}
#if HAVE_IPV6
/* const char *
* inet_ntop6(src, dst, size)
* convert IPv6 binary address into presentation (printable) format
* author:
* Paul Vixie, 1996.
*/
static const char *
inet_ntop6(const unsigned char *src, char *dst, size_t size)
{
/*
* Note that int32_t and int16_t need only be "at least" large enough
* to contain a value of the specified size. On some systems, like
* Crays, there is no such thing as an integer variable with 16 bits.
* Keep this in mind if you think this function should have been coded
* to use pointer overlays. All the world's not a VAX.
*/
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
struct { int base, len; } best, cur;
u16 words[IN6ADDRSZ / INT16SZ];
int i;
const unsigned char *next_src, *src_end;
u16 *next_dest;
/*
* Preprocess:
* Copy the input (bytewise) array into a wordwise array.
* Find the longest run of 0x00's in src[] for :: shorthanding.
*/
next_src = src;
src_end = src + IN6ADDRSZ;
next_dest = words;
best.base = -1;
cur.base = -1;
i = 0;
do {
unsigned int next_word = (unsigned int)*next_src++;
next_word <<= 8;
next_word |= (unsigned int)*next_src++;
*next_dest++ = next_word;
if (next_word == 0) {
if (cur.base == -1) {
cur.base = i;
cur.len = 1;
}
else {
cur.len++;
}
} else {
if (cur.base != -1) {
if (best.base == -1 || cur.len > best.len) {
best = cur;
}
cur.base = -1;
}
}
i++;
} while (next_src < src_end);
if (cur.base != -1) {
if (best.base == -1 || cur.len > best.len) {
best = cur;
}
}
if (best.base != -1 && best.len < 2) {
best.base = -1;
}
/*
* Format the result.
*/
tp = tmp;
for (i = 0; i < (IN6ADDRSZ / INT16SZ);) {
/* Are we inside the best run of 0x00's? */
if (i == best.base) {
*tp++ = ':';
i += best.len;
continue;
}
/* Are we following an initial run of 0x00s or any real hex? */
if (i != 0) {
*tp++ = ':';
}
/* Is this address an encapsulated IPv4? */
if (i == 6 && best.base == 0 &&
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) {
return (NULL);
}
tp += strlen(tp);
break;
}
tp += Snprintf(tp, sizeof tmp - (tp - tmp), "%x", words[i]);
i++;
}
/* Was it a trailing run of 0x00's? */
if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) {
*tp++ = ':';
}
*tp++ = '\0';
/*
* Check for overflow, copy, and we're done.
*/
if ((size_t)(tp - tmp) > size) {
#ifndef WIN32
errno = ENOSPC;
#endif
return (NULL);
}
strncpy(dst, tmp, size);
return (dst);
}
#endif

245
nbase/inet_pton.c Normal file
View File

@@ -0,0 +1,245 @@
/* Copyright (c) 1996 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/* Modified by Fyodor (fyodor@insecure.org) for inclusion in the Nmap
* Security Scanner.
*
* $Id$
*/
#include "nbase.h"
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#if HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#if HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#if HAVE_STRING_H
#include <string.h>
#endif
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#ifndef IN6ADDRSZ
#define IN6ADDRSZ 16
#endif
#ifndef INT16SZ
#define INT16SZ 2
#endif
#ifndef INADDRSZ
#define INADDRSZ 4
#endif
#if !defined(EAFNOSUPPORT) && defined(WSAEAFNOSUPPORT)
#define EAFNOSUPPORT WSAEAFNOSUPPORT
#endif
/*
* WARNING: Don't even consider trying to compile this on a system where
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
*/
static int inet_pton4 (const char *src, unsigned char *dst);
#if HAVE_IPV6
static int inet_pton6 (const char *src, unsigned char *dst);
#endif
/* int
* inet_pton(af, src, dst)
* convert from presentation format (which usually means ASCII printable)
* to network format (which is usually some kind of binary format).
* return:
* 1 if the address was valid for the specified address family
* 0 if the address wasn't valid (`dst' is untouched in this case)
* -1 if some other error occurred (`dst' is untouched in this case, too)
* author:
* Paul Vixie, 1996.
*/
int
inet_pton(int af, const char *src, void *dst)
{
switch (af) {
case AF_INET:
return (inet_pton4(src, (unsigned char *) dst));
#if HAVE_IPV6
case AF_INET6:
return (inet_pton6(src, (unsigned char *) dst));
#endif
default:
#ifndef WIN32
errno = EAFNOSUPPORT;
#endif
return (-1);
}
/* NOTREACHED */
}
/* int
* inet_pton4(src, dst)
* like inet_aton() but without all the hexadecimal and shorthand.
* return:
* 1 if `src' is a valid dotted quad, else 0.
* notice:
* does not touch `dst' unless it's returning 1.
* author:
* Paul Vixie, 1996.
*/
static int
inet_pton4(const char *src, unsigned char *dst)
{
static const char digits[] = "0123456789";
int saw_digit, octets, ch;
unsigned char tmp[INADDRSZ], *tp;
saw_digit = 0;
octets = 0;
*(tp = tmp) = 0;
while ((ch = *src++) != '\0') {
const char *pch;
if ((pch = strchr(digits, ch)) != NULL) {
unsigned int newval = (unsigned int) (*tp * 10 + (pch - digits));
if (newval > 255)
return (0);
*tp = newval;
if (! saw_digit) {
if (++octets > 4)
return (0);
saw_digit = 1;
}
} else if (ch == '.' && saw_digit) {
if (octets == 4)
return (0);
*++tp = 0;
saw_digit = 0;
} else
return (0);
}
if (octets < 4)
return (0);
memcpy(dst, tmp, INADDRSZ);
return (1);
}
#if HAVE_IPV6
/* int
* inet_pton6(src, dst)
* convert presentation level address to network order binary form.
* return:
* 1 if `src' is a valid [RFC1884 2.2] address, else 0.
* notice:
* (1) does not touch `dst' unless it's returning 1.
* (2) :: in a full address is silently ignored.
* credit:
* inspired by Mark Andrews.
* author:
* Paul Vixie, 1996.
*/
static int
inet_pton6(const char *src, unsigned char *dst)
{
static const char xdigits_l[] = "0123456789abcdef",
xdigits_u[] = "0123456789ABCDEF";
unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
const char *xdigits, *curtok;
int ch, saw_xdigit;
unsigned int val;
memset((tp = tmp), '\0', IN6ADDRSZ);
endp = tp + IN6ADDRSZ;
colonp = NULL;
/* Leading :: requires some special handling. */
if (*src == ':')
if (*++src != ':')
return (0);
curtok = src;
saw_xdigit = 0;
val = 0;
while ((ch = *src++) != '\0') {
const char *pch;
if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
pch = strchr((xdigits = xdigits_u), ch);
if (pch != NULL) {
val <<= 4;
val |= (pch - xdigits);
if (val > 0xffff)
return (0);
saw_xdigit = 1;
continue;
}
if (ch == ':') {
curtok = src;
if (!saw_xdigit) {
if (colonp)
return (0);
colonp = tp;
continue;
}
if (tp + INT16SZ > endp)
return (0);
*tp++ = (unsigned char) (val >> 8) & 0xff;
*tp++ = (unsigned char) val & 0xff;
saw_xdigit = 0;
val = 0;
continue;
}
if (ch == '.' && ((tp + INADDRSZ) <= endp) &&
inet_pton4(curtok, tp) > 0) {
tp += INADDRSZ;
saw_xdigit = 0;
break; /* '\0' was seen by inet_pton4(). */
}
return (0);
}
if (saw_xdigit) {
if (tp + INT16SZ > endp)
return (0);
*tp++ = (unsigned char) (val >> 8) & 0xff;
*tp++ = (unsigned char) val & 0xff;
}
if (colonp != NULL) {
/*
* Since some memmove()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand.
*/
const int n = tp - colonp;
int i;
for (i = 1; i <= n; i++) {
endp[- i] = colonp[n - i];
colonp[n - i] = 0;
}
tp = endp;
}
if (tp != endp)
return (0);
memcpy(dst, tmp, IN6ADDRSZ);
return (1);
}
#endif

504
nbase/nbase.h Normal file
View File

@@ -0,0 +1,504 @@
/***************************************************************************
* nbase.h -- The main include file exposing the external API for *
* libnbase, a library of base (often compatability) routines. Programs *
* using libnbase can guarantee the availability of functions like *
* (v)snprintf and inet_pton. This library also provides consistency and *
* extended features for some functions. It was originally written for *
* use in the Nmap Security Scanner ( http://nmap.org ). *
* *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#ifndef NBASE_H
#define NBASE_H
/* NOTE -- libnbase offers the following features that you should probably
* be aware of:
*
* * 'inline' is defined to what is neccessary for the C compiler being
* used (which may be nothing)
*
* * snprintf, inet_pton, memcpy, and bzero are
* provided if you don't have them (prototypes for these are
* included either way).
*
* * WORDS_BIGENDIAN is defined if platform is big endian
*
* * Definitions included which give the operating system type. They
* will generally be one of the following: LINUX, FREEBSD, NETBSD,
* OPENBSD, SOLARIS, SUNOS, BSDI, IRIX, NETBSD
*
* * Insures that getopt_* functions exist (such as getopt_long_only)
*
* * Various string functions such as Strncpy() and strcasestr() see protos
* for more info.
*
* * IPv6 structures like 'sockaddr_storage' are provided if they do
* not already exist.
*
* * Various Windows -> UNIX compatability definitions are added (such as defining EMSGSIZE to WSAEMSGSIZE)
*/
#if HAVE_CONFIG_H
#include "nbase_config.h"
#else
#ifdef WIN32
#include "nbase_winconfig.h"
#endif /* WIN32 */
#endif /* HAVE_CONFIG_H */
#ifdef WIN32
#include "nbase_winunix.h"
#endif
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdlib.h>
#include <ctype.h>
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#if HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#if HAVE_STRING_H
#include <string.h>
#endif
#if HAVE_NETDB_H
#include <netdb.h>
#endif
#if HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#include <stdio.h>
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 64
#endif
#ifndef MAXPATHLEN
#define MAXPATHLEN 2048
#endif
#ifndef HAVE___ATTRIBUTE__
#define __attribute__(args)
#endif
#include <stdarg.h>
/* Keep assert() defined for security reasons */
#undef NDEBUG
/* Integer types */
typedef uint8_t u8;
typedef int8_t s8;
typedef uint16_t u16;
typedef int16_t s16;
typedef uint32_t u32;
typedef int32_t s32;
typedef uint64_t u64;
typedef int64_t s64;
/* Mathematicial MIN/MAX/ABS (absolute value) macros */
#ifndef MAX
#define MAX(x,y) (((x)>(y))?(x):(y))
#endif
#ifndef MIN
#define MIN(x,y) (((x)<(y))?(x):(y))
#endif
#ifndef ABS
#define ABS(x) (((x) >= 0)?(x):-(x))
#endif
/* Timeval subtraction in microseconds */
#define TIMEVAL_SUBTRACT(a,b) (((a).tv_sec - (b).tv_sec) * 1000000 + (a).tv_usec - (b).tv_usec)
/* Timeval subtract in milliseconds */
#define TIMEVAL_MSEC_SUBTRACT(a,b) ((((a).tv_sec - (b).tv_sec) * 1000) + ((a).tv_usec - (b).tv_usec) / 1000)
/* Timeval subtract in seconds; truncate towards zero */
#define TIMEVAL_SEC_SUBTRACT(a,b) ((a).tv_sec - (b).tv_sec + (((a).tv_usec < (b).tv_usec) ? - 1 : 0))
/* Timeval subtract in fractional seconds; convert to float */
#define TIMEVAL_FSEC_SUBTRACT(a,b) ((a).tv_sec - (b).tv_sec + (((a).tv_usec - (b).tv_usec)/1000000.0))
/* assign one timeval to another timeval plus some msecs: a = b + msecs */
#define TIMEVAL_MSEC_ADD(a, b, msecs) { (a).tv_sec = (b).tv_sec + ((msecs) / 1000); (a).tv_usec = (b).tv_usec + ((msecs) % 1000) * 1000; (a).tv_sec += (a).tv_usec / 1000000; (a).tv_usec %= 1000000; }
#define TIMEVAL_ADD(a, b, usecs) { (a).tv_sec = (b).tv_sec + ((usecs) / 1000000); (a).tv_usec = (b).tv_usec + ((usecs) % 1000000); (a).tv_sec += (a).tv_usec / 1000000; (a).tv_usec %= 1000000; }
/* Find our if one timeval is before or after another, avoiding the integer
overflow that can result when doing a TIMEVAL_SUBTRACT on two widely spaced
timevals. */
#define TIMEVAL_BEFORE(a, b) (((a).tv_sec < (b).tv_sec) || ((a).tv_sec == (b).tv_sec && (a).tv_usec < (b).tv_usec))
#define TIMEVAL_AFTER(a, b) (((a).tv_sec > (b).tv_sec) || ((a).tv_sec == (b).tv_sec && (a).tv_usec > (b).tv_usec))
/* Convert a timeval to floating point seconds */
#define TIMEVAL_SECS(a) ((double) (a).tv_sec + (double) (a).tv_usec / 1000000)
/* sprintf family */
#if !defined(HAVE_SNPRINTF) && defined(__cplusplus)
extern "C" int snprintf (char *str, size_t sz, const char *format, ...)
__attribute__ ((format (printf, 3, 4)));
#endif
#if !defined(HAVE_VSNPRINTF) && defined(__cplusplus)
extern "C" int vsnprintf (char *str, size_t sz, const char *format,
va_list ap)
__attribute__((format (printf, 3, 0)));
#endif
#if !defined(HAVE_ASPRINTF) && defined(__cplusplus)
extern "C" int asprintf (char **ret, const char *format, ...)
__attribute__ ((format (printf, 2, 3)));
#endif
#if !defined(HAVE_VASPRINTF) && defined(__cplusplus)
extern "C" int vasprintf (char **ret, const char *format, va_list ap)
__attribute__((format (printf, 2, 0)));
#endif
#if !defined(HAVE_ASNPRINTF) && defined(__cplusplus)
extern "C" int asnprintf (char **ret, size_t max_sz, const char *format, ...)
__attribute__ ((format (printf, 3, 4)));
#endif
#if !defined(HAVE_VASNPRINTF) && defined(__cplusplus)
extern "C" int vasnprintf (char **ret, size_t max_sz, const char *format,
va_list ap)
__attribute__((format (printf, 3, 0)));
#endif
#if defined(NEED_SNPRINTF_PROTO) && defined(__cplusplus)
extern "C" int snprintf (char *, size_t, const char *, ...);
#endif
#if defined(NEED_VSNPRINTF_PROTO) && defined(__cplusplus)
extern "C" int vsnprintf (char *, size_t, const char *, va_list);
#endif
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#else
#ifndef HAVE_GETOPT_LONG_ONLY
#include "getopt.h"
#endif
#endif /* HAVE_GETOPT_H */
/* More Windows-specific stuff */
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN /* Whatever this means! From winclude.h*/
/* Apparently Windows doesn't have S_ISDIR */
#ifndef S_ISDIR
#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
#endif
/* Windows doesn't have the access() defines */
#ifndef F_OK
#define F_OK 00
#endif
#ifndef W_OK
#define W_OK 02
#endif
#ifndef R_OK
#define R_OK 04
#endif
/* wtf was ms thinking? */
#define access _access
#define stat _stat
#define execve _execve
#define getpid _getpid
#define dup _dup
#define dup2 _dup2
#define strdup _strdup
#define write _write
#define open _open
#define stricmp _stricmp
#define putenv _putenv
#if !defined(__GNUC__)
#define snprintf _snprintf
#endif
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
#define execv _execv
#endif /* WIN32 */
/* Apparently Windows doesn't like /dev/null */
#ifdef WIN32
#define DEVNULL "NUL"
#else
#define DEVNULL "/dev/null"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Returns the UNIX/Windows errno-equivalent. Note that the Windows
call is socket/networking specific. Also, WINDOWS TENDS TO RESET
THE ERROR, so it will return success the next time. So SAVE THE
RESULTS and re-use them, don't keep calling socket_errno(). The
windows error number returned is like WSAMSGSIZE, but nbase.h
includes #defines to correlate many of the common UNIX errors
with their closest Windows equivalents. So you can use EMSGSIZE
or EINTR. */
int socket_errno();
/* We can't just use strerror to get socket errors on Windows because it has
its own set of error codes: WSACONNRESET not ECONNRESET for example. This
function will do the right thing on Windows. Call it like
socket_strerror(socket_errno())
*/
char *socket_strerror(int errnum);
/* The usleep() function is important as well */
#ifndef HAVE_USLEEP
#if defined( HAVE_NANOSLEEP) || defined(WIN32)
void usleep(unsigned long usec);
#endif
#endif
/***************** String functions -- See nbase_str.c ******************/
/* I modified this conditional because !@# Redhat does not easily provide
the prototype even though the function exists */
#if !defined(HAVE_STRCASESTR) || (defined(LINUX) && !defined(__USE_GNU) && !defined(_GNU_SOURCE))
/* strcasestr is like strstr() except case insensitive */
char *strcasestr(const char *haystack, const char *pneedle);
#endif
#ifndef HAVE_STRCASECMP
int strcasecmp(const char *s1, const char *s2);
#endif
#ifndef HAVE_STRNCASECMP
int strncasecmp(const char *s1, const char *s2, size_t n);
#endif
#ifndef HAVE_GETTIMEOFDAY
int gettimeofday(struct timeval *tv, struct timeval *tz);
#endif
#ifndef HAVE_SLEEP
unsigned int sleep(unsigned int seconds);
#endif
/* Strncpy is like strcpy() except it ALWAYS zero-terminates, even if
it must truncate */
int Strncpy(char *dest, const char *src, size_t n);
int Vsnprintf(char *, size_t, const char *, va_list)
__attribute__ ((format (printf, 3, 0)));
int Snprintf(char *, size_t, const char *, ...)
__attribute__ ((format (printf, 3, 4)));
/* Trivial function that returns nonzero if all characters in str of
length strlength are printable (as defined by isprint()) */
int stringisprintable(const char *str, int strlength);
/* parse_long is like strtol or atoi, but it allows digits only.
No whitespace, sign, or radix prefix. */
long parse_long(const char *s, char **tail);
/* This function takes a byte count and stores a short ascii equivalent
in the supplied buffer. Eg: 0.122MB, 10.322Kb or 128B. */
char *format_bytecount(unsigned long long bytes, char *buf, size_t buflen);
/* Compare a canonical option name (e.g. "max-scan-delay") with a
user-generated option such as "max_scan_delay" and returns 0 if the
two values are considered equivalant (for example, - and _ are
considered to be the same), nonzero otherwise. */
int optcmp(const char *a, const char *b);
/* Convert non-printable characters to replchar in the string */
void replacenonprintable(char *str, int strlength, char replchar);
/* Returns one if the file pathname given exists, is not a directory and
* is readable by the executing process. Returns two if it is readable
* and is a directory. Otherwise returns 0. */
int fileexistsandisreadable(const char *pathname);
/* Portable, incompatible replacements for dirname and basename. */
char *path_get_dirname(const char *path);
char *path_get_basename(const char *path);
/* A few simple wrappers for the most common memory allocation routines which will exit() if the
allocation fails, so you don't always have to check -- see nbase_memalloc.c */
void *safe_malloc(size_t size);
void *safe_realloc(void *ptr, size_t size);
/* Zero-initializing version of safe_malloc */
void *safe_zalloc(size_t size);
/* Some routines for obtaining simple (not secure on systems that
lack /dev/random and friends' "random" numbers */
int get_random_bytes(void *buf, int numbytes);
int get_random_int();
unsigned short get_random_ushort();
unsigned int get_random_uint();
u32 get_random_u32();
u16 get_random_u16();
u8 get_random_u8();
u32 get_random_unique_u32();
/* Create a new socket inheritable by subprocesses. On non-Windows systems it's
just a normal socket. */
int inheritable_socket(int af, int style, int protocol);
/* The dup function on Windows works only on file descriptors, not socket
handles. This function accomplishes the same thing for sockets. */
int dup_socket(int sd);
int unblock_socket(int sd);
int block_socket(int sd);
/* CRC32 Cyclic Redundancy Check */
unsigned long nbase_crc32(unsigned char *buf, int len);
/* CRC32C Cyclic Redundancy Check (Castagnoli) */
unsigned long nbase_crc32c(unsigned char *buf, int len);
/* Adler32 Checksum */
unsigned long nbase_adler32(unsigned char *buf, int len);
double tval2secs(const char *tspec);
long tval2msecs(const char *tspec);
const char *tval_unit(const char *tspec);
int fselect(int s, fd_set *rmaster, fd_set *wmaster, fd_set *emaster, struct timeval *tv);
char *hexdump(const u8 *cp, u32 length);
char *executable_path(const char *argv0);
/* addrset management functions and definitions */
/* A set of addresses. Used to match against allow/deny lists. */
struct addrset_elem;
/* A set of addresses. Used to match against allow/deny lists. */
struct addrset {
/* Linked list of struct addset_elem. */
struct addrset_elem *head;
};
void nbase_set_log(void (*log_user_func)(const char *, ...),void (*log_debug_func)(const char *, ...));
extern void addrset_init(struct addrset *set);
extern void addrset_free(struct addrset *set);
extern int addrset_add_spec(struct addrset *set, const char *spec, int af, int dns);
extern int addrset_add_file(struct addrset *set, FILE *fd, int af, int dns);
extern int addrset_contains(const struct addrset *set, const struct sockaddr *sa);
#ifndef STDIN_FILENO
#define STDIN_FILENO 0
#endif
#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif
#ifndef STDERR_FILENO
#define STDERR_FILENO 2
#endif
#include "nbase_ipv6.h"
#ifdef __cplusplus
}
#endif
#endif /* NBASE_H */

128
nbase/nbase.vcxproj Normal file
View File

@@ -0,0 +1,128 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Static|Win32">
<Configuration>Static</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{B630C8F7-3138-43E8-89ED-78742FA2AC5F}</ProjectGuid>
<RootNamespace>nbase</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Static|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Static|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Debug\</IntDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Static|Win32'">.\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Release\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Static|Win32'">Release\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)nbase.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalOptions>/D "_CRT_SECURE_NO_DEPRECATE" %(AdditionalOptions)</AdditionalOptions>
<PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)nbase.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Static|Win32'">
<ClCompile>
<AdditionalOptions>/D "_CRT_SECURE_NO_DEPRECATE" %(AdditionalOptions)</AdditionalOptions>
<PreprocessorDefinitions>WIN32;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)nbase.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="getopt.c" />
<ClCompile Include="inet_ntop.c" />
<ClCompile Include="inet_pton.c" />
<ClCompile Include="nbase_addrset.c" />
<ClCompile Include="nbase_memalloc.c" />
<ClCompile Include="nbase_misc.c" />
<ClCompile Include="nbase_rnd.c" />
<ClCompile Include="nbase_str.c" />
<ClCompile Include="nbase_time.c" />
<ClCompile Include="nbase_winunix.c" />
<ClCompile Include="strcasecmp.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="getopt.h" />
<ClInclude Include="nbase.h" />
<ClInclude Include="nbase_addrset.h" />
<ClInclude Include="nbase_ipv6.h" />
<ClInclude Include="nbase_winconfig.h" />
<ClInclude Include="nbase_winunix.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

611
nbase/nbase_addrset.c Normal file
View File

@@ -0,0 +1,611 @@
/***************************************************************************
* nbase_addrset.c -- Address set (addrset) management. *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* The code in this file has tests in the file ncat/tests/test-addrset.sh. Run that
program after making any big changes. Also, please add tests for any new
features. */
#include "nbase.h"
#include "nbase_addrset.h"
/* A fancy logging system to allow this file to take advantage of different logging
systems used by various programs */
static void default_log_user(const char * a, ...){};
static void (*log_user)(const char *, ...) = default_log_user;
static void default_log_debug(const char * a, ...){};
static void (*log_debug)(const char *, ...) = default_log_debug;
void nbase_set_log(void (*log_user_func)(const char *, ...),void (*log_debug_func)(const char *, ...)){
if (log_user_func == NULL)
log_user = default_log_user;
else
log_user = log_user_func;
if (log_debug_func == NULL)
log_debug = default_log_debug;
else
log_debug = log_debug_func;
}
void addrset_init(struct addrset *set)
{
set->head = NULL;
}
void addrset_free(struct addrset *set)
{
struct addrset_elem *elem, *next;
for (elem = set->head; elem != NULL; elem = next) {
next = elem->next;
free(elem);
}
}
/* A debugging function to print out the contents of an addrset_elem. For IPv4
this is the four bit vectors. For IPv6 it is the address and netmask. */
void addrset_elem_print(const struct addrset_elem *elem)
{
int i, j;
if (elem->type == ADDRSET_TYPE_IPV4_BITVECTOR) {
for (i = 0; i < 4; i++) {
for (j = 0; j < sizeof(octet_bitvector) / sizeof(bitvector_t); j++)
printf("%08lX ", elem->u.ipv4.bits[i][j]);
printf("\n");
}
#ifdef HAVE_IPV6
} else if (elem->type == ADDRSET_TYPE_IPV6_NETMASK) {
for (i = 0; i < 16; i += 2) {
if (i > 0)
printf(":");
printf("%02X", elem->u.ipv6.addr.s6_addr[i]);
printf("%02X", elem->u.ipv6.addr.s6_addr[i + 1]);
}
printf(" ");
for (i = 0; i < 16; i += 2) {
if (i > 0)
printf(":");
printf("%02X", elem->u.ipv6.mask.s6_addr[i]);
printf("%02X", elem->u.ipv6.mask.s6_addr[i + 1]);
}
printf("\n");
#endif
}
printf("---\n");
}
/* This is a wrapper around getaddrinfo that automatically handles hints for
IPv4/IPv6, TCP/UDP, and whether name resolution is allowed. */
static int resolve_name(const char *name, struct addrinfo **result, int af, int use_dns)
{
struct addrinfo hints = { 0 };
int rc;
hints.ai_protocol = IPPROTO_TCP;
/* First do a non-DNS lookup for any address family (just checks for a valid
numeric address). We recognize numeric addresses no matter the setting of
af. This is also the last step if use_dns is false. */
hints.ai_flags |= AI_NUMERICHOST;
hints.ai_family = AF_UNSPEC;
*result = NULL;
rc = getaddrinfo(name, NULL, &hints, result);
if (rc == 0 || !use_dns)
return rc;
/* Do a DNS lookup now. When we look up a name we only want addresses
corresponding to the value of af. */
hints.ai_flags &= ~AI_NUMERICHOST;
hints.ai_family = af;
*result = NULL;
rc = getaddrinfo(name, NULL, &hints, result);
return rc;
}
/* This is an address family-agnostic version of inet_ntop. */
static char *address_to_string(const struct sockaddr *sa, size_t sa_len,
char *buf, size_t len)
{
getnameinfo(sa, sa_len, buf, len, NULL, 0, NI_NUMERICHOST);
return buf;
}
/* Break an IPv4 address into an array of octets. */
static void in_addr_to_octets(const struct in_addr *ia, uint8_t octets[4])
{
octets[0] = (uint8_t) (ia->s_addr & 0xFF);
octets[1] = (uint8_t) ((ia->s_addr & (0xFF << 8)) >> 8);
octets[2] = (uint8_t) ((ia->s_addr & (0xFF << 16)) >> 16);
octets[3] = (uint8_t) ((ia->s_addr & (0xFF << 24)) >> 24);
}
#define BITVECTOR_BITS (sizeof(bitvector_t) * CHAR_BIT)
#define BIT_SET(v, n) ((v)[(n) / BITVECTOR_BITS] |= 1UL << ((n) % BITVECTOR_BITS))
#define BIT_IS_SET(v, n) (((v)[(n) / BITVECTOR_BITS] & 1UL << ((n) % BITVECTOR_BITS)) != 0)
static int parse_ipv4_ranges(struct addrset_elem *elem, const char *spec);
static void apply_ipv4_netmask_bits(struct addrset_elem *elem, int bits);
#ifdef HAVE_IPV6
static void make_ipv6_netmask(struct in6_addr *mask, int bits);
#endif
/* Add a host specification into the address set. Returns 1 on success, 0 on
error. */
int addrset_add_spec(struct addrset *set, const char *spec, int af, int dns)
{
char *local_spec;
char *netmask_s;
char *tail;
long netmask_bits;
struct addrinfo *addrs, *addr;
struct addrset_elem *elem;
int rc;
/* Make a copy of the spec to mess with. */
local_spec = strdup(spec);
if (local_spec == NULL)
return 0;
/* Read the CIDR netmask bits, if present. */
netmask_s = strchr(local_spec, '/');
if (netmask_s == NULL) {
/* A negative value means unspecified; default depends on the address
family. */
netmask_bits = -1;
} else {
*netmask_s = '\0';
netmask_s++;
errno = 0;
netmask_bits = parse_long(netmask_s, &tail);
if (errno != 0 || *tail != '\0' || tail == netmask_s) {
log_user("Error parsing netmask in \"%s\".\n", spec);
free(local_spec);
return 0;
}
}
elem = (struct addrset_elem *) safe_malloc(sizeof(*elem));
memset(elem->u.ipv4.bits, 0, sizeof(elem->u.ipv4.bits));
/* Check if this is an IPv4 address, with optional ranges and wildcards. */
if (parse_ipv4_ranges(elem, local_spec)) {
if (netmask_bits > 32) {
log_user("Illegal netmask in \"%s\". Must be between 0 and 32.\n", spec);
free(local_spec);
free(elem);
return 0;
}
apply_ipv4_netmask_bits(elem, netmask_bits);
log_debug("Add IPv4 range %s/%ld to addrset.\n", local_spec, netmask_bits > 0 ? netmask_bits : 32);
elem->type = ADDRSET_TYPE_IPV4_BITVECTOR;
elem->next = set->head;
set->head = elem;
free(local_spec);
return 1;
} else {
free(elem);
}
/* When all else fails, resolve the name. */
rc = resolve_name(local_spec, &addrs, af, dns);
if (rc != 0) {
log_user("Error resolving name \"%s\": %s\n", local_spec, gai_strerror(rc));
free(local_spec);
return 0;
}
if (addrs == NULL)
log_user("Warning: no addresses found for %s.\n", local_spec);
free(local_spec);
/* Walk the list of addresses and add them all to the set with netmasks. */
for (addr = addrs; addr != NULL; addr = addr->ai_next) {
char addr_string[128];
elem = (struct addrset_elem *) safe_malloc(sizeof(*elem));
memset(elem->u.ipv4.bits, 0, sizeof(elem->u.ipv4.bits));
address_to_string(addr->ai_addr, addr->ai_addrlen, addr_string, sizeof(addr_string));
/* Note: it is possible that in this loop we are dealing with addresses
of more than one family (e.g., IPv4 and IPv6). But we have at most
one netmask value for all of them. Whatever netmask we have is
applied blindly to whatever addresses there are, which may not be
what you want if a /24 is applied to IPv6 and will cause an error if
a /120 is applied to IPv4. */
if (addr->ai_family == AF_INET) {
const struct sockaddr_in *sin = (struct sockaddr_in *) addr->ai_addr;
uint8_t octets[4];
elem->type = ADDRSET_TYPE_IPV4_BITVECTOR;
in_addr_to_octets(&sin->sin_addr, octets);
BIT_SET(elem->u.ipv4.bits[0], octets[0]);
BIT_SET(elem->u.ipv4.bits[1], octets[1]);
BIT_SET(elem->u.ipv4.bits[2], octets[2]);
BIT_SET(elem->u.ipv4.bits[3], octets[3]);
if (netmask_bits > 32) {
log_user("Illegal netmask in \"%s\". Must be between 0 and 32.\n", spec);
free(elem);
return 0;
}
apply_ipv4_netmask_bits(elem, netmask_bits);
log_debug("Add IPv4 %s/%ld to addrset.\n", addr_string, netmask_bits > 0 ? netmask_bits : 32);
#ifdef HAVE_IPV6
} else if (addr->ai_family == AF_INET6) {
const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) addr->ai_addr;
elem->type = ADDRSET_TYPE_IPV6_NETMASK;
elem->u.ipv6.addr = sin6->sin6_addr;
if (netmask_bits > 128) {
log_user("Illegal netmask in \"%s\". Must be between 0 and 128.\n", spec);
free(elem);
return 0;
}
make_ipv6_netmask(&elem->u.ipv6.mask, netmask_bits);
log_debug("Add IPv6 %s/%ld to addrset.\n", addr_string, netmask_bits > 0 ? netmask_bits : 128);
#endif
} else {
log_debug("ignoring address %s for %s. Family %d socktype %d protocol %d.\n", addr_string, spec, addr->ai_family, addr->ai_socktype, addr->ai_protocol);
free(elem);
continue;
}
elem->next = set->head;
set->head = elem;
}
if (addrs != NULL)
freeaddrinfo(addrs);
return 1;
}
/* Add whitespace-separated host specifications from fd into the address set.
Returns 1 on success, 0 on error. */
int addrset_add_file(struct addrset *set, FILE *fd, int af, int dns)
{
char buf[1024];
int c, i;
for (;;) {
/* Skip whitespace. */
while ((c = getc(fd)) != EOF) {
if (!isspace(c))
break;
}
if (c == EOF)
break;
ungetc(c, fd);
i = 0;
while ((c = getc(fd)) != EOF) {
if (isspace(c))
break;
if (i + 1 > sizeof(buf) - 1) {
/* Truncate the specification to give a little context. */
buf[11] = '\0';
log_user("Host specification starting with \"%s\" is too long.\n", buf);
return 0;
}
buf[i++] = c;
}
buf[i] = '\0';
if (!addrset_add_spec(set, buf, af, dns))
return 0;
}
return 1;
}
/* Parse an IPv4 address with optional ranges and wildcards into bit vectors.
Each octet must match the regular expression '(\*|#?(-#?)?(,#?(-#?)?)*)',
where '#' stands for an integer between 0 and 255. Return 1 on success, 0 on
error. */
static int parse_ipv4_ranges(struct addrset_elem *elem, const char *spec)
{
const char *p;
int octet_index, i;
p = spec;
octet_index = 0;
while (*p != '\0' && octet_index < 4) {
if (*p == '*') {
for (i = 0; i < 256; i++)
BIT_SET(elem->u.ipv4.bits[octet_index], i);
p++;
} else {
for (;;) {
long start, end;
char *tail;
errno = 0;
start = parse_long(p, &tail);
/* Is this a range open on the left? */
if (tail == p) {
if (*p == '-')
start = 0;
else
return 0;
}
if (errno != 0 || start < 0 || start > 255)
return 0;
p = tail;
/* Look for a range. */
if (*p == '-') {
p++;
errno = 0;
end = parse_long(p, &tail);
/* Is this range open on the right? */
if (tail == p)
end = 255;
if (errno != 0 || end < 0 || end > 255 || end < start)
return 0;
p = tail;
} else {
end = start;
}
/* Fill in the range in the bit vector. */
for (i = start; i <= end; i++)
BIT_SET(elem->u.ipv4.bits[octet_index], i);
if (*p != ',')
break;
p++;
}
}
octet_index++;
if (octet_index < 4) {
if (*p != '.')
return 0;
p++;
}
}
if (*p != '\0' || octet_index < 4)
return 0;
return 1;
}
/* Expand a single-octet bit vector to include any additional addresses that
result when mask is applied. */
static void apply_ipv4_netmask_octet(octet_bitvector bits, uint8_t mask)
{
unsigned int i, j;
uint32_t chunk_size;
/* Process the bit vector in chunks, first of size 1, then of size 2, up to
size 128. Check the next bit of the mask. If it is 1, do nothing.
Otherwise, pair up the chunks (first with the second, third with the
fourth, etc.). For each pair of chunks, set a bit in one chunk if it is
set in the other. chunk_size also serves as an index into the mask. */
for (chunk_size = 1; chunk_size < 256; chunk_size <<= 1) {
if ((mask & chunk_size) != 0)
continue;
for (i = 0; i < 256; i += chunk_size * 2) {
for (j = 0; j < chunk_size; j++) {
if (BIT_IS_SET(bits, i + j))
BIT_SET(bits, i + j + chunk_size);
else if (BIT_IS_SET(bits, i + j + chunk_size))
BIT_SET(bits, i + j);
}
}
}
}
/* Expand an addrset_elem's IPv4 bit vectors to include any additional addresses
that result when the given netmask is applied. The mask is in network byte
order. */
static void apply_ipv4_netmask(struct addrset_elem *elem, uint32_t mask)
{
mask = ntohl(mask);
/* Apply the mask one octet at a time. It's done this way because ranges
span exactly one octet. */
apply_ipv4_netmask_octet(elem->u.ipv4.bits[0], (mask & 0xFF000000) >> 24);
apply_ipv4_netmask_octet(elem->u.ipv4.bits[1], (mask & 0x00FF0000) >> 16);
apply_ipv4_netmask_octet(elem->u.ipv4.bits[2], (mask & 0x0000FF00) >> 8);
apply_ipv4_netmask_octet(elem->u.ipv4.bits[3], (mask & 0x000000FF));
}
/* Expand an addrset_elem's IPv4 bit vectors to include any additional addresses
that result from the application of a CIDR-style netmask with the given
number of bits. If bits is negative it is taken to be 32. */
static void apply_ipv4_netmask_bits(struct addrset_elem *elem, int bits)
{
uint32_t mask;
if (bits > 32)
return;
if (bits < 0)
bits = 32;
if (bits == 0)
mask = htonl(0x00000000);
else
mask = htonl(0xFFFFFFFF << (32 - bits));
apply_ipv4_netmask(elem, mask);
}
#ifdef HAVE_IPV6
/* Fill in an in6_addr with a CIDR-style netmask with the given number of bits.
If bits is negative it is taken to be 128. The netmask is written in network
byte order. */
static void make_ipv6_netmask(struct in6_addr *mask, int bits)
{
int i;
memset(mask, 0, sizeof(*mask));
if (bits > 128)
return;
if (bits < 0)
bits = 128;
if (bits == 0)
return;
i = 0;
/* 0 < bits <= 128, so this loop goes at most 15 times. */
for ( ; bits > 8; bits -= 8)
mask->s6_addr[i++] = 0xFF;
mask->s6_addr[i] = 0xFF << (8 - bits);
}
#endif
static int match_ipv4_bits(const octet_bitvector bits[4], const struct sockaddr *sa)
{
uint8_t octets[4];
if (sa->sa_family != AF_INET)
return 0;
in_addr_to_octets(&((const struct sockaddr_in *) sa)->sin_addr, octets);
return BIT_IS_SET(bits[0], octets[0])
&& BIT_IS_SET(bits[1], octets[1])
&& BIT_IS_SET(bits[2], octets[2])
&& BIT_IS_SET(bits[3], octets[3]);
}
#ifdef HAVE_IPV6
static int match_ipv6_netmask(const struct in6_addr *addr,
const struct in6_addr *mask, const struct sockaddr *sa)
{
const uint8_t *a = addr->s6_addr;
const uint8_t *m = mask->s6_addr;
const uint8_t *b = ((const struct sockaddr_in6 *) sa)->sin6_addr.s6_addr;
int i;
if (sa->sa_family != AF_INET6)
return 0;
for (i = 0; i < 16; i++) {
if ((a[i] & m[i]) != (b[i] & m[i]))
return 0;
}
return 1;
}
#endif
static int addrset_elem_match(const struct addrset_elem *elem, const struct sockaddr *sa)
{
switch (elem->type) {
case ADDRSET_TYPE_IPV4_BITVECTOR:
return match_ipv4_bits(elem->u.ipv4.bits, sa);
#ifdef HAVE_IPV6
case ADDRSET_TYPE_IPV6_NETMASK:
return match_ipv6_netmask(&elem->u.ipv6.addr, &elem->u.ipv6.mask, sa);
#endif
}
return 0;
}
int addrset_contains(const struct addrset *set, const struct sockaddr *sa)
{
struct addrset_elem *elem;
for (elem = set->head; elem != NULL; elem = elem->next) {
if (addrset_elem_match(elem, sa))
return 1;
}
return 0;
}

138
nbase/nbase_addrset.h Normal file
View File

@@ -0,0 +1,138 @@
/***************************************************************************
* nbase_addrset.h *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
#ifndef _NBASE_ADDRSET_H
#define _NBASE_ADDRSET_H
//#define HAVE_IPV6 1
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#ifndef WIN32
#include <sys/socket.h>
#endif
#include "nbase.h"
/* We use bit vectors to represent what values are allowed in an IPv4 octet.
Each vector is built up of an array of bitvector_t (any convenient integer
type). */
typedef unsigned long bitvector_t;
/* A 256-element bit vector, representing legal values for one octet. */
typedef bitvector_t octet_bitvector[(256 - 1) / (sizeof(unsigned long) * CHAR_BIT) + 1];
enum addrset_elem_type {
ADDRSET_TYPE_IPV4_BITVECTOR,
#ifdef HAVE_IPV6
ADDRSET_TYPE_IPV6_NETMASK,
#endif
};
/* A chain of tests for set inclusion. If one test is passed, the address is in
the set. */
struct addrset_elem {
enum addrset_elem_type type;
union {
struct {
/* A bit vector for each address octet. */
octet_bitvector bits[4];
} ipv4;
#ifdef HAVE_IPV6
struct {
struct in6_addr addr;
struct in6_addr mask;
} ipv6;
#endif
} u;
struct addrset_elem *next;
};
#endif

236
nbase/nbase_config.h.in Normal file
View File

@@ -0,0 +1,236 @@
/***************************************************************************
* nbase_config.h.in -- Autoconf uses this template, combined with the *
* configure script knowledge about system capabilities, to build the *
* nbase_config.h file that lets nbase (and libraries that call it) better *
* understand system particulars. *
* *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#ifndef NBASE_CONFIG_H
#define NBASE_CONFIG_H
#undef HAVE_USLEEP
#undef HAVE_NANOSLEEP
#undef HAVE_STRUCT_ICMP
#undef HAVE_IP_IP_SUM
#undef inline
#undef STDC_HEADERS
#undef HAVE_STRING_H
#undef HAVE_NETDB_H
#undef HAVE_GETOPT_H
#undef HAVE_UNISTD_H
#undef HAVE_STRINGS_H
#undef HAVE_BSTRING_H
#undef WORDS_BIGENDIAN
#undef HAVE_MEMORY_H
#undef HAVE_LIBIBERTY_H
#undef HAVE_FCNTL_H
#undef HAVE_ERRNO_H
/* both bzero() and memcpy() are used in the source */
#undef HAVE_BZERO
#undef HAVE_MEMCPY
#undef HAVE_STRERROR
#undef HAVE_SYS_PARAM_H
#undef HAVE_SYS_SOCKIO_H
#undef HAVE_SYS_SOCKET_H
#undef HAVE_SYS_WAIT_H
#undef HAVE_NET_IF_H
#undef BSD_NETWORKING
#undef HAVE_STRCASESTR
#undef HAVE_STRCASECMP
#undef HAVE_STRNCASECMP
#undef HAVE_GETTIMEOFDAY
#undef HAVE_SLEEP
#undef HAVE_SIGNAL
#undef HAVE_GETOPT
#undef HAVE_GETOPT_LONG_ONLY
#undef HAVE_SOCKADDR_SA_LEN
#undef HAVE_NETINET_IF_ETHER_H
#undef HAVE_NETINET_IN_H
#undef HAVE_SYS_TIME_H
#undef PWD_H
#undef HAVE_ARPA_INET_H
#undef HAVE_SYS_RESOURCE_H
#undef HAVE_INTTYPES_H
#undef HAVE_MACH_O_DYLD_H
#undef HAVE_RPC_TYPES_H
#undef HAVE_SYS_STAT_H
#undef SPRINTF_RETURNS_STRING
#undef STUPID_SOLARIS_CHECKSUM_BUG
/* IPv6 stuff */
#undef HAVE_IPV6
#undef HAVE_AF_INET6
#undef HAVE_SOCKADDR_IN6
#undef HAVE_SOCKADDR_STORAGE
#undef HAVE_GETADDRINFO
#undef HAVE_GAI_STRERROR
#undef HAVE_GETNAMEINFO
#undef HAVE_INET_NTOP
#undef HAVE_INET_PTON
#undef int8_t
#undef int16_t
#undef int32_t
#undef int64_t
#undef uint8_t
#undef uint16_t
#undef uint32_t
#undef uint64_t
#undef HAVE_SNPRINTF
#undef HAVE_VASNPRINTF
#undef HAVE_ASPRINTF
#undef HAVE_VASPRINTF
#undef HAVE_VFPRINTF
#undef HAVE_VSNPRINTF
#undef NEED_SNPRINTF_PROTO
#undef NEED_VSNPRINTF_PROTO
/* define if your compiler has __attribute__ */
#undef HAVE___ATTRIBUTE__
#undef HAVE_OPENSSL
#undef HAVE_PROC_SELF_EXE
#undef LINUX
#undef FREEBSD
#undef OPENBSD
#undef SOLARIS
#undef SUNOS
#undef BSDI
#undef IRIX
#undef HPUX
#undef NETBSD
#endif /* NBASE_CONFIG_H */

166
nbase/nbase_crc32ct.h Normal file
View File

@@ -0,0 +1,166 @@
/***************************************************************************
* nbase_crc32ct.h -- CRC-32C (Castagnoli) table definitions. *
* *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#ifndef NBASE_CRC32CT_H
#define NBASE_CRC32CT_H
#define CRC32C_POLY 0x1EDC6F41
#define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])
static unsigned long crc_c[256] = {
0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L,
};
#endif /* NBASE_CRC32CT_H */

245
nbase/nbase_ipv6.h Normal file
View File

@@ -0,0 +1,245 @@
/***************************************************************************
* nbase_ipv6.h -- IPv6 portability classes and structures These were *
* written by fyodor@insecure.org . *
* *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#ifndef NBASE_IPV6_H
#define NBASE_IPV6_H
#ifdef __amigaos__
#ifndef _NMAP_AMIGAOS_H_
#include "../nmap_amigaos.h"
#endif
#endif
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#if HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#if HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifndef HAVE_AF_INET6
#define AF_INET6 10
#define PF_INET6 10
#endif /* HAVE_AF_INET6 */
#ifndef HAVE_INET_PTON
/* int
* inet_pton(af, src, dst)
* convert from presentation format (which usually means ASCII printable)
* to network format (which is usually some kind of binary format).
* return:
* 1 if the address was valid for the specified address family
* 0 if the address wasn't valid (`dst' is untouched in this case)
* -1 if some other error occurred (`dst' is untouched in this case, too)
* author:
* Paul Vixie, 1996.
*/
int inet_pton(int af, const char *src, void *dst);
#endif /* HAVE_INET_PTON */
#ifndef HAVE_INET_NTOP
/* char *
* inet_ntop(af, src, dst, size)
* convert a network format address to presentation format.
* return:
* pointer to presentation format address (`dst'), or NULL (see errno).
* author:
* Paul Vixie, 1996.
*/
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
#endif /* HAVE_INET_NTOP */
#ifndef HAVE_SOCKADDR_STORAGE
/* Just needs to be big enough to hold sockaddr_in or
sockaddr_in6. I should really align it at 64 bits, but 32 is
probably fine as hosts that actually want to store a
sockaddr_in6 in here should already have this defined (see
RFC2355). */
struct sockaddr_storage {
u32 padding[32];
};
#endif /* SOCKADDR_STORAGE */
/* Compares two sockaddr_storage structures with a return value like strcmp.
First the address families are compared, then the addresses if the families
are equal. The structures must be real full-length sockaddr_storage
structures, not something shorter like sockaddr_in. */
int sockaddr_storage_cmp(const struct sockaddr_storage *a,
const struct sockaddr_storage *b);
/* Does sockaddr_storage_cmp(a, b) == 0 for you. */
int sockaddr_storage_equal(const struct sockaddr_storage *a,
const struct sockaddr_storage *b);
/* This function is an easier version of inet_ntop because you don't
need to pass a dest buffer. Instead, it returns a static buffer that
you can use until the function is called again (by the same or another
thread in the process). If there is a wierd error (like sslen being
too short) then NULL will be returned. */
const char *inet_ntop_ez(const struct sockaddr_storage *ss, size_t sslen);
#if !HAVE_GETNAMEINFO || !HAVE_GETADDRINFO
#if !defined(EAI_MEMORY)
#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */
#define EAI_AGAIN 2 /* temporary failure in name resolution */
#define EAI_BADFLAGS 3 /* invalid value for ai_flags */
#define EAI_FAIL 4 /* non-recoverable failure in name resolution */
#define EAI_FAMILY 5 /* ai_family not supported */
#define EAI_MEMORY 6 /* memory allocation failure */
#define EAI_NODATA 7 /* no address associated with hostname */
#define EAI_NONAME 8 /* hostname nor servname provided, or not known */
#define EAI_SERVICE 9 /* servname not supported for ai_socktype */
#define EAI_SOCKTYPE 10 /* ai_socktype not supported */
#define EAI_SYSTEM 11 /* system error returned in errno */
#define EAI_BADHINTS 12
#define EAI_PROTOCOL 13
#define EAI_MAX 14
#endif /* EAI_MEMORY */
#endif /* !HAVE_GETNAMEINFO || !HAVE_GETADDRINFO */
#if !HAVE_GETNAMEINFO
/* This replacement version is *NOT* a full implementation by any
stretch of the imagination */
/* getnameinfo flags */
#if !defined(NI_NAMEREQD)
#define NI_NOFQDN 8
#define NI_NUMERICHOST 16
#define NI_NAMEREQD 32
#define NI_NUMERICSERV 64
#define NI_DGRAM 128
#endif
struct sockaddr;
int getnameinfo(const struct sockaddr *sa, size_t salen,
char *host, size_t hostlen,
char *serv, size_t servlen, int flags);
#endif /* !HAVE_GETNAMEINFO */
#if !HAVE_GETADDRINFO
/* This replacement version is *NOT* a full implementation by any
stretch of the imagination */
struct addrinfo {
int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
int ai_family; /* PF_xxx */
int ai_socktype; /* SOCK_xxx */
int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
size_t ai_addrlen; /* length of ai_addr */
char *ai_canonname; /* canonical name for nodename */
struct sockaddr *ai_addr; /* binary address */
struct addrinfo *ai_next; /* next structure in linked list */
};
/* getaddrinfo Flags */
#if !defined(AI_PASSIVE) || !defined(AI_CANONNAME) || !defined(AI_NUMERICHOST)
#define AI_PASSIVE 1
#define AI_CANONNAME 2
#define AI_NUMERICHOST 4
#endif
void freeaddrinfo(struct addrinfo *res);
int getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints, struct addrinfo **res);
#endif /* !HAVE_GETADDRINFO */
#ifndef HAVE_GAI_STRERROR
const char *gai_strerror(int errcode);
#endif
#endif /* NBASE_IPV6_H */

144
nbase/nbase_memalloc.c Normal file
View File

@@ -0,0 +1,144 @@
/***************************************************************************
* nbase_memalloc.c -- A few simple functions related to memory *
* allocation. Right now they are just safe_ versions of well known calls *
* like malloc that quit if the allocation fails (so you don't have to *
* have a bunch of ugly checks in your code. These were written by *
* fyodor@insecure.org . *
* *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include "nbase.h"
#include <stdio.h>
static void fatal(char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
static void fatal(char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fflush(stdout);
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\nQUITTING!\n");
va_end(ap);
exit(1);
}
void *safe_malloc(size_t size)
{
void *mymem;
if ((int) size < 0) /* Catch caller errors */
fatal("Tried to malloc negative amount of memory!!!");
mymem = malloc(size);
if (mymem == NULL)
fatal("Malloc Failed! Probably out of space.");
return mymem;
}
void *safe_realloc(void *ptr, size_t size)
{
void *mymem;
if ((int) size < 0) /* Catch caller errors */
fatal("Tried to realloc negative amount of memory!!!");
mymem = realloc(ptr, size);
if (mymem == NULL)
fatal("Realloc Failed! Probably out of space.");
return mymem;
}
/* Zero-initializing version of safe_malloc */
void *safe_zalloc(size_t size)
{
void *mymem;
if ((int) size < 0)
fatal("Tried to malloc negative amount of memory!!!");
mymem = calloc(1, size);
if (mymem == NULL)
fatal("Malloc Failed! Probably out of space.");
return mymem;
}

834
nbase/nbase_misc.c Normal file
View File

@@ -0,0 +1,834 @@
/***************************************************************************
* nbase_misc.c -- Some small miscelaneous utility/compatability *
* functions. *
* *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include "nbase.h"
#ifndef WIN32
#include <errno.h>
#ifndef errno
extern int errno;
#endif
#else
#include <winsock2.h>
#endif
#include <limits.h>
#include <stdio.h>
#include "nbase_ipv6.h"
#include "nbase_crc32ct.h"
#include <assert.h>
#include <fcntl.h>
#ifdef WIN32
#include <conio.h>
#endif
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 46
#endif
/* Returns the UNIX/Windows errno-equivalent. Note that the Windows
call is socket/networking specific. The windows error number
returned is like WSAMSGSIZE, but nbase.h includes #defines to
correlate many of the common UNIX errors with their closest Windows
equivalents. So you can use EMSGSIZE or EINTR. */
int socket_errno() {
#ifdef WIN32
return WSAGetLastError();
#else
return errno;
#endif
}
/* We can't just use strerror to get socket errors on Windows because it has
its own set of error codes: WSACONNRESET not ECONNRESET for example. This
function will do the right thing on Windows. Call it like
socket_strerror(socket_errno())
*/
char *socket_strerror(int errnum) {
#ifdef WIN32
static char buffer[128];
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_MAX_WIDTH_MASK,
0, errnum, 0, buffer, sizeof(buffer), NULL);
return buffer;
#else
return strerror(errnum);
#endif
}
/* Compares two sockaddr_storage structures with a return value like strcmp.
First the address families are compared, then the addresses if the families
are equal. The structures must be real full-length sockaddr_storage
structures, not something shorter like sockaddr_in. */
int sockaddr_storage_cmp(const struct sockaddr_storage *a,
const struct sockaddr_storage *b) {
if (a->ss_family < b->ss_family)
return -1;
else if (a->ss_family > b->ss_family)
return 1;
if (a->ss_family == AF_INET) {
struct sockaddr_in *sin_a = (struct sockaddr_in *) a;
struct sockaddr_in *sin_b = (struct sockaddr_in *) b;
if (sin_a->sin_addr.s_addr < sin_b->sin_addr.s_addr)
return -1;
else if (sin_a->sin_addr.s_addr > sin_b->sin_addr.s_addr)
return 1;
else
return 0;
} else if (a->ss_family == AF_INET6) {
struct sockaddr_in6 *sin6_a = (struct sockaddr_in6 *) a;
struct sockaddr_in6 *sin6_b = (struct sockaddr_in6 *) b;
return memcmp(sin6_a->sin6_addr.s6_addr, sin6_b->sin6_addr.s6_addr,
sizeof(sin6_a->sin6_addr.s6_addr));
} else {
assert(0);
}
return 0; /* Not reached */
}
int sockaddr_storage_equal(const struct sockaddr_storage *a,
const struct sockaddr_storage *b) {
return sockaddr_storage_cmp(a, b) == 0;
}
/* This function is an easier version of inet_ntop because you don't
need to pass a dest buffer. Instead, it returns a static buffer that
you can use until the function is called again (by the same or another
thread in the process). If there is a wierd error (like sslen being
too short) then NULL will be returned. */
const char *inet_ntop_ez(const struct sockaddr_storage *ss, size_t sslen) {
const struct sockaddr_in *sin = (struct sockaddr_in *) ss;
static char str[INET6_ADDRSTRLEN];
#if HAVE_IPV6
const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) ss;
#endif
str[0] = '\0';
if (sin->sin_family == AF_INET) {
if (sslen < sizeof(struct sockaddr_in))
return NULL;
return inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str));
}
#if HAVE_IPV6
else if(sin->sin_family == AF_INET6) {
if (sslen < sizeof(struct sockaddr_in6))
return NULL;
return inet_ntop(AF_INET6, &sin6->sin6_addr, str, sizeof(str));
}
#endif
//Some laptops report the ip and address family of disabled wifi cards as null
//so yes, we will hit this sometimes.
return NULL;
}
/* Create a new socket inheritable by subprocesses. On non-Windows systems it's
just a normal socket. */
int inheritable_socket(int af, int style, int protocol) {
#ifdef WIN32
/* WSASocket is just like socket, except that the sockets it creates are
inheritable by subprocesses (such as are created by CreateProcess), while
those created by socket are not. */
return WSASocket(af, style, protocol, NULL, 0, 0);
#else
return socket(af, style, protocol);
#endif
}
/* The dup function on Windows works only on file descriptors, not socket
handles. This function accomplishes the same thing for sockets. */
int dup_socket(int sd) {
#ifdef WIN32
HANDLE copy;
if (DuplicateHandle(GetCurrentProcess(), (HANDLE) sd,
GetCurrentProcess(), &copy,
0, FALSE, DUPLICATE_SAME_ACCESS) == 0) {
return -1;
}
return (int) copy;
#else
return dup(sd);
#endif
}
int unblock_socket(int sd) {
#ifdef WIN32
u_long one = 1;
if(sd != 501) // Hack related to WinIP Raw Socket support
ioctlsocket (sd, FIONBIO, &one);
#else
int options;
/*Unblock our socket to prevent recvfrom from blocking forever
on certain target ports. */
options = O_NONBLOCK | fcntl(sd, F_GETFL);
fcntl(sd, F_SETFL, options);
#endif //WIN32
return 1;
}
/* Convert a socket to blocking mode */
int block_socket(int sd) {
#ifdef WIN32
unsigned long options=0;
if(sd == 501) return 1;
ioctlsocket(sd, FIONBIO, &options);
#else
int options;
options = (~O_NONBLOCK) & fcntl(sd, F_GETFL);
fcntl(sd, F_SETFL, options);
#endif
return 1;
}
/* Convert a time specification into a count of seconds. A time specification is
* a non-negative real number, possibly followed by a units suffix. The suffixes
* are "ms" for milliseconds, "s" for seconds, "m" for minutes, or "h" for
* hours. Seconds is the default with no suffix. -1 is returned if the string
* can't be parsed. */
double tval2secs(const char *tspec) {
double d;
char *tail;
errno = 0;
d = strtod(tspec, &tail);
if (*tspec == '\0' || errno != 0)
return -1;
if (strcasecmp(tail, "ms") == 0)
return d / 1000.0;
else if (*tail == '\0' || strcasecmp(tail, "s") == 0)
return d;
else if (strcasecmp(tail, "m") == 0)
return d * 60.0;
else if (strcasecmp(tail, "h") == 0)
return d * 60.0 * 60.0;
else
return -1;
}
long tval2msecs(const char *tspec) {
double s, ms;
s = tval2secs(tspec);
if (s == -1)
return -1;
ms = s * 1000.0;
if (ms > LONG_MAX || ms < LONG_MIN)
return -1;
return (long) ms;
}
/* Returns the unit portion of a time specification (such as "ms", "s", "m", or
"h"). Returns NULL if there was a parsing error or no unit is present. */
const char *tval_unit(const char *tspec) {
double d;
char *tail;
errno = 0;
d = strtod(tspec, &tail);
/* Avoid GCC 4.6 error "variable 'd' set but not used
[-Wunused-but-set-variable]". */
(void) d;
if (*tspec == '\0' || errno != 0 || *tail == '\0')
return NULL;
return tail;
}
/* A replacement for select on Windows that allows selecting on stdin
* (file descriptor 0) and selecting on zero file descriptors (just for
* the timeout). Plain Windows select doesn't work on non-sockets like
* stdin and returns an error if no file descriptors were given, because
* they were NULL or empty. This only works for sockets and stdin; if
* you have a descriptor referring to a normal open file in the set,
* Windows will return WSAENOTSOCK. */
int fselect(int s, fd_set *rmaster, fd_set *wmaster, fd_set *emaster, struct timeval *tv)
{
#ifdef WIN32
static int stdin_thread_started = 0;
int fds_ready = 0;
int iter = -1, i;
struct timeval stv;
fd_set rset, wset, eset;
/* Figure out whether there are any FDs in the sets, as @$@!$# Windows
returns WSAINVAL (10022) if you call a select() with no FDs, even though
the Linux man page says that doing so is a good, reasonably portable way
to sleep with subsecond precision. Sigh. */
for(i = s; i > STDIN_FILENO; i--) {
if ((rmaster != NULL && FD_ISSET(i, rmaster))
|| (wmaster != NULL && FD_ISSET(i, wmaster))
|| (emaster != NULL && FD_ISSET(i, emaster)))
break;
s--;
}
/* Handle the case where stdin is not being read from. */
if (rmaster == NULL || !FD_ISSET(STDIN_FILENO, rmaster)) {
if (s > 0) {
/* Do a normal select. */
return select(s, rmaster, wmaster, emaster, tv);
} else {
/* No file descriptors given. Just sleep. */
if (tv == NULL) {
/* Sleep forever. */
while (1)
sleep(10000);
} else {
usleep(tv->tv_sec * 1000000UL + tv->tv_usec);
return 0;
}
}
}
/* This is a hack for Windows, which doesn't allow select()ing on
* non-sockets (like stdin). We remove stdin from the fd_set and
* loop while select()ing on everything else, with a timeout of
* 125ms. Then we check if stdin is ready and increment fds_ready
* and set stdin in rmaster if it looks good. We just keep looping
* until we have something or it times out.
*/
/* nbase_winunix.c has all the nasty details behind checking if
* stdin has input. It involves a background thread, which we start
* now if necessary. */
if (!stdin_thread_started) {
int ret = win_stdin_start_thread();
assert(ret != 0);
stdin_thread_started = 1;
}
FD_CLR(STDIN_FILENO, rmaster);
if (tv) {
int usecs = (tv->tv_sec * 1000000) + tv->tv_usec;
iter = usecs / 125000;
if (usecs % 125000)
iter++;
}
FD_ZERO(&rset);
FD_ZERO(&wset);
FD_ZERO(&eset);
while (!fds_ready && iter) {
stv.tv_sec = 0;
stv.tv_usec = 125000;
if (rmaster)
rset = *rmaster;
if (wmaster)
wset = *wmaster;
if (emaster)
eset = *emaster;
fds_ready = 0;
/* selecting on anything other than stdin? */
if (s > 1)
fds_ready = select(s, &rset, &wset, &eset, &stv);
if (fds_ready > -1 && win_stdin_ready()) {
FD_SET(STDIN_FILENO, &rset);
fds_ready++;
}
if (tv)
iter--;
}
if (rmaster)
*rmaster = rset;
if (wmaster)
*wmaster = wset;
if (emaster)
*emaster = eset;
return fds_ready;
#else
return select(s, rmaster, wmaster, emaster, tv);
#endif
}
/*
* CRC32 Cyclic Redundancy Check
*
* From: http://www.ietf.org/rfc/rfc1952.txt
*
* Copyright (c) 1996 L. Peter Deutsch
*
* Permission is granted to copy and distribute this document for any
* purpose and without charge, including translations into other
* languages and incorporation into compilations, provided that the
* copyright notice and this notice are preserved, and that any
* substantive changes or deletions from the original are clearly
* marked.
*
*/
/* Table of CRCs of all 8-bit messages. */
static unsigned long crc_table[256];
/* Flag: has the table been computed? Initially false. */
static int crc_table_computed = 0;
/* Make the table for a fast CRC. */
static void make_crc_table(void)
{
unsigned long c;
int n, k;
for (n = 0; n < 256; n++) {
c = (unsigned long) n;
for (k = 0; k < 8; k++) {
if (c & 1) {
c = 0xedb88320L ^ (c >> 1);
} else {
c = c >> 1;
}
}
crc_table[n] = c;
}
crc_table_computed = 1;
}
/*
Update a running crc with the bytes buf[0..len-1] and return
the updated crc. The crc should be initialized to zero. Pre- and
post-conditioning (one's complement) is performed within this
function so it shouldn't be done by the caller. Usage example:
unsigned long crc = 0L;
while (read_buffer(buffer, length) != EOF) {
crc = update_crc(crc, buffer, length);
}
if (crc != original_crc) error();
*/
static unsigned long update_crc(unsigned long crc,
unsigned char *buf, int len)
{
unsigned long c = crc ^ 0xffffffffL;
int n;
if (!crc_table_computed)
make_crc_table();
for (n = 0; n < len; n++) {
c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
}
return c ^ 0xffffffffL;
}
/* Return the CRC of the bytes buf[0..len-1]. */
unsigned long nbase_crc32(unsigned char *buf, int len)
{
return update_crc(0L, buf, len);
}
/*
* CRC-32C (Castagnoli) Cyclic Redundancy Check.
* Taken straight from RFC 4960 (SCTP).
*/
/* Return the CRC-32C of the bytes buf[0..len-1] */
unsigned long nbase_crc32c(unsigned char *buf, int len)
{
int i;
unsigned long crc32 = ~0L;
unsigned long result;
unsigned char byte0, byte1, byte2, byte3;
for (i = 0; i < len; i++) {
CRC32C(crc32, buf[i]);
}
result = ~crc32;
/* result now holds the negated polynomial remainder;
* since the table and algorithm is "reflected" [williams95].
* That is, result has the same value as if we mapped the message
* to a polynomial, computed the host-bit-order polynomial
* remainder, performed final negation, then did an end-for-end
* bit-reversal.
* Note that a 32-bit bit-reversal is identical to four inplace
* 8-bit reversals followed by an end-for-end byteswap.
* In other words, the bytes of each bit are in the right order,
* but the bytes have been byteswapped. So we now do an explicit
* byteswap. On a little-endian machine, this byteswap and
* the final ntohl cancel out and could be elided.
*/
byte0 = result & 0xff;
byte1 = (result >> 8) & 0xff;
byte2 = (result >> 16) & 0xff;
byte3 = (result >> 24) & 0xff;
crc32 = ((byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3);
return crc32;
}
/*
* Adler32 Checksum Calculation.
* Taken straight from RFC 2960 (SCTP).
*/
#define ADLER32_BASE 65521 /* largest prime smaller than 65536 */
/*
* Update a running Adler-32 checksum with the bytes buf[0..len-1]
* and return the updated checksum. The Adler-32 checksum should
* be initialized to 1.
*/
static unsigned long update_adler32(unsigned long adler,
unsigned char *buf, int len)
{
unsigned long s1 = adler & 0xffff;
unsigned long s2 = (adler >> 16) & 0xffff;
int n;
for (n = 0; n < len; n++) {
s1 = (s1 + buf[n]) % ADLER32_BASE;
s2 = (s2 + s1) % ADLER32_BASE;
}
return (s2 << 16) + s1;
}
/* Return the Adler32 of the bytes buf[0..len-1] */
unsigned long nbase_adler32(unsigned char *buf, int len)
{
return update_adler32(1L, buf, len);
}
#undef ADLER32_BASE
/* This function returns a string containing the hexdump of the supplied
* buffer. It uses current locale to determine if a character is printable or
* not. It prints 73char+\n wide lines like these:
0000 e8 60 65 86 d7 86 6d 30 35 97 54 87 ff 67 05 9e .`e...m05.T..g..
0010 07 5a 98 c0 ea ad 50 d2 62 4f 7b ff e1 34 f8 fc .Z....P.bO{..4..
0020 c4 84 0a 6a 39 ad 3c 10 63 b2 22 c4 24 40 f4 b1 ...j9.<.c.".$@..
* The lines look basically like Wireshark's hex dump.
* WARNING: This function returns a pointer to a DYNAMICALLY allocated buffer
* that the caller is supposed to free().
* */
char *hexdump(const u8 *cp, u32 length){
static char asciify[257]; /* Stores cha6acter table */
int asc_init=0; /* Flag to generate table only once */
u32 i=0, hex=0, asc=0; /* Array indexes */
u32 line_count=0; /* For byte count at line start */
char *current_line=NULL; /* Current line to write */
char *buffer=NULL; /* Dynamic buffer we return */
#define LINE_LEN 74 /* Lenght of printed line */
char line2print[LINE_LEN]; /* Stores current line */
char printbyte[16]; /* For byte conversion */
int bytes2alloc; /* For buffer */
memset(line2print, ' ', LINE_LEN); /* We fill the line with spaces */
/* On the first run, generate a list of nice printable characters
* (according to current locale) */
if( asc_init==0){
asc_init=1;
for(i=0; i<256; i++){
if( isalnum(i) || isdigit(i) || ispunct(i) ){ asciify[i]=i; }
else{ asciify[i]='.'; }
}
}
/* Allocate enough space to print the hex dump */
bytes2alloc=(length%16==0)? (1 + LINE_LEN * (length/16)) : (1 + LINE_LEN * (1+(length/16))) ;
buffer=(char *)safe_zalloc(bytes2alloc);
current_line=buffer;
#define HEX_START 7
#define ASC_START 57
/* This is how or line looks like.
0000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f .`e...m05.T..g..[\n]
01234567890123456789012345678901234567890123456789012345678901234567890123
0 1 2 3 4 5 6 7
^ ^ ^
| | |
HEX_START ASC_START Newline
*/
i=0;
while( i < length ){
memset(line2print, ' ', LINE_LEN); /* Fill line with spaces */
snprintf(line2print, sizeof(line2print), "%04x", (16*line_count++) % 0xFFFF); /* Add line No.*/
line2print[4]=' '; /* Replace the '\0' inserted by snprintf() with a space */
hex=HEX_START; asc=ASC_START;
do { /* Print 16 bytes in both hex and ascii */
if (i%16 == 8) hex++; /* Insert space every 8 bytes */
snprintf(printbyte, sizeof(printbyte), "%02x", cp[i]);/* First print the hex number */
line2print[hex++]=printbyte[0];
line2print[hex++]=printbyte[1];
line2print[hex++]=' ';
line2print[asc++]=asciify[ cp[i] ]; /* Then print its ASCII equivalent */
i++;
} while (i < length && i%16 != 0);
/* Copy line to output buffer */
line2print[LINE_LEN-1]='\n';
memcpy(current_line, line2print, LINE_LEN);
current_line += LINE_LEN;
}
buffer[bytes2alloc-1]='\0';
return buffer;
} /* End of hexdump() */
/* This is like strtol or atoi, but it allows digits only. No whitespace, sign,
or radix prefix. */
long parse_long(const char *s, char **tail)
{
if (!isdigit((int) (unsigned char) *s)) {
*tail = (char *) s;
return 0;
}
return strtol(s, (char **) tail, 10);
}
/* This function takes a byte count and stores a short ascii equivalent
in the supplied buffer. Eg: 0.122MB, 10.322Kb or 128B. */
char *format_bytecount(unsigned long long bytes, char *buf, size_t buflen) {
assert(buf != NULL);
if (bytes < 1000)
Snprintf(buf, buflen, "%uB", (unsigned int) bytes);
else if (bytes < 1000000)
Snprintf(buf, buflen, "%.3fKB", bytes / 1000.0);
else
Snprintf(buf, buflen, "%.3fMB", bytes / 1000000.0);
return buf;
}
/* Compare a canonical option name (e.g. "max-scan-delay") with a
user-generated option such as "max_scan_delay" and returns 0 if the
two values are considered equivalant (for example, - and _ are
considered to be the same), nonzero otherwise. */
int optcmp(const char *a, const char *b) {
while(*a && *b) {
if (*a == '_' || *a == '-') {
if (*b != '_' && *b != '-')
return 1;
}
else if (*a != *b)
return 1;
a++; b++;
}
if (*a || *b)
return 1;
return 0;
}
/* Returns one if the file pathname given exists, is not a directory and
* is readable by the executing process. Returns two if it is readable
* and is a directory. Otherwise returns 0. */
int fileexistsandisreadable(const char *pathname) {
char *pathname_buf = strdup(pathname);
int status = 0;
struct stat st;
#ifdef WIN32
// stat on windows only works for "dir_name" not for "dir_name/" or "dir_name\\"
int pathname_len = strlen(pathname_buf);
char last_char = pathname_buf[pathname_len - 1];
if( last_char == '/'
|| last_char == '\\')
pathname_buf[pathname_len - 1] = '\0';
#endif
if (stat(pathname_buf, &st) == -1)
status = 0;
else if (access(pathname_buf, R_OK) != -1)
status = S_ISDIR(st.st_mode) ? 2 : 1;
free(pathname_buf);
return status;
}
#if HAVE_PROC_SELF_EXE
static char *executable_path_proc_self_exe(void) {
char buf[1024];
char *path;
int n;
n = readlink("/proc/self/exe", buf, sizeof(buf));
if (n < 0 || n >= sizeof(buf))
return NULL;
path = (char *) safe_malloc(n + 1);
/* readlink does not null-terminate. */
memcpy(path, buf, n);
path[n] = '\0';
return path;
}
#endif
#if HAVE_MACH_O_DYLD_H
#include <mach-o/dyld.h>
/* See the dyld(3) man page on OS X. */
static char *executable_path_NSGetExecutablePath(void) {
char buf[1024];
uint32_t size;
size = sizeof(buf);
if (_NSGetExecutablePath(buf, &size) == 0)
return strdup(buf);
else
return NULL;
}
#endif
#if WIN32
static char *executable_path_GetModuleFileName(void) {
char buf[1024];
int n;
n = GetModuleFileName(GetModuleHandle(0), buf, sizeof(buf));
if (n <= 0 || n >= sizeof(buf))
return NULL;
return strdup(buf);
}
#endif
static char *executable_path_argv0(const char *argv0) {
if (argv0 == NULL)
return NULL;
/* We can get the path from argv[0] if it contains a directory separator.
(Otherwise it was looked up in $PATH). */
if (strchr(argv0, '/') != NULL)
return strdup(argv0);
#if WIN32
if (strchr(argv0, '\\') != NULL)
return strdup(argv0);
#endif
return NULL;
}
char *executable_path(const char *argv0) {
char *path;
path = NULL;
#if HAVE_PROC_SELF_EXE
if (path == NULL)
path = executable_path_proc_self_exe();
#endif
#if HAVE_MACH_O_DYLD_H
if (path == NULL)
path = executable_path_NSGetExecutablePath();
#endif
#if WIN32
if (path == NULL)
path = executable_path_GetModuleFileName();
#endif
if (path == NULL)
path = executable_path_argv0(argv0);
return path;
}

383
nbase/nbase_rnd.c Normal file
View File

@@ -0,0 +1,383 @@
/***************************************************************************
* nbase_rnd.c -- Some simple routines for obtaining random numbers for *
* casual use. These are pretty secure on systems with /dev/urandom, but *
* falls back to poor entropy for seeding on systems without such support. *
* *
* Based on DNET / OpenBSD arc4random(). *
* *
* Copyright (c) 2000 Dug Song <dugsong@monkey.org> *
* Copyright (c) 1996 David Mazieres <dm@lcs.mit.edu> *
* *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include "nbase.h"
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#if HAVE_SYS_TIME_H
#include <sys/time.h>
#endif /* HAV_SYS_TIME_H */
#ifdef WIN32
#include <wincrypt.h>
#endif /* WIN32 */
/* data for our random state */
struct nrand_handle {
u8 i, j, s[256], *tmp;
int tmplen;
};
typedef struct nrand_handle nrand_h;
static void nrand_addrandom(nrand_h *rand, u8 *buf, int len) {
int i;
u8 si;
/* Mix entropy in buf with s[]...
*
* This is the ARC4 key-schedule. It is rather poor and doesn't mix
* the key in very well. This causes a bias at the start of the stream.
* To eliminate most of this bias, the first N bytes of the stream should
* be dropped.
*/
rand->i--;
for (i = 0; i < 256; i++) {
rand->i = (rand->i + 1);
si = rand->s[rand->i];
rand->j = (rand->j + si + buf[i % len]);
rand->s[rand->i] = rand->s[rand->j];
rand->s[rand->j] = si;
}
rand->j = rand->i;
}
static u8 nrand_getbyte(nrand_h *r) {
u8 si, sj;
/* This is the core of ARC4 and provides the pseudo-randomness */
r->i = (r->i + 1);
si = r->s[r->i];
r->j = (r->j + si);
sj = r->s[r->j];
r->s[r->i] = sj; /* The start of the the swap */
r->s[r->j] = si; /* The other half of the swap */
return (r->s[(si + sj) & 0xff]);
}
int nrand_get(nrand_h *r, void *buf, size_t len) {
u8 *p;
size_t i;
/* Hand out however many bytes were asked for */
for (p = buf, i = 0; i < len; i++) {
p[i] = nrand_getbyte(r);
}
return (0);
}
void nrand_init(nrand_h *r) {
u8 seed[256]; /* Starts out with "random" stack data */
int i;
/* Gather seed entropy with best the OS has to offer */
#ifdef WIN32
HCRYPTPROV hcrypt = 0;
CryptAcquireContext(&hcrypt, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
CryptGenRandom(hcrypt, sizeof(seed), seed);
CryptReleaseContext(hcrypt, 0);
#else
struct timeval *tv = (struct timeval *)seed;
int *pid = (int *)(seed + sizeof(*tv));
int fd;
gettimeofday(tv, NULL); /* fill lowest seed[] with time */
*pid = getpid(); /* fill next lowest seed[] with pid */
/* Try to fill the rest of the state with OS provided entropy */
if ((fd = open("/dev/urandom", O_RDONLY)) != -1 ||
(fd = open("/dev/arandom", O_RDONLY)) != -1) {
ssize_t n;
do {
errno = 0;
n = read(fd, seed + sizeof(*tv) + sizeof(*pid),
sizeof(seed) - sizeof(*tv) - sizeof(*pid));
} while (n < 0 && errno == EINTR);
close(fd);
}
#endif
/* Fill up our handle with starter values */
for (i = 0; i < 256; i++) { r->s[i] = i; };
r->i = r->j = 0;
nrand_addrandom(r, seed, 128); /* lower half of seed data for entropy */
nrand_addrandom(r, seed + 128, 128); /* Now use upper half */
r->tmp = NULL;
r->tmplen = 0;
/* This stream will start biased. Get rid of 1K of the stream */
nrand_get(r, seed, 256); nrand_get(r, seed, 256);
nrand_get(r, seed, 256); nrand_get(r, seed, 256);
}
int get_random_bytes(void *buf, int numbytes) {
static nrand_h state;
static int state_init = 0;
/* Initialize if we need to */
if (!state_init) {
nrand_init(&state);
state_init = 1;
}
/* Now fill our buffer */
nrand_get(&state, buf, numbytes);
return 0;
}
int get_random_int() {
int i;
get_random_bytes(&i, sizeof(int));
return i;
}
unsigned int get_random_uint() {
unsigned int i;
get_random_bytes(&i, sizeof(unsigned int));
return i;
}
u32 get_random_u32() {
u32 i;
get_random_bytes(&i, sizeof(i));
return i;
}
u16 get_random_u16() {
u16 i;
get_random_bytes(&i, sizeof(i));
return i;
}
u8 get_random_u8() {
u8 i;
get_random_bytes(&i, sizeof(i));
return i;
}
unsigned short get_random_ushort() {
unsigned short s;
get_random_bytes(&s, sizeof(unsigned short));
return s;
}
/* This function is magic ;-)
*
* Sometimes Nmap wants to generate IPs that look random
* but don't have any duplicates. The strong RC4 generator
* can't be used for this purpose because it can generate duplicates
* if you get enough IPs (birthday paradox).
*
* This routine exploits the fact that a LCG won't repeat for the
* entire duration of it's period. An LCG has some pretty bad
* properties though so this routine does extra work to try to
* tweak the LCG output so that is has very good statistics but
* doesn't repeat. The tweak used was mostly made up on the spot
* but is generally based on good ideas and has been moderately
* tested. See links and reasoning below.
*/
u32 get_random_unique_u32() {
static u32 state, tweak1, tweak2, tweak3;
static int state_init = 0;
u32 output;
/* Initialize if we need to */
if (!state_init) {
get_random_bytes(&state, sizeof(state));
get_random_bytes(&tweak1, sizeof(tweak1));
get_random_bytes(&tweak2, sizeof(tweak2));
get_random_bytes(&tweak3, sizeof(tweak3));
state_init = 1;
}
/* What is this math crap?
*
* The whole idea behind this generator is that an LCG can be constructed
* with a period of exactly 2^32. As long as the LCG is fed back onto
* itself the period will be 2^32. The tweak after the LCG is just
* a good permutation in GF(2^32).
*
* To accomplish the tweak the notion of rounds and round keys from
* block ciphers has been borrowed. The only special aspect of this
* block cipher is that the first round short-circuits the LCG.
*
* This block cipher uses three rounds. Each round is as follows:
*
* 1) Affine transform in GF(2^32)
* 2) Rotate left by round constant
* 3) XOR with round key
*
* For round one the affine transform is used as an LCG.
*/
/* Reasoning:
*
* Affine transforms were chosen both to make a LCG and also
* to try to introduce non-linearity.
*
* The rotate up each round was borrowed from SHA-1 and was introduced
* to help obscure the obvious short cycles when you truncate an LCG with
* a power-of-two period like the one used.
*
* The XOR with the round key was borrowed from several different
* published functions (but see Xorshift)
* and provides a different sequence for the full LCG.
* There are 3 32 bit round keys. This generator can
* generate 2^96 different sequences of period 2^32.
*
* This generator was tested with Dieharder. It did not fail any test.
*/
/* See:
*
* http://en.wikipedia.org/wiki/Galois_field
* http://en.wikipedia.org/wiki/Affine_cipher
* http://en.wikipedia.org/wiki/Linear_congruential_generator
* http://en.wikipedia.org/wiki/Xorshift
* http://en.wikipedia.org/wiki/Sha-1
*
* http://seclists.org/nmap-dev/2009/q3/0695.html
*/
/* First off, we need to evolve the state with our LCG
* We'll use the LCG from Numerical Recipes (m=2^32,
* a=1664525, c=1013904223). All by itself this generator
* pretty bad. We're going to try to fix that without causing
* duplicates.
*/
state = (((state * 1664525) & 0xFFFFFFFF) + 1013904223) & 0xFFFFFFFF;
output = state;
/* With a normal LCG, we would just output the state.
* In this case, though, we are going to try to destroy the
* linear correlation between IPs by approximating a random permutation
* in GF(2^32) (collision-free)
*/
/* Then rotate and XOR */
output = ((output << 7) | (output >> (32 - 7)));
output = output ^ tweak1; /* This is the round key */
/* End round 1, start round 2 */
/* Then put it through an affine transform (glibc constants) */
output = (((output * 1103515245) & 0xFFFFFFFF) + 12345) & 0xFFFFFFFF;
/* Then rotate and XOR some more */
output = ((output << 15) | (output >> (32 - 15)));
output = output ^ tweak2;
/* End round 2, start round 3 */
/* Then put it through another affine transform (Quick C/C++ constants) */
output = (((output * 214013) & 0xFFFFFFFF) + 2531011) & 0xFFFFFFFF;
/* Then rotate and XOR some more */
output = ((output << 5) | (output >> (32 - 5)));
output = output ^ tweak3;
return output;
}

235
nbase/nbase_str.c Normal file
View File

@@ -0,0 +1,235 @@
/***************************************************************************
* nbase_str.c -- string related functings in the nbase library. These *
* were written by fyodor@insecure.org . *
* *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include "nbase.h"
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#ifndef HAVE_STRCASESTR
char *strcasestr(const char *haystack, const char *pneedle) {
char buf[512];
unsigned int needlelen;
const char *p;
char *needle, *q, *foundto;
/* Should crash if !pneedle -- this is OK */
if (!*pneedle) return (char *) haystack;
if (!haystack) return NULL;
needlelen = (unsigned int) strlen(pneedle);
if (needlelen >= sizeof(buf)) {
needle = (char *) safe_malloc(needlelen + 1);
} else needle = buf;
p = pneedle; q = needle;
while((*q++ = tolower((int) (unsigned char) *p++)))
;
p = haystack - 1; foundto = needle;
while(*++p) {
if(tolower((int) (unsigned char) *p) == *foundto) {
if(!*++foundto) {
/* Yeah, we found it */
if (needlelen >= sizeof(buf))
free(needle);
return (char *) (p - needlelen + 1);
}
} else foundto = needle;
}
if (needlelen >= sizeof(buf))
free(needle);
return NULL;
}
#endif
int Strncpy(char *dest, const char *src, size_t n) {
strncpy(dest, src, n);
if (dest[n-1] == '\0')
return 0;
dest[n-1] = '\0';
return -1;
}
int Vsnprintf(char *s, size_t n, const char *fmt, va_list ap)
{
int ret;
ret = vsnprintf(s, n, fmt, ap);
if (ret < 0 || (unsigned) ret >= n)
s[n - 1] = '\0';
return ret;
}
int Snprintf(char *s, size_t n, const char *fmt, ...)
{
va_list ap;
int ret;
va_start(ap, fmt);
ret = Vsnprintf(s, n, fmt, ap);
va_end(ap);
return ret;
}
/* Trivial function that returns nonzero if all characters in str of length strlength are
printable (as defined by isprint()) */
int stringisprintable(const char *str, int strlength) {
int i;
for(i=0; i < strlength; i++)
if (!isprint((int) (unsigned char) str[i]))
return 0;
return 1;
}
/* Convert non-printable characters to replchar in the string */
void replacenonprintable(char *str, int strlength, char replchar) {
int i;
for(i=0; i < strlength; i++)
if (!isprint((int) (unsigned char) str[i]))
str[i] = replchar;
return;
}
/* Returns the position of the last directory separator (slash, also backslash
on Win32) in a path. Returns -1 if none was found. */
static int find_last_path_separator(const char *path) {
#ifndef WIN32
const char *PATH_SEPARATORS = "/";
#else
const char *PATH_SEPARATORS = "\\/";
#endif
const char *p;
p = path + strlen(path) - 1;
while (p >= path) {
if (strchr(PATH_SEPARATORS, *p) != NULL)
return (int)(p - path);
p--;
}
return -1;
}
/* Returns the directory name part of a path (everything up to the last
directory separator). If there is no separator, returns ".". If there is only
one separator and it is the first character, returns "/". Returns NULL on
error. The returned string must be freed. */
char *path_get_dirname(const char *path) {
char *result;
int i;
i = find_last_path_separator(path);
if (i == -1)
return strdup(".");
if (i == 0)
return strdup("/");
result = (char *) safe_malloc(i + 1);
strncpy(result, path, i);
result[i] = '\0';
return result;
}
/* Returns the file name part of a path (everything after the last directory
separator). Returns NULL on error. The returned string must be freed. */
char *path_get_basename(const char *path) {
int i;
i = find_last_path_separator(path);
return strdup(path + i + 1);
}

134
nbase/nbase_time.c Normal file
View File

@@ -0,0 +1,134 @@
/***************************************************************************
* nbase_time.c -- Some small time-related utility/compatability *
* functions. *
* *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include "nbase.h"
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <time.h>
#ifdef WIN32
#include <sys/timeb.h>
#include <winsock2.h>
#endif
#ifndef HAVE_USLEEP
void usleep(unsigned long usec) {
#ifdef HAVE_NANOSLEEP
struct timespec ts;
ts.tv_sec = usec / 1000000;
ts.tv_nsec = (usec % 1000000) * 1000;
nanosleep(&ts, NULL);
#else /* Windows style */
Sleep( usec / 1000 );
#endif /* HAVE_NANOSLEEP */
}
#endif
#ifdef WIN32
int gettimeofday(struct timeval *tv, struct timeval *tz)
{
struct _timeb timebuffer;
_ftime( &timebuffer );
tv->tv_sec = (long) timebuffer.time;
tv->tv_usec = timebuffer.millitm * 1000;
return 0;
};
unsigned int sleep(unsigned int seconds)
{
Sleep(1000*seconds);
return(0);
};
#endif /* WIN32 */

166
nbase/nbase_winconfig.h Normal file
View File

@@ -0,0 +1,166 @@
/***************************************************************************
* nbase_winconfig.h -- Since the Windows port is currently eschewing *
* autoconf-style configure scripts, nbase_winconfig.h contains the *
* platform-specific definitions for Windows and is used as a replacement *
* for nbase_config.h *
* *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#ifndef NBASE_WINCONFIG_H
#define NBASE_WINCONFIG_H
/* It doesn't really have strucct IP, but we use a different one instead
of the one that comes with Nmap */
#define HAVE_STRUCT_IP 1
/* #define HAVE_STRUCT_ICMP 1 */
#define HAVE_STRNCASECMP 1
#define HAVE_IP_IP_SUM 1
#define STDC_HEADERS 1
#define HAVE_STRING_H 1
#define HAVE_MEMORY_H 1
#define HAVE_FCNTL_H 1
#define HAVE_ERRNO_H 1
#define HAVE_SYS_STAT_H 1
#define HAVE_MEMCPY 1
#define HAVE_STRERROR 1
/* #define HAVE_SYS_SOCKIO_H 1 */
/* #undef HAVE_TERMIOS_H */
#define HAVE_ERRNO_H 1
#define HAVE_GAI_STRERROR 1
/* #define HAVE_STRCASESTR 1 */
#define HAVE_STRCASECMP 1
#define HAVE_NETINET_IF_ETHER_H 1
#define HAVE_SYS_STAT_H 1
/* #define HAVE_INTTYPES_H */
#ifdef _MSC_VER
/* <wspiapi.h> only comes with Visual Studio. */
#define HAVE_WSPIAPI_H 1
#else
#undef HAVE_WSPIAPI_H
#endif
#define HAVE_GETADDRINFO 1
#define HAVE_GETNAMEINFO 1
#define HAVE_SNPRINTF 1
#define HAVE_VASPRINTF 1
#define HAVE_VSNPRINTF 1
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
typedef signed __int8 int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef signed __int64 int64_t;
#define HAVE_IPV6 1
#define HAVE_AF_INET6 1
#define HAVE_SOCKADDR_STORAGE 1
/* Without these, Windows will give us all sorts of crap about using functions
like strcpy() even if they are done safely */
#define _CRT_SECURE_NO_DEPRECATE 1
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS 1
#endif
#pragma warning(disable: 4996)
#ifdef __GNUC__
#define bzero(addr, num) __builtin_memset (addr, '\0', num)
#else
#define __attribute__(x)
#endif
#define HAVE_OPENSSL 1
/* Apparently __func__ isn't yet supported */
#define __func__ __FUNCTION__
#endif /* NBASE_WINCONFIG_H */

244
nbase/nbase_winunix.c Normal file
View File

@@ -0,0 +1,244 @@
/***************************************************************************
* nbase_winunix.h -- Background code that allows checking for input on *
* stdin on Windows without blocking. *
* *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include <assert.h>
#include "nbase.h"
#include "nbase_winunix.h"
/*
This code makes it possible to check for input on stdin on Windows without
blocking. There are two obstacles that need to be overcome. The first is that
select on Windows works for sockets only, not stdin. The other is that the
Windows command shell doesn't echo typed characters to the screen unless the
program is actively reading from stdin (which would normally mean blocking).
The strategy is to create a background thread that constantly reads from stdin.
The thread blocks while reading, which lets characters be echoed. The thread
writes each block of data into an anonymous pipe. We juggle file descriptors and
Windows file handles to make the rest of the program think that the other end of
the pipe is stdin. Only the thread keeps a reference to the real stdin. Windows
has a PeekNamedPipe function that we use to check for input in the pipe without
blocking.
Call win_stdin_start_thread to start the thread and win_stdin_ready for the
non-blocking input check. Any other operations on stdin (read, scanf, etc.)
should be transparent, except I noticed that eof(0) returns 1 when there is
nothing in the pipe, but will return 0 again if more is written to the pipe. Any
data buffered but not delivered to the program before starting the background
thread may be lost when the thread is started.
*/
/* The background thread that reads and buffers the true stdin. */
static HANDLE stdin_thread = NULL;
/* This is a copy of the true stdin file handle before any redirection. It is
read by the thread. */
static HANDLE thread_stdin_handle = NULL;
/* The thread writes to this pipe and standard input is reassigned to be the
read end of it. */
static HANDLE stdin_pipe_r = NULL, stdin_pipe_w = NULL;
/* This is the thread that reads from the true stdin (thread_stdin_handle) and
writes to stdin_pipe_w, which is reassigned to be the stdin that the rest of
the program sees. Once started, it never finishes except in case of error.
win_stdin_start_thread is responsible for setting up thread_stdin_handle. */
static DWORD WINAPI win_stdin_thread_func(void *data) {
DWORD n, nwritten;
char buffer[BUFSIZ];
for (;;) {
if (ReadFile(thread_stdin_handle, buffer, sizeof(buffer), &n, NULL) == 0)
break;
if (n == -1 || n == 0)
break;
if (WriteFile(stdin_pipe_w, buffer, n, &nwritten, NULL) == 0)
break;
if (nwritten != n)
break;
}
CloseHandle(thread_stdin_handle);
CloseHandle(stdin_pipe_w);
return 0;
}
/* Get the newline translation mode (_O_TEXT or _O_BINARY) of a file
descriptor. _O_TEXT does CRLF-LF translation and _O_BINARY does none.
Complementary to _setmode. */
static int _getmode(int fd)
{
int mode;
/* There is no standard _getmode function, but _setmode returns the
previous value. Set it to a dummy value and set it back. */
mode = _setmode(fd, _O_BINARY);
_setmode(fd, mode);
return mode;
}
/* Start the reader thread and do all the file handle/descriptor redirection.
Returns nonzero on success, zero on error. */
int win_stdin_start_thread(void) {
int stdin_fd;
int stdin_fmode;
assert(stdin_thread == NULL);
assert(stdin_pipe_r == NULL);
assert(stdin_pipe_w == NULL);
assert(thread_stdin_handle == NULL);
/* Create the pipe that win_stdin_thread_func writes to. We reassign the
read end to be the new stdin that the rest of the program sees. */
if (CreatePipe(&stdin_pipe_r, &stdin_pipe_w, NULL, 0) == 0)
return 0;
/* Make a copy of the stdin handle to be used by win_stdin_thread_func. It
will remain a reference to the the true stdin after we fake stdin to read
from the pipe instead. */
if (DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE),
GetCurrentProcess(), &thread_stdin_handle,
0, FALSE, DUPLICATE_SAME_ACCESS) == 0) {
CloseHandle(stdin_pipe_r);
CloseHandle(stdin_pipe_w);
return 0;
}
/* Set the stdin handle to read from the pipe. */
if (SetStdHandle(STD_INPUT_HANDLE, stdin_pipe_r) == 0) {
CloseHandle(stdin_pipe_r);
CloseHandle(stdin_pipe_w);
CloseHandle(thread_stdin_handle);
return 0;
}
/* Need to redirect file descriptor 0 also. _open_osfhandle makes a new file
descriptor from an existing handle. */
/* Remember the newline translation mode (_O_TEXT or _O_BINARY), and
restore it in the new file descriptor. */
stdin_fmode = _getmode(STDIN_FILENO);
stdin_fd = _open_osfhandle((intptr_t) GetStdHandle(STD_INPUT_HANDLE), _O_RDONLY | stdin_fmode);
if (stdin_fd == -1) {
CloseHandle(stdin_pipe_r);
CloseHandle(stdin_pipe_w);
CloseHandle(thread_stdin_handle);
return 0;
}
dup2(stdin_fd, STDIN_FILENO);
/* Finally, start up the thread. We don't bother keeping a reference to it
because it runs until program termination. From here on out all reads
from the stdin handle or file descriptor 0 will be reading from the
anonymous pipe that is fed by the thread. */
stdin_thread = CreateThread(NULL, 0, win_stdin_thread_func, NULL, 0, NULL);
if (stdin_thread == NULL) {
CloseHandle(stdin_pipe_r);
CloseHandle(stdin_pipe_w);
CloseHandle(thread_stdin_handle);
return 0;
}
return 1;
}
/* Check if input is available on stdin, once all the above has taken place. */
int win_stdin_ready(void) {
DWORD n;
assert(stdin_pipe_r != NULL);
if (!PeekNamedPipe(stdin_pipe_r, NULL, 0, NULL, &n, NULL))
return 1;
return n > 0;
}

207
nbase/nbase_winunix.h Normal file
View File

@@ -0,0 +1,207 @@
/***************************************************************************
* nbase_winunix.h -- Misc. compatability routines that generally try to *
* reproduce UNIX-centric concepts on Windows. *
* *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#ifndef NBASE_WINUNIX_H
#define NBASE_WINUNIX_H
#include "nbase_winconfig.h"
/* Define the earliest version of Windows we support. These control
what parts of the Windows API are available. The available constants
are in <sdkddkver.h>.
http://msdn.microsoft.com/en-us/library/aa383745.aspx
http://blogs.msdn.com/oldnewthing/archive/2007/04/11/2079137.aspx */
#undef _WIN32_WINNT
#define _WIN32_WINNT _WIN32_WINNT_WIN2K
#undef NTDDI_VERSION
#define NTDDI_VERSION NTDDI_WIN2KSP4
/* Winsock defines its own error codes that are analogous to but
different from those in <errno.h>. The error macros have similar
names, for example
EINTR -> WSAEINTR
ECONNREFUSED -> WSAECONNREFUSED
But the values are different. The errno codes are small integers,
while the Winsock codes start at 10000 or so.
http://msdn.microsoft.com/en-us/library/ms737828
Later in this file there is a block of code that defines the errno
names to their Winsock equivalents, so that you can write code using
the errno names only, and have it still work on Windows. However this
causes some problems that are worked around in the following few
lines. First, we prohibit the inclusion of <errno.h>, so that the
only error codes visible are those we explicitly define in this file.
This will cause a compilation error if someone uses a code we're not
yet aware of instead of using an incompatible value at runtime.
Second, because <errno.h> is not defined, the C++0x header
<system_error> doesn't compile, so we pretend not to have C++0x to
avoid it. */
#define _INC_ERRNO /* suppress errno.h */
#define _ERRNO_H_ /* Also for errno.h suppresion */
#define _SYSTEM_ERROR_
#define _HAS_CPP0X 0
/* Suppress winsock.h */
#define _WINSOCKAPI_
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h> /* IPv6 stuff */
#if HAVE_WSPIAPI_H
/* <wspiapi.h> is necessary for getaddrinfo before Windows XP, but it isn't
available on some platforms like MinGW. */
#include <wspiapi.h>
#endif
#include <time.h>
#include <iptypes.h>
#include <stdlib.h>
#include <malloc.h>
#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <process.h>
#include <limits.h>
#include <WINCRYPT.H>
#include <math.h>
#define SIOCGIFCONF 0x8912 /* get iface list */
#ifndef GLOBALS
#define GLOBALS 1
#endif
#define munmap(ptr, len) win32_munmap(ptr, len)
/* Windows error message names */
#define ECONNABORTED WSAECONNABORTED
#define ECONNRESET WSAECONNRESET
#define ECONNREFUSED WSAECONNREFUSED
#undef EAGAIN
#define EAGAIN WSAEWOULDBLOCK
#define EWOULDBLOCK WSAEWOULDBLOCK
#define EHOSTUNREACH WSAEHOSTUNREACH
#define ENETDOWN WSAENETDOWN
#define ENETUNREACH WSAENETUNREACH
#define ENETRESET WSAENETRESET
#define ETIMEDOUT WSAETIMEDOUT
#define EHOSTDOWN WSAEHOSTDOWN
#define EINPROGRESS WSAEINPROGRESS
#undef EINVAL
#define EINVAL WSAEINVAL /* Invalid argument */
#undef EPERM
#define EPERM WSAEACCES /* Operation not permitted */
#undef EACCES
#define EACCES WSAEACCES /* Operation not permitted */
#undef EINTR
#define EINTR WSAEINTR /* Interrupted system call */
#define ENOBUFS WSAENOBUFS /* No buffer space available */
#undef ENOENT
#define ENOENT WSAENOENT /* No such file or directory */
#define EMSGSIZE WSAEMSGSIZE /* Message too long */
#undef ENOMEM
#define ENOMEM WSAENOBUFS
#undef ENOTSOCK
#define ENOTSOCK WSAENOTSOCK
#undef EIO
#define EIO WSASYSCALLFAILURE
#define close(x) closesocket(x)
typedef unsigned short u_short_t;
int win_stdin_start_thread(void);
int win_stdin_ready(void);
#endif /* NBASE_WINUNIX_H */

639
nbase/snprintf.c Normal file
View File

@@ -0,0 +1,639 @@
/* Note -- this file was obtained from tcpdump-2000-9-17 CVS snapshot *
* ( www.tcpdump.org). It has been modified slightly for *
* compatability with libnbase. Modification etails may be in the *
* nbase CHANGELOG - fyodor@insecure.org */
/*
* Copyright (c) 1995-1999 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* $Id$ */
#if HAVE_CONFIG_H
#include "nbase_config.h"
#else
#ifdef WIN32
#include "nbase_winconfig.h"
#endif /* WIN32 */
#endif /* HAVE_CONFIG_H */
#ifndef lint
static const char rcsid[] =
"@(#) $Header$";
#endif
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#if HAVE_LIBIBERTY_H
#include <libiberty.h>
#endif
#include "nbase.h"
#ifndef min
#define min(a,b) ((a)>(b)?(b):(a))
#endif
#ifndef max
#define max(a,b) ((b)>(a)?(b):(a))
#endif
enum format_flags {
minus_flag = 1,
plus_flag = 2,
space_flag = 4,
alternate_flag = 8,
zero_flag = 16
};
/*
* Common state
*/
struct state {
unsigned char *str;
unsigned char *s;
unsigned char *theend;
size_t sz;
size_t max_sz;
int (*append_char)(struct state *, unsigned char);
int (*reserve)(struct state *, size_t);
/* XXX - methods */
};
#ifndef HAVE_VSNPRINTF
static int
sn_reserve (struct state *state, size_t n)
{
return state->s + n > state->theend;
}
static int
sn_append_char (struct state *state, unsigned char c)
{
if (sn_reserve (state, 1)) {
return 1;
} else {
*state->s++ = c;
return 0;
}
}
#endif
static int
as_reserve (struct state *state, size_t n)
{
if (state->s + n > state->theend) {
int off = state->s - state->str;
unsigned char *tmp;
if (state->max_sz && state->sz >= state->max_sz)
return 1;
state->sz = max(state->sz * 2, state->sz + n);
if (state->max_sz)
state->sz = min(state->sz, state->max_sz);
tmp = safe_realloc(state->str, state->sz);
state->str = tmp;
state->s = state->str + off;
state->theend = state->str + state->sz - 1;
}
return 0;
}
static int
as_append_char (struct state *state, unsigned char c)
{
if(as_reserve (state, 1))
return 1;
else {
*state->s++ = c;
return 0;
}
}
static int
append_number(struct state *state,
unsigned long num, unsigned base, char *rep,
int width, int prec, int flags, int minusp)
{
int len = 0;
int i;
/* given precision, ignore zero flag */
if(prec != -1)
flags &= ~zero_flag;
else
prec = 1;
/* zero value with zero precision -> "" */
if(prec == 0 && num == 0)
return 0;
do{
if((*state->append_char)(state, rep[num % base]))
return 1;
len++;
num /= base;
}while(num);
prec -= len;
/* pad with prec zeros */
while(prec-- > 0){
if((*state->append_char)(state, '0'))
return 1;
len++;
}
/* add length of alternate prefix (added later) to len */
if(flags & alternate_flag && (base == 16 || base == 8))
len += base / 8;
/* pad with zeros */
if(flags & zero_flag){
width -= len;
if(minusp || (flags & space_flag) || (flags & plus_flag))
width--;
while(width-- > 0){
if((*state->append_char)(state, '0'))
return 1;
len++;
}
}
/* add alternate prefix */
if(flags & alternate_flag && (base == 16 || base == 8)){
if(base == 16)
if((*state->append_char)(state, rep[10] + 23)) /* XXX */
return 1;
if((*state->append_char)(state, '0'))
return 1;
}
/* add sign */
if(minusp){
if((*state->append_char)(state, '-'))
return 1;
len++;
} else if(flags & plus_flag) {
if((*state->append_char)(state, '+'))
return 1;
len++;
} else if(flags & space_flag) {
if((*state->append_char)(state, ' '))
return 1;
len++;
}
if(flags & minus_flag)
/* swap before padding with spaces */
for(i = 0; i < len / 2; i++){
char c = state->s[-i-1];
state->s[-i-1] = state->s[-len+i];
state->s[-len+i] = c;
}
width -= len;
while(width-- > 0){
if((*state->append_char)(state, ' '))
return 1;
len++;
}
if(!(flags & minus_flag))
/* swap after padding with spaces */
for(i = 0; i < len / 2; i++){
char c = state->s[-i-1];
state->s[-i-1] = state->s[-len+i];
state->s[-len+i] = c;
}
return 0;
}
static int
append_string (struct state *state,
unsigned char *arg,
int width,
int prec,
int flags)
{
if(prec != -1)
width -= prec;
else
width -= strlen((char *)arg);
if(!(flags & minus_flag))
while(width-- > 0)
if((*state->append_char) (state, ' '))
return 1;
if (prec != -1) {
while (*arg && prec--)
if ((*state->append_char) (state, *arg++))
return 1;
} else {
while (*arg)
if ((*state->append_char) (state, *arg++))
return 1;
}
if(flags & minus_flag)
while(width-- > 0)
if((*state->append_char) (state, ' '))
return 1;
return 0;
}
static int
append_char(struct state *state,
unsigned char arg,
int width,
int flags)
{
while(!(flags & minus_flag) && --width > 0)
if((*state->append_char) (state, ' '))
return 1;
if((*state->append_char) (state, arg))
return 1;
while((flags & minus_flag) && --width > 0)
if((*state->append_char) (state, ' '))
return 1;
return 0;
}
/*
* This can't be made into a function...
*/
#define PARSE_INT_FORMAT(res, arg, unsig) \
if (long_flag) \
res = (unsig long)va_arg(arg, unsig long); \
else if (short_flag) \
res = (unsig short)va_arg(arg, unsig int); \
else \
res = (unsig int)va_arg(arg, unsig int)
/*
* zyxprintf - return 0 or -1
*/
static int
xyzprintf (struct state *state, const char *char_format, va_list ap)
{
const unsigned char *format = (const unsigned char *)char_format;
unsigned char c;
while((c = *format++)) {
if (c == '%') {
int flags = 0;
int width = 0;
int prec = -1;
int long_flag = 0;
int short_flag = 0;
/* flags */
while((c = *format++)){
if(c == '-')
flags |= minus_flag;
else if(c == '+')
flags |= plus_flag;
else if(c == ' ')
flags |= space_flag;
else if(c == '#')
flags |= alternate_flag;
else if(c == '0')
flags |= zero_flag;
else
break;
}
if((flags & space_flag) && (flags & plus_flag))
flags ^= space_flag;
if((flags & minus_flag) && (flags & zero_flag))
flags ^= zero_flag;
/* width */
if (isdigit((int) c))
do {
width = width * 10 + c - '0';
c = *format++;
} while(isdigit((int) c));
else if(c == '*') {
width = va_arg(ap, int);
c = *format++;
}
/* precision */
if (c == '.') {
prec = 0;
c = *format++;
if (isdigit((int) c))
do {
prec = prec * 10 + c - '0';
c = *format++;
} while(isdigit((int) c));
else if (c == '*') {
prec = va_arg(ap, int);
c = *format++;
}
}
/* size */
if (c == 'h') {
short_flag = 1;
c = *format++;
} else if (c == 'l') {
long_flag = 1;
c = *format++;
}
switch (c) {
case 'c' :
if(append_char(state, va_arg(ap, int), width, flags))
return -1;
break;
case 's' :
if (append_string(state,
va_arg(ap, unsigned char*),
width,
prec,
flags))
return -1;
break;
case 'd' :
case 'i' : {
long arg;
unsigned long num;
int minusp = 0;
PARSE_INT_FORMAT(arg, ap, signed);
if (arg < 0) {
minusp = 1;
num = -arg;
} else
num = arg;
if (append_number (state, num, 10, "0123456789",
width, prec, flags, minusp))
return -1;
break;
}
case 'u' : {
unsigned long arg;
PARSE_INT_FORMAT(arg, ap, unsigned);
if (append_number (state, arg, 10, "0123456789",
width, prec, flags, 0))
return -1;
break;
}
case 'o' : {
unsigned long arg;
PARSE_INT_FORMAT(arg, ap, unsigned);
if (append_number (state, arg, 010, "01234567",
width, prec, flags, 0))
return -1;
break;
}
case 'x' : {
unsigned long arg;
PARSE_INT_FORMAT(arg, ap, unsigned);
if (append_number (state, arg, 0x10, "0123456789abcdef",
width, prec, flags, 0))
return -1;
break;
}
case 'X' :{
unsigned long arg;
PARSE_INT_FORMAT(arg, ap, unsigned);
if (append_number (state, arg, 0x10, "0123456789ABCDEF",
width, prec, flags, 0))
return -1;
break;
}
case 'p' : {
unsigned long arg = (unsigned long)va_arg(ap, void*);
if (append_number (state, arg, 0x10, "0123456789ABCDEF",
width, prec, flags, 0))
return -1;
break;
}
case 'n' : {
int *arg = va_arg(ap, int*);
*arg = state->s - state->str;
break;
}
case '\0' :
--format;
/* FALLTHROUGH */
case '%' :
if ((*state->append_char)(state, c))
return -1;
break;
default :
if ( (*state->append_char)(state, '%')
|| (*state->append_char)(state, c))
return -1;
break;
}
} else
if ((*state->append_char) (state, c))
return -1;
}
return 0;
}
#ifndef HAVE_SNPRINTF
int
snprintf (char *str, size_t sz, const char *format, ...)
{
va_list args;
int ret;
va_start(args, format);
ret = vsnprintf (str, sz, format, args);
#ifdef PARANOIA
{
int ret2;
char *tmp;
tmp = safe_malloc (sz);
ret2 = vsprintf (tmp, format, args);
if (ret != ret2 || strcmp(str, tmp))
abort ();
free (tmp);
}
#endif
va_end(args);
return ret;
}
#endif
#ifndef HAVE_VASNPRINTF
int
vasnprintf (char **ret, size_t max_sz, const char *format, va_list args)
{
int st;
size_t len;
struct state state;
state.max_sz = max_sz;
state.sz = 1;
state.str = safe_malloc(state.sz);
state.s = state.str;
state.theend = state.s + state.sz - 1;
state.append_char = as_append_char;
state.reserve = as_reserve;
st = xyzprintf (&state, format, args);
if (st) {
free (state.str);
*ret = NULL;
return -1;
} else {
char *tmp;
*state.s = '\0';
len = state.s - state.str;
tmp = safe_realloc(state.str, len+1);
if (tmp == NULL) {
free (state.str);
*ret = NULL;
return -1;
}
*ret = tmp;
return len;
}
}
#endif
#ifndef HAVE_VASPRINTF
int
vasprintf (char **ret, const char *format, va_list args)
{
return vasnprintf (ret, 0, format, args);
}
#endif
#ifndef HAVE_ASPRINTF
int
asprintf (char **ret, const char *format, ...)
{
va_list args;
int val;
va_start(args, format);
val = vasprintf (ret, format, args);
#ifdef PARANOIA
{
int ret2;
char *tmp;
tmp = safe_malloc (val + 1);
ret2 = vsprintf (tmp, format, args);
if (val != ret2 || strcmp(*ret, tmp))
abort ();
free (tmp);
}
#endif
va_end(args);
return val;
}
#endif
#ifndef HAVE_ASNPRINTF
int
asnprintf (char **ret, size_t max_sz, const char *format, ...)
{
va_list args;
int val;
va_start(args, format);
val = vasnprintf (ret, max_sz, format, args);
#ifdef PARANOIA
{
int ret2;
char *tmp;
tmp = safe_malloc (val + 1);
ret2 = vsprintf (tmp, format, args);
if (val != ret2 || strcmp(*ret, tmp))
abort ();
free (tmp);
}
#endif
va_end(args);
return val;
}
#endif
#ifndef HAVE_VSNPRINTF
int
vsnprintf (char *str, size_t sz, const char *format, va_list args)
{
struct state state;
int ret;
unsigned char *ustr = (unsigned char *)str;
state.max_sz = 0;
state.sz = sz;
state.str = ustr;
state.s = ustr;
state.theend = ustr + sz - 1;
state.append_char = sn_append_char;
state.reserve = sn_reserve;
ret = xyzprintf (&state, format, args);
*state.s = '\0';
if (ret)
return sz;
else
return state.s - state.str;
}
#endif

144
nbase/strcasecmp.c Normal file
View File

@@ -0,0 +1,144 @@
/***************************************************************************
* strcasecmp.c -- strcasecmp and strncasecmp for systems (like Windows) *
* which do not already have them. *
* *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#if !defined(HAVE_STRCASECMP) || !defined(HAVE_STRNCASECMP)
#include <stdlib.h>
#include <string.h>
#include "nbase.h"
#endif
#ifndef HAVE_STRCASECMP
int strcasecmp(const char *s1, const char *s2)
{
int i, ret;
char *cp1, *cp2;
cp1 = safe_malloc(strlen(s1) + 1);
cp2 = safe_malloc(strlen(s2) + 1);
for (i = 0; i < strlen(s1) + 1; i++)
cp1[i] = tolower((int) (unsigned char) s1[i]);
for (i = 0; i < strlen(s2) + 1; i++)
cp2[i] = tolower((int) (unsigned char) s2[i]);
ret = strcmp(cp1, cp2);
free(cp1);
free(cp2);
return ret;
}
#endif
#ifndef HAVE_STRNCASECMP
int strncasecmp(const char *s1, const char *s2, size_t n)
{
int i, ret;
char *cp1, *cp2;
cp1 = safe_malloc(strlen(s1) + 1);
cp2 = safe_malloc(strlen(s2) + 1);
for (i = 0; i < strlen(s1) + 1; i++)
cp1[i] = tolower((int) (unsigned char) s1[i]);
for (i = 0; i < strlen(s2) + 1; i++)
cp2[i] = tolower((int) (unsigned char) s2[i]);
ret = strncmp(cp1, cp2, n);
free(cp1);
free(cp2);
return ret;
}
#endif

3
ncat/COPYING Normal file
View File

@@ -0,0 +1,3 @@
Ncat is distributed under the same license terms as Nmap. See the
COPYING file in the Nmap tarball, the man page legal section, or
http://nmap.org/man/man-legal.html .

229
ncat/ChangeLog Normal file
View File

@@ -0,0 +1,229 @@
# Ncat Changelog ($Id$); -*-text-*-
o Reworked the test program test/test-cmdline-split slightly and added
additional test cases. Rewrote cmdline_split in ncat_posix.c [Josh Marlow]
o Added a test program, test/test-cmdline-split to test the cmdline_split
function in test/test-cmdline-split in preparation for an eventual rewrite of
cmdline_split [Josh Marlow].
Ncat 0.2
o Ported to Windows on Visual C++ Express 2008. Support isn't perfect because
of the lack of a fork() call and because we had to implement a hack to get
select()-like support for stdin on Windows, but most everything works fine.
We hope to get around these issues in the future. [Kris Katterjohn, Mixter]
o Added IPv6 listen support (including --broker). Host access control is not
yet supported. [Kris]
o Added SSL listen support (including --broker) [Kris]
o Fixed SSL and IPv6 connect issues [Mixter]
o Added IPv4 host access control to UDP listener and --broker [Kris]
o Brokering mode now continually listens for connections rather than exiting
after the last client disconnects. [Kris]
o Changed -l to mostly behave like OpenBSD Netcat. Instead of -l specifying
the local port number and -s specifying the local address to listen on, -l
is a non-option flag and you specify the local address/port like you do
a host to connect to in client-mode. [Kris]
o Ncat's default port number is now 31337 instead of 5000. This because 5000
is used for other protocols, such as UPnP. [Kris]
o Specifying no port number with -l now works to listen on Ncat's default
port number. The original Netcat seems to just use an ephemeral port in
this case, and other incarnations make you specify a port number. So now
you don't have to specify a host or port number with -l, in which case
Ncat listens on any address, port 31337. [Kris]
o Fixed Ncat so that it actually works like it should when transferring a file
between instances. Running "ncat -l 3333 <input" and then connecting with
"ncat host 3333 >output" should send the input file from the server to the
client. However actually doing this would either silently fail or complain
about a broken pipe. Thanks to eldraco for reporting this problem. [Kris]
o Client-mode Ncat now exits upon receipt of EOF from the network side [Kris]
o Client-mode Ncat now just tries to read anything from the network (still via
the Nsock library) rather than reading in a line-based manner. While being
an improvement in its own right, this is especially helpful for the new
Telnet negotiation option. [Kris]
o Increased the default network data buffer sizes (reading and writing) from
a measly 256 bytes to a more respectable 8K for TCP and 128K for UDP. UDP's
is this large because a read returns an entire datagram, or discards what's
left if there is no room. [Kris]
o The proxy options have now changed. Instead of having separate option names
for all of the different types of proxy protocols that will be supported,
--proxy is available to specify the proxy address and optional port, and
--proxy-type is available to specify the proxy protocol to use. [Kris]
o Added an HTTP proxy server feature, which creates a simple forking HTTP proxy
server on the listening port (only supports CONNECT). This is specified by
"--proxy-type http" in server mode. [Kris]
o The SOCKSv4 proxy option is now specified by "--proxy-type socks4" instead
of --socks4-proxy. This option also now takes the username from --proxy-auth
rather than the previous user@host:port syntax. [Kris]
o The HTTP proxy option is now specified by "--proxy-type http" instead of
--http-proxy. Also, the HTTP CONNECT request now uses CRLF for the EOL
instead of just LF. [Kris]
o Removed the SOCKS proxy server support because it was broken, didn't have
any support for SOCKSv5, and we now have an HTTP proxy server for a similar
purpose. [Kris]
o Fixed --proxy-auth which always caused a segmentation fault. [Kris]
o Fixed an issue which commonly occurred when using --proxy-type socks4 and
when reading from a piped or redirected stdin. The problem was that Ncat
was sending the data read from stdin across the network before it was fully
connected to the proxy. Thanks to Jah for noticing this problem. [Kris]
o The output options -o and -x are no longer mutually exclusive. Also, the
documented alias for -x (--hex-dump) now works. [Kris]
o Renamed -t (--idle-timeout) to -i [Kris]
o Added -t/--telnet to handle DO/DONT WILL/WONT Telnet negotiations [Kris]
o Added -C/--crlf to try to use CRLF for line-endings. This comes in handy
when talking to some stringent servers directly from a terminal in one of
the many common plain-text protocols which specify CRLF as the required EOL
sequence. [Kris]
o Added -w/--wait for specifying a connect timeout [Kris]
o Added -g and -G for IPv4 loose source routing [Kris]
o Added -p to specify a local port to bind to in client-mode [Kris]
o Added -n/--nodns to not resolve any hostnames [Mixter]
o Added -c/--sh-exec, which is like -e but executes via /bin/sh [Kris]
o Made -s (set source address) actually work in client-mode [Kris]
o Changed --recvonly and --sendonly to --recv-only and --send-only [Kris]
o Options taking a time (-d, -i, -w) are now more flexible: you can append
an "s" for seconds, "m" for minutes or "h" for hours (e.g. 30s) [Kris]
o Fixed a bug which could cause Nsock tracing (use of -v one or more times)
to print very inaccurate times [Kris]
o Removed unused XOR code [Kris]
o Added file dependency checking to the Makefile. So now, for instance, if
a header file is modified, running make again will recompile all of the
files which depend on it. [Kris]
o Improved the build system by removing the automake requirement ([Mixter])
and by cutting down configure.ac and Makefile.in a lot ([Kris]). Other
various build/configure improvements were made as well.
o Lots of documentation rewrites/updates, including separating the man page
into sections such as "Proxy Options", "Client-Mode Options", etc. [Kris]
o Lots of code cleaning up [Kris]
Ncat 0.10rc3
o Autoconf build process. ./configure;make!
o Fixed Segmentation faults on outgoing connections that appeared on on
certain platforms/architectures/compilers.
o Improved overall build quality and portability to other platforms and
architectures. Should build on multiple different platforms quite well.
o Fixed some bounds checking on a SOCKS4 server buffer in ncat_connect.c
o Fixed some documentation typos and --help/usage typos.
Ncat 0.10rc2
o Fixed inetd-like support so executed programs actually exit when the
client does and don't hang.
o Fixed some looping read/write issue with EOF handling.
-- Thanks to Sebastian Garcia.
o Moved connect message "Lookup of $foo returned $bar" to the verbosity
output set instead of the default output.
o Fixed bug in SOCKS4 server on rejected/refused connections.
o First official release!
Ncat 0.10rc1
o Removed access to XOR code with a view to totally removing it in the next
release of Ncat
o One or two minor bug fixes.
Ncat 0.09
o Added hexdump() support.
o Added XOR cipher support.
o Added --allow, --deny support IP address handling CIDR.
o General code tidy up; better documentation in header file.
o Various error messages cleaned up. Added new #define for NCAT_SHORT.
o Added missing 'strerror(errno)' handling to some error messages.
o Cleaned up various bits of code.
o Reformatted code heavily into K&R layout.
o Fixed XOR so it'll use longer passwords.
o Worked on various cross-platform portability issues.
-- Thanks to Jonathan Saylor.
Ncat 0.08
o Added millisecond resolution timer for blocking read/writes.
o Added HTTP/1.1 CONNECT method proxying support.
o Added Base64 encoder for handling Proxy-Authorization support.
o Support added for --broker, full I/O multiplexing support.
o Added additional feature of --talk
Ncat 0.07
o Added feature of fork()'ing off on executing a 3rd party program to allow
continued incoming connections.
o Added support for ASCII logging.
o Added support for hexdump logging.
o Various bits of code cleaned up.
Ncat 0.06
o Added --listen support.
o Added TCP/UDP support for --listen.
o Added command line parser for handling options to pass to the command to
be executed.
o Polished up --help, --verbose & --version.

19
ncat/INSTALL Normal file
View File

@@ -0,0 +1,19 @@
Building Ncat
=============
On UNIX systems, ideally, you should just be able to do:
./configure
make
After building is successful, to install:
make install
For instructions on how to build Ncat for Microsoft Windows or for far more
in-depth compilation, installation, and removal notes, read the Nmap Install
Guide at http://nmap.org/install/.
For instructions on how to build Ncat Portable for Microsoft Windows, read
the how-to available at https://secwiki.org/w/Nmap/Ncat_Portable.

181
ncat/Makefile.in Normal file
View File

@@ -0,0 +1,181 @@
# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
# Ncat Makefile
SHELL = @SHELL@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
includedir = @includedir@
oldincludedir = /usr/include
top_builddir = .
pkgdatadir = $(datadir)/ncat
INSTALL = @INSTALL@
transform = @program_transform_name@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
mandir = @mandir@
srcdir = @srcdir@
NBASEDIR = ../nbase
NSOCKDIR = ../nsock/src
NSOCKLIB = $(NSOCKDIR)/libnsock.a
NBASELIB = $(NBASEDIR)/libnbase.a
CC = @CC@
CPPFLAGS = @CPPFLAGS@
CFLAGS = @CFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
DEFS = @DEFS@ -DNCAT_DATADIR="\"$(pkgdatadir)\""
# With GCC, add extra security checks to source code.
DEFS += -D_FORTIFY_SOURCE=2
INCLS = -I. -I.. -I../nsock/include/ -I$(NBASEDIR)
RM = rm -f
STRIP = @STRIP@
OPENSSL_LIBS = @OPENSSL_LIBS@
HAVE_OPENSSL = @HAVE_OPENSSL@
PCAP_LIBS = @PCAP_LIBS@
CPPFLAGS += $(DEFS) $(INCLS)
SHTOOL = ../shtool
# DESTDIR can be used by package maintainers to install Ncat under its
# usual directory structure into a different tree.
DESTDIR =
SRCS = ncat_main.c ncat_connect.c ncat_core.c ncat_posix.c ncat_listen.c ncat_proxy.c ncat_ssl.c base64.c http.c util.c sys_wrap.c
OBJS = ncat_main.o ncat_connect.o ncat_core.o ncat_posix.o ncat_listen.o ncat_proxy.o ncat_ssl.o base64.o http.o util.o sys_wrap.o
DATAFILES =
ifneq ($(HAVE_OPENSSL),)
SRCS += http_digest.c
OBJS += http_digest.o
DATAFILES = certs/ca-bundle.crt
endif
TARGET = ncat
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES = $(CONFIG_HEADER) config.cache config.log config.status
TEST_PROGS = test/addrset test/test-uri test/test-cmdline-split
ifneq ($(HAVE_OPENSSL),)
TEST_PROGS += test/test-wildcard
endif
all: $(TARGET) $(TEST_PROGS)
$(TARGET): $(OBJS) $(NSOCKLIB)
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(OBJS) $(NSOCKLIB) $(NBASELIB) $(OPENSSL_LIBS) $(PCAP_LIBS) $(LIBS)
%.o: %.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(srcdir)/configure: $(srcdir)/configure.ac $(CONFIGURE_DEPENDENCIES)
cd $(srcdir) && autoconf
config.h:
@if test ! -f config.h; then \
cd $(top_builddir) && CONFIG_FILES= CONFIG_HEADERS=config.h \
$(SHELL) ./config.status; \
fi
test/addrset: test/addrset.o ncat_core.o sys_wrap.o util.o
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^ $(LIBS) $(NSOCKLIB) $(NBASELIB) $(OPENSSL_LIBS) $(PCAP_LIBS)
test/test-uri: test/test-uri.o base64.o http.o ncat_core.o sys_wrap.o util.o
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^ $(LIBS) $(NSOCKLIB) $(NBASELIB) $(OPENSSL_LIBS) $(PCAP_LIBS)
test/test-cmdline-split: test/test-cmdline-split.o ncat_posix.o ncat_core.o sys_wrap.o util.o
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^ $(LIBS) $(NSOCKLIB) $(NBASELIB) $(OPENSSL_LIBS) $(PCAP_LIBS)
test/test-wildcard: test/test-wildcard.o ncat_core.o ncat_ssl.o sys_wrap.o util.o
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^ $(LIBS) $(NSOCKLIB) $(NBASELIB) $(OPENSSL_LIBS) $(PCAP_LIBS)
.PHONY: uninstall all clean distclean
../libnetutil/libnetutil.a: ../libnetutil/Makefile
@echo Compiling libnetutil;
cd ../libnetutil && $(MAKE)
$(NBASEDIR)/libnbase.a: $(NBASEDIR)/Makefile
@echo Compiling libnbase;
cd $(NBASEDIR) && $(MAKE)
$(NSOCKDIR)/libnsock.a: $(NSOCKDIR)/Makefile
@echo Compiling libnsock;
cd $(NSOCKDIR) && $(MAKE)
install: $(TARGET)
@echo Installing Ncat;
$(SHTOOL) mkdir -f -p -m 755 $(DESTDIR)$(bindir) $(DESTDIR)$(mandir)/man1
$(INSTALL) -c -m 755 ncat $(DESTDIR)$(bindir)/ncat
$(STRIP) -x $(DESTDIR)$(bindir)/ncat
if [ -n "$(DATAFILES)" ]; then \
$(SHTOOL) mkdir -f -p -m 755 $(DESTDIR)$(pkgdatadir); \
$(INSTALL) -c -m 644 $(DATAFILES) $(DESTDIR)$(pkgdatadir)/; \
fi
$(INSTALL) -c -m 644 docs/$(TARGET).1 $(DESTDIR)$(mandir)/man1/$(TARGET).1
uninstall:
@echo Uninstalling Ncat;
$(RM) -f $(DESTDIR)$(bindir)/$(TARGET)
$(RM) -f $(DESTDIR)$(mandir)/man1/$(TARGET).1
$(RM) -rf $(DESTDIR)$(pkgdatadir)/
ncat_clean:
$(RM) -f *.o test/*.o $(TARGET) $(TEST_PROGS) makefile.dep
clean: ncat_clean
distclean: clean
-rm -f Makefile $(CONFIG_CLEAN_FILES)
TESTS = ./test-addrset.sh ./test-cmdline-split ./test-uri
ifneq ($(HAVE_OPENSSL),)
TESTS += ./test-wildcard
endif
check: $(TARGET) $(TEST_PROGS)
cd test && ($(addsuffix &&,$(TESTS)) echo "All tests passed.")
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
makefile.dep:
$(CC) -MM $(CPPFLAGS) $(SRCS) > $@
include makefile.dep

26
ncat/aclocal.m4 vendored Normal file
View File

@@ -0,0 +1,26 @@
# generated automatically by aclocal 1.10.1 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
# 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 8
# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS.
AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
m4_include([../acinclude.m4])

148
ncat/base64.c Normal file
View File

@@ -0,0 +1,148 @@
/***************************************************************************
* base64.c -- Base64 encoding. *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include "base64.h"
#include "nbase.h"
static int b64enc_internal(const unsigned char *data, int len, char *dest)
{
/* base64 alphabet, taken from rfc3548 */
char *b64alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char *buf = dest;
/* Encode three bytes per iteration ala rfc3548. */
while (len >= 3) {
buf[0] = b64alpha[(data[0] >> 2) & 0x3f];
buf[1] = b64alpha[((data[0] << 4) & 0x30) | ((data[1] >> 4) & 0xf)];
buf[2] = b64alpha[((data[1] << 2) & 0x3c) | ((data[2] >> 6) & 0x3)];
buf[3] = b64alpha[data[2] & 0x3f];
data += 3;
buf += 4;
len -= 3;
}
/* Pad the remaining bytes. len is 0, 1, or 2 here. */
if (len > 0) {
buf[0] = b64alpha[(data[0] >> 2) & 0x3f];
if (len > 1) {
buf[1] = b64alpha[((data[0] << 4) & 0x30) | ((data[1] >> 4) & 0xf)];
buf[2] = b64alpha[(data[1] << 2) & 0x3c];
} else {
buf[1] = b64alpha[(data[0] << 4) & 0x30];
buf[2] = '=';
}
buf[3] = '=';
buf += 4;
}
/*
* As mentioned in rfc3548, we need to be careful about
* how we null terminate and handle embedded null-termination.
*/
*buf = '\0';
return (buf - dest);
}
/* Take in plain text and encode into base64. */
char *b64enc(const unsigned char *data, int len)
{
char *dest;
/* malloc enough space to do something useful */
dest = (char*)safe_malloc(4 * len / 3 + 4);
dest[0] = '\0';
/* Call internal function to base64 encode data */
b64enc_internal(data, len, dest);
return (dest);
}

90
ncat/base64.h Normal file
View File

@@ -0,0 +1,90 @@
/***************************************************************************
* base64.h *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
char *b64enc(const unsigned char *data, int len);

47
ncat/certs/README Normal file
View File

@@ -0,0 +1,47 @@
The file ca-bundle.crt contains certificates extracted from Microsoft
Windows. These are installed and used as the default trusted root
certificates when SSL certificate verification is requested with
--ssl-verify. On some platforms (some Unixes), these certificates are
used in addition to any certificates installed by the operating system.
Microsoft's bundle was preferred over Mozilla's because Microsoft may be
more selective in the organizations it trusts. When this bundle was
created, Microsoft's store had 107 certificates while Mozilla's had 126.
See below for how to use an alternative trust store.
== How to extract the trusted root CA certificates on Windows
These instructions require the openssl command-line utility.
On Windows XP, run the rootsupd.exe tool to downoad the full list of
trusted certificates. Otherwise there is only a partial list
(certificates are downloaded on demand).
http://support.microsoft.com/kb/931125
http://www.download.windowsupdate.com/msdownload/update/v3/static/trustedr/en/rootsupd.exe
Press "Start", then "Run...". Type "certmgr.msc" and press Enter. Open
the folder "Trusted Root Certification Authorities" and its subfolder
"Certificates". Click on "Expiration Date" to sort. Select the first
certificate that is not expired, then press Shift+down arrow until all
the non-expired certificates are selected. Right-click on the list of
certificates, and in the context menu, select "All Tasks", then
"Export...". Export to the file ca-bundle.p7b.
In a Cygwin shell, enter the directory containing ca-bundle.p7b and run
the command
openssl pkcs7 -in ca-bundle.p7b -inform der -print_certs -out ca-bundle.crt
That will create a file ca-bundle.crt containing all the certificates,
each preceded by its subject and issuer.
== Alternative sources for a certificate bundle
Another commonly used trust store is the one provided by Mozilla. The
cURL package includes a script that automatically creates a suitable PEM
file from a file in Mozilla's source repository. They also provide
ready-made PEM files to download. See http://curl.haxx.se/docs/caextract.html.
Here is how to download Mozilla's trust store:
$ wget https://raw.github.com/bagder/curl/master/lib/mk-ca-bundle.pl
$ perl mk-ca-bundle.pl

8290
ncat/certs/ca-bundle.crt Normal file

File diff suppressed because it is too large Load Diff

1465
ncat/config.guess vendored Executable file

File diff suppressed because it is too large Load Diff

150
ncat/config.h.in Normal file
View File

@@ -0,0 +1,150 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
#undef HAVE_DOPRNT
/* Define to 1 if you have the `dup2' function. */
#undef HAVE_DUP2
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define to 1 if you have the `fork' function. */
#undef HAVE_FORK
/* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY
/* Define to 1 to enable HTTP Digest authentication (requires OpenSSL). */
#undef HAVE_HTTP_DIGEST
/* Define to 1 if you have the `inet_ntoa' function. */
#undef HAVE_INET_NTOA
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `crypto' library (-lcrypto). */
#undef HAVE_LIBCRYPTO
/* Define to 1 if you have the `ssl' library (-lssl). */
#undef HAVE_LIBSSL
/* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
to 0 otherwise. */
#undef HAVE_MALLOC
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `memset' function. */
#undef HAVE_MEMSET
/* Define to 1 if you have the <netdb.h> header file. */
#undef HAVE_NETDB_H
/* Define to 1 if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
/* Define to 1 if you have OpenSSL. */
#undef HAVE_OPENSSL
/* Define to 1 if your system has a GNU libc compatible `realloc' function,
and to 0 otherwise. */
#undef HAVE_REALLOC
/* Define to 1 if you have the `select' function. */
#undef HAVE_SELECT
/* Define to 1 if you have the `socket' function. */
#undef HAVE_SOCKET
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strcasecmp' function. */
#undef HAVE_STRCASECMP
/* Define to 1 if you have the `strchr' function. */
#undef HAVE_STRCHR
/* Define to 1 if you have the `strdup' function. */
#undef HAVE_STRDUP
/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strncasecmp' function. */
#undef HAVE_STRNCASECMP
/* Define to 1 if you have the `strtol' function. */
#undef HAVE_STRTOL
/* Define to 1 if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define to 1 if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
/* Define to 1 if you have the <sys/socket.h> header file. */
#undef HAVE_SYS_SOCKET_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/timeb.h> header file. */
#undef HAVE_SYS_TIMEB_H
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
#undef HAVE_SYS_WAIT_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the `vprintf' function. */
#undef HAVE_VPRINTF
/* Define to the type of arg 1 for `select'. */
#undef SELECT_TYPE_ARG1
/* Define to the type of args 2, 3 and 4 for `select'. */
#undef SELECT_TYPE_ARG234
/* Define to the type of arg 5 for `select'. */
#undef SELECT_TYPE_ARG5
/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
#undef STAT_MACROS_BROKEN
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to rpl_malloc if the replacement function should be used. */
#undef malloc
/* Define to rpl_realloc if the replacement function should be used. */
#undef realloc

1569
ncat/config.sub vendored Executable file

File diff suppressed because it is too large Load Diff

93
ncat/config_win.h Normal file
View File

@@ -0,0 +1,93 @@
/***************************************************************************
* config_win.h *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id: ncat.h 16595 2010-01-27 02:51:16Z fyodor $ */
/* These are preprocessor definitions in effect on Windows, where Autoconf
isn't available to create config.h. */
#define HAVE_OPENSSL 1
#define HAVE_HTTP_DIGEST 1

6339
ncat/configure vendored Executable file

File diff suppressed because it is too large Load Diff

210
ncat/configure.ac Normal file
View File

@@ -0,0 +1,210 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59)
AC_INIT(ncat_main.c)
AM_CONFIG_HEADER(config.h)
AC_CANONICAL_HOST
use_openssl="yes"
specialssldir=""
AC_ARG_WITH(openssl,[ --with-openssl=DIR Use optional openssl libs and includes from [DIR]/lib/ and [DIR]/include/openssl/],
[ case "$with_openssl" in
yes)
;;
no)
use_openssl="no"
;;
*)
specialssldir="$with_openssl"
LDFLAGS="$LDFLAGS -L$with_openssl/lib"
CFLAGS="-I$with_openssl/include $CFLAGS"
;;
esac]
)
# Checks for programs.
AC_PROG_CC
if test -n "$GCC"; then
CFLAGS="$CFLAGS -Wall"
fi
AC_PROG_INSTALL
AC_PATH_TOOL([STRIP], [strip], [/bin/true])
# Checks for header files.
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS([fcntl.h limits.h netdb.h netinet/in.h stdlib.h string.h strings.h sys/param.h sys/socket.h sys/time.h sys/timeb.h unistd.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STAT
AC_C_CONST
AC_HEADER_TIME
# Checks for library functions.
AC_FUNC_FORK
AC_FUNC_SELECT_ARGTYPES
AC_TYPE_SIGNAL
AC_FUNC_VPRINTF
AC_CHECK_FUNCS([dup2 gettimeofday inet_ntoa memset select socket strcasecmp strchr strdup strerror strncasecmp strtol])
AC_SEARCH_LIBS(setsockopt, socket)
# Ncat does not call gethostbyname directly, but some of the libraries
# it links to (such as libpcap) do. Instead it calls getaddrinfo. At
# one point we changed this test to use getaddrinfo rather than
# gethostbyname, but on a Solaris 9 SPARC box that function could be
# called without -lnsl, while gethostbyname sitll required -lnsl, so
# we changed the test back.
AC_SEARCH_LIBS(gethostbyname, nsl)
# OpenSSL requires dlopen on some platforms
AC_SEARCH_LIBS(dlopen, dl)
# If they didn't specify it, we try to find it
if test "$use_openssl" = "yes" -a -z "$specialssldir" ; then
AC_CHECK_HEADER(openssl/ssl.h,,
[ use_openssl="no"
AC_MSG_WARN([Failed to find openssl/ssl.h so OpenSSL will not be used.
If it is installed you can try the --with-openssl=DIR argument]) ])
if test "$use_openssl" = "yes"; then
AC_CHECK_HEADER(openssl/err.h,,
[ use_openssl="no"
AC_MSG_WARN([Failed to find openssl/err.h so OpenSSL will not be used.
If it is installed you can try the --with-openssl=DIR argument]) ])
fi
if test "$use_openssl" = "yes"; then
AC_CHECK_HEADER(openssl/rand.h,,
[ use_openssl="no"
AC_MSG_WARN([Failed to find openssl/rand.h so OpenSSL will not be used.
If it is installed you can try the --with-openssl=DIR argument]) ])
fi
if test "$use_openssl" = "yes"; then
AC_CHECK_LIB(crypto, BIO_int_ctrl,
[],
[ use_openssl="no"
AC_MSG_WARN([Failed to find libcrypto so OpenSSL will not be used.
If it is installed you can try the --with-openssl=DIR argument]) ])
fi
if test "$use_openssl" = "yes"; then
AC_CHECK_LIB(ssl, SSL_new,
[],
[ use_openssl="no"
AC_MSG_WARN([Failed to find libssl so OpenSSL will not be used.
If it is installed you can try the --with-openssl=DIR argument]) ])
fi
fi
OPENSSL_LIBS=
if test "$use_openssl" = "yes"; then
AC_DEFINE([HAVE_OPENSSL], [1], [Define to 1 if you have OpenSSL.])
AC_DEFINE([HAVE_HTTP_DIGEST], [1], [Define to 1 to enable HTTP Digest authentication (requires OpenSSL).])
OPENSSL_LIBS="-lssl -lcrypto"
# Define in Makefile also.
HAVE_OPENSSL=yes
AC_SUBST(HAVE_OPENSSL)
fi
AC_SUBST(OPENSSL_LIBS)
libpcapdir=../libpcap
AC_SUBST(libpcapdir)
dnl Check whether libpcap is already available
have_libpcap=no
# By default, search for pcap library
test "${with_libpcap+set}" != "set" && with_libpcap=yes
AC_ARG_WITH(libpcap,
AC_HELP_STRING([--with-libpcap=DIR], [Look for pcap in DIR/include and DIR/libs.])
AC_HELP_STRING([--with-libpcap=included], [Always use version included with Nmap]),
[ case "$with_libpcap" in
yes)
AC_CHECK_HEADER(pcap.h,[
AC_CHECK_LIB(pcap, pcap_datalink,
[have_libpcap=yes ])])
;;
included)
have_libpcap=no
;;
*)
_cppflags=$CXXFLAGS
_ldflags=$LDFLAGS
CPPFLAGS="-I$with_libpcap/include $CPPFLAGS"
LDFLAGS="-L$with_libpcap/lib $LDFLAGS"
AC_CHECK_HEADER(pcap.h,[
AC_CHECK_LIB(pcap, pcap_datalink,
[have_libpcap=yes
LIBPCAP_INC=$with_libpcap/include
LIBPCAP_LIB=$with_libpcap/lib])])
LDFLAGS=$_ldflags
CXXFLAGS=$_cppflags
;;
esac]
)
if test $have_libpcap = yes; then
if test "${LIBPCAP_INC+set}" = "set"; then
_cflags=$CXXFLAGS
_ldflags=$LDFLAGS
CPPFLAGS="-I$LIBPCAP_INC $CPPFLAGS"
LDFLAGS="-L$LIBPCAP_LIB $LDFLAGS"
fi
# link with -lpcap for the purposes of this test
LIBS_OLD="$LIBS"
LIBS="$LIBS -lpcap"
PCAP_IS_SUITABLE([have_libpcap=yes], [have_libpcap=no], [have_libpcap=yes])
LIBS="$LIBS_OLD"
fi
PCAP_LIBS="-lpcap"
if test $have_libpcap = yes; then
PCAP_DEPENDS=""
PCAP_BUILD=""
PCAP_CLEAN=""
PCAP_DIST_CLEAN=""
AC_DEFINE(HAVE_LIBPCAP)
else
if test "${LIBPCAP_INC+set}" = "set"; then
LDFLAGS="-L$libpcapdir $_ldflags"
CPPFLAGS="$CPPFLAGS -I$LIBPCAP_INC"
else
LDFLAGS="-L$libpcapdir $LDFLAGS"
CPPFLAGS="$CPPFLAGS -I$libpcapdir"
fi
PCAP_DEPENDS='$(LIBPCAPDIR)/libpcap.a'
PCAP_BUILD="pcap_build"
PCAP_CLEAN="pcap_clean"
PCAP_DIST_CLEAN="pcap_dist_clean"
fi
AC_SUBST(PCAP_DEPENDS)
AC_SUBST(PCAP_BUILD)
AC_SUBST(PCAP_CLEAN)
AC_SUBST(PCAP_DIST_CLEAN)
AC_SUBST(PCAP_LIBS)
# Needed on AIX.
AC_CHECK_LIB(odm, odm_initialize)
# Needed on AIX.
AC_CHECK_LIB(odm, odm_initialize)
AC_CHECK_LIB(cfg, _system_configuration)
AC_CONFIG_FILES(Makefile)
AC_OUTPUT
# NCAT ASCII ART
if test -f docs/ncat-ascii-art.txt; then
cat docs/ncat-ascii-art.txt
fi
echo "Configuration complete."

28
ncat/docs/AUTHORS Normal file
View File

@@ -0,0 +1,28 @@
Ncat AUTHORS
============
Ncat is based in concept (but not code) on the original "Netcat"
written by Hobbit circa 1994. Ncat combines the original Netcat
feature set as well as various other ideas from other Netcat-like
products, such as CryptCat, Socat, GNU Netcat, etc.
Ncat was originally written from the ground up by Chris Gibson
(chris@linuxops.net) and was funded by the Google Summer of Code Program
2005.
Development, bug fixes, security auditing, improvements by Sean
(infamous42md@hotpop.com).
Starting with the Google Summer of Code 2008, Ncat development was
picked back up by Mixter and Kris Katterjohn. This included many bug
fixes, new features and code cleanups.
The Ncat requirements, ideas and general support and help were given by
Fyodor.
Many helpful comments, suggestions and other useful information was
taken from the nmap-dev list (@insecure.org) as well as other
contributors via email.
Ncat shares the Nmap infrastructure libraries (Nsock and Nbase) which
were originally written by Fyodor.

146
ncat/docs/README Normal file
View File

@@ -0,0 +1,146 @@
. .
\`-"'"-'/
} 6 6 {
==. Y ,==
/^^^\ .
/ \ )
( )-( )/ _
-""---""--- /
/ Ncat \_/
( ____
\_.=|____E
README for Ncat
---------------
Ncat is a reimplementation of the currently splintered and reasonably
unmaintained Netcat family. Ncat will do pretty much everything that
all the other Netcat's do, all in one place. Plus it has the added
benefit of spanky new features and ongoing development.
Ncat was designed with the original Netcat interface in mind. Rather
than replacing the old Netcat interface with a brand new (and thus more
convoluted) set of options, the Ncat interface was intentionally kept
clean and simple to use, just like the original product.
Ncat provides most of the features present in the original Netcat but with
a complete overhaul and rewrite, along with completely new features and a
combination of other well received features of other Netcat products, such
as IPv6 and SSL support.
The port scanning support has been entirely removed from Ncat. The
reason for this is fairly obvious: there is a better port scanner out
there already... :)
Ncat can act as either a client or server, using TCP or UDP over IPv4 or
IPv6. SSL support is provided for both the client and server mode.
There is also a new "connection brokering" feature which enables two or
more hosts to connect that previously were unable to directly communicate
with each other.
For example: "Host A" can connect to "Host B" but not "Host C"
"Host C" can connect to "Host B" but not "Host A"
It is clear, then, that if you could connect to "Host B" then "Host A"
and "Host C" could directly communicate...
[HostA] <------> [HostB-with-Ncat-Broker] <------> [HostC]
Ncat's connection brokering will allow you to connect between Host A and
Host C via Host B without the trouble of having to have SOCKS support,
etc. This is still somewhat experimental behaviour.
Ncat has support for HTTP "CONNECT" via an HTTP proxy server such as Squid.
It can also connect via a SOCKS4 server and is very flexible in terms of
how it shuffles your data around.
Ncat can also spawn it's own it's own HTTP CONNECT proxy server for your
own relaying requirements.
Ncat has the ability to execute a program and handle the I/O for its data
over the socket. In other words, Ncat can "add" networking support to
applications that currently have none.
For example, you could:
ncat --exec "/bin/bash" -l 5000
NOTE: This is exceptionally dangerous behaviour, as it leaves an open shell
sitting directly accessible to anyone who is able to connect to port 5000.
See the allow and deny options below for securing your Ncat processes.
Ncat has a TCP and UDP "redir"-style redirection feature to allow the user
to redirect traffic from one host to another.
For example:
ncat --exec "/usr/local/bin/ncat www.example.com 80" -l 8888
This command binds Ncat to the local machine on port 8888 and redirects
connections to www.example.com. You may also find uses for this as a "host
hiding" system. Similar to SOCKS4 but without any of the hassle of having
to have SOCKS support in the application.
This also begs the question of, "What would happen if you decided you wanted
to pass the --udp flag in to the above command somewhere?"
In this case, you would have a TCP to UDP "gender changer".
If you have an application that only makes only TCP connections, for example,
you could spawn a Ncat process to listen on a the applications TCP port and
then redirect the TCP connection out to the final destination, only over UDP.
The --allow and --deny options are provided to prevent unauthorized access to
any Ncat process that is listening on a port. These options are also paired
with the --allowfile and --denyfile options, similar in behaviour to Nmap.
The allow and deny options accept a number of different IP address formats
for maximum flexibility:
A single IP address, of the format:
ip.ip.ip.ip
EG: 192.168.10.1
A CIDR-style IP address range, of the format:
ip.ip.ip.ip/cidr
EG: 192.168.10.0/24
An IP and full netmask, of the format:
ip.ip.ip.ip:nm.nm.nm.nm
EG: 192.168.10.4:255.255.255.255
An IP address with wildcards:
ip.ip.ip.*
ip.ip.*.*
ip.*.*.*
These rules may also be used in a flat file, delimited by newlines. An
example of a full ACL is included in docs/examples/ labelled 'iplist'. Also
note that comments start with a # and are perfectly acceptable for use in
the ACL's.
For example, the file "ipaccess" might look like:
# Abuse from ADSL user.
88.223.14.1/32
# This guy is scanning us for SOCKS4 servers to abuse, block his /24
194.213.167.*
To implement this IP address ACL simply run:
ncat --denyfile /path/to/file/ipaccess -l 7000
For further documentation, please see the man page.
--Chris Gibson and Kris Katterjohn

29
ncat/docs/THANKS Normal file
View File

@@ -0,0 +1,29 @@
Ncat Acknowledgements
=====================
This file is a short rambling of various "thank-you"'s to all
the very generous support and advice received from various
parties.
First and foremost: Thanks go out to Fyodor for all the support
and great ideas throughout the course of development and no doubt
also in the future.
Thanks to Google and the Summer of Code team. The points of
contact with Google being Chris DiBona, Natalie and Jude. Thanks to
you all for making this possible. Without whom I wouldn't even
be writing this.
Also, thank you to all the folks from #c on Undernet who kicked
me in the right direction when things were at their most broken.
Thanks to Jan for all her support and, well, general tolerance. :)
Thanks to all the people who've submitted bug reports, given me
ideas, helped me test Ncat or just given me general encouragement
over the previous years. It is most appreciated.
Finally, thanks to Hobbit for writing the original Netcat; it still
rocks.
--Chris Gibson, <chris@linuxops.net>

15
ncat/docs/examples/README Normal file
View File

@@ -0,0 +1,15 @@
/examples/scripts
~~~~~~~~~~~~~~~~~
These are a set of small scripts to further demonstrate some
uses for Ncat. You *will* have to change some values yourself,
such as in "http-proxy", if your proxy server requires authorization,
you'll have to add your own authorization information.
/examples/logs/
~~~~~~~~~~~~~~~
These are a set of output logfiles generated by Ncat to briefly
demonstrate Ncat's logging abilities.
--Chris Gibson, <chris@linuxops.net>

View File

@@ -0,0 +1,23 @@
#
# This is a sample IP access list that
# could potentially be used with Ncat
# to allow or deny specific users from
# connecting to an Ncat process, such as
# a standard listen operation to being
# able to access your newly spawned SOCKS4
# server.
#
# Obviously, these IP addresses are pretty
# useless to most people. It is an example
# afterall. :)
#
# Chris Gibson, <chris@linuxops.net>
# lo interface.
127.0.0.1/8
# eth0 internal network.
192.168.0.0/24
# eth1 to outside world.
55.20.30.1/32

View File

@@ -0,0 +1,3 @@
HELO xxx.xxx.xxx
220 smtp.google.com ESMTP
250 smtp.google.com Hello xxx.xxx.xxx [xxx.xxx.xxx.xxx], pleased to meet you

View File

@@ -0,0 +1,47 @@
[0000] 47 45 54 20 2F 69 6E 64 65 78 2E 68 74 6D 6C 20 GET..ind ex.html.
[0010] 48 54 54 50 2F 31 2E 30 0A HTTP.1.0 .
[0000] 55 73 65 72 2D 41 67 65 6E 74 3A 20 4E 63 61 74 User.Age nt..Ncat
[0010] 0A .
[0000] 48 6F 73 74 3A 20 77 77 77 2E 67 6F 6F 67 6C 65 Host..ww w.google
[0010] 2E 63 6F 6D 0A .com.
[0000] 0A .
[0000] 48 54 54 50 2F 31 2E 30 20 33 30 32 20 46 6F 75 HTTP.1.0 .302.Fou
[0010] 6E 64 0D 0A 4C 6F 63 61 74 69 6F 6E 3A 20 68 74 nd..Loca tion..ht
[0020] 74 70 3A 2F 2F 77 77 77 2E 67 6F 6F 67 6C 65 2E tp...www .google.
[0030] 63 6F 2E 75 6B 2F 63 78 66 65 72 3F 63 3D 50 52 co.uk.cx fer.c.PR
[0040] 45 46 25 33 44 3A 54 4D 25 33 44 31 31 32 34 37 EF.3D.TM .3D11247
[0050] 35 35 38 30 32 3A 53 25 33 44 48 75 52 73 51 62 55802.S. 3DHuRsQb
[0060] 51 69 43 59 52 71 4A 6E 5A 32 26 70 72 65 76 3D QiCYRqJn Z2.prev.
[0070] 2F 69 6E 64 65 78 2E 68 74 6D 6C 0D 0A 53 65 74 .index.h tml..Set
[0080] 2D 43 6F 6F 6B 69 65 3A 20 50 52 45 46 3D 49 44 .Cookie. .PREF.ID
[0090] 3D 31 63 31 31 36 32 63 66 36 63 63 33 65 35 63 .1c1162c f6cc3e5c
[00a0] 64 3A 43 52 3D 31 3A 54 4D 3D 31 31 32 34 37 35 d.CR.1.T M.112475
[00b0] 35 38 30 32 3A 4C 4D 3D 31 31 32 34 37 35 35 38 5802.LM. 11247558
[00c0] 30 32 3A 53 3D 5F 38 33 69 47 45 53 67 6F 7A 6E 02.S..83 iGESgozn
[00d0] 33 49 4F 6D 34 3B 20 65 78 70 69 72 65 73 3D 53 3IOm4..e xpires.S
[00e0] 75 6E 2C 20 31 37 2D 4A 61 6E 2D 32 30 33 38 20 un..17.J an.2038.
[00f0] 31 39 3A 31 34 3A 30 37 20 47 4D 54 3B 20 70 61 19.14.07 .GMT..pa
[0100] 74 68 3D 2F 3B 20 64 6F 6D 61 69 6E 3D 2E 67 6F th....do main..go
[0110] 6F 67 6C 65 2E 63 6F 6D 0D 0A 43 6F 6E 74 65 6E ogle.com ..Conten
[0120] 74 2D 54 79 70 65 3A 20 74 65 78 74 2F 68 74 6D t.Type.. text.htm
[0130] 6C 0D 0A 53 65 72 76 65 72 3A 20 47 57 53 2F 32 l..Serve r..GWS.2
[0140] 2E 31 0D 0A 43 6F 6E 74 65 6E 74 2D 4C 65 6E 67 .1..Cont ent.Leng
[0150] 74 68 3A 20 32 32 37 0D 0A 44 61 74 65 3A 20 54 th..227. .Date..T
[0160] 75 65 2C 20 32 33 20 41 75 67 20 32 30 30 35 20 ue..23.A ug.2005.
[0170] 30 30 3A 31 30 3A 30 32 20 47 4D 54 0D 0A 43 6F 00.10.02 .GMT..Co
[0180] 6E 6E 65 63 74 69 6F 6E 3A 20 4B 65 65 70 2D 41 nnection ..Keep.A
[0190] 6C 69 76 65 0D 0A 0D 0A 3C 48 54 4D 4C 3E 3C 48 live.... .HTML..H
[01a0] 45 41 44 3E 3C 54 49 54 4C 45 3E 33 30 32 20 4D EAD..TIT LE.302.M
[01b0] 6F 76 65 64 3C 2F 54 49 54 4C 45 3E 3C 2F 48 45 oved..TI TLE...HE
[01c0] 41 44 3E 3C 42 4F 44 59 3E 0A 3C 48 31 3E 33 30 AD..BODY ...H1.30
[01d0] 32 20 4D 6F 76 65 64 3C 2F 48 31 3E 0A 54 68 65 2.Moved. .H1..The
[01e0] 20 64 6F 63 75 6D 65 6E 74 20 68 61 73 20 6D 6F .documen t.has.mo
[01f0] 76 65 64 0A 3C 41 20 48 52 45 46 3D 22 68 74 74 ved..A.H REF..htt
[0200] 70 3A 2F 2F 77 77 77 2E 67 6F 6F 67 6C 65 2E 63 p...www. google.c
[0210] 6F 2E 75 6B 2F 63 78 66 65 72 3F 63 3D 50 52 45 o.uk.cxf er.c.PRE
[0220] 46 25 33 44 3A 54 4D 25 33 44 31 31 32 34 37 35 F.3D.TM. 3D112475
[0230] 35 38 30 32 3A 53 25 33 44 48 75 52 73 51 62 51 5802.S.3 DHuRsQbQ
[0240] 69 43 59 52 71 4A 6E 5A 32 26 61 6D 70 3B 70 72 iCYRqJnZ 2.amp.pr
[0250] 65 76 3D 2F 69 6E 64 65 78 2E 68 74 6D 6C 22 3E ev..inde x.html..
[0260] 68 65 72 65 3C 2F 41 3E 2E 0D 0A 3C 2F 42 4F 44 here..A. .....BOD
[0270] 59 3E 3C 2F 48 54 4D 4C 3E 0D 0A Y...HTML ...

View File

@@ -0,0 +1,6 @@
These are various scripts that demonstrate some
potential usage for Ncat.
If you find a neat usage for Ncat and possibly
write a few lines of code to automate something,
then please email them over to Chris Gibson (chris@linuxops.net)

View File

@@ -0,0 +1,5 @@
NCAT_PATH=../../..
PROXY_HOST=www.cnn.com:80
PROXY_AUTH=user:pass
$NCAT_PATH/ncat --http-proxy "$PROXY_HOST" --proxy-auth "$PROXY_AUTH" localhost 3128

View File

@@ -0,0 +1,14 @@
HTTP-SCAN with Ncat
~~~~~~~~~~~~~~~~~~~
This is a simple exercise that uses a small amount of
scripted automation that will throw out the banner
information of n number of hosts listed in the file "iplist".
Ncat uses the "get.request" HTTP header to get the newly
connected webserver to tell you about itself.
Usage: ./scan-example
Variables to change: None, but you may want to change "iplist"
to other more informative hosts.

View File

@@ -0,0 +1,3 @@
HEAD / HTTP/1.0

View File

@@ -0,0 +1,5 @@
www.google.com
www.microsoft.com
www.apache.org
www.freebsd.org
www.apple.com

View File

@@ -0,0 +1,7 @@
NCAT_PATH=../../../..
if [ -a "$NCAT_PATH/ncat" ]
then
for addr in `cat iplist`; do $NCAT_PATH/ncat --disable-eof-exit $addr 80 < get.request; done;
else
echo "Ncat is not buit. Please build Ncat before you use these scripts";
fi

View File

@@ -0,0 +1,57 @@
Connected to 66.102.9.147:80
HTTP/1.0 302 Found
Location: http://www.google.co.uk/
Set-Cookie: PREF=ID=b6262fee80b28ffc:TM=1137945347:LM=1137945347:S=s7TLf6mcMNGW-33R; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com
Content-Type: text/html
Server: GWS/2.1
Content-Length: 224
Date: Sun, 22 Jan 2006 15:55:47 GMT
Connection: Keep-Alive
Connected to 207.46.198.30:80
HTTP/1.1 200 OK
Connection: close
Date: Sun, 22 Jan 2006 15:55:48 GMT
Server: Microsoft-IIS/6.0
P3P: CP="ALL IND DSP COR ADM CONo CUR CUSo IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI"
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 21061
Connected to 209.237.227.195:80
HTTP/1.1 200 OK
Date: Sun, 22 Jan 2006 15:55:48 GMT
Server: Apache/2.2.0 (Unix)
Last-Modified: Wed, 18 Jan 2006 03:00:54 GMT
ETag: "997bf1-2d93-419e2580"
Accept-Ranges: bytes
Content-Length: 11667
Cache-Control: max-age=86400
Expires: Mon, 23 Jan 2006 15:55:48 GMT
Connection: close
Content-Type: text/html; charset=ISO-8859-1
Connected to 216.136.204.117:80
HTTP/1.1 200 OK
Date: Sun, 22 Jan 2006 15:55:49 GMT
Server: Apache/1.3.x LaHonda (Unix)
Last-Modified: Fri, 20 Jan 2006 21:24:33 GMT
ETag: "26f8f7-9839-43d15511"
Accept-Ranges: bytes
Content-Length: 38969
Connection: close
Content-Type: text/html
X-Pad: avoid browser bug
Connected to 17.112.152.32:80
HTTP/1.0 200 OK
Age: 328
Date: Sun, 22 Jan 2006 15:50:20 GMT
Content-Length: 26131
Content-Type: text/html
Expires: Sun, 22 Jan 2006 16:10:20 GMT
Cache-Control: max-age=1200
Server: Apache/1.3.29 (Darwin) PHP/4.3.1

View File

@@ -0,0 +1,11 @@
. .
\`-"'"-'/
} 6 6 {
==. Y ,==
/^^^\ .
/ \ ) Ncat: A modern interpretation of classic Netcat
( )-( )/
-""---""--- /
/ Ncat \_/
( ____
\_.=|____E

565
ncat/docs/ncat.1 Normal file
View File

@@ -0,0 +1,565 @@
'\" t
.\" Title: Ncat
.\" Author: [see the "Authors" section]
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
.\" Date: 11/14/2011
.\" Manual: Ncat Reference Guide
.\" Source: Ncat
.\" Language: English
.\"
.TH "NCAT" "1" "11/14/2011" "Ncat" "Ncat Reference Guide"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.\" http://bugs.debian.org/507673
.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
.\" -----------------------------------------------------------------
.\" * MAIN CONTENT STARTS HERE *
.\" -----------------------------------------------------------------
.SH "NAME"
ncat \- Concatenate and redirect sockets
.SH "SYNOPSIS"
.HP \w'\fBncat\fR\ 'u
\fBncat\fR [\fIOPTIONS\fR...] [\fIhostname\fR] [\fIport\fR]
.SH "DESCRIPTION"
.PP
Ncat is a feature\-packed networking utility which reads and writes data across networks from the command line\&. Ncat was written for the Nmap Project and is the culmination of the currently splintered family of Netcat incarnations\&. It is designed to be a reliable back\-end tool to instantly provide network connectivity to other applications and users\&. Ncat will not only work with IPv4 and IPv6 but provides the user with a virtually limitless number of potential uses\&.
.PP
Among Ncat\*(Aqs vast number of features there is the ability to chain Ncats together; redirection of TCP, UDP, and SCTP ports to other sites; SSL support; and proxy connections via SOCKS4 or HTTP proxies (with optional proxy authentication as well)\&. Some general principles apply to most applications and thus give you the capability of instantly adding networking support to software that would normally never support it\&.
.SH "OPTIONS SUMMARY"
.PP
.sp
.if n \{\
.RS 4
.\}
.nf
Ncat 5\&.61TEST3 ( http://nmap\&.org/ncat )
Usage: ncat [options] [hostname] [port]
Options taking a time assume seconds\&. Append \*(Aqms\*(Aq for milliseconds,
\*(Aqs\*(Aq for seconds, \*(Aqm\*(Aq for minutes, or \*(Aqh\*(Aq for hours (e\&.g\&. 500ms)\&.
\-4 Use IPv4 only
\-6 Use IPv6 only
\-C, \-\-crlf Use CRLF for EOL sequence
\-c, \-\-sh\-exec <command> Executes the given command via /bin/sh
\-e, \-\-exec <command> Executes the given command
\-g hop1[,hop2,\&.\&.\&.] Loose source routing hop points (8 max)
\-G <n> Loose source routing hop pointer (4, 8, 12, \&.\&.\&.)
\-m, \-\-max\-conns <n> Maximum <n> simultaneous connections
\-h, \-\-help Display this help screen
\-d, \-\-delay <time> Wait between read/writes
\-o, \-\-output <filename> Dump session data to a file
\-x, \-\-hex\-dump <filename> Dump session data as hex to a file
\-i, \-\-idle\-timeout <time> Idle read/write timeout
\-p, \-\-source\-port port Specify source port to use
\-s, \-\-source addr Specify source address to use (doesn\*(Aqt affect \-l)
\-l, \-\-listen Bind and listen for incoming connections
\-k, \-\-keep\-open Accept multiple connections in listen mode
\-n, \-\-nodns Do not resolve hostnames via DNS
\-t, \-\-telnet Answer Telnet negotiations
\-u, \-\-udp Use UDP instead of default TCP
\-\-sctp Use SCTP instead of default TCP
\-v, \-\-verbose Set verbosity level (can be used up to 3 times)
\-w, \-\-wait <time> Connect timeout
\-\-append\-output Append rather than clobber specified output files
\-\-send\-only Only send data, ignoring received; quit on EOF
\-\-recv\-only Only receive data, never send anything
\-\-allow Allow only given hosts to connect to Ncat
\-\-allowfile A file of hosts allowed to connect to Ncat
\-\-deny Deny given hosts from connecting to Ncat
\-\-denyfile A file of hosts denied from connecting to Ncat
\-\-broker Enable Ncat\*(Aqs connection brokering mode
\-\-chat Start a simple Ncat chat server
\-\-proxy <addr[:port]> Specify address of host to proxy through
\-\-proxy\-type <type> Specify proxy type ("http" or "socks4")
\-\-proxy\-auth <auth> Authenticate with HTTP or SOCKS proxy server
\-\-ssl Connect or listen with SSL
\-\-ssl\-cert Specify SSL certificate file (PEM) for listening
\-\-ssl\-key Specify SSL private key (PEM) for listening
\-\-ssl\-verify Verify trust and domain name of certificates
\-\-ssl\-trustfile PEM file containing trusted SSL certificates
\-\-version Display Ncat\*(Aqs version information and exit
See the ncat(1) manpage for full options, descriptions and usage examples
.fi
.if n \{\
.RE
.\}
.sp
.SH "CONNECT MODE AND LISTEN MODE"
.\" connect mode (Ncat)
.\" client mode (Ncat)
.\" listen mode (Ncat)
.\" server mode (Ncat)
.PP
Ncat operates in one of two primary modes: connect mode and listen mode\&. Other modes, such as the HTTP proxy server, act as special cases of these two\&. In connect mode, Ncat works as a client\&. In listen mode it is a server\&.
.PP
In connect mode, the
\fB\fIhostname\fR\fR
and
\fB\fIport\fR\fR
arguments tell what to connect to\&.
\fB\fIhostname\fR\fR
is required, and may be a hostname or IP address\&. If
\fB\fIport\fR\fR
is supplied, it must be a decimal port number\&. If omitted, it defaults to 31337\&..\" default port of Ncat.\" 31337
.PP
In listen mode,
\fB\fIhostname\fR\fR
and
\fB\fIport\fR\fR
control the address the server will bind to\&. Both arguments are optional in listen mode\&. If
\fB\fIhostname\fR\fR
is omitted, it defaults to listening on all available addresses over IPv4 and IPv6\&. If
\fB\fIport\fR\fR
is omitted, it defaults to 31337\&.
.SH "PROTOCOL OPTIONS"
.PP
\fB\-4\fR (IPv4 only) .\" -4 (Ncat option)
.RS 4
Force the use of IPv4 only\&.
.RE
.PP
\fB\-6\fR (IPv6 only) .\" -6 (Ncat option)
.RS 4
Force the use of IPv6 only\&.
.RE
.PP
\fB\-u\fR, \fB\-\-udp\fR (Use UDP) .\" -u (Ncat option) .\" --udp (Ncat option)
.RS 4
Use UDP for the connection (the default is TCP)\&.
.RE
.PP
\fB\-\-sctp\fR (Use SCTP) .\" --sctp (Ncat option)
.RS 4
Use SCTP for the connection (the default is TCP)\&. SCTP support is implemented in TCP\-compatible mode\&.
.RE
.SH "CONNECT MODE OPTIONS"
.PP
\fB\-g \fR\fB\fIhop1\fR\fR\fB[,\fIhop2\fR,\&.\&.\&.]\fR (Loose source routing) .\" -g (Ncat option)
.RS 4
Sets hops for IPv4 loose source routing\&. You can use
\fB\-g\fR
once with a comma\-separated list of hops, use
\fB\-g\fR
multiple times with single hops to build the list, or combine the two\&. Hops can be given as IP addresses or hostnames\&.
.RE
.PP
\fB\-G \fR\fB\fIptr\fR\fR (Set source routing pointer) .\" -G (Ncat option)
.RS 4
Sets the IPv4 source route
\(lqpointer\(rq
for use with
\fB\-g\fR\&. The argument must be a multiple of 4 and no more than 28\&. Not all operating systems support setting this pointer to anything other than four\&.
.RE
.PP
\fB\-p \fR\fB\fIport\fR\fR, \fB\-\-source\-port \fR\fB\fIport\fR\fR (Specify source port) .\" --source-port (Ncat option) .\" -p (Ncat option)
.RS 4
Set the port number for Ncat to bind to\&.
.RE
.PP
\fB\-s \fR\fB\fIhost\fR\fR, \fB\-\-source \fR\fB\fIhost\fR\fR (Specify source address) .\" --source (Ncat option) .\" -s (Ncat option)
.RS 4
Set the address for Ncat to bind to\&.
.RE
.SH "LISTEN MODE OPTIONS"
.PP
See
the section called \(lqACCESS CONTROL OPTIONS\(rq
for information on limiting the hosts that may connect to the listening Ncat process\&.
.PP
\fB\-l\fR, \fB\-\-listen\fR (Listen for connections) .\" --listen (Ncat option) .\" -l (Ncat option)
.RS 4
Listen for connections rather than connecting to a remote machine
.RE
.PP
\fB\-m \fR\fB\fInumconns\fR\fR, \fB\-\-max\-conns \fR\fB\fInumconns\fR\fR (Specify maximum number of connections) .\" --max-conns (Ncat option) .\" -m (Ncat option)
.RS 4
The maximum number of simultaneous connections accepted by an Ncat instance\&. 100 is the default\&.
.RE
.PP
\fB\-k\fR, \fB\-\-keep\-open\fR (Accept multiple connections) .\" --keep-open (Ncat option) .\" -k (Ncat option)
.RS 4
Normally a listening server accepts only one connection and then quits when the connection is closed\&. This option makes it accept multiple simultaneous connections and wait for more connections after they have all been closed\&. It must be combined with
\fB\-\-listen\fR\&. In this mode there is no way for Ncat to know when its network input is finished, so it will keep running until interrupted\&. This also means that it will never close its output stream, so any program reading from Ncat and looking for end\-of\-file will also hang\&.
.RE
.PP
\fB\-\-broker\fR (Connection brokering) .\" --broker (Ncat option)
.RS 4
Allow multiple parties to connect to a centralised Ncat server and communicate with each other\&. Ncat can broker communication between systems that are behind a NAT or otherwise unable to directly connect\&. This option is used in conjunction with
\fB\-\-listen\fR, which causes the
\fB\-\-listen\fR
port to have broker mode enabled\&.
.RE
.PP
\fB\-\-chat\fR (Ad\-hoc \(lqchat server\(rq) .\" --chat (Ncat option)
.RS 4
The
\fB\-\-chat\fR
option enables chat mode, intended for the exchange of text between several users\&. In chat mode, connection brokering is turned on\&. Ncat prefixes each message received with an ID before relaying it to the other connections\&. The ID is unique for each connected client\&. This helps distinguish who sent what\&. Additionally, non\-printing characters such as control characters are escaped to keep them from doing damage to a terminal\&.
.RE
.SH "SSL OPTIONS"
.PP
\fB\-\-ssl\fR (Use SSL) .\" --ssl (Ncat option)
.RS 4
In connect mode, this option transparently negotiates an SSL session with an SSL server to securely encrypt the connection\&. This is particularly handy for talking to SSL enabled HTTP servers, etc\&.
.sp
In server mode, this option listens for incoming SSL connections, rather than plain untunneled traffic\&.
.RE
.PP
\fB\-\-ssl\-verify\fR (Verify server certificates) .\" --ssl-verify (Ncat option)
.RS 4
In client mode,
\fB\-\-ssl\-verify\fR
is like
\fB\-\-ssl\fR
except that it also requires verification of the server certificate\&. Ncat comes with a default set of trusted certificates in the file
ca\-bundle\&.crt.\" ca-bundle.crt\&. Some operating systems provide a default list of trusted certificates; these will also be used if available\&. Use
\fB\-\-ssl\-trustfile\fR
to give a custom list\&. Use
\fB\-v\fR
one or more times to get details about verification failures\&.
.\" revoked certificates
Ncat does not check for revoked certificates.\" certification revocation\&.
.sp
This option has no effect in server mode\&.
.RE
.PP
\fB\-\-ssl\-cert \fR\fB\fIcertfile\&.pem\fR\fR (Specify SSL certificate) .\" --ssl-cert (Ncat option)
.RS 4
This option gives the location of a PEM\-encoded certificate files used to authenticate the server (in listen mode) or the client (in connect mode)\&. Use it in combination with
\fB\-\-ssl\-key\fR\&.
.RE
.PP
\fB\-\-ssl\-key \fR\fB\fIkeyfile\&.pem\fR\fR (Specify SSL private key) .\" --ssl-key (Ncat option)
.RS 4
This option gives the location of the PEM\-encoded private key file that goes with the certificate named with
\fB\-\-ssl\-cert\fR\&.
.RE
.PP
\fB\-\-ssl\-trustfile \fR\fB\fIcert\&.pem\fR\fR (List trusted certificates) .\" --ssl-trustfile (Ncat option)
.RS 4
This option sets a list of certificates that are trusted for purposes of certificate verification\&. It has no effect unless combined with
\fB\-\-ssl\-verify\fR\&. The argument to this option is the name of a PEM.\" PEM (Privacy Enhanced Mail)
file containing trusted certificates\&. Typically, the file will contain certificates of certification authorities, though it may also contain server certificates directly\&. When this option is used, Ncat does not use its default certificates\&.
.RE
.SH "PROXY OPTIONS"
.PP
\fB\-\-proxy \fR\fB\fIhost\fR\fR\fB[:\fR\fB\fIport\fR\fR\fB]\fR (Specify proxy address) .\" --proxy (Ncat option)
.RS 4
Requests proxying through
\fIhost\fR:\fIport\fR, using the protocol specified by
\fB\-\-proxy\-type\fR\&.
.sp
If no port is specified, the proxy protocol\*(Aqs well\-known port is used (1080 for SOCKS and 3128 for HTTP)\&. However, when specifying an IPv6 HTTP proxy server using the IP address rather than the hostname, the port number MUST be specified as well\&. If the proxy requires authentication, use
\fB\-\-proxy\-auth\fR\&.
.RE
.PP
\fB\-\-proxy\-type \fR\fB\fIproto\fR\fR (Specify proxy protocol) .\" --proxy-type (Ncat option)
.RS 4
In connect mode, this option requests the protocol
\fIproto\fR
to connect through the proxy host specified by
\fB\-\-proxy\fR\&. In listen mode, this option has Ncat act as a proxy server using the specified protocol\&.
.sp
The currently available protocols in connect mode are
http
(CONNECT) and
socks4
(SOCKSv4)\&. The only server currently supported is
http\&. If this option is not used, the default protocol is
http\&.
.RE
.PP
\fB\-\-proxy\-auth \fR\fB\fIuser\fR\fR\fB[:\fIpass\fR]\fR (Specify proxy credentials) .\" --proxy-auth (Ncat option)
.RS 4
In connect mode, gives the credentials that will be used to connect to the proxy server\&. In listen mode, gives the credentials that will be required of connecting clients\&. For use with
\fB\-\-proxy\-type http\fR, the form should be user:pass\&. For
\fB\-\-proxy\-type socks4\fR, it should be a username only\&.
.RE
.SH "COMMAND EXECUTION OPTIONS"
.PP
\fB\-e \fR\fB\fIcommand\fR\fR, \fB\-\-exec \fR\fB\fIcommand\fR\fR (Execute command) .\" --exec (Ncat option) .\" -e (Ncat option)
.RS 4
Execute the specified command after a connection has been established\&. The command must be specified as a full pathname\&. All input from the remote client will be sent to the application and responses sent back to the remote client over the socket, thus making your command\-line application interactive over a socket\&. Combined with
\fB\-\-keep\-open\fR, Ncat will handle multiple simultaneous connections to your specified port/application like inetd\&. Ncat will only accept a maximum, definable, number of simultaneous connections controlled by the
\fB\-m\fR
option\&. By default this is set to 100\&.
.RE
.PP
\fB\-c \fR\fB\fIcommand\fR\fR, \fB\-\-sh\-exec \fR\fB\fIcommand\fR\fR (Execute command via sh) .\" --sh-exec (Ncat option) .\" -c (Ncat option)
.RS 4
Same as
\fB\-e\fR, except it tries to execute the command via
/bin/sh\&. This means you don\*(Aqt have to specify the full path for the command, and shell facilities like environment variables are available\&.
.RE
.SH "ACCESS CONTROL OPTIONS"
.PP
\fB\-\-allow \fR\fB\fIhost\fR\fR\fB[,\fIhost\fR,\&.\&.\&.]\fR (Allow connections) .\" --allow (Ncat option)
.RS 4
The list of hosts specified will be the only hosts allowed to connect to the Ncat process\&. All other connection attempts will be disconnected\&. In case of a conflict between
\fB\-\-allow\fR
and
\fB\-\-deny\fR,
\fB\-\-allow\fR
takes precedence\&. Host specifications follow the same syntax used by Nmap\&.
.RE
.PP
\fB\-\-allowfile \fR\fB\fIfile\fR\fR (Allow connections from file) .\" --allowfile (Ncat option)
.RS 4
This has the same functionality as
\fB\-\-allow\fR, except that the allowed hosts are provided in a new\-line delimited allow file, rather than directly on the command line\&.
.RE
.PP
\fB\-\-deny \fR\fB\fIhost\fR\fR\fB[,\fIhost\fR,\&.\&.\&.]\fR (Deny connections) .\" --deny (Ncat option)
.RS 4
Issue Ncat with a list of hosts that will not be allowed to connect to the listening Ncat process\&. Specified hosts will have their session silently terminated if they try to connect\&. be disconnected\&. In case of a conflict between
\fB\-\-allow\fR
and
\fB\-\-deny\fR,
\fB\-\-allow\fR
takes precedence\&. Host specifications follow the same syntax used by Nmap\&.
.RE
.PP
\fB\-\-denyfile \fR\fB\fIfile\fR\fR (Deny connections from file) .\" --denyfile (Ncat option)
.RS 4
This is the same functionality as
\fB\-\-deny\fR, except that excluded hosts are provided in a new\-line delimited deny file, rather than directly on the command line\&.
.RE
.SH "TIMING OPTIONS"
.PP
These options accept a
time
parameter\&. This is specified in seconds by default, though you can append
ms,
s,
m, or
h
to the value to specify milliseconds, seconds, minutes, or hours\&.
.PP
\fB\-d \fR\fB\fItime\fR\fR, \fB\-\-delay \fR\fB\fItime\fR\fR (Specify line delay) .\" --delay (Ncat option) .\" -d (Ncat option)
.RS 4
Set the delay interval for lines sent\&. This effectively limits the number of lines that Ncat will send in the specified period\&. This may be useful for low\-bandwidth sites, or have other uses such as coping with annoying
\fBiptables \-\-limit\fR
options\&.
.RE
.PP
\fB\-i \fR\fB\fItime\fR\fR, \fB\-\-idle\-timeout \fR\fB\fItime\fR\fR (Specify idle timeout) .\" --idle-timeout (Ncat option) .\" -i (Ncat option)
.RS 4
Set a fixed timeout for idle connections\&. If the idle timeout is reached, the connection is terminated\&.
.RE
.PP
\fB\-w \fR\fB\fItime\fR\fR, \fB\-\-wait \fR\fB\fItime\fR\fR (Specify connect timeout) .\" --wait (Ncat option) .\" -w (Ncat option)
.RS 4
Set a fixed timeout for connection attempts\&.
.RE
.SH "OUTPUT OPTIONS"
.PP
\fB\-o \fR\fB\fIfile\fR\fR, \fB\-\-output \fR\fB\fIfile\fR\fR (Save session data) .\" --output (Ncat option) .\" -o (Ncat option)
.RS 4
Dump session data to a file
.RE
.PP
\fB\-x \fR\fB\fIfile\fR\fR, \fB\-\-hex\-dump \fR\fB\fIfile\fR\fR (Save session data in hex) .\" --hex-dump (Ncat option) .\" -x (Ncat option)
.RS 4
Dump session data in hex to a file\&. This can be used to
\(lqreplay\(rq
sessions\&.
.RE
.PP
\fB\-\-append\-output\fR (Append output) .\" --append-output (Ncat option)
.RS 4
Issue Ncat with
\fB\-\-append\-ouput\fR
along with
\fB\-o\fR
and/or
\fB\-x\fR
and it will append the resulted output rather than truncating the specified output files\&.
.RE
.PP
\fB\-v\fR, \fB\-\-verbose\fR (Be verbose) .\" --verbose (Ncat option) .\" -v (Ncat option)
.RS 4
Issue Ncat with
\fB\-v\fR
and it will be verbose and display all kinds of useful connection based information\&. Use more than once (\fB\-vv\fR,
\fB\-vvv\fR) for greater verbosity\&.
\fB\-vvv\fR
is the maximum level\&.
.RE
.SH "MISC OPTIONS"
.PP
\fB\-C\fR, \fB\-\-crlf\fR (Use CRLF as EOL) .\" --crlf (Ncat option) .\" -C (Ncat option)
.RS 4
This option tells Ncat to convert LF.\" LF line ending
line endings to CRLF.\" CRLF line ending
when taking input from standard input\&..\" standard input
This is useful for talking to some stringent servers directly from a terminal in one of the many common plain\-text protocols that use CRLF for end\-of\-line\&.
.RE
.PP
\fB\-h\fR, \fB\-\-help\fR (Help screen) .\" --help (Ncat option) .\" -h (Ncat option)
.RS 4
Displays a short help screen with common options and parameters, and then exits\&.
.RE
.PP
\fB\-\-recv\-only\fR (Only receive data) .\" --recv-only (Ncat option)
.RS 4
If this option is passed, Ncat will only receive data and will not try to send anything\&.
.RE
.PP
\fB\-\-send\-only\fR (Only send data) .\" --send-only (Ncat option)
.RS 4
If this option is passed, then Ncat will only send data and will ignore anything received\&. This option also causes Ncat to close the network connection and terminate after EOF is received on standard input\&.
.RE
.PP
\fB\-t\fR, \fB\-\-telnet\fR (Answer Telnet negotiations) .\" -t (Ncat option)
.RS 4
Handle DO/DONT WILL/WONT Telnet negotiations\&. This makes it possible to script Telnet sessions with Ncat\&.
.RE
.PP
\fB\-\-version\fR (Display version) .\" --version (Ncat option)
.RS 4
Displays the Ncat version number and exits\&.
.RE
.SH "EXAMPLES"
.PP
Connect to example\&.org on TCP port 8080\&.
.RS 4
\fBncat example\&.org 8080\fR
.RE
.PP
Listen for connections on TCP port 8080\&.
.RS 4
\fBncat \-l 8080\fR
.RE
.PP
Redirect TCP port 8080 on the local machine to host on port 80\&.
.RS 4
\fBncat \-\-sh\-exec "ncat example\&.org 80" \-l 8080 \-\-keep\-open\fR
.RE
.PP
Bind to TCP port 8081 and attach /bin/bash for the world to access freely\&.
.RS 4
\fBncat \-\-exec "/bin/bash" \-l 8081 \-\-keep\-open\fR
.RE
.PP
Bind a shell to TCP port 8081, limit access to hosts on a local network, and limit the maximum number of simultaneous connections to 3\&.
.RS 4
\fBncat \-\-exec "/bin/bash" \-\-max\-conns 3 \-\-allow 192\&.168\&.0\&.0/24 \-l 8081 \-\-keep\-open\fR
.RE
.PP
Connect to smtphost:25 through a SOCKS4 server on port 1080\&.
.RS 4
\fBncat \-\-proxy socks4host \-\-proxy\-type socks4 \-\-proxy\-auth user smtphost 25\fR
.RE
.PP
Create an HTTP proxy server on localhost port 8888\&.
.RS 4
\fBncat \-l \-\-proxy\-type http localhost 8888\fR
.RE
.PP
Send a file over TCP port 9899 from host2 (client) to host1 (server)\&.
.RS 4
HOST1$
\fBncat \-l 9899 > outputfile\fR
.sp
HOST2$
\fBncat HOST1 9899 < inputfile\fR
.RE
.PP
Transfer in the other direction, turning Ncat into a \(lqone file\(rq server\&.
.RS 4
HOST1$
\fBncat \-l 9899 < inputfile\fR
.sp
HOST2$
\fBncat HOST1 9899 > outputfile\fR
.RE
.SH "EXIT CODE"
.PP
The exit code reflects whether a connection was made and completed successfully\&. 0 means there was no error\&. 1 means there was a network error of some kind, for example
\(lqConnection refused\(rq
or
\(lqConnection reset\(rq\&. 2 is reserved for all other errors, like an invalid option or a nonexistent file\&.
.SH "BUGS"
.PP
Like its authors, Ncat isn\*(Aqt perfect\&. But you can help make it better by sending bug reports or even writing patches\&. If Ncat doesn\*(Aqt behave the way you expect, first upgrade to the latest version available from
\m[blue]\fB\%http://nmap.org\fR\m[]\&. If the problem persists, do some research to determine whether it has already been discovered and addressed\&. Try Googling the error message or browsing the
nmap\-dev
archives at
\m[blue]\fB\%http://seclists.org/\fR\m[]\&.
.\" nmap-dev mailing list
Read this full manual page as well\&. If nothing comes of this, mail a bug report to
nmap\-dev@insecure\&.org\&. Please include everything you have learned about the problem, as well as what version of Ncat you are running and what operating system version it is running on\&. Problem reports and Ncat usage questions sent to nmap\-dev@insecure\&.org are far more likely to be answered than those sent to Fyodor directly\&.
.PP
Code patches to fix bugs are even better than bug reports\&. Basic instructions for creating patch files with your changes are available at
\m[blue]\fB\%http://nmap.org/data/HACKING\fR\m[]\&. Patches may be sent to
nmap\-dev
(recommended) or to Fyodor directly\&.
.SH "AUTHORS"
.sp
.RS 4
.ie n \{\
\h'-04'\(bu\h'+03'\c
.\}
.el \{\
.sp -1
.IP \(bu 2.3
.\}
Chris Gibson
chris@linuxops\&.net
.RE
.sp
.RS 4
.ie n \{\
\h'-04'\(bu\h'+03'\c
.\}
.el \{\
.sp -1
.IP \(bu 2.3
.\}
Kris Katterjohn
katterjohn@gmail\&.com
.RE
.sp
.RS 4
.ie n \{\
\h'-04'\(bu\h'+03'\c
.\}
.el \{\
.sp -1
.IP \(bu 2.3
.\}
Mixter
mixter@gmail\&.com
.RE
.sp
.RS 4
.ie n \{\
\h'-04'\(bu\h'+03'\c
.\}
.el \{\
.sp -1
.IP \(bu 2.3
.\}
Fyodor
fyodor@insecure\&.org
(\m[blue]\fB\%http://insecure.org\fR\m[])
.RE
.PP
The original Netcat was written by *Hobbit*
hobbit@avian\&.org\&. While Ncat isn\*(Aqt built on any code from the
\(lqtraditional\(rq
Netcat (or any other implementation), Ncat is most definitely based on Netcat in spirit and functionality\&.

48
ncat/docs/ncat.usage.txt Normal file
View File

@@ -0,0 +1,48 @@
Ncat 5.61TEST3 ( http://nmap.org/ncat )
Usage: ncat [options] [hostname] [port]
Options taking a time assume seconds. Append 'ms' for milliseconds,
's' for seconds, 'm' for minutes, or 'h' for hours (e.g. 500ms).
-4 Use IPv4 only
-6 Use IPv6 only
-C, --crlf Use CRLF for EOL sequence
-c, --sh-exec <command> Executes the given command via /bin/sh
-e, --exec <command> Executes the given command
-g hop1[,hop2,...] Loose source routing hop points (8 max)
-G <n> Loose source routing hop pointer (4, 8, 12, ...)
-m, --max-conns <n> Maximum <n> simultaneous connections
-h, --help Display this help screen
-d, --delay <time> Wait between read/writes
-o, --output <filename> Dump session data to a file
-x, --hex-dump <filename> Dump session data as hex to a file
-i, --idle-timeout <time> Idle read/write timeout
-p, --source-port port Specify source port to use
-s, --source addr Specify source address to use (doesn't affect -l)
-l, --listen Bind and listen for incoming connections
-k, --keep-open Accept multiple connections in listen mode
-n, --nodns Do not resolve hostnames via DNS
-t, --telnet Answer Telnet negotiations
-u, --udp Use UDP instead of default TCP
--sctp Use SCTP instead of default TCP
-v, --verbose Set verbosity level (can be used up to 3 times)
-w, --wait <time> Connect timeout
--append-output Append rather than clobber specified output files
--send-only Only send data, ignoring received; quit on EOF
--recv-only Only receive data, never send anything
--allow Allow only given hosts to connect to Ncat
--allowfile A file of hosts allowed to connect to Ncat
--deny Deny given hosts from connecting to Ncat
--denyfile A file of hosts denied from connecting to Ncat
--broker Enable Ncat's connection brokering mode
--chat Start a simple Ncat chat server
--proxy <addr[:port]> Specify address of host to proxy through
--proxy-type <type> Specify proxy type ("http" or "socks4")
--proxy-auth <auth> Authenticate with HTTP or SOCKS proxy server
--ssl Connect or listen with SSL
--ssl-cert Specify SSL certificate file (PEM) for listening
--ssl-key Specify SSL private key (PEM) for listening
--ssl-verify Verify trust and domain name of certificates
--ssl-trustfile PEM file containing trusted SSL certificates
--version Display Ncat's version information and exit
See the ncat(1) manpage for full options, descriptions and usage examples

882
ncat/docs/ncat.xml Normal file
View File

@@ -0,0 +1,882 @@
<refentry id="ncat-man">
<refmeta>
<refentrytitle>Ncat</refentrytitle>
<manvolnum>1</manvolnum>
<refmiscinfo class="source">Ncat</refmiscinfo>
<refmiscinfo class="manual">Ncat Reference Guide</refmiscinfo>
</refmeta>
<refnamediv id="ncat-man-name">
<refname>ncat</refname>
<refpurpose>Concatenate and redirect sockets</refpurpose>
</refnamediv>
<refsynopsisdiv id="ncat-man-synopsis">
<cmdsynopsis>
<command>ncat</command>
<arg choice="opt" rep="repeat">
<replaceable>OPTIONS</replaceable>
</arg>
<arg choice="opt">
<replaceable>hostname</replaceable>
</arg>
<arg choice="opt">
<replaceable>port</replaceable>
</arg>
</cmdsynopsis>
</refsynopsisdiv>
<refsect1 id="ncat-man-description">
<title>Description</title>
<para>Ncat is a feature-packed networking utility which reads and writes
data across networks from the command line. Ncat was written for the Nmap
Project and is the culmination of the currently splintered family of Netcat
incarnations. It is designed to
be a reliable back-end tool to instantly provide network connectivity to other
applications and users. Ncat will not only work with IPv4 and IPv6 but provides
the user with a virtually limitless number of potential uses.</para>
<para>Among Ncat's vast number of features there is the ability to chain Ncats
together; redirection of TCP, UDP, and SCTP ports to other sites; SSL support; and proxy
connections via SOCKS4 or HTTP proxies (with optional proxy
authentication as well). Some general principles apply to most applications
and thus give you the capability of instantly adding networking support to
software that would normally never support it.</para>
</refsect1>
<refsect1 id="ncat-man-options-summary">
<title>Options Summary</title>
<para>
<screen><xi:include href="ncat.usage.txt" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude" /></screen>
</para>
</refsect1>
<refsect1 id="ncat-man-modes">
<indexterm><primary>connect mode (Ncat)</primary></indexterm>
<indexterm><primary>client mode (Ncat)</primary><see>connect mode</see></indexterm>
<indexterm><primary>listen mode (Ncat)</primary></indexterm>
<indexterm><primary>server mode (Ncat)</primary><see>listen mode</see></indexterm>
<title>Connect Mode and Listen Mode</title>
<para>
Ncat operates in one of two primary modes: connect mode and listen
mode. Other modes, such as the HTTP proxy server, act as special
cases of these two. In connect mode, Ncat works as a client. In
listen mode it is a server.
</para>
<para>
In connect mode, the <option><replaceable>hostname</replaceable></option>
and <option><replaceable>port</replaceable></option> arguments tell
what to connect to.
<option><replaceable>hostname</replaceable></option> is required,
and may be a hostname or IP address. If
<option><replaceable>port</replaceable></option> is supplied, it
must be a decimal port number. If omitted, it defaults to
31337.<indexterm><primary>default port of Ncat</primary></indexterm><indexterm><primary>31337</primary><see>default port of Ncat</see></indexterm>
</para>
<para>
In listen mode, <option><replaceable>hostname</replaceable></option>
and <option><replaceable>port</replaceable></option> control the
address the server will bind to. Both arguments are optional in
listen mode. If <option><replaceable>hostname</replaceable></option>
is omitted, it defaults to listening on all available addresses over
IPv4 and IPv6. If <option><replaceable>port</replaceable></option> is
omitted, it defaults to 31337.
</para>
</refsect1>
<refsect1 id="ncat-man-proto-options">
<title>Protocol Options</title>
<variablelist>
<varlistentry>
<term>
<option>-4</option> (IPv4 only)
<indexterm><primary><option>-4</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>Force the use of IPv4 only.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-6</option> (IPv6 only)
<indexterm><primary><option>-6</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>Force the use of IPv6 only.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-u</option>,
<option>--udp</option> (Use UDP)
<indexterm><primary><option>-u</option> (Ncat option)</primary><see><option>--udp</option></see></indexterm>
<indexterm><primary><option>--udp</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>Use UDP for the connection (the default is TCP).</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--sctp</option> (Use SCTP)
<indexterm><primary><option>--sctp</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>Use SCTP for the connection (the default is TCP).
SCTP support is implemented in TCP-compatible mode.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="ncat-man-connect-options">
<title>Connect Mode Options</title>
<variablelist>
<varlistentry>
<term>
<option>-g <replaceable>hop1</replaceable><optional>,<replaceable>hop2</replaceable>,...</optional></option> (Loose source routing)
<indexterm><primary><option>-g</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>Sets hops for IPv4 loose source routing. You can use <option>-g</option>
once with a comma-separated list of hops, use <option>-g</option> multiple
times with single hops to build the list, or combine the two. Hops can be
given as IP addresses or hostnames.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-G <replaceable>ptr</replaceable></option> (Set source routing pointer)
<indexterm><primary><option>-G</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>Sets the IPv4 source route <quote>pointer</quote> for use with <option>-g</option>.
The argument must be a multiple of 4 and no more than 28. Not all operating
systems support setting this pointer to anything other than four.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-p <replaceable>port</replaceable></option>,
<option>--source-port <replaceable>port</replaceable></option> (Specify source port)
<indexterm><primary><option>--source-port</option> (Ncat option)</primary></indexterm>
<indexterm><primary><option>-p</option> (Ncat option)</primary><see><option>--source-port</option></see></indexterm>
</term>
<listitem>
<para>Set the port number for Ncat to bind to.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-s <replaceable>host</replaceable></option>,
<option>--source <replaceable>host</replaceable></option> (Specify source address)
<indexterm><primary><option>--source</option> (Ncat option)</primary></indexterm>
<indexterm><primary><option>-s</option> (Ncat option)</primary><see><option>--source</option></see></indexterm>
</term>
<listitem>
<para>Set the address for Ncat to bind to.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="ncat-man-listen-options">
<title>Listen Mode Options</title>
<para>See <xref linkend="ncat-man-access-options"/> for information on limiting the
hosts that may connect to the listening Ncat process.</para>
<variablelist>
<varlistentry>
<term>
<option>-l</option>,
<option>--listen</option> (Listen for connections)
<indexterm><primary><option>--listen</option> (Ncat option)</primary></indexterm>
<indexterm><primary><option>-l</option> (Ncat option)</primary><see><option>--listen</option></see></indexterm>
</term>
<listitem>
<para>Listen for connections rather than connecting to a remote
machine</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-m <replaceable>numconns</replaceable></option>,
<option>--max-conns <replaceable>numconns</replaceable></option> (Specify maximum number of connections)
<indexterm><primary><option>--max-conns</option> (Ncat option)</primary></indexterm>
<indexterm><primary><option>-m</option> (Ncat option)</primary><see><option>--max-conns</option></see></indexterm>
</term>
<listitem>
<para>The maximum number of simultaneous connections accepted by an Ncat
instance. 100 is the default.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-k</option>,
<option>--keep-open</option> (Accept multiple connections)
<indexterm><primary><option>--keep-open</option> (Ncat option)</primary></indexterm>
<indexterm><primary><option>-k</option> (Ncat option)</primary><see><option>--keep-open</option></see></indexterm>
</term>
<listitem>
<para>Normally a listening server accepts only one connection and
then quits when the connection is closed. This option makes it accept
multiple simultaneous connections and wait for more connections after
they have all been closed. It must be combined with
<option>--listen</option>. In this mode there is no way for Ncat to
know when its network input is finished, so it will keep running
until interrupted. This also means that it will never close its
output stream, so any program reading from Ncat and looking for
end-of-file will also hang.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--broker</option> (Connection brokering)
<indexterm><primary><option>--broker</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>Allow multiple parties to connect to a centralised Ncat server
and communicate with each other. Ncat can broker communication between
systems that are behind a NAT or otherwise unable to directly connect.
This option is used in conjunction with <option>--listen</option>, which
causes the <option>--listen</option> port to have broker mode enabled.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--chat</option> (Ad-hoc <quote>chat server</quote>)
<indexterm><primary><option>--chat</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>The <option>--chat</option> option enables chat mode, intended
for the exchange of text between several users. In chat mode,
connection brokering is turned on. Ncat prefixes each message received
with an ID before relaying it to the other connections. The ID is
unique for each connected client. This helps distinguish who sent
what. Additionally, non-printing characters such as control characters
are escaped to keep them from doing damage to a terminal.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="ncat-man-ssl-options">
<title>SSL Options</title>
<variablelist>
<varlistentry>
<term>
<option>--ssl</option> (Use SSL)
<indexterm><primary><option>--ssl</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>In connect mode, this option transparently negotiates an SSL
session with an SSL server to securely encrypt the connection. This is
particularly handy for talking to SSL enabled HTTP servers, etc.</para>
<para>In server mode, this option listens for incoming SSL connections,
rather than plain untunneled traffic.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--ssl-verify</option> (Verify server certificates)
<indexterm><primary><option>--ssl-verify</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>In client mode, <option>--ssl-verify</option> is like
<option>--ssl</option> except that it also requires verification of
the server certificate. Ncat comes with a default set of trusted
certificates in the file
<filename>ca-bundle.crt</filename><indexterm><primary><filename>ca-bundle.crt</filename></primary></indexterm>.
Some operating systems provide a default list of
trusted certificates; these will also be used if available. Use
<option>--ssl-trustfile</option> to give a custom list. Use
<option>-v</option> one or more times to get details about
verification failures.</para>
<indexterm><primary>revoked certificates</primary><see>certificate revocation</see></indexterm>
<para>Ncat does not check for revoked
certificates<indexterm><primary>certification revocation</primary></indexterm>.</para>
<para>This option has no effect in server mode.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--ssl-cert <replaceable>certfile.pem</replaceable></option> (Specify SSL certificate)
<indexterm><primary><option>--ssl-cert</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>This option gives the location of a PEM-encoded
certificate files used to authenticate the server (in listen
mode) or the client (in connect mode). Use it in combination
with <option>--ssl-key</option>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--ssl-key <replaceable>keyfile.pem</replaceable></option> (Specify SSL private key)
<indexterm><primary><option>--ssl-key</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>This option gives the location of the PEM-encoded
private key file that goes with the certificate named with
<option>--ssl-cert</option>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--ssl-trustfile <replaceable>cert.pem</replaceable></option> (List trusted certificates)
<indexterm><primary><option>--ssl-trustfile</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>This option sets a list of certificates that are trusted for
purposes of certificate verification. It has no effect unless combined
with <option>--ssl-verify</option>. The argument to this option is the
name of a PEM<indexterm><primary>PEM (Privacy Enhanced Mail)</primary></indexterm>
file containing trusted certificates. Typically, the file will contain
certificates of certification authorities, though it may also contain
server certificates directly. When this option is used, Ncat does not
use its default certificates.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="ncat-man-proxy-options">
<title>Proxy Options</title>
<variablelist>
<varlistentry>
<term>
<option>--proxy <replaceable>host</replaceable>[:<replaceable>port</replaceable>]</option> (Specify proxy address)
<indexterm><primary><option>--proxy</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>Requests proxying through <replaceable>host</replaceable>:<replaceable>port</replaceable>,
using the protocol specified by <option>--proxy-type</option>.</para>
<para>If no port is specified, the proxy protocol's well-known port is used (1080 for
SOCKS and 3128 for HTTP). However, when specifying an IPv6 HTTP proxy server using
the IP address rather than the hostname, the port number MUST be specified as well.
If the proxy requires authentication, use <option>--proxy-auth</option>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--proxy-type <replaceable>proto</replaceable></option> (Specify proxy protocol)
<indexterm><primary><option>--proxy-type</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>In connect mode, this option requests the protocol <replaceable>proto</replaceable>
to connect through the proxy host specified by <option>--proxy</option>. In listen mode,
this option has Ncat act as a proxy server using the specified protocol.</para>
<para>The currently available protocols in connect mode are <literal>http</literal>
(CONNECT) and <literal>socks4</literal> (SOCKSv4). The only server currently supported
is <literal>http</literal>.
If this option is not used, the default protocol is <literal>http</literal>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--proxy-auth <replaceable>user</replaceable><optional>:<replaceable>pass</replaceable></optional></option> (Specify proxy credentials)
<indexterm><primary><option>--proxy-auth</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>In connect mode, gives the credentials that will be used to
connect to the proxy server. In listen mode, gives the credentials
that will be required of connecting clients. For use with
<option>--proxy-type http</option>, the form should be user:pass. For
<option>--proxy-type socks4</option>, it should be a username only.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="ncat-man-command-options">
<title>Command Execution Options</title>
<variablelist>
<varlistentry>
<term>
<option>-e <replaceable>command</replaceable></option>,
<option>--exec <replaceable>command</replaceable></option> (Execute command)
<indexterm><primary><option>--exec</option> (Ncat option)</primary></indexterm>
<indexterm><primary><option>-e</option> (Ncat option)</primary><see><option>--exec</option></see></indexterm>
</term>
<listitem>
<para>Execute the specified command after a connection has been
established. The command must be specified as a full pathname. All
input from the remote client will be sent to the application and
responses sent back to the remote client over the socket, thus
making your command-line application interactive over a
socket. Combined with <option>--keep-open</option>,
Ncat will handle multiple simultaneous connections to your
specified port/application like inetd. Ncat will only
accept a maximum, definable, number of simultaneous connections
controlled by the <option>-m</option> option. By default this is set
to 100.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-c <replaceable>command</replaceable></option>,
<option>--sh-exec <replaceable>command</replaceable></option> (Execute command via sh)
<indexterm><primary><option>--sh-exec</option> (Ncat option)</primary></indexterm>
<indexterm><primary><option>-c</option> (Ncat option)</primary><see><option>--sh-exec</option></see></indexterm>
</term>
<listitem>
<para>Same as <option>-e</option>, except it tries to execute
the command via <filename>/bin/sh</filename>. This means you don't
have to specify the full path for the command, and shell facilities
like environment variables are available.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="ncat-man-access-options">
<title>Access Control Options</title>
<variablelist>
<varlistentry>
<term>
<option>--allow <replaceable>host</replaceable><optional>,<replaceable>host</replaceable>,...</optional></option> (Allow connections)
<indexterm><primary><option>--allow</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>The list of hosts specified will be the only hosts allowed
to connect to the Ncat process. All other connection attempts will
be disconnected. In case of a conflict between
<option>--allow</option> and <option>--deny</option>,
<option>--allow</option> takes precedence. Host
specifications follow the same syntax used
by Nmap.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--allowfile <replaceable>file</replaceable></option> (Allow connections from file)
<indexterm><primary><option>--allowfile</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>This has the same functionality as <option>--allow</option>,
except that the allowed hosts are provided in a new-line delimited allow
file, rather than directly on the command line.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--deny <replaceable>host</replaceable><optional>,<replaceable>host</replaceable>,...</optional></option> (Deny connections)
<indexterm><primary><option>--deny</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>Issue Ncat with a list of hosts that will not be allowed to connect
to the listening Ncat process. Specified hosts will have their session
silently terminated if they try to connect.
be disconnected. In case of a conflict between
<option>--allow</option> and <option>--deny</option>,
<option>--allow</option> takes precedence. Host
specifications follow the same syntax used by Nmap.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--denyfile <replaceable>file</replaceable></option> (Deny connections from file)
<indexterm><primary><option>--denyfile</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>This is the same functionality as <option>--deny</option>,
except that excluded hosts are provided in a new-line delimited deny
file, rather than directly on the command line.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="ncat-man-timing-options">
<title>Timing Options</title>
<para>These options accept a <literal>time</literal> parameter. This is specified
in seconds by default, though you can append <literal>ms</literal>, <literal>s</literal>, <literal>m</literal>,
or <literal>h</literal> to the value to specify milliseconds, seconds, minutes, or hours.</para>
<variablelist>
<varlistentry>
<term>
<option>-d <replaceable>time</replaceable></option>,
<option>--delay <replaceable>time</replaceable></option> (Specify line delay)
<indexterm><primary><option>--delay</option> (Ncat option)</primary></indexterm>
<indexterm><primary><option>-d</option> (Ncat option)</primary><see><option>--delay</option></see></indexterm>
</term>
<listitem>
<para>Set the delay interval for lines sent. This effectively limits
the number of lines that Ncat will send in the specified period. This
may be useful for low-bandwidth sites, or have other uses such as
coping with
annoying <command>iptables --limit</command> options.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-i <replaceable>time</replaceable></option>,
<option>--idle-timeout <replaceable>time</replaceable></option> (Specify idle timeout)
<indexterm><primary><option>--idle-timeout</option> (Ncat option)</primary></indexterm>
<indexterm><primary><option>-i</option> (Ncat option)</primary><see><option>--idle-timeout</option></see></indexterm>
</term>
<listitem>
<para>Set a fixed timeout for idle connections. If the idle timeout
is reached, the connection is terminated.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-w <replaceable>time</replaceable></option>,
<option>--wait <replaceable>time</replaceable></option> (Specify connect timeout)
<indexterm><primary><option>--wait</option> (Ncat option)</primary></indexterm>
<indexterm><primary><option>-w</option> (Ncat option)</primary><see><option>--wait</option></see></indexterm>
</term>
<listitem>
<para>Set a fixed timeout for connection attempts.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="ncat-man-output-options">
<title>Output Options</title>
<variablelist>
<varlistentry>
<term>
<option>-o <replaceable>file</replaceable></option>,
<option>--output <replaceable>file</replaceable></option> (Save session data)
<indexterm><primary><option>--output</option> (Ncat option)</primary></indexterm>
<indexterm><primary><option>-o</option> (Ncat option)</primary><see><option>--output</option></see></indexterm>
</term>
<listitem>
<para>Dump session data to a file</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-x <replaceable>file</replaceable></option>,
<option>--hex-dump <replaceable>file</replaceable></option> (Save session data in hex)
<indexterm><primary><option>--hex-dump</option> (Ncat option)</primary></indexterm>
<indexterm><primary><option>-x</option> (Ncat option)</primary><see><option>--hex-dump</option></see></indexterm>
</term>
<listitem>
<para>Dump session data in hex to a file. This can be used to
<quote>replay</quote> sessions.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--append-output</option> (Append output)
<indexterm><primary><option>--append-output</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>Issue Ncat with <option>--append-ouput</option> along with
<option>-o</option> and/or <option>-x</option> and it will append
the resulted output rather than truncating the specified output files.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-v</option>,
<option>--verbose</option> (Be verbose)
<indexterm><primary><option>--verbose</option> (Ncat option)</primary></indexterm>
<indexterm><primary><option>-v</option> (Ncat option)</primary><see><option>--verbose</option></see></indexterm>
</term>
<listitem>
<para>Issue Ncat with <option>-v</option> and it will be verbose and
display all kinds of useful connection based information. Use more
than once (<option>-vv</option>, <option>-vvv</option>) for greater
verbosity. <option>-vvv</option> is the maximum level.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="ncat-man-misc-options">
<title>Misc Options</title>
<variablelist>
<varlistentry>
<term>
<option>-C</option>,
<option>--crlf</option> (Use CRLF as EOL)
<indexterm><primary><option>--crlf</option> (Ncat option)</primary></indexterm>
<indexterm><primary><option>-C</option> (Ncat option)</primary><see><option>--crlf</option></see></indexterm>
</term>
<listitem>
<para>This option tells Ncat to convert
LF<indexterm><primary>LF line ending</primary></indexterm>
line endings to
CRLF<indexterm><primary>CRLF line ending</primary></indexterm>
when taking input from
standard input.<indexterm><primary>standard input</primary></indexterm>
This is useful for talking to some stringent
servers directly from a terminal in one of the many common plain-text
protocols that use CRLF for end-of-line.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-h</option>,
<option>--help</option> (Help screen)
<indexterm><primary><option>--help</option> (Ncat option)</primary></indexterm>
<indexterm><primary><option>-h</option> (Ncat option)</primary><see><option>--help</option></see></indexterm>
</term>
<listitem>
<para>Displays a short help screen with common options and parameters,
and then exits.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--recv-only</option> (Only receive data)
<indexterm><primary><option>--recv-only</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>If this option is passed, Ncat will only receive data and will
not try to send anything.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--send-only</option> (Only send data)
<indexterm><primary><option>--send-only</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>If this option is passed, then Ncat will only send data and will
ignore anything received. This option also causes Ncat to close the
network connection and terminate after EOF is received on standard
input.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>-t</option>,
<option>--telnet</option> (Answer Telnet negotiations)
<indexterm><primary><option>-t</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>Handle DO/DONT WILL/WONT Telnet negotiations. This makes it
possible to script Telnet sessions with Ncat.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>--version</option> (Display version)
<indexterm><primary><option>--version</option> (Ncat option)</primary></indexterm>
</term>
<listitem>
<para>Displays the Ncat version number and exits.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="ncat-man-examples">
<title>Examples</title>
<variablelist>
<varlistentry>
<term>
Connect to example.org on TCP port 8080.
</term>
<listitem>
<para><command>ncat example.org 8080</command></para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Listen for connections on TCP port 8080.
</term>
<listitem>
<para><command>ncat -l 8080</command></para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Redirect TCP port 8080 on the local machine to host on port 80.
</term>
<listitem>
<para><command>ncat --sh-exec "ncat example.org 80" -l 8080 --keep-open</command></para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Bind to TCP port 8081 and attach <filename>/bin/bash</filename>
for the world to access freely.
</term>
<listitem>
<para><command>ncat --exec "/bin/bash" -l 8081 --keep-open</command></para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Bind a shell to TCP port 8081, limit access to hosts on a local
network, and limit the maximum number of simultaneous connections to 3.
</term>
<listitem>
<para><command>ncat --exec "/bin/bash" --max-conns 3 --allow 192.168.0.0/24 -l 8081 --keep-open</command></para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Connect to smtphost:25 through a SOCKS4 server on port 1080.
</term>
<listitem>
<para><command>ncat --proxy socks4host --proxy-type socks4 --proxy-auth user smtphost 25</command></para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Create an HTTP proxy server on localhost port 8888.
</term>
<listitem>
<para><command>ncat -l --proxy-type http localhost 8888</command></para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Send a file over TCP port 9899 from host2 (client) to host1
(server).
</term>
<listitem>
<para>HOST1$ <command>ncat -l 9899 &gt; outputfile</command></para>
<para>HOST2$ <command>ncat HOST1 9899 &lt; inputfile</command></para>
</listitem>
</varlistentry>
<varlistentry>
<term>
Transfer in the other direction, turning Ncat into a <quote>one
file</quote> server.
</term>
<listitem>
<para>HOST1$ <command>ncat -l 9899 &lt; inputfile</command></para>
<para>HOST2$ <command>ncat HOST1 9899 &gt; outputfile</command></para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id="ncat-man-exit-code">
<title>Exit Code</title>
<para>The exit code reflects whether a connection was made and
completed successfully. 0 means there was no error. 1 means there
was a network error of some kind, for example <quote>Connection
refused</quote> or <quote>Connection reset</quote>. 2 is reserved
for all other errors, like an invalid option or a nonexistent
file.</para>
</refsect1>
<refsect1 id="ncat-man-bugs">
<title>Bugs</title>
<para>Like its authors, Ncat isn't perfect. But you can help make
it better by sending bug reports or even writing patches. If Ncat
doesn't behave the way you expect, first upgrade to the latest
version available from <ulink
url="http://nmap.org"/>. If the problem persists,
do some research to determine whether it has already been
discovered and addressed. Try Googling the error message or
browsing the <citetitle>nmap-dev</citetitle> archives at <ulink
url="http://seclists.org/" />.
<indexterm><primary><citetitle>nmap-dev</citetitle> mailing list</primary></indexterm>
Read this full manual page as
well. If nothing comes of this, mail a bug report to
<email>nmap-dev@insecure.org</email>. Please include everything
you have learned about the problem, as well as what version of
Ncat you are running and what operating system version it is
running on. Problem reports and Ncat usage questions sent to
nmap-dev@insecure.org are far more likely to be answered than
those sent to Fyodor directly.</para>
<para>Code patches to fix bugs are even better than bug reports.
Basic instructions for creating patch files with your changes are
available at <ulink
url="http://nmap.org/data/HACKING" />. Patches may
be sent to <citetitle>nmap-dev</citetitle> (recommended) or to Fyodor directly.</para>
</refsect1>
<refsect1 id="ncat-man-author">
<title>Authors</title>
<itemizedlist>
<listitem>
<para>Chris Gibson <email>chris@linuxops.net</email></para>
</listitem>
<listitem>
<para>Kris Katterjohn <email>katterjohn@gmail.com</email></para>
</listitem>
<listitem>
<para>Mixter <email>mixter@gmail.com</email></para>
</listitem>
<listitem>
<para>Fyodor <email>fyodor@insecure.org</email>
(<ulink url="http://insecure.org" />)</para>
</listitem>
</itemizedlist>
<para>The original Netcat was written by *Hobbit* <email>hobbit@avian.org</email>.
While Ncat isn't built on any code from the <quote>traditional</quote> Netcat (or any
other implementation), Ncat is most definitely based on Netcat in spirit
and functionality.</para>
</refsect1>
</refentry>

1645
ncat/http.c Normal file

File diff suppressed because it is too large Load Diff

253
ncat/http.h Normal file
View File

@@ -0,0 +1,253 @@
/***************************************************************************
* http.h *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#ifndef _HTTP_H
#define _HTTP_H
#include "ncat_config.h"
#include "util.h"
#include <stdio.h>
#include <stdlib.h>
/* This is an abstraction over a socket (really a struct fdinfo) that provides
rudimentary buffering. It is useful for the line-oriented parts of HTTP. */
struct socket_buffer {
struct fdinfo fdn;
char buffer[BUFSIZ];
char *p;
char *end;
};
void socket_buffer_init(struct socket_buffer *buf, int sd);
int socket_buffer_read(struct socket_buffer *buf, char *out, size_t size);
char *socket_buffer_readline(struct socket_buffer *buf, size_t *n, size_t maxlen);
int socket_buffer_readcount(struct socket_buffer *buf, char *out, size_t size);
char *socket_buffer_remainder(struct socket_buffer *buf, size_t *len);
/* A broken-down URI as defined in RFC 3986, except that the query and fragment
parts are included in the path. */
struct uri {
char *scheme;
char *host;
int port;
char *path;
};
void uri_init(struct uri *uri);
void uri_free(struct uri *uri);
struct uri *uri_parse(struct uri *uri, const char *uri_s);
struct uri *uri_parse_authority(struct uri *uri, const char *authority);
enum http_version {
HTTP_09,
HTTP_10,
HTTP_11,
HTTP_UNKNOWN,
};
struct http_header {
char *name;
char *value;
struct http_header *next;
};
struct http_request {
char *method;
struct uri uri;
enum http_version version;
struct http_header *header;
unsigned long content_length;
unsigned long bytes_transferred;
};
struct http_response {
enum http_version version;
int code;
char *phrase;
struct http_header *header;
unsigned long content_length;
unsigned long bytes_transferred;
};
void http_header_free(struct http_header *header);
char *http_header_get(const struct http_header *header, const char *name);
const struct http_header *http_header_next(const struct http_header *header, const struct http_header *p, const char *name);
char *http_header_get_first(const struct http_header *header, const char *name);
struct http_header *http_header_set(struct http_header *header, const char *name, const char *value);
struct http_header *http_header_remove(struct http_header *header, const char *name);
int http_header_remove_hop_by_hop(struct http_header **header);
char *http_header_to_string(const struct http_header *header, size_t *n);
void http_request_init(struct http_request *request);
void http_request_free(struct http_request *request);
char *http_request_to_string(const struct http_request *request, size_t *n);
void http_response_init(struct http_response *response);
void http_response_free(struct http_response *response);
char *http_response_to_string(const struct http_response *response, size_t *n);
int http_read_header(struct socket_buffer *buf, char **result);
int http_parse_header(struct http_header **result, const char *header);
int http_request_parse_header(struct http_request *request, const char *header);
int http_response_parse_header(struct http_response *response, const char *header);
int http_read_request_line(struct socket_buffer *buf, char **line);
int http_parse_request_line(const char *line, struct http_request *request);
int http_read_status_line(struct socket_buffer *buf, char **line);
int http_parse_status_line(const char *line, struct http_response *response);
int http_parse_status_line_code(const char *line);
enum http_auth_scheme { AUTH_UNKNOWN, AUTH_BASIC, AUTH_DIGEST };
enum http_digest_algorithm { ALGORITHM_MD5, ALGORITHM_UNKNOWN };
enum http_digest_qop { QOP_NONE = 0, QOP_AUTH = 1 << 0, QOP_AUTH_INT = 1 << 1 };
struct http_challenge {
enum http_auth_scheme scheme;
char *realm;
struct {
char *nonce;
char *opaque;
enum http_digest_algorithm algorithm;
/* A bit mask of supported qop values ("auth", "auth-int", etc.). */
unsigned char qop;
} digest;
};
struct http_credentials {
enum http_auth_scheme scheme;
union {
char *basic;
struct {
char *username;
char *realm;
char *nonce;
char *uri;
char *response;
enum http_digest_algorithm algorithm;
enum http_digest_qop qop;
char *nc;
char *cnonce;
} digest;
} u;
};
void http_challenge_init(struct http_challenge *challenge);
void http_challenge_free(struct http_challenge *challenge);
struct http_challenge *http_header_get_proxy_challenge(const struct http_header *header, struct http_challenge *challenge);
void http_credentials_init_basic(struct http_credentials *credentials);
void http_credentials_init_digest(struct http_credentials *credentials);
void http_credentials_free(struct http_credentials *credentials);
struct http_credentials *http_header_get_proxy_credentials(const struct http_header *header, struct http_credentials *credentials);
#if HAVE_HTTP_DIGEST
/* Initialize the server secret used in generating nonces. */
int http_digest_init_secret(void);
int http_digest_nonce_time(const char *nonce, struct timeval *tv);
/* Return a Proxy-Authenticate header. */
char *http_digest_proxy_authenticate(const char *realm, int stale);
/* Return a Proxy-Authorization header answering the given challenge. */
char *http_digest_proxy_authorization(const struct http_challenge *challenge,
const char *username, const char *password,
const char *method, const char *uri);
int http_digest_check_credentials(const char *username, const char *realm,
const char *password, const char *method,
const struct http_credentials *credentials);
#endif
#endif

394
ncat/http_digest.c Normal file
View File

@@ -0,0 +1,394 @@
/***************************************************************************
* ncat_digest.c -- HTTP Digest authentication handling. *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
/* Nonces returned by make_nonce have the form
timestamp-MD5(secret:timestamp)
using representative values, this may look like
1263929285.015273-a8e75fae174fc0e6a5df47bf9900beb6
Sending a timestamp in the clear allows us to compute how long ago the nonce
was issued without local state. Including microseconds reduces the chance
that the same nonce will be issued for two different requests. When a nonce
is received from a client, the time is extracted and then the nonce is
recalculated locally to make sure they match. This is similar to the strategy
recommended in section 3.2.1 of RFC 2617.
When Ncat does Digest authentication as a client, it only does so to make a
single CONNECT request to a proxy server. Therefore we don't use a differing
nc (nonce count) but always the constant 00000001. */
#include "ncat.h"
#include "http.h"
#include <openssl/md5.h>
#include <openssl/rand.h>
/* What's a good length for this? I think it exists only to prevent us from
hashing known plaintext from the server. */
#define CNONCE_LENGTH 8
#define SECRET_LENGTH 16
static unsigned char secret[SECRET_LENGTH];
static int secret_initialized = 0;
static int append_quoted_string(char **buf, size_t *size, size_t *offset, const char *s)
{
const char *t;
strbuf_append_str(buf, size, offset, "\"");
for (;;) {
t = s;
while (!((*t >= 0 && *t <= 31) || *t == 127 || *t == '\\'))
t++;
strbuf_append(buf, size, offset, s, t - s);
if (*t == '\0')
break;
strbuf_sprintf(buf, size, offset, "\\%c", *t);
s = t + 1;
}
strbuf_append_str(buf, size, offset, "\"");
return *size;
}
/* n is the size of src. dest must have at least n * 2 + 1 allocated bytes. */
static char *enhex(char *dest, const unsigned char *src, size_t n)
{
unsigned int i;
for (i = 0; i < n; i++)
Snprintf(dest + i * 2, 3, "%02x", src[i]);
return dest;
}
/* Initialize the server secret used in generating nonces. Return -1 on
failure. */
int http_digest_init_secret(void)
{
if (!RAND_status())
return -1;
if (RAND_bytes(secret, sizeof(secret)) != 1)
return -1;
secret_initialized = 1;
return 0;
}
static char *make_nonce(const struct timeval *tv)
{
char *buf = NULL;
size_t size = 0, offset = 0;
MD5_CTX md5;
unsigned char hashbuf[MD5_DIGEST_LENGTH];
char hash_hex[MD5_DIGEST_LENGTH * 2 + 1];
char time_buf[32];
/* Crash if someone forgot to call http_digest_init_secret. */
if (!secret_initialized)
bye("Server secret not initialized for Digest authentication. Call http_digest_init_secret.");
Snprintf(time_buf, sizeof(time_buf), "%lu.%06lu",
(long unsigned) tv->tv_sec, (long unsigned) tv->tv_usec);
MD5_Init(&md5);
MD5_Update(&md5, secret, sizeof(secret));
MD5_Update(&md5, ":", 1);
MD5_Update(&md5, time_buf, strlen(time_buf));
MD5_Final(hashbuf, &md5);
enhex(hash_hex, hashbuf, sizeof(hashbuf));
strbuf_sprintf(&buf, &size, &offset, "%s-%s", time_buf, hash_hex);
return buf;
}
/* Arguments are assumed to be non-NULL, with the exception of nc and cnonce,
which may be garbage only if qop == QOP_NONE. */
static void make_response(char buf[MD5_DIGEST_LENGTH * 2 + 1],
const char *username, const char *realm, const char *password,
const char *method, const char *uri, const char *nonce,
enum http_digest_qop qop, const char *nc, const char *cnonce)
{
char HA1_hex[MD5_DIGEST_LENGTH * 2 + 1], HA2_hex[MD5_DIGEST_LENGTH * 2 + 1];
unsigned char hashbuf[MD5_DIGEST_LENGTH];
MD5_CTX md5;
/* Calculate H(A1). */
MD5_Init(&md5);
MD5_Update(&md5, username, strlen(username));
MD5_Update(&md5, ":", 1);
MD5_Update(&md5, realm, strlen(realm));
MD5_Update(&md5, ":", 1);
MD5_Update(&md5, password, strlen(password));
MD5_Final(hashbuf, &md5);
enhex(HA1_hex, hashbuf, sizeof(hashbuf));
/* Calculate H(A2). */
MD5_Init(&md5);
MD5_Update(&md5, method, strlen(method));
MD5_Update(&md5, ":", 1);
MD5_Update(&md5, uri, strlen(uri));
MD5_Final(hashbuf, &md5);
enhex(HA2_hex, hashbuf, sizeof(hashbuf));
/* Calculate response. */
MD5_Init(&md5);
MD5_Update(&md5, HA1_hex, strlen(HA1_hex));
MD5_Update(&md5, ":", 1);
MD5_Update(&md5, nonce, strlen(nonce));
if (qop == QOP_AUTH) {
MD5_Update(&md5, ":", 1);
MD5_Update(&md5, nc, strlen(nc));
MD5_Update(&md5, ":", 1);
MD5_Update(&md5, cnonce, strlen(cnonce));
MD5_Update(&md5, ":", 1);
MD5_Update(&md5, "auth", strlen("auth"));
}
MD5_Update(&md5, ":", 1);
MD5_Update(&md5, HA2_hex, strlen(HA2_hex));
MD5_Final(hashbuf, &md5);
enhex(buf, hashbuf, sizeof(hashbuf));
}
/* Extract the issuance time from a nonce (without checking other aspects of
validity. If the time can't be extracted, returns -1, 0 otherwise. */
int http_digest_nonce_time(const char *nonce, struct timeval *tv)
{
unsigned long sec, usec;
if (sscanf(nonce, "%lu.%lu", &sec, &usec) != 2)
return -1;
tv->tv_sec = sec;
tv->tv_usec = usec;
return 0;
}
char *http_digest_proxy_authenticate(const char *realm, int stale)
{
char *buf = NULL;
size_t size = 0, offset = 0;
struct timeval tv;
char *nonce;
if (gettimeofday(&tv, NULL) == -1)
return NULL;
strbuf_append_str(&buf, &size, &offset, "Digest realm=");
append_quoted_string(&buf, &size, &offset, realm);
nonce = make_nonce(&tv);
strbuf_append_str(&buf, &size, &offset, ", nonce=");
append_quoted_string(&buf, &size, &offset, nonce);
free(nonce);
strbuf_append_str(&buf, &size, &offset, ", qop=\"auth\"");
if (stale)
strbuf_append_str(&buf, &size, &offset, ", stale=true");
return buf;
}
char *http_digest_proxy_authorization(const struct http_challenge *challenge,
const char *username, const char *password,
const char *method, const char *uri)
{
/* For now we authenticate successfully at most once, so we don't need a
varying client nonce count. */
static const u32 nc = 0x00000001;
char response_hex[MD5_DIGEST_LENGTH * 2 + 1];
unsigned char cnonce[CNONCE_LENGTH];
char cnonce_buf[CNONCE_LENGTH * 2 + 1];
char nc_buf[8 + 1];
char *buf = NULL;
size_t size = 0, offset = 0;
enum http_digest_qop qop;
if (challenge->scheme != AUTH_DIGEST || challenge->realm == NULL
|| challenge->digest.nonce == NULL
|| challenge->digest.algorithm != ALGORITHM_MD5)
return NULL;
if (challenge->digest.qop & QOP_AUTH) {
Snprintf(nc_buf, sizeof(nc_buf), "%08x", nc);
if (!RAND_status())
return NULL;
if (RAND_bytes(cnonce, sizeof(cnonce)) != 1)
return NULL;
enhex(cnonce_buf, cnonce, sizeof(cnonce));
qop = QOP_AUTH;
} else {
qop = QOP_NONE;
}
strbuf_append_str(&buf, &size, &offset, " Digest");
strbuf_append_str(&buf, &size, &offset, " username=");
append_quoted_string(&buf, &size, &offset, username);
strbuf_append_str(&buf, &size, &offset, ", realm=");
append_quoted_string(&buf, &size, &offset, challenge->realm);
strbuf_append_str(&buf, &size, &offset, ", nonce=");
append_quoted_string(&buf, &size, &offset, challenge->digest.nonce);
strbuf_append_str(&buf, &size, &offset, ", uri=");
append_quoted_string(&buf, &size, &offset, uri);
if (qop == QOP_AUTH) {
strbuf_append_str(&buf, &size, &offset, ", qop=auth");
strbuf_append_str(&buf, &size, &offset, ", cnonce=");
append_quoted_string(&buf, &size, &offset, cnonce_buf);
strbuf_sprintf(&buf, &size, &offset, ", nc=%s", nc_buf);
}
make_response(response_hex, username, challenge->realm, password,
method, uri, challenge->digest.nonce, qop, nc_buf, cnonce_buf);
strbuf_append_str(&buf, &size, &offset, ", response=");
append_quoted_string(&buf, &size, &offset, response_hex);
if (challenge->digest.opaque != NULL) {
strbuf_append_str(&buf, &size, &offset, ", opaque=");
append_quoted_string(&buf, &size, &offset, challenge->digest.opaque);
}
strbuf_append_str(&buf, &size, &offset, "\r\n");
return buf;
}
/* Check that a nonce is one that we issued, and that the response is what is
expected. This doesn't do any checking aginst the lifetime of the nonce. */
int http_digest_check_credentials(const char *username, const char *realm,
const char *password, const char *method,
const struct http_credentials *credentials)
{
char response_hex[MD5_DIGEST_LENGTH * 2 + 1];
struct timeval tv;
char *nonce;
if (credentials->scheme != AUTH_DIGEST
|| credentials->u.digest.username == NULL
|| credentials->u.digest.realm == NULL
|| credentials->u.digest.nonce == NULL
|| credentials->u.digest.uri == NULL
|| credentials->u.digest.response == NULL) {
return 0;
}
if (credentials->u.digest.qop != QOP_NONE && credentials->u.digest.qop != QOP_AUTH)
return 0;
if (credentials->u.digest.qop == QOP_AUTH
&& (credentials->u.digest.nc == NULL
|| credentials->u.digest.cnonce == NULL)) {
return 0;
}
if (strcmp(username, credentials->u.digest.username) != 0)
return 0;
if (strcmp(realm, credentials->u.digest.realm) != 0)
return 0;
if (http_digest_nonce_time(credentials->u.digest.nonce, &tv) == -1)
return 0;
nonce = make_nonce(&tv);
if (strcmp(nonce, credentials->u.digest.nonce) != 0) {
/* We could not have handed out this nonce. */
free(nonce);
return 0;
}
free(nonce);
make_response(response_hex, credentials->u.digest.username, realm,
password, method, credentials->u.digest.uri,
credentials->u.digest.nonce, credentials->u.digest.qop,
credentials->u.digest.nc, credentials->u.digest.cnonce);
return strcmp(response_hex, credentials->u.digest.response) == 0;
}

198
ncat/missing Executable file
View File

@@ -0,0 +1,198 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
# Copyright (C) 1996, 1997, 2001, 2002 Free Software Foundation, Inc.
# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.in; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi
case "$1" in
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing - GNU libit 0.0"
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
aclocal*)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`acinclude.m4' or \`$configure_ac'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`$configure_ac'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`acconfig.h' or \`$configure_ac'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' $configure_ac`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case "$f" in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake*)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`$configure_ac'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
bison|yacc)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if [ ! -f y.tab.h ]; then
echo >y.tab.h
fi
if [ ! -f y.tab.c ]; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex|flex)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if [ ! -f lex.yy.c ]; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
makeinfo)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
fi
touch $file
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and you do not seem to have it handy on your
system. You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequirements for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0

40
ncat/mkinstalldirs Executable file
View File

@@ -0,0 +1,40 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain
# $Id: mkinstalldirs,v 1.1.1.1 2006/01/21 16:58:25 evii Exp $
errstatus=0
for file
do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d
do
pathcomp="$pathcomp$d"
case "$pathcomp" in
-* ) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
fi
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# mkinstalldirs ends here

199
ncat/ncat.h Normal file
View File

@@ -0,0 +1,199 @@
/***************************************************************************
* ncat.h *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#ifndef NCAT_H_
#define NCAT_H_
#include "ncat_config.h"
#include <nbase.h>
#ifdef HAVE_OPENSSL
#include <openssl/ssl.h>
#endif
#include "nsock.h"
#include "util.h"
#include "sys_wrap.h"
#include "ncat_connect.h"
#include "ncat_core.h"
#include "ncat_exec.h"
#include "ncat_listen.h"
#include "ncat_proxy.h"
#include "ncat_ssl.h"
/* Ncat information for output, etc. */
#define NCAT_NAME "Ncat"
#define NCAT_URL "http://nmap.org/ncat"
#define NCAT_VERSION "5.61TEST3"
#ifndef __GNUC__
#ifndef __attribute__
#define __attribute__(x)
#endif
#endif
/* structs */
#ifdef WIN32
#pragma pack(1)
#endif
struct socks4_data {
char version;
char type;
unsigned short port;
unsigned long address;
char username[256];
} __attribute__((packed));
#ifdef WIN32
#pragma pack()
#endif
/* defines */
/* Client-mode timeout for reads, infinite */
#define DEFAULT_READ_TIMEOUT -1
/* Client-mode timeout for writes, in msecs */
#define DEFAULT_WRITE_TIMEOUT 2000
/* Client-mode timeout for connection establishment, in msecs */
#define DEFAULT_CONNECT_TIMEOUT 10000
/* The default length of Ncat buffers */
#define DEFAULT_BUF_LEN (1024)
#define DEFAULT_TCP_BUF_LEN (1024 * 8)
#define DEFAULT_UDP_BUF_LEN (1024 * 128)
/* Default Ncat port */
#define DEFAULT_NCAT_PORT 31337
/* Default port for SOCKS4 */
#define DEFAULT_SOCKS4_PORT 1080
/* The default port Ncat will connect to when trying to connect to an HTTP
* proxy server. The current setting is the default for squid and probably
* other HTTP proxies. But it may also be 8080, 8888, etc.
*/
#define DEFAULT_PROXY_PORT 3128
/* Listen() backlog */
#define BACKLOG 10
/* The default maximum number of simultaneous connections Ncat will accept to
* a listening port. You may want to increase or decrease this value depending
* on your specific needs.
*/
#define DEFAULT_MAX_CONNS 100
/* SOCKS4 protocol responses */
#define SOCKS4_VERSION 4
#define SOCKS_CONNECT 1
#define SOCKS_BIND 2
#define SOCKS_CONN_ACC 90 /* woot */
#define SOCKS_CONN_REF 91
#define SOCKS_CONN_IDENT 92
#define SOCKS_CONN_IDENTDIFF 93
/* Length of IPv6 address */
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 46
#endif
#ifndef IPPROTO_SCTP
#define IPPROTO_SCTP 132
#endif
/* Dummy WNOHANG for Windows */
#ifndef WNOHANG
#define WNOHANG 0
#endif
#endif

39
ncat/ncat.sln Normal file
View File

@@ -0,0 +1,39 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual C++ Express 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ncat", "ncat.vcproj", "{C1E04411-E021-468B-83F1-CB624BBA7589}"
ProjectSection(ProjectDependencies) = postProject
{F8D6D1E3-D4EA-402C-98AA-168E5309BAF4} = {F8D6D1E3-D4EA-402C-98AA-168E5309BAF4}
{B630C8F7-3138-43E8-89ED-78742FA2AC5F} = {B630C8F7-3138-43E8-89ED-78742FA2AC5F}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nsock", "..\nsock\nsock.vcproj", "{F8D6D1E3-D4EA-402C-98AA-168E5309BAF4}"
ProjectSection(ProjectDependencies) = postProject
{B630C8F7-3138-43E8-89ED-78742FA2AC5F} = {B630C8F7-3138-43E8-89ED-78742FA2AC5F}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nbase", "..\nbase\nbase.vcproj", "{B630C8F7-3138-43E8-89ED-78742FA2AC5F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C1E04411-E021-468B-83F1-CB624BBA7589}.Debug|Win32.ActiveCfg = Debug|Win32
{C1E04411-E021-468B-83F1-CB624BBA7589}.Debug|Win32.Build.0 = Debug|Win32
{C1E04411-E021-468B-83F1-CB624BBA7589}.Release|Win32.ActiveCfg = Release|Win32
{C1E04411-E021-468B-83F1-CB624BBA7589}.Release|Win32.Build.0 = Release|Win32
{F8D6D1E3-D4EA-402C-98AA-168E5309BAF4}.Debug|Win32.ActiveCfg = Debug|Win32
{F8D6D1E3-D4EA-402C-98AA-168E5309BAF4}.Debug|Win32.Build.0 = Debug|Win32
{F8D6D1E3-D4EA-402C-98AA-168E5309BAF4}.Release|Win32.ActiveCfg = Release|Win32
{F8D6D1E3-D4EA-402C-98AA-168E5309BAF4}.Release|Win32.Build.0 = Release|Win32
{B630C8F7-3138-43E8-89ED-78742FA2AC5F}.Debug|Win32.ActiveCfg = Debug|Win32
{B630C8F7-3138-43E8-89ED-78742FA2AC5F}.Debug|Win32.Build.0 = Debug|Win32
{B630C8F7-3138-43E8-89ED-78742FA2AC5F}.Release|Win32.ActiveCfg = Release|Win32
{B630C8F7-3138-43E8-89ED-78742FA2AC5F}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

256
ncat/ncat.vcxproj Normal file
View File

@@ -0,0 +1,256 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Static|Win32">
<Configuration>Static</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{C1E04411-E021-468B-83F1-CB624BBA7589}</ProjectGuid>
<RootNamespace>ncat</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Static|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Static|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Static|Win32'">.\Release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Static|Win32'">.\Release\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Static|Win32'">true</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Midl>
<TypeLibraryName>.\Debug/ncat.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..;../nbase;..\nsock\include;..\mswin32\pcap-include;..\mswin32\OpenSSL\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\Debug/ncat.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
<ObjectFileName>.\Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
<WarningLevel>Level2</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<ResourceCompile>
<ResourceOutputFileName>
</ResourceOutputFileName>
</ResourceCompile>
<Link>
<AdditionalDependencies>nbase.lib;ws2_32.lib;IPHlpAPI.Lib;wpcap.lib;nsock.lib;advapi32.lib;libeay32.lib;ssleay32.lib</AdditionalDependencies>
<OutputFile>.\Debug\ncat.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>..\mswin32\lib;..\nsock;..\nbase;..\mswin32\OpenSSL\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
<DelayLoadDLLs>wpcap.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\Debug/ncat.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<PostBuildEvent>
<Command>xcopy "..\mswin32\OpenSSL\bin\*.dll" "$(Configuration)\" /y</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
<TypeLibraryName>.\Release/ncat.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>.;..;../nbase;..\nsock\include;..\mswin32\pcap-include;..\mswin32\OpenSSL\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\Release/ncat.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
<ObjectFileName>.\Release/</ObjectFileName>
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
<WarningLevel>Level2</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
<AdditionalDependencies>nsock.lib;nbase.lib;ws2_32.lib;IPHlpAPI.Lib;wpcap.lib;advapi32.lib;libeay32.lib;ssleay32.lib</AdditionalDependencies>
<OutputFile>.\Release/ncat.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>..\mswin32\lib;..\nsock;..\nbase;..\mswin32\OpenSSL\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
<DelayLoadDLLs>wpcap.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
<ProgramDatabaseFile>.\Release/ncat.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<RandomizedBaseAddress>true</RandomizedBaseAddress>
<DataExecutionPrevention>true</DataExecutionPrevention>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<PostBuildEvent>
<Command>xcopy "..\mswin32\OpenSSL\bin\*.dll" "$(Configuration)\" /y</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Static|Win32'">
<Midl>
<TypeLibraryName>.\Release/ncat.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>.;..;../nbase;..\nsock\include;..\mswin32\pcap-include;..\mswin32\OpenSSL\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<PrecompiledHeaderOutputFile>.\Release/ncat.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
<ObjectFileName>.\Release/</ObjectFileName>
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
<WarningLevel>Level2</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
<AdditionalDependencies>nsock.lib;nbase.lib;ws2_32.lib;IPHlpAPI.Lib;advapi32.lib;libeay32.lib;ssleay32.lib;user32.lib;gdi32.lib</AdditionalDependencies>
<OutputFile>.\Release/ncat.exe</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>..\mswin32\lib;..\nsock;..\nbase;..\mswin32\OpenSSL\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
<DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs>
<ProgramDatabaseFile>.\Release/ncat.pdb</ProgramDatabaseFile>
<SubSystem>Console</SubSystem>
<RandomizedBaseAddress>true</RandomizedBaseAddress>
<DataExecutionPrevention>true</DataExecutionPrevention>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="base64.c" />
<ClCompile Include="http.c" />
<ClCompile Include="http_digest.c" />
<ClCompile Include="ncat_connect.c" />
<ClCompile Include="ncat_core.c" />
<ClCompile Include="ncat_exec_win.c" />
<ClCompile Include="ncat_listen.c" />
<ClCompile Include="ncat_main.c" />
<ClCompile Include="ncat_proxy.c" />
<ClCompile Include="ncat_ssl.c" />
<ClCompile Include="ncat_win.c" />
<ClCompile Include="sys_wrap.c" />
<ClCompile Include="util.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="base64.h" />
<ClInclude Include="http.h" />
<ClInclude Include="..\mswin32\ifaddrlist.h" />
<ClInclude Include="..\mswin32\IPExport.h" />
<ClInclude Include="ncat.h" />
<ClInclude Include="ncat_connect.h" />
<ClInclude Include="ncat_core.h" />
<ClInclude Include="ncat_exec.h" />
<ClInclude Include="ncat_listen.h" />
<ClInclude Include="ncat_proxy.h" />
<ClInclude Include="ncat_ssl.h" />
<ClInclude Include="..\mswin32\packet_types.h" />
<ClInclude Include="..\mswin32\resource.h" />
<ClInclude Include="sockaddr_u.h" />
<ClInclude Include="sys_wrap.h" />
<ClInclude Include="util.h" />
</ItemGroup>
<ItemGroup>
<CustomBuild Include="certs\ca-bundle.crt">
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Copying %(Filename).crt to output directory...</Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy /y "%(FullPath)" "$(TargetDir)%(Filename).crt" &gt; nul
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(TargetDir)%(Filename).crt;%(Outputs)</Outputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Copying %(Filename).crt to output directory...</Message>
<Message Condition="'$(Configuration)|$(Platform)'=='Static|Win32'">Copying %(Filename).crt to output directory...</Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">copy /y "%(FullPath)" "$(TargetDir)%(Filename).crt" &gt; nul
</Command>
<Command Condition="'$(Configuration)|$(Platform)'=='Static|Win32'">copy /y "%(FullPath)" "$(TargetDir)%(Filename).crt" &gt; nul
</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(TargetDir)%(Filename).crt;%(Outputs)</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Static|Win32'">$(TargetDir)%(Filename).crt;%(Outputs)</Outputs>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\nbase\nbase.vcxproj">
<Project>{b630c8f7-3138-43e8-89ed-78742fa2ac5f}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="..\nsock\nsock.vcxproj">
<Project>{f8d6d1e3-d4ea-402c-98aa-168e5309baf4}</Project>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

97
ncat/ncat_config.h Normal file
View File

@@ -0,0 +1,97 @@
/***************************************************************************
* ncat_config.h *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* This is a wrapper that selects config.h or config_win.h depending on whether
we're using Autoconf or a static Windows configuration file. */
#if HAVE_CONFIG_H
#include "config.h"
#elif WIN32
#include "config_win.h"
#else
#error "No config.h, and not WIN32"
#endif

835
ncat/ncat_connect.c Normal file
View File

@@ -0,0 +1,835 @@
/***************************************************************************
* ncat_connect.c -- Ncat connect mode. *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include "base64.h"
#include "nsock.h"
#include "ncat.h"
#include "util.h"
#include "sys_wrap.h"
#include "nbase.h"
#include "http.h"
#ifndef WIN32
#include <unistd.h>
#include <netdb.h>
#endif
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#ifdef HAVE_OPENSSL
#include <openssl/ssl.h>
#include <openssl/err.h>
#endif
struct conn_state {
nsock_iod sock_nsi;
nsock_iod stdin_nsi;
nsock_event_id idle_timer_event_id;
int crlf_state;
};
static struct conn_state cs = {
NULL,
NULL,
0,
0
};
static void connect_handler(nsock_pool nsp, nsock_event evt, void *data);
static void post_connect(nsock_pool nsp, nsock_iod iod);
static void read_stdin_handler(nsock_pool nsp, nsock_event evt, void *data);
static void read_socket_handler(nsock_pool nsp, nsock_event evt, void *data);
static void write_socket_handler(nsock_pool nsp, nsock_event evt, void *data);
static void idle_timer_handler(nsock_pool nsp, nsock_event evt, void *data);
static void refresh_idle_timer(nsock_pool nsp);
#ifdef HAVE_OPENSSL
/* This callback is called for every certificate in a chain. ok is true if
OpenSSL's internal verification has verified the certificate. We don't change
anything about the verification, we only need access to the certificates to
provide diagnostics. */
static int verify_callback(int ok, X509_STORE_CTX *store)
{
X509 *cert = X509_STORE_CTX_get_current_cert(store);
int err = X509_STORE_CTX_get_error(store);
/* Print the subject, issuer, and fingerprint depending on the verbosity
level. */
if ((!ok && o.verbose) || o.debug > 1) {
char digest_buf[SHA1_STRING_LENGTH + 1];
loguser("Subject: ");
X509_NAME_print_ex_fp(stderr, X509_get_subject_name(cert), 0, XN_FLAG_COMPAT);
loguser_noprefix("\n");
loguser("Issuer: ");
X509_NAME_print_ex_fp(stderr, X509_get_issuer_name(cert), 0, XN_FLAG_COMPAT);
loguser_noprefix("\n");
assert(ssl_cert_fp_str_sha1(cert, digest_buf, sizeof(digest_buf)) != NULL);
loguser("SHA-1 fingerprint: %s\n", digest_buf);
}
if (!ok && o.verbose) {
loguser("Certificate verification failed (%s).\n",
X509_verify_cert_error_string(err));
}
return ok;
}
static void set_ssl_ctx_options(SSL_CTX *ctx)
{
if (o.sslverify) {
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_callback);
if (o.ssltrustfile == NULL) {
ssl_load_default_ca_certs(ctx);
} else {
if (o.debug)
logdebug("Using trusted CA certificates from %s.\n", o.ssltrustfile);
if (SSL_CTX_load_verify_locations(ctx, o.ssltrustfile, NULL) != 1) {
bye("Could not load trusted certificates from %s.\n%s",
o.ssltrustfile, ERR_error_string(ERR_get_error(), NULL));
}
}
} else {
if (o.ssl && o.debug)
logdebug("Not doing certificate verification.\n");
}
if (o.sslcert != NULL && o.sslkey != NULL) {
if (SSL_CTX_use_certificate_file(ctx, o.sslcert, SSL_FILETYPE_PEM) != 1)
bye("SSL_CTX_use_certificate_file(): %s.", ERR_error_string(ERR_get_error(), NULL));
if (SSL_CTX_use_PrivateKey_file(ctx, o.sslkey, SSL_FILETYPE_PEM) != 1)
bye("SSL_CTX_use_Privatekey_file(): %s.", ERR_error_string(ERR_get_error(), NULL));
} else {
if ((o.sslcert == NULL)!= (o.sslkey == NULL))
bye("The --ssl-key and --ssl-cert options must be used together.");
}
}
#endif
/* Depending on verbosity, print a message that a connection was established. */
static void connect_report(nsock_iod nsi)
{
union sockaddr_u peer;
nsi_getlastcommunicationinfo(nsi, NULL, NULL, NULL,
&peer.sockaddr, sizeof(peer.storage));
if (o.verbose) {
#ifdef HAVE_OPENSSL
if (nsi_checkssl(nsi)) {
X509 *cert;
X509_NAME *subject;
char digest_buf[SHA1_STRING_LENGTH + 1];
loguser("SSL connection to %s:%hu.", inet_socktop(&peer), nsi_peerport(nsi));
cert = SSL_get_peer_certificate((SSL *) nsi_getssl(nsi));
assert(cert != NULL);
subject = X509_get_subject_name(cert);
if (subject != NULL) {
char buf[256];
int n;
n = X509_NAME_get_text_by_NID(subject, NID_organizationName, buf, sizeof(buf));
if (n >= 0 && n <= sizeof(buf) - 1)
loguser_noprefix(" %s", buf);
}
loguser_noprefix("\n");
assert(ssl_cert_fp_str_sha1(cert, digest_buf, sizeof(digest_buf)) != NULL);
loguser("SHA-1 fingerprint: %s\n", digest_buf);
} else {
loguser("Connected to %s:%hu.\n", inet_socktop(&peer), nsi_peerport(nsi));
}
#else
loguser("Connected to %s:%hu.\n", inet_socktop(&peer), nsi_peerport(nsi));
#endif
}
}
/* Just like inet_socktop, but it puts IPv6 addresses in square brackets. */
static const char *sock_to_url(const union sockaddr_u *su)
{
static char buf[INET6_ADDRSTRLEN + 32];
const char *host_str;
unsigned short port;
host_str = inet_socktop(su);
port = inet_port(su);
if (su->storage.ss_family == AF_INET)
Snprintf(buf, sizeof(buf), "%s:%hu", host_str, port);
else if (su->storage.ss_family == AF_INET6)
Snprintf(buf, sizeof(buf), "[%s]:%hu]", host_str, port);
else
bye("Unknown address family in sock_to_url_host.");
return buf;
}
static int append_connect_request_line(char **buf, size_t *size, size_t *offset,
const union sockaddr_u *su)
{
return strbuf_sprintf(buf, size, offset, "CONNECT %s HTTP/1.0\r\n",
sock_to_url(su));
}
static char *http_connect_request(const union sockaddr_u *su, int *n)
{
char *buf = NULL;
size_t size = 0, offset = 0;
append_connect_request_line(&buf, &size, &offset, su);
strbuf_append_str(&buf, &size, &offset, "\r\n");
*n = offset;
return buf;
}
static char *http_connect_request_auth(const union sockaddr_u *su, int *n,
struct http_challenge *challenge)
{
char *buf = NULL;
size_t size = 0, offset = 0;
append_connect_request_line(&buf, &size, &offset, su);
strbuf_append_str(&buf, &size, &offset, "Proxy-Authorization:");
if (challenge->scheme == AUTH_BASIC) {
char *auth_str;
auth_str = b64enc((unsigned char *) o.proxy_auth, strlen(o.proxy_auth));
strbuf_sprintf(&buf, &size, &offset, " Basic %s\r\n", auth_str);
free(auth_str);
#if HAVE_HTTP_DIGEST
} else if (challenge->scheme == AUTH_DIGEST) {
char *proxy_auth;
char *username, *password;
char *response_hdr;
/* Split up the proxy auth argument. */
proxy_auth = Strdup(o.proxy_auth);
username = strtok(proxy_auth, ":");
password = strtok(NULL, ":");
if (password == NULL) {
free(proxy_auth);
return NULL;
}
response_hdr = http_digest_proxy_authorization(challenge,
username, password, "CONNECT", sock_to_url(&httpconnect));
if (response_hdr == NULL) {
free(proxy_auth);
return NULL;
}
strbuf_append_str(&buf, &size, &offset, response_hdr);
free(proxy_auth);
free(response_hdr);
#endif
} else {
bye("Unknown authentication type.");
}
strbuf_append_str(&buf, &size, &offset, "\r\n");
*n = offset;
return buf;
}
/* Return a usable socket descriptor after proxy negotiation, or -1 on any
error. If any bytes are received through the proxy after negotiation, they
are written to stdout. */
static int do_proxy_http(void)
{
struct socket_buffer sockbuf;
char *request;
char *status_line, *header;
char *remainder;
size_t len;
int sd, code;
int n;
sd = do_connect(SOCK_STREAM);
if (sd == -1) {
loguser("Proxy connection failed: %s.\n", socket_strerror(socket_errno()));
return -1;
}
status_line = NULL;
header = NULL;
/* First try a request with no authentication. */
request = http_connect_request(&httpconnect, &n);
if (send(sd, request, n, 0) < 0) {
loguser("Error sending proxy request: %s.\n", socket_strerror(socket_errno()));
free(request);
return -1;
}
free(request);
socket_buffer_init(&sockbuf, sd);
if (http_read_status_line(&sockbuf, &status_line) != 0) {
loguser("Error reading proxy response Status-Line.\n");
goto bail;
}
code = http_parse_status_line_code(status_line);
logdebug("Proxy returned status code %d.\n", code);
free(status_line);
status_line = NULL;
if (http_read_header(&sockbuf, &header) != 0) {
loguser("Error reading proxy response header.\n");
goto bail;
}
if (code == 407 && o.proxy_auth != NULL) {
struct http_header *h;
struct http_challenge challenge;
close(sd);
sd = -1;
if (http_parse_header(&h, header) != 0) {
loguser("Error parsing proxy response header.\n");
goto bail;
}
free(header);
header = NULL;
if (http_header_get_proxy_challenge(h, &challenge) == NULL) {
loguser("Error getting Proxy-Authenticate challenge.\n");
http_header_free(h);
goto bail;
}
http_header_free(h);
sd = do_connect(SOCK_STREAM);
if (sd == -1) {
loguser("Proxy reconnection failed: %s.\n", socket_strerror(socket_errno()));
goto bail;
}
request = http_connect_request_auth(&httpconnect, &n, &challenge);
if (request == NULL) {
loguser("Error building Proxy-Authorization header.\n");
http_challenge_free(&challenge);
goto bail;
}
logdebug("Reconnection header:\n%s", request);
if (send(sd, request, n, 0) < 0) {
loguser("Error sending proxy request: %s.\n", socket_strerror(socket_errno()));
free(request);
http_challenge_free(&challenge);
goto bail;
}
free(request);
http_challenge_free(&challenge);
socket_buffer_init(&sockbuf, sd);
if (http_read_status_line(&sockbuf, &status_line) != 0) {
loguser("Error reading proxy response Status-Line.\n");
goto bail;
}
code = http_parse_status_line_code(status_line);
logdebug("Proxy returned status code %d.\n", code);
free(status_line);
status_line = NULL;
if (http_read_header(&sockbuf, &header) != 0) {
loguser("Error reading proxy response header.\n");
goto bail;
}
}
free(header);
header = NULL;
if (code != 200) {
loguser("Proxy returned status code %d.\n", code);
return -1;
}
remainder = socket_buffer_remainder(&sockbuf, &len);
Write(STDOUT_FILENO, remainder, len);
return sd;
bail:
if (sd != -1)
close(sd);
if (status_line != NULL)
free(status_line);
if (header != NULL)
free(header);
return -1;
}
int ncat_connect(void) {
nsock_pool mypool;
int rc;
/* Create an nsock pool */
if ((mypool = nsp_new(NULL)) == NULL)
bye("Failed to create nsock_pool.");
if (o.debug > 1)
/* A trace level of 1 still gives you an awful lot. */
nsp_settrace(mypool, stderr, 1, nsock_gettimeofday());
/* Allow connections to broadcast addresses. */
nsp_setbroadcast(mypool, 1);
#ifdef HAVE_OPENSSL
set_ssl_ctx_options((SSL_CTX *)nsp_ssl_init(mypool));
#endif
if (httpconnect.storage.ss_family == AF_UNSPEC
&& socksconnect.storage.ss_family == AF_UNSPEC) {
/* A non-proxy connection. Create an iod for a new socket. */
cs.sock_nsi = nsi_new(mypool, NULL);
if (cs.sock_nsi == NULL)
bye("Failed to create nsock_iod.");
if (nsi_set_hostname(cs.sock_nsi, o.target) == -1)
bye("Failed to set hostname on iod.");
if (srcaddr.storage.ss_family != AF_UNSPEC)
nsi_set_localaddr(cs.sock_nsi, &srcaddr.storage, sizeof(srcaddr.storage));
if (o.numsrcrtes) {
unsigned char *ipopts = NULL;
size_t ipoptslen = 0;
if (o.af != AF_INET)
bye("Sorry, -g can only currently be used with IPv4.");
ipopts = buildsrcrte(targetss.in.sin_addr, o.srcrtes, o.numsrcrtes, o.srcrteptr, &ipoptslen);
nsi_set_ipoptions(cs.sock_nsi, ipopts, ipoptslen);
free(ipopts); /* Nsock has its own copy */
}
if (o.udp) {
nsock_connect_udp(mypool, cs.sock_nsi, connect_handler,
NULL, &targetss.sockaddr, targetsslen,
inet_port(&targetss));
}
#ifdef HAVE_OPENSSL
else if (o.sctp && o.ssl) {
nsock_connect_ssl(mypool, cs.sock_nsi, connect_handler,
o.conntimeout, NULL,
&targetss.sockaddr, targetsslen,
IPPROTO_SCTP, inet_port(&targetss),
NULL);
}
#endif
else if (o.sctp) {
nsock_connect_sctp(mypool, cs.sock_nsi, connect_handler,
o.conntimeout, NULL,
&targetss.sockaddr, targetsslen,
inet_port(&targetss));
}
#ifdef HAVE_OPENSSL
else if (o.ssl) {
nsock_connect_ssl(mypool, cs.sock_nsi, connect_handler,
o.conntimeout, NULL,
&targetss.sockaddr, targetsslen,
IPPROTO_TCP, inet_port(&targetss),
NULL);
}
#endif
else {
nsock_connect_tcp(mypool, cs.sock_nsi, connect_handler,
o.conntimeout, NULL,
&targetss.sockaddr, targetsslen,
inet_port(&targetss));
}
} else {
/* A proxy connection. */
static int connect_socket;
int len;
char *line;
size_t n;
if (httpconnect.storage.ss_family != AF_UNSPEC) {
connect_socket = do_proxy_http();
if (connect_socket == -1)
return 1;
} else if (socksconnect.storage.ss_family != AF_UNSPEC) {
struct socket_buffer stateful_buf;
struct socks4_data socks4msg;
char socksbuf[8];
connect_socket = do_connect(SOCK_STREAM);
if (connect_socket == -1) {
loguser("Proxy connection failed: %s.\n", socket_strerror(socket_errno()));
return 1;
}
socket_buffer_init(&stateful_buf, connect_socket);
if (o.verbose) {
loguser("Connected to proxy %s:%hu\n", inet_socktop(&targetss),
inet_port(&targetss));
}
/* Fill the socks4_data struct */
zmem(&socks4msg, sizeof(socks4msg));
socks4msg.version = SOCKS4_VERSION;
socks4msg.type = SOCKS_CONNECT;
socks4msg.port = socksconnect.in.sin_port;
socks4msg.address = socksconnect.in.sin_addr.s_addr;
if (o.proxy_auth)
Strncpy(socks4msg.username, (char *) o.proxy_auth, sizeof(socks4msg.username));
len = 8 + strlen(socks4msg.username) + 1;
if (send(connect_socket, (char *) &socks4msg, len, 0) < 0) {
loguser("Error sending proxy request: %s.\n", socket_strerror(socket_errno()));
return 1;
}
/* The size of the socks4 response is 8 bytes. So read exactly
8 bytes from the buffer */
if (socket_buffer_readcount(&stateful_buf, socksbuf, 8) < 0) {
loguser("Error: short reponse from proxy.\n");
return 1;
}
if (socksbuf[1] != 90) {
loguser("Proxy connection failed.\n");
return 1;
}
/* Clear out whatever is left in the socket buffer which may be
already sent by proxy server along with http response headers. */
line = socket_buffer_remainder(&stateful_buf, &n);
/* Write the leftover data to stdout. */
Write(STDOUT_FILENO, line, n);
}
/* Once the proxy negotiation is done, Nsock takes control of the
socket. */
cs.sock_nsi = nsi_new2(mypool, connect_socket, NULL);
/* Create IOD for nsp->stdin */
if ((cs.stdin_nsi = nsi_new2(mypool, 0, NULL)) == NULL)
bye("Failed to create stdin nsiod.");
post_connect(mypool, cs.sock_nsi);
}
/* connect */
rc = nsock_loop(mypool, -1);
if (o.verbose) {
struct timeval end_time;
double time;
gettimeofday(&end_time, NULL);
time = TIMEVAL_MSEC_SUBTRACT(end_time, start_time) / 1000.0;
loguser("%lu bytes sent, %lu bytes received in %.2f seconds.\n",
nsi_get_write_count(cs.sock_nsi),
nsi_get_read_count(cs.sock_nsi), time);
}
nsp_delete(mypool);
return rc == NSOCK_LOOP_ERROR ? 1 : 0;
}
static void connect_handler(nsock_pool nsp, nsock_event evt, void *data)
{
enum nse_status status = nse_status(evt);
enum nse_type type = nse_type(evt);
assert(type == NSE_TYPE_CONNECT || type == NSE_TYPE_CONNECT_SSL);
if (status == NSE_STATUS_ERROR) {
loguser("%s.\n", socket_strerror(nse_errorcode(evt)));
exit(1);
} else if (status == NSE_STATUS_TIMEOUT) {
loguser("%s.\n", socket_strerror(ETIMEDOUT));
exit(1);
} else {
assert(status == NSE_STATUS_SUCCESS);
}
#ifdef HAVE_OPENSSL
if (nsi_checkssl(cs.sock_nsi)) {
/* Check the domain name. ssl_post_connect_check prints an
error message if appropriate. */
if (!ssl_post_connect_check((SSL *)nsi_getssl(cs.sock_nsi), o.target))
bye("Certificate verification error.");
}
#endif
connect_report(cs.sock_nsi);
/* Create IOD for nsp->stdin */
if ((cs.stdin_nsi = nsi_new2(nsp, 0, NULL)) == NULL)
bye("Failed to create stdin nsiod.");
post_connect(nsp, nse_iod(evt));
}
/* Handle --exec if appropriate, otherwise start the initial read events and set
the idle timeout. */
static void post_connect(nsock_pool nsp, nsock_iod iod)
{
/* Command to execute. */
if (o.cmdexec) {
struct fdinfo info;
info.fd = nsi_getsd(iod);
#ifdef HAVE_OPENSSL
info.ssl = (SSL *) nsi_getssl(iod);
#endif
/* Convert Nsock's non-blocking socket to an ordinary blocking one. It's
possible for a program to write fast enough that it will get an
EAGAIN on write on a non-blocking socket.*/
block_socket(info.fd);
netexec(&info, o.cmdexec);
}
/* Start the initial reads. */
if (!o.sendonly)
nsock_read(nsp, cs.sock_nsi, read_socket_handler, -1, NULL);
if (!o.recvonly)
nsock_readbytes(nsp, cs.stdin_nsi, read_stdin_handler, -1, NULL, 0);
/* The --idle-timeout option says to exit after a certain period of
inactivity. We start a timer here and reset it on every read event; see
refresh_idle_timer. */
if (o.idletimeout > 0) {
cs.idle_timer_event_id =
nsock_timer_create(nsp, idle_timer_handler, o.idletimeout, NULL);
}
}
static void read_stdin_handler(nsock_pool nsp, nsock_event evt, void *data)
{
enum nse_status status = nse_status(evt);
enum nse_type type = nse_type(evt);
char *buf, *tmp = NULL;
int nbytes;
assert(type == NSE_TYPE_READ);
if (status == NSE_STATUS_EOF) {
if (o.sendonly) {
/* In --send-only mode, exit after EOF on stdin. */
nsock_loop_quit(nsp);
}
return;
} else if (status == NSE_STATUS_ERROR) {
loguser("%s.\n", socket_strerror(nse_errorcode(evt)));
exit(1);
} else if (status == NSE_STATUS_TIMEOUT) {
loguser("%s.\n", socket_strerror(ETIMEDOUT));
exit(1);
} else if (status == NSE_STATUS_CANCELLED || status == NSE_STATUS_KILL) {
return;
} else {
assert(status == NSE_STATUS_SUCCESS);
}
buf = nse_readbuf(evt, &nbytes);
/* read from stdin */
if (o.linedelay)
ncat_delay_timer(o.linedelay);
if (o.crlf) {
if (fix_line_endings(buf, &nbytes, &tmp, &cs.crlf_state))
buf = tmp;
}
nsock_write(nsp, cs.sock_nsi, write_socket_handler, -1, NULL, buf, nbytes);
ncat_log_send(buf, nbytes);
if (tmp)
free(tmp);
refresh_idle_timer(nsp);
}
static void read_socket_handler(nsock_pool nsp, nsock_event evt, void *data)
{
enum nse_status status = nse_status(evt);
enum nse_type type = nse_type(evt);
char *buf;
int nbytes;
assert(type == NSE_TYPE_READ);
if (status == NSE_STATUS_EOF) {
nsock_loop_quit(nsp);
return;
} else if (status == NSE_STATUS_ERROR) {
loguser("%s.\n", socket_strerror(nse_errorcode(evt)));
exit(1);
} else if (status == NSE_STATUS_TIMEOUT) {
loguser("%s.\n", socket_strerror(ETIMEDOUT));
exit(1);
} else if (status == NSE_STATUS_CANCELLED || status == NSE_STATUS_KILL) {
return;
} else {
assert(status == NSE_STATUS_SUCCESS);
}
buf = nse_readbuf(evt, &nbytes);
if (o.linedelay)
ncat_delay_timer(o.linedelay);
if (o.telnet)
dotelnet(nsi_getsd(nse_iod(evt)), (unsigned char *) buf, nbytes);
/* Write socket data to stdout */
Write(STDOUT_FILENO, buf, nbytes);
ncat_log_recv(buf, nbytes);
nsock_readbytes(nsp, cs.sock_nsi, read_socket_handler, -1, NULL, 0);
refresh_idle_timer(nsp);
}
static void write_socket_handler(nsock_pool nsp, nsock_event evt, void *data)
{
enum nse_status status = nse_status(evt);
enum nse_type type = nse_type(evt);
assert(type == NSE_TYPE_WRITE);
if (status == NSE_STATUS_ERROR) {
loguser("%s.\n", socket_strerror(nse_errorcode(evt)));
exit(1);
} else if (status == NSE_STATUS_TIMEOUT) {
loguser("%s.\n", socket_strerror(ETIMEDOUT));
exit(1);
} else if (status == NSE_STATUS_CANCELLED || status == NSE_STATUS_KILL) {
return;
} else {
assert(status == NSE_STATUS_SUCCESS);
}
/* The write to the socket was successful. Allow reading more from stdin
now. */
nsock_readbytes(nsp, cs.stdin_nsi, read_stdin_handler, -1, NULL, 0);
}
static void idle_timer_handler(nsock_pool nsp, nsock_event evt, void *data)
{
enum nse_status status = nse_status(evt);
enum nse_type type = nse_type(evt);
assert(type == NSE_TYPE_TIMER);
if (status == NSE_STATUS_CANCELLED || status == NSE_STATUS_KILL)
return;
assert(status == NSE_STATUS_SUCCESS);
loguser("Idle timeout expired (%d ms).\n", o.idletimeout);
exit(1);
}
static void refresh_idle_timer(nsock_pool nsp)
{
if (o.idletimeout <= 0)
return;
nsock_event_cancel(nsp, cs.idle_timer_event_id, 0);
cs.idle_timer_event_id =
nsock_timer_create(nsp, idle_timer_handler, o.idletimeout, NULL);
}

93
ncat/ncat_connect.h Normal file
View File

@@ -0,0 +1,93 @@
/***************************************************************************
* ncat_connect.h *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include "nsock.h"
/* handle nsock-powered connections */
extern int ncat_connect(void);

470
ncat/ncat_core.c Normal file
View File

@@ -0,0 +1,470 @@
/***************************************************************************
* ncat_core.c -- Contains option defintions and miscellaneous functions. *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include "ncat.h"
#include "util.h"
#include "sys_wrap.h"
#ifndef WIN32
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <ctype.h>
#include <time.h>
#include <assert.h>
/* Only two for now because we might have to listen on IPV4 and IPV6 */
union sockaddr_u listenaddrs[NUM_LISTEN_ADDRS];
int num_listenaddrs = 0;
union sockaddr_u srcaddr;
size_t srcaddrlen;
union sockaddr_u targetss;
size_t targetsslen;
union sockaddr_u httpconnect;
union sockaddr_u socksconnect;
/* Global options structure. */
struct options o;
/* The time the program was started, for exit statistics in connect mode. */
struct timeval start_time;
/* Initializes global options to their default values. */
void options_init(void) {
o.verbose = 0;
o.debug = 0;
o.target = NULL;
o.af = AF_UNSPEC;
o.broker = 0;
o.listen = 0;
o.keepopen = 0;
o.sendonly = 0;
o.recvonly = 0;
o.telnet = 0;
o.udp = 0;
o.sctp = 0;
o.linedelay = 0;
o.chat = 0;
o.nodns = 0;
o.normlog = NULL;
o.hexlog = NULL;
o.normlogfd = -1;
o.hexlogfd = -1;
o.append = 0;
o.idletimeout = 0;
o.crlf = 0;
o.allow = 0;
o.deny = 0;
addrset_init(&o.allowset);
addrset_init(&o.denyset);
o.httpserver = 0;
o.numsrcrtes = 0;
o.srcrteptr = 4;
o.conn_limit = -1; /* Unset. */
o.conntimeout = DEFAULT_CONNECT_TIMEOUT;
o.cmdexec = NULL;
o.shellexec = 0;
o.proxy_auth = NULL;
o.proxytype = NULL;
#ifdef HAVE_OPENSSL
o.ssl = 0;
o.sslcert = NULL;
o.sslkey = NULL;
o.sslverify = 0;
o.ssltrustfile = NULL;
#endif
}
/* Tries to resolve the given name (or literal IP) into a sockaddr structure.
Pass 0 for the port if you don't care. Returns 0 if hostname cannot be
resolved. */
int resolve(char *hostname, unsigned short port,
struct sockaddr_storage *ss, size_t *sslen, int af)
{
struct addrinfo hints;
struct addrinfo *result;
char portbuf[16];
int rc;
assert(ss);
assert(sslen);
memset(&hints, 0, sizeof(hints));
hints.ai_family = af;
hints.ai_socktype = SOCK_DGRAM;
if (o.nodns)
hints.ai_flags |= AI_NUMERICHOST;
/* Make the port number a string to give to getaddrinfo. */
rc = Snprintf(portbuf, sizeof(portbuf), "%hu", port);
assert(rc >= 0 && rc < sizeof(portbuf));
rc = getaddrinfo(hostname, portbuf, &hints, &result);
if (rc != 0 || result == NULL)
return 0;
assert(result->ai_addrlen > 0 && result->ai_addrlen <= (int) sizeof(struct sockaddr_storage));
*sslen = result->ai_addrlen;
memcpy(ss, result->ai_addr, *sslen);
freeaddrinfo(result);
return 1;
}
int fdinfo_close(struct fdinfo *fdn)
{
#ifdef HAVE_OPENSSL
if (o.ssl && fdn->ssl != NULL) {
SSL_shutdown(fdn->ssl);
SSL_free(fdn->ssl);
fdn->ssl = NULL;
}
#endif
return close(fdn->fd);
}
/* Do a recv on an fdinfo, without other side effects. */
int fdinfo_recv(struct fdinfo *fdn, char *buf, size_t size)
{
#ifdef HAVE_OPENSSL
if (o.ssl && fdn->ssl)
return SSL_read(fdn->ssl, buf, size);
#endif
return recv(fdn->fd, buf, size, 0);
}
int fdinfo_pending(struct fdinfo *fdn)
{
#ifdef HAVE_OPENSSL
if (o.ssl && fdn->ssl)
return SSL_pending(fdn->ssl);
#endif
return 0;
}
/* Read from a client socket into buf, returning the number of bytes read, or -1
on an error. This takes care of delays, Telnet negotiation, and logging.
If there is more data pending that won't be noticed by select, a 1 is stored
in *pending, otherwise 0 is stored there. The caller must loop, processing
read data until *pending is false. The reason for this is the SSL_read
function that this function may call, which takes data out of the socket
buffer (so select may not indicate the socket is readable) and keeps it in
its own buffer. *pending holds the result of calling SSL_pending. See
http://www.mail-archive.com/openssl-dev@openssl.org/msg24324.html. */
int ncat_recv(struct fdinfo *fdn, char *buf, size_t size, int *pending)
{
int n;
*pending = 0;
n = fdinfo_recv(fdn, buf, size);
if (n <= 0)
return n;
if (o.linedelay)
ncat_delay_timer(o.linedelay);
if (o.telnet)
dotelnet(fdn->fd, (unsigned char *) buf, n);
ncat_log_recv(buf, n);
/* SSL can buffer our input, so doing another select() won't necessarily
work for us. Indicate to the caller that this function must be called
again to get more data. */
*pending = fdinfo_pending(fdn);
return n;
}
/* Do a send on an fdinfo, without any logging or other side effects. */
int fdinfo_send(struct fdinfo *fdn, const char *buf, size_t size)
{
#ifdef HAVE_OPENSSL
if (o.ssl && fdn->ssl != NULL)
return SSL_write(fdn->ssl, buf, size);
#endif
return send(fdn->fd, buf, size, 0);
}
int ncat_send(struct fdinfo *fdn, const char *buf, size_t size)
{
int n;
if (o.recvonly)
return size;
n = fdinfo_send(fdn, buf, size);
if (n <= 0)
return n;
ncat_log_send(buf, size);
return n;
}
/* Broadcast a message to all the descriptors in fds. Returns -1 if any of the
sends failed. */
int ncat_broadcast(fd_set *fds, const fd_list_t *fdlist, const char *msg, size_t size)
{
struct fdinfo *fdn;
int i, ret;
if (o.recvonly)
return 0;
ret = 0;
for (i = 0; i <= fdlist->fdmax; i++) {
if (!FD_ISSET(i, fds))
continue;
fdn = get_fdinfo(fdlist, i);
if (fdinfo_send(fdn, msg, size) <= 0) {
if (o.debug > 1)
logdebug("Error sending to fd %d: %s.\n", i, socket_strerror(socket_errno()));
ret = -1;
}
}
ncat_log_send(msg, size);
return ret;
}
/* Do telnet WILL/WONT DO/DONT negotiations */
void dotelnet(int s, unsigned char *buf, size_t bufsiz)
{
unsigned char *end = buf + bufsiz, *p;
unsigned char tbuf[3];
for (p = buf; buf < end; p++) {
if (*p != 255) /* IAC */
break;
tbuf[0] = *p++;
/* Answer DONT for WILL or WONT */
if (*p == 251 || *p == 252)
tbuf[1] = 254;
/* Answer WONT for DO or DONT */
else if (*p == 253 || *p == 254)
tbuf[1] = 252;
tbuf[2] = *++p;
send(s, (const char *) tbuf, 3, 0);
}
}
/* sleep(), usleep(), msleep(), Sleep() -- all together now, "portability".
*
* There is no upper or lower limit to the delayval, so if you pass in a short
* length of time <100ms, then you're likely going to get odd results.
* This is because the Linux timeslice is 10ms-200ms. So don't expect
* it to return for atleast that long.
*
* Block until the specified time has elapsed, then return 1.
*/
int ncat_delay_timer(int delayval)
{
struct timeval s;
s.tv_sec = delayval / 1000;
s.tv_usec = (delayval % 1000) * (long) 1000;
select(0, NULL, NULL, NULL, &s);
return 1;
}
/* Open a logfile for writing.
* Return the open file descriptor. */
int ncat_openlog(const char *logfile, int append)
{
if(append)
return Open(logfile, O_WRONLY | O_CREAT | O_APPEND, 0664);
else
return Open(logfile, O_WRONLY | O_CREAT | O_TRUNC, 0664);
}
static int ncat_hexdump(int logfd, const char *data, int len);
void ncat_log_send(const char *data, size_t len)
{
if (o.normlogfd != -1)
Write(o.normlogfd, data, len);
if (o.hexlogfd != -1)
ncat_hexdump(o.hexlogfd, data, len);
}
void ncat_log_recv(const char *data, size_t len)
{
/* Currently the log formats don't distinguish sends and receives. */
ncat_log_send(data, len);
}
/* Convert session data to a neat hexdump logfile */
static int ncat_hexdump(int logfd, const char *data, int len)
{
const char *p = data;
char c;
int i;
char bytestr[4] = { 0 };
char addrstr[10] = { 0 };
char hexstr[16 * 3 + 5] = { 0 };
char charstr[16 * 1 + 5] = { 0 };
char outstr[80] = { 0 };
/* FIXME: needs to be audited closer */
for (i = 1; i <= len; i++) {
if (i % 16 == 1) {
/* Hex address output */
Snprintf(addrstr, sizeof(addrstr), "%.4x", (u_int)(p - data));
}
c = *p;
/* If the character isn't printable. Control characters, etc. */
if (isprint((int) (unsigned char) c) == 0)
c = '.';
/* hex for output */
Snprintf(bytestr, sizeof(bytestr), "%02X ", (unsigned char) *p);
strncat(hexstr, bytestr, sizeof(hexstr) - strlen(hexstr) - 1);
/* char for output */
Snprintf(bytestr, sizeof(bytestr), "%c", c);
strncat(charstr, bytestr, sizeof(charstr) - strlen(charstr) - 1);
if (i % 16 == 0) {
/* neatly formatted output */
Snprintf(outstr, sizeof(outstr), "[%4.4s] %-50.50s %s\n",
addrstr, hexstr, charstr);
Write(logfd, outstr, strlen(outstr));
zmem(outstr, sizeof(outstr));
hexstr[0] = 0;
charstr[0] = 0;
} else if (i % 8 == 0) {
/* cat whitespaces where necessary */
strncat(hexstr, " ", sizeof(hexstr) - strlen(hexstr) - 1);
strncat(charstr, " ", sizeof(charstr) - strlen(charstr) - 1);
}
/* get the next byte */
p++;
}
/* if there's still data left in the buffer, print it */
if (strlen(hexstr) > 0) {
Snprintf(outstr, sizeof(outstr), "[%4.4s] %-50.50s %s\n",
addrstr, hexstr, charstr);
Write(logfd, outstr, strlen(outstr));
zmem(outstr, sizeof(outstr));
}
return 1;
}

216
ncat/ncat_core.h Normal file
View File

@@ -0,0 +1,216 @@
/***************************************************************************
* ncat_core.h *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include "nsock.h"
#include "nbase.h"
#include "util.h"
#include "sockaddr_u.h"
/* Maximum size of the srcaddrs array. In this case two because we can only have
a IPV4 INADDR_ANY and a IPV6 in6addr_any at most or a user defined address */
#define NUM_LISTEN_ADDRS 2
extern union sockaddr_u listenaddrs[NUM_LISTEN_ADDRS];
extern int num_listenaddrs;
extern union sockaddr_u srcaddr;
extern size_t srcaddrlen;
extern union sockaddr_u targetss;
extern size_t targetsslen;
extern union sockaddr_u httpconnect;
extern union sockaddr_u socksconnect;
struct options {
unsigned short portno;
int verbose;
int debug;
char *target;
int af;
int broker;
int listen;
int keepopen;
int sendonly;
int recvonly;
int telnet;
int udp;
int sctp;
int linedelay;
int chat;
int nodns;
const char *normlog;
const char *hexlog;
int normlogfd;
int hexlogfd;
int append;
int idletimeout;
int crlf;
/* Were any hosts specifically allowed? If so, deny all others. */
int allow;
int deny;
struct addrset allowset;
struct addrset denyset;
int httpserver;
/* Loose source-routing stuff */
struct in_addr srcrtes[8];
int numsrcrtes;
int srcrteptr;
/* Maximum number of simultaneous connections */
int conn_limit;
int conntimeout;
char *cmdexec;
int shellexec;
char *proxy_auth;
char *proxytype;
int ssl;
char *sslcert;
char *sslkey;
int sslverify;
char *ssltrustfile;
};
extern struct options o;
/* The time the program was started, for exit statistics in connect mode. */
extern struct timeval start_time;
/* Initializes global options to their default values. */
void options_init(void);
/* Tries to resolve the given name (or literal IP) into a sockaddr structure.
Pass 0 for the port if you don't care. Returns 0 if hostname cannot be
resolved. */
int resolve(char *hostname, unsigned short port,
struct sockaddr_storage *ss, size_t *sslen, int af);
int fdinfo_close(struct fdinfo *fdn);
int fdinfo_recv(struct fdinfo *fdn, char *buf, size_t size);
int fdinfo_send(struct fdinfo *fdn, const char *buf, size_t size);
int fdinfo_pending(struct fdinfo *fdn);
int ncat_recv(struct fdinfo *fdn, char *buf, size_t size, int *pending);
int ncat_send(struct fdinfo *fdn, const char *buf, size_t size);
/* Broadcast a message to all the descriptors in fds. Returns -1 if any of the
sends failed. */
extern int ncat_broadcast(fd_set *fds, const fd_list_t *fdlist, const char *msg, size_t size);
/* Do telnet WILL/WONT DO/DONT negotiations */
extern void dotelnet(int s, unsigned char *buf, size_t bufsiz);
/* sleep(), usleep(), msleep(), Sleep() -- all together now, "portability".
*
* There is no upper or lower limit to the delayval, so if you pass in a short
* length of time <100ms, then you're likely going to get odd results.
* This is because the Linux timeslice is 10ms-200ms. So don't expect
* it to return for at least that long.
*
* Block until the specified time has elapsed, then return 1.
*/
extern int ncat_delay_timer(int delayval);
/* Open a logfile for writing.
* Return the open file descriptor. */
extern int ncat_openlog(const char *logfile, int append);
extern void ncat_log_send(const char *data, size_t len);
extern void ncat_log_recv(const char *data, size_t len);
extern int ncat_hostaccess(char *matchaddr, char *filename, char *remoteip);
/* Make it so that line endings read from a console are always \n (not \r\n).
Defined in ncat_posix.c and ncat_win.c. */
extern void set_lf_mode(void);

102
ncat/ncat_exec.h Normal file
View File

@@ -0,0 +1,102 @@
/***************************************************************************
* ncat_exec.h *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
/* fork and exec a child process with netexec. Close the given file descriptor
in the parent process. Return the child's PID or -1 on error. */
extern int netrun(struct fdinfo *info, char *cmdexec);
/* exec the given command line. Before the exec, redirect stdin, stdout, and
stderr to the given file descriptor. Never returns. */
extern void netexec(struct fdinfo *info, char *cmdexec);
#ifdef WIN32
/* Set a pseudo-signal handler that is called when a thread representing a
child process dies. This is only used on Windows. */
extern void set_pseudo_sigchld_handler(void (*handler)(void));
#endif

613
ncat/ncat_exec_win.c Normal file
View File

@@ -0,0 +1,613 @@
/***************************************************************************
* ncat_exec_win.c -- Windows-specific subprocess execution. *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include <assert.h>
#include "ncat.h"
/* This structure holds information about a subprocess with redirected input
and output handles. */
struct subprocess_info {
HANDLE proc;
struct fdinfo fdn;
HANDLE child_in_r;
HANDLE child_in_w;
HANDLE child_out_r;
HANDLE child_out_w;
};
/* A list of subprocesses, so we can kill them when the program exits. */
static HANDLE subprocesses[DEFAULT_MAX_CONNS];
static int subprocess_max_index = 0;
/* Prevent concurrent access to the subprocesses table by the main process and
a thread. Protects subprocesses and subprocesses_max_index. */
static HANDLE subprocesses_mutex = NULL;
static int start_subprocess(char *cmdexec, struct subprocess_info *info);
static DWORD WINAPI subprocess_thread_func(void *data);
static int register_subprocess(HANDLE proc);
static int unregister_subprocess(HANDLE proc);
static int get_subprocess_slot(void);
/* Have we registered the termination handler yet? */
static int atexit_registered = 0;
static void terminate_subprocesses(void);
static void sigint_handler(int s);
/* This may be set with set_pseudo_sigchld_handler. It is called when a thread
representing a child process ends. */
static void (*pseudo_sigchld_handler)(void) = NULL;
/* Simulates blocking of SIGCHLD while the handler runs. Also prevents
concurrent modification of pseudo_sigchld_handler. */
static HANDLE pseudo_sigchld_mutex = NULL;
/* Run a child process, redirecting its standard file handles to a socket
descriptor. Return the child's PID or -1 on error. */
int netrun(struct fdinfo *fdn, char *cmdexec)
{
struct subprocess_info *info;
HANDLE thread;
int pid;
info = (struct subprocess_info *) safe_malloc(sizeof(*info));
info->fdn = *fdn;
pid = start_subprocess(cmdexec, info);
if (pid == -1) {
free(info);
close(info->fdn.fd);
return -1;
}
/* Start up the thread to handle process I/O. */
thread = CreateThread(NULL, 0, subprocess_thread_func, info, 0, NULL);
if (thread == NULL) {
if (o.verbose)
logdebug("Error in CreateThread: %d\n", GetLastError());
free(info);
return -1;
}
CloseHandle(thread);
return pid;
}
/* Run the given command line as if by exec. Doesn't return. */
void netexec(struct fdinfo *fdn, char *cmdexec)
{
struct subprocess_info *info;
int pid;
DWORD ret;
info = (struct subprocess_info *) safe_malloc(sizeof(*info));
info->fdn = *fdn;
pid = start_subprocess(cmdexec, info);
if (pid == -1)
ExitProcess(2);
/* Run the subprocess thread function, but don't put it in a thread. Just
run it and exit with its return value because we're simulating exec. */
ExitProcess(subprocess_thread_func(info));
}
/* Set a pseudo-signal handler that is called when a thread representing a
child process dies. This is only used on Windows. */
extern void set_pseudo_sigchld_handler(void (*handler)(void))
{
if (pseudo_sigchld_mutex == NULL) {
pseudo_sigchld_mutex = CreateMutex(NULL, FALSE, NULL);
assert(pseudo_sigchld_mutex != NULL);
}
assert(WaitForSingleObject(pseudo_sigchld_mutex, INFINITE) == WAIT_OBJECT_0);
pseudo_sigchld_handler = handler;
assert(ReleaseMutex(pseudo_sigchld_mutex) != 0);
}
/* Run a command and redirect its input and output handles to a pair of
anonymous pipes. The process handle and pipe handles are returned in the
info struct. Returns the PID of the new process, or -1 on error. */
static int run_command_redirected(char *cmdexec, struct subprocess_info *info) {
/* Each named pipe we create has to have a unique name. */
static int pipe_serial_no = 0;
char pipe_name[32];
SECURITY_ATTRIBUTES sa;
STARTUPINFO si;
PROCESS_INFORMATION pi;
/* Make the pipe handles inheritable. */
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
/* The child's input pipe is an ordinary blocking pipe. */
if (CreatePipe(&info->child_in_r, &info->child_in_w, &sa, 0) == 0) {
if (o.verbose)
logdebug("Error in CreatePipe: %d\n", GetLastError());
return -1;
}
/* Pipe names must have this special form. */
Snprintf(pipe_name, sizeof(pipe_name), "\\\\.\\pipe\\ncat-%d", pipe_serial_no);
if (o.debug > 1)
logdebug("Creating named pipe \"%s\"\n", pipe_name);
/* The output pipe has to be nonblocking, which requires this complicated
setup. */
info->child_out_r = CreateNamedPipe(pipe_name,
PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_BYTE, 1, 4096, 4096, 1000, &sa);
if (info->child_out_r == 0) {
if (o.verbose)
logdebug("Error in CreateNamedPipe: %d\n", GetLastError());
CloseHandle(info->child_in_r);
CloseHandle(info->child_in_w);
return -1;
}
info->child_out_w = CreateFile(pipe_name,
GENERIC_WRITE, 0, &sa, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
if (info->child_out_w == 0) {
CloseHandle(info->child_in_r);
CloseHandle(info->child_in_w);
CloseHandle(info->child_out_r);
return -1;
}
pipe_serial_no++;
/* Don't inherit our end of the pipes. */
SetHandleInformation(info->child_in_w, HANDLE_FLAG_INHERIT, 0);
SetHandleInformation(info->child_out_r, HANDLE_FLAG_INHERIT, 0);
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
si.hStdInput = info->child_in_r;
si.hStdOutput = info->child_out_w;
si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
si.dwFlags |= STARTF_USESTDHANDLES;
memset(&pi, 0, sizeof(pi));
if (CreateProcess(NULL, cmdexec, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi) == 0) {
if (o.verbose)
logdebug("Error in CreateProcess: %d\n", GetLastError());
CloseHandle(info->child_in_r);
CloseHandle(info->child_in_w);
CloseHandle(info->child_out_r);
CloseHandle(info->child_out_w);
return -1;
}
/* Close hThread here because we have no use for it. hProcess is closed in
subprocess_info_close. */
CloseHandle(pi.hThread);
info->proc = pi.hProcess;
return pi.dwProcessId;
}
static const char *get_shell(void)
{
const char *comspec;
comspec = getenv("COMSPEC");
if (comspec == NULL)
comspec = "cmd.exe";
return comspec;
}
static void subprocess_info_close(struct subprocess_info *info)
{
#ifdef HAVE_OPENSSL
if (info->fdn.ssl != NULL) {
SSL_shutdown(info->fdn.ssl);
SSL_free(info->fdn.ssl);
}
#endif
closesocket(info->fdn.fd);
CloseHandle(info->proc);
CloseHandle(info->child_in_r);
CloseHandle(info->child_in_w);
CloseHandle(info->child_out_r);
CloseHandle(info->child_out_w);
}
/* Start a subprocess with run_command_redirected and register it with the
termination handler. Takes care of o.shellexec. Returns the PID of the
subprocess or -1 on error. */
static int start_subprocess(char *cmdexec, struct subprocess_info *info)
{
char *cmdbuf;
int pid;
if (o.shellexec) {
/* Run with cmd.exe. */
const char *shell;
size_t cmdlen;
shell = get_shell();
cmdlen = strlen(shell) + strlen(cmdexec) + 32;
cmdbuf = (char *) safe_malloc(cmdlen);
Snprintf(cmdbuf, cmdlen, "%s /C %s", shell, cmdexec);
} else {
cmdbuf = cmdexec;
}
if (o.debug)
logdebug("Executing: %s\n", cmdbuf);
pid = run_command_redirected(cmdbuf, info);
if (cmdbuf != cmdexec)
free(cmdbuf);
if (pid == -1)
return -1;
if (register_subprocess(info->proc) == -1) {
if (o.verbose)
logdebug("Couldn't register subprocess with termination handler; not executing.\n");
TerminateProcess(info->proc, 2);
subprocess_info_close(info);
return -1;
}
return pid;
}
/* Relay data between a socket and a process until the process dies or stops
sending or receiving data. The socket descriptor and process pipe handles
are in the data argument, which must be a pointer to struct subprocess_info.
This function is a workaround for the fact that we can't just run a process
after redirecting its input handles to a socket. If the process, for
example, redirects its own stdin, it somehow confuses the socket and stdout
stops working. This is exactly what ncat does (as part of the Windows stdin
workaround), so it can't be ignored.
This function can be invoked through CreateThread to simulate fork+exec, or
called directly to simulate exec. It frees the subprocess_info struct and
closes the socket and pipe handles before returning. Returns the exit code
of the subprocess. */
static DWORD WINAPI subprocess_thread_func(void *data) {
struct subprocess_info *info;
char pipe_buffer[BUFSIZ];
OVERLAPPED overlap = { 0 };
HANDLE events[3];
DWORD ret;
int crlf_state = 0;
info = (struct subprocess_info *) data;
/* Three events we watch for: socket read, pipe read, and process end. */
events[0] = (HANDLE) WSACreateEvent();
WSAEventSelect(info->fdn.fd, events[0], FD_READ | FD_CLOSE);
events[1] = info->child_out_r;
events[2] = info->proc;
/* To avoid blocking or polling, we use asynchronous I/O, or what Microsoft
calls "overlapped" I/O, on the process pipe. WaitForMultipleObjects
reports when the read operation is complete. */
ReadFile(info->child_out_r, pipe_buffer, sizeof(pipe_buffer), NULL, &overlap);
/* Loop until EOF or error. */
for (;;) {
DWORD n, nwritten;
int i;
i = WaitForMultipleObjects(3, events, FALSE, INFINITE);
if (i == WAIT_OBJECT_0) {
/* Read from socket, write to process. */
char buffer[BUFSIZ];
int pending;
ResetEvent(events[0]);
do {
n = ncat_recv(&info->fdn, buffer, sizeof(buffer), &pending);
if (n <= 0)
goto loop_end;
if (WriteFile(info->child_in_w, buffer, n, &nwritten, NULL) == 0)
break;
if (nwritten != n)
goto loop_end;
} while (pending);
} else if (i == WAIT_OBJECT_0 + 1) {
char *crlf = NULL, *wbuf;
/* Read from process, write to socket. */
if (GetOverlappedResult(info->child_out_r, &overlap, &n, FALSE)) {
int n_r;
wbuf = pipe_buffer;
n_r = n;
if (o.crlf) {
if (fix_line_endings((char *) pipe_buffer, &n_r, &crlf, &crlf_state))
wbuf = crlf;
}
/* The above call to WSAEventSelect puts the socket in
non-blocking mode, but we want this send to block, not
potentially return WSAEWOULDBLOCK. We call block_socket, but
first we must clear out the select event. */
WSAEventSelect(info->fdn.fd, events[0], 0);
block_socket(info->fdn.fd);
nwritten = ncat_send(&info->fdn, wbuf, n_r);
if (crlf != NULL)
free(crlf);
if (nwritten != n_r)
break;
/* Restore the select event (and non-block the socket again.) */
WSAEventSelect(info->fdn.fd, events[0], FD_READ | FD_CLOSE);
/* Queue another ansychronous read. */
ReadFile(info->child_out_r, pipe_buffer, sizeof(pipe_buffer), NULL, &overlap);
} else {
if (GetLastError() != ERROR_IO_PENDING)
/* Error or end of file. */
break;
}
} else if (i == WAIT_OBJECT_0 + 2) {
/* The child died. There are no more writes left in the pipe
because WaitForMultipleObjects guarantees events with lower
indexes are handled first. */
break;
} else {
break;
}
}
loop_end:
WSACloseEvent(events[0]);
assert(unregister_subprocess(info->proc) != -1);
GetExitCodeProcess(info->proc, &ret);
if (ret == STILL_ACTIVE) {
DWORD rc;
if (o.debug > 1)
logdebug("Subprocess still running, terminating it.\n");
rc = TerminateProcess(info->proc, 0);
if (rc == 0) {
if (o.debug > 1)
logdebug("TerminateProcess failed with code %d.\n", rc);
}
}
GetExitCodeProcess(info->proc, &ret);
if (o.debug > 1)
logdebug("Subprocess ended with exit code %d.\n", ret);
shutdown(info->fdn.fd, 2);
subprocess_info_close(info);
free(info);
assert(WaitForSingleObject(pseudo_sigchld_mutex, INFINITE) == WAIT_OBJECT_0);
if (pseudo_sigchld_handler != NULL)
pseudo_sigchld_handler();
assert(ReleaseMutex(pseudo_sigchld_mutex) != 0);
return ret;
}
/* Find a free slot in the subprocesses table. Update subprocesses_max_index to
be one greater than the maximum index containing a non-NULL handle. (It is
assumed that the index returned by this function will be filled by a
handle.) */
static int get_subprocess_slot(void)
{
int i, free_index, max_index;
assert(WaitForSingleObject(subprocesses_mutex, INFINITE) == WAIT_OBJECT_0);
free_index = -1;
max_index = 0;
for (i = 0; i < subprocess_max_index; i++) {
HANDLE proc = subprocesses[i];
DWORD ret;
if (proc == NULL) {
if (free_index == -1)
free_index = i;
} else {
max_index = i + 1;
}
}
if ((free_index == -1 || free_index == max_index)
&& max_index < sizeof(subprocesses) / sizeof(subprocesses[0]))
free_index = max_index++;
subprocess_max_index = max_index;
assert(ReleaseMutex(subprocesses_mutex) != 0);
return free_index;
}
/* Add a process to the list of processes to kill at program exit. Once you
call this function, the process handle "belongs" to it and you shouldn't
modify the handle until you call unregister_subprocess. Returns -1 on
error. */
static int register_subprocess(HANDLE proc)
{
int i, rc;
if (subprocesses_mutex == NULL) {
subprocesses_mutex = CreateMutex(NULL, FALSE, NULL);
assert(subprocesses_mutex != NULL);
}
if (pseudo_sigchld_mutex == NULL) {
pseudo_sigchld_mutex = CreateMutex(NULL, FALSE, NULL);
assert(pseudo_sigchld_mutex != NULL);
}
assert(WaitForSingleObject(subprocesses_mutex, INFINITE) == WAIT_OBJECT_0);
i = get_subprocess_slot();
if (i == -1) {
if (o.verbose)
logdebug("No free process slots for termination handler.\n");
} else {
subprocesses[i] = proc;
if (o.debug > 1)
logdebug("Register subprocess %p at index %d.\n", proc, i);
if (!atexit_registered) {
/* We register both an atexit and a SIGINT handler because ^C
doesn't seem to cause atexit handlers to be called. */
atexit(terminate_subprocesses);
signal(SIGINT, sigint_handler);
atexit_registered = 1;
}
}
assert(ReleaseMutex(subprocesses_mutex) != 0);
return i;
}
/* Remove a process handle from the termination handler list. Returns -1 if the
process was not already registered. */
static int unregister_subprocess(HANDLE proc)
{
int i;
assert(WaitForSingleObject(subprocesses_mutex, INFINITE) == WAIT_OBJECT_0);
for (i = 0; i < subprocess_max_index; i++) {
if (proc == subprocesses[i])
break;
}
if (i < subprocess_max_index) {
subprocesses[i] = NULL;
if (o.debug > 1)
logdebug("Unregister subprocess %p from index %d.\n", proc, i);
} else {
i = -1;
}
assert(ReleaseMutex(subprocesses_mutex) != 0);
return i;
}
static void terminate_subprocesses(void)
{
int i;
if (o.debug)
logdebug("Terminating subprocesses\n");
assert(WaitForSingleObject(subprocesses_mutex, INFINITE) == WAIT_OBJECT_0);
if (o.debug > 1)
logdebug("max_index %d\n", subprocess_max_index);
for (i = 0; i < subprocess_max_index; i++) {
HANDLE proc = subprocesses[i];
DWORD ret;
if (proc == NULL)
continue;
GetExitCodeProcess(proc, &ret);
if (ret == STILL_ACTIVE) {
if (o.debug > 1)
logdebug("kill index %d\n", i);
TerminateProcess(proc, 0);
}
subprocesses[i] = NULL;
}
assert(ReleaseMutex(subprocesses_mutex) != 0);
}
static void sigint_handler(int s)
{
terminate_subprocesses();
ExitProcess(0);
}

974
ncat/ncat_listen.c Normal file
View File

@@ -0,0 +1,974 @@
/***************************************************************************
* ncat_listen.c -- --listen mode. *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include "ncat.h"
#include <assert.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <limits.h>
#ifndef WIN32
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#else
#include <fcntl.h>
#endif
#ifdef HAVE_OPENSSL
#include <openssl/ssl.h>
#include <openssl/err.h>
#endif
/* read_fds is the clients we are accepting data from. broadcast_fds is the
clients were are sending data to. broadcast_fds doesn't include the listening
socket and stdin. Network clients are not added to read_fds when --send-only
is used, because they would be always selected without having data read.
write_fds is the list of clients that are waiting for some kind of response
from us, like a pending ssl negotiation. */
static fd_set master_readfds, master_writefds, master_broadcastfds;
#ifdef HAVE_OPENSSL
/* sslpending_fds containts the list of ssl sockets that are waiting to complete
the ssl handshake */
static fd_set sslpending_fds;
#endif
/* These are bookkeeping data structures that are parallel to read_fds and
broadcast_fds. */
static fd_list_t client_fdlist, broadcast_fdlist;
static int listen_socket[NUM_LISTEN_ADDRS];
/* Has stdin seen EOF? */
static int stdin_eof = 0;
static int crlf_state = 0;
static void handle_connection(int socket_accept);
static int read_stdin(void);
static int read_socket(int recv_fd);
static void post_handle_connection(struct fdinfo sinfo);
static void read_and_broadcast(int recv_socket);
static int chat_announce_connect(int fd, const union sockaddr_u *su);
static int chat_announce_disconnect(int fd);
static char *chat_filter(char *buf, size_t size, int fd, int *nwritten);
/* The number of connected clients is the difference of conn_inc and conn_dec.
It is split up into two variables for signal safety. conn_dec is modified
(asynchronously) only in signal handlers and conn_inc is modified
(synchronously) only in the main program. get_conn_count loops while conn_dec
is being modified. */
static unsigned int conn_inc = 0;
static volatile unsigned int conn_dec = 0;
static volatile sig_atomic_t conn_dec_changed;
static void decrease_conn_count(void) {
conn_dec_changed = 1;
conn_dec++;
}
static int get_conn_count(void)
{
unsigned int count;
/* conn_dec is modified in a signal handler, so loop until it stops
changing. */
do {
conn_dec_changed = 0;
count = conn_inc - conn_dec;
} while (conn_dec_changed);
assert(count <= INT_MAX);
return count;
}
#ifndef WIN32
static void sigchld_handler(int signum)
{
while (waitpid(-1, NULL, WNOHANG) > 0)
decrease_conn_count();
}
#endif
static int ncat_listen_stream(int proto)
{
int rc, i, fds_ready;
fd_set listen_fds;
/* clear out structs */
FD_ZERO(&master_readfds);
FD_ZERO(&master_writefds);
FD_ZERO(&master_broadcastfds);
FD_ZERO(&listen_fds);
#ifdef HAVE_OPENSSL
FD_ZERO(&sslpending_fds);
#endif
zmem(&client_fdlist, sizeof(client_fdlist));
zmem(&broadcast_fdlist, sizeof(broadcast_fdlist));
#ifdef WIN32
set_pseudo_sigchld_handler(decrease_conn_count);
#else
/* Reap on SIGCHLD */
Signal(SIGCHLD, sigchld_handler);
/* Ignore the SIGPIPE that occurs when a client disconnects suddenly and we
send data to it before noticing. */
Signal(SIGPIPE, SIG_IGN);
#endif
#ifdef HAVE_OPENSSL
if (o.ssl)
setup_ssl_listen();
#endif
/* We need a list of fds to keep current fdmax. The second parameter is a
number added to the supplied connection limit, that will compensate
maxfds for the added by default listen and stdin sockets. */
init_fdlist(&client_fdlist, sadd(o.conn_limit, num_listenaddrs + 1));
for (i = 0; i < NUM_LISTEN_ADDRS; i++)
listen_socket[i] = -1;
for (i = 0; i < num_listenaddrs; i++) {
/* setup the main listening socket */
listen_socket[i] = do_listen(SOCK_STREAM, proto, &listenaddrs[i]);
/* Make our listening socket non-blocking because there are timing issues
* which could cause us to block on accept() even though select() says it's
* readable. See UNPv1 2nd ed, p422 for more.
*/
unblock_socket(listen_socket[i]);
/* setup select sets and max fd */
FD_SET(listen_socket[i], &master_readfds);
add_fd(&client_fdlist, listen_socket[i]);
FD_SET(listen_socket[i], &listen_fds);
}
add_fd(&client_fdlist, STDIN_FILENO);
init_fdlist(&broadcast_fdlist, o.conn_limit);
while (1) {
/* We pass these temporary descriptor sets to fselect, since fselect
modifies the sets it receives. */
fd_set readfds = master_readfds, writefds = master_writefds;
struct fdinfo *fdi = NULL;
if (o.debug > 1)
logdebug("selecting, fdmax %d\n", client_fdlist.fdmax);
if (o.debug > 1 && o.broker)
logdebug("Broker connection count is %d\n", get_conn_count());
fds_ready = fselect(client_fdlist.fdmax + 1, &readfds, &writefds, NULL, NULL);
if (o.debug > 1)
logdebug("select returned %d fds ready\n", fds_ready);
/*
* FIXME: optimize this loop to look only at the fds in the fd list,
* doing it this way means that if you have one descriptor that is very
* large, say 500, and none close to it, that you'll loop many times for
* nothing.
*/
for (i = 0; i <= client_fdlist.fdmax && fds_ready > 0; i++) {
/* Loop through descriptors until there's something to read */
if (!FD_ISSET(i, &readfds) && !FD_ISSET(i, &writefds))
continue;
if (o.debug > 1)
logdebug("fd %d is ready\n", i);
#ifdef HAVE_OPENSSL
/* Is this an ssl socket pending a handshake? If so handle it. */
if (o.ssl && FD_ISSET(i, &sslpending_fds)) {
FD_CLR(i, &master_readfds);
FD_CLR(i, &master_writefds);
fdi = get_fdinfo(&client_fdlist, i);
switch(ssl_handshake(fdi)){
case NCAT_SSL_HANDSHAKE_COMPLETED:
/* Clear from sslpending_fds once ssl is established */
FD_CLR(i, &sslpending_fds);
rm_fd(&client_fdlist, i);
post_handle_connection(*fdi);
break;
case NCAT_SSL_HANDSHAKE_PENDING_WRITE:
FD_SET(i, &master_writefds);
break;
case NCAT_SSL_HANDSHAKE_PENDING_READ:
FD_SET(i, &master_readfds);
break;
case NCAT_SSL_HANDSHAKE_FAILED:
default:
SSL_free(fdi->ssl);
Close(fdi->fd);
FD_CLR(i, &sslpending_fds);
FD_CLR(i, &master_readfds);
rm_fd(&client_fdlist, i);
/* Are we in single listening mode(without -k)? If so
then we should quit also. */
if (!o.keepopen && !o.broker)
return 1;
--conn_inc;
break;
}
} else
#endif
if (FD_ISSET(i, &listen_fds)) {
/* we have a new connection request */
handle_connection(i);
} else if (i == STDIN_FILENO) {
if(o.broker) {
read_and_broadcast(i);
}else {
/* Read from stdin and write to all clients. */
rc = read_stdin();
if (rc == 0 && o.sendonly)
/* There will be nothing more to send. If we're not
receiving anything, we can quit here. */
return 0;
if (rc < 0)
return 1;
}
} else if (!o.sendonly) {
if(o.broker) {
read_and_broadcast(i);
}else {
/* Read from a client and write to stdout. */
rc = read_socket(i);
if (rc <= 0 && !o.keepopen)
return rc == 0 ? 0 : 1;
}
}
fds_ready--;
}
}
return 0;
}
/* Accept a connection on a listening socket. Allow or deny the connection.
Fork a command if o.cmdexec is set. Otherwise, add the new socket to the
watch set. */
static void handle_connection(int socket_accept)
{
union sockaddr_u remoteaddr;
socklen_t ss_len;
struct fdinfo s = { 0 };
int conn_count;
zmem(&s, sizeof(s));
ss_len = sizeof(remoteaddr.storage);
errno = 0;
s.fd = accept(socket_accept, &remoteaddr.sockaddr, &ss_len);
if (s.fd < 0) {
if (o.debug)
logdebug("Error in accept: %s\n", strerror(errno));
close(s.fd);
return;
}
if (o.verbose) {
if (o.chat)
loguser("Connection from %s on file descriptor %d.\n", inet_socktop(&remoteaddr), s.fd);
else
loguser("Connection from %s.\n", inet_socktop(&remoteaddr));
}
if (!o.keepopen && !o.broker) {
int i;
for (i = 0; i < num_listenaddrs; i++) {
Close(listen_socket[i]);
FD_CLR(listen_socket[i], &master_readfds);
rm_fd(&client_fdlist, listen_socket[i]);
}
}
if (o.verbose)
loguser("Connection from %s:%hu.\n", inet_socktop(&remoteaddr), inet_port(&remoteaddr));
/* Check conditions that might cause us to deny the connection. */
conn_count = get_conn_count();
if (conn_count >= o.conn_limit) {
if (o.verbose)
loguser("New connection denied: connection limit reached (%d)\n", conn_count);
Close(s.fd);
return;
}
if (!allow_access(&remoteaddr)) {
if (o.verbose)
loguser("New connection denied: not allowed\n");
Close(s.fd);
return;
}
s.remoteaddr = remoteaddr;
conn_inc++;
unblock_socket(s.fd);
#ifdef HAVE_OPENSSL
if (o.ssl) {
/* Add the socket to the necessary descriptor lists. */
FD_SET(s.fd, &sslpending_fds);
FD_SET(s.fd, &master_readfds);
FD_SET(s.fd, &master_writefds);
/* Add it to our list of fds too for maintaining maxfd. */
if (add_fdinfo(&client_fdlist, &s) < 0)
bye("add_fdinfo() failed.");
} else
#endif
post_handle_connection(s);
}
/* This function handles the post connection specific actions that are needed
* after a socket has been initialized(normal socket or ssl socket). */
static void post_handle_connection(struct fdinfo sinfo)
{
/*
* Are we executing a command? If so then don't add this guy
* to our descriptor list or set.
*/
if (o.cmdexec) {
if (o.keepopen)
netrun(&sinfo, o.cmdexec);
else
netexec(&sinfo, o.cmdexec);
} else {
/* Now that a client is connected, pay attention to stdin. */
if (!stdin_eof)
FD_SET(STDIN_FILENO, &master_readfds);
if (!o.sendonly) {
/* add to our lists */
FD_SET(sinfo.fd, &master_readfds);
/* add it to our list of fds for maintaining maxfd */
if (add_fdinfo(&client_fdlist, &sinfo) < 0)
bye("add_fdinfo() failed.");
}
FD_SET(sinfo.fd, &master_broadcastfds);
if (add_fdinfo(&broadcast_fdlist, &sinfo) < 0)
bye("add_fdinfo() failed.");
if (o.chat)
chat_announce_connect(sinfo.fd, &sinfo.remoteaddr);
}
}
/* Read from stdin and broadcast to all client sockets. Return the number of
bytes read, or -1 on error. */
int read_stdin(void)
{
int nbytes;
char buf[DEFAULT_TCP_BUF_LEN];
char *tempbuf = NULL;
nbytes = read(STDIN_FILENO, buf, sizeof(buf));
if (nbytes <= 0) {
if (nbytes < 0 && o.verbose)
logdebug("Error reading from stdin: %s\n", strerror(errno));
if (nbytes == 0 && o.debug)
logdebug("EOF on stdin\n");
/* Don't close the file because that allows a socket to be fd 0. */
FD_CLR(STDIN_FILENO, &master_readfds);
/* Buf mark that we've seen EOF so it doesn't get re-added to the
select list. */
stdin_eof = 1;
return nbytes;
}
if (o.crlf)
fix_line_endings((char *) buf, &nbytes, &tempbuf, &crlf_state);
if (o.linedelay)
ncat_delay_timer(o.linedelay);
/* Write to everything in the broadcast set. */
if (tempbuf != NULL) {
ncat_broadcast(&master_broadcastfds, &broadcast_fdlist, tempbuf, nbytes);
free(tempbuf);
tempbuf = NULL;
} else {
ncat_broadcast(&master_broadcastfds, &broadcast_fdlist, buf, nbytes);
}
return nbytes;
}
/* Read from a client socket and write to stdout. Return the number of bytes
read from the socket, or -1 on error. */
int read_socket(int recv_fd)
{
char buf[DEFAULT_TCP_BUF_LEN];
struct fdinfo *fdn;
int nbytes, pending;
fdn = get_fdinfo(&client_fdlist, recv_fd);
assert(fdn != NULL);
nbytes = 0;
do {
int n;
n = ncat_recv(fdn, buf, sizeof(buf), &pending);
if (n <= 0) {
if (o.debug)
logdebug("Closing connection.\n");
#ifdef HAVE_OPENSSL
if (o.ssl && fdn->ssl) {
if (nbytes == 0)
SSL_shutdown(fdn->ssl);
SSL_free(fdn->ssl);
}
#endif
close(recv_fd);
FD_CLR(recv_fd, &master_readfds);
rm_fd(&client_fdlist, recv_fd);
FD_CLR(recv_fd, &master_broadcastfds);
rm_fd(&broadcast_fdlist, recv_fd);
conn_inc--;
if (get_conn_count() == 0)
FD_CLR(STDIN_FILENO, &master_readfds);
return n;
}
Write(STDOUT_FILENO, buf, n);
nbytes += n;
} while (pending);
return nbytes;
}
/* This is sufficiently different from the TCP code (wrt SSL, etc) that it
* resides in its own simpler function
*/
static int ncat_listen_dgram(int proto)
{
int sockfd[NUM_LISTEN_ADDRS];
int i, fdn = -1;
int fdmax, nbytes, fds_ready;
char buf[DEFAULT_UDP_BUF_LEN] = {0};
char *tempbuf = NULL;
fd_set read_fds;
union sockaddr_u remotess;
socklen_t sslen = sizeof(remotess.storage);
for (i = 0; i < NUM_LISTEN_ADDRS; i++) {
sockfd[i] = -1;
}
FD_ZERO(&read_fds);
/* Initialize remotess struct so recvfrom() doesn't hit the fan.. */
zmem(&remotess.storage, sizeof(remotess.storage));
remotess.storage.ss_family = o.af;
#ifdef WIN32
set_pseudo_sigchld_handler(decrease_conn_count);
#else
/* Reap on SIGCHLD */
Signal(SIGCHLD, sigchld_handler);
/* Ignore the SIGPIPE that occurs when a client disconnects suddenly and we
send data to it before noticing. */
Signal(SIGPIPE, SIG_IGN);
#endif
/* set for selecting udp listening sockets */
fd_set listen_fds;
fd_list_t listen_fdlist;
FD_ZERO(&listen_fds);
init_fdlist(&listen_fdlist, num_listenaddrs);
for (i = 0; i < num_listenaddrs; i++) {
/* create the UDP listen sockets */
sockfd[i] = do_listen(SOCK_DGRAM, proto, &listenaddrs[i]);
FD_SET(sockfd[i],&listen_fds);
add_fd(&listen_fdlist, sockfd[i]);
}
while (1) {
int i, j, conn_count, socket_n;
if (fdn != -1) {
/*remove socket descriptor which is burnt */
FD_CLR(sockfd[fdn], &listen_fds);
rm_fd(&listen_fdlist, sockfd[fdn]);
/* Rebuild the udp socket which got burnt */
sockfd[fdn] = do_listen(SOCK_DGRAM, proto, &listenaddrs[fdn]);
FD_SET(sockfd[fdn],&listen_fds);
add_fd(&listen_fdlist, sockfd[fdn]);
}
fdn = -1;
socket_n = -1;
fd_set fds;
FD_ZERO(&fds);
while (1) {
/*
* We just select to get a list of sockets which we can talk to
*/
if (o.debug > 1)
logdebug("selecting, fdmax %d\n", listen_fdlist.fdmax);
fds = listen_fds;
fds_ready = fselect(listen_fdlist.fdmax + 1, &fds, NULL, NULL, NULL);
if (o.debug > 1)
logdebug("select returned %d fds ready\n", fds_ready);
/*
* Figure out which listening socket got a connection. This loop should
* really call a function for each ready socket instead of breaking on
* the first one.
*/
for (i = 0; i <= listen_fdlist.fdmax && fds_ready >0; i++) {
/* Loop through descriptors until there is something ready */
if (!FD_ISSET(i, &fds))
continue;
/* Check each listening socket */
for (j = 0; j < num_listenaddrs; j++) {
if (i == sockfd[j]) {
if (o.debug >1)
logdebug("Valid descriptor %d \n", i);
fdn = j;
socket_n = i;
break;
}
}
/* if we found a valid socket break */
if (fdn != -1) {
fds_ready--;
break;
}
}
/* Make sure someone connected */
if (fdn == -1)
continue;
/*
* We just peek so we can get the client connection details without
* removing anything from the queue. Sigh.
*/
nbytes = Recvfrom(socket_n, buf, sizeof(buf), MSG_PEEK,
&remotess.sockaddr, &sslen);
/* Check conditions that might cause us to deny the connection. */
conn_count = get_conn_count();
if (conn_count >= o.conn_limit) {
if (o.verbose)
loguser("New connection denied: connection limit reached (%d)\n", conn_count);
} else if (!allow_access(&remotess)) {
if (o.verbose)
loguser("New connection denied: not allowed\n");
} else {
/* Good to go. */
break;
}
/* Dump the current datagram */
Recv(socket_n, buf, sizeof(buf), 0);
}
if (o.debug > 1)
logdebug("Valid Connection from %d\n", socket_n);
conn_inc++;
/*
* We're using connected udp. This has the down side of only
* being able to handle one udp client at a time
*/
Connect(socket_n, &remotess.sockaddr, sslen);
/* clean slate for buf */
zmem(buf, sizeof(buf));
/* are we executing a command? then do it */
if (o.cmdexec) {
struct fdinfo info = { 0 };
info.fd = socket_n;
if (o.keepopen)
netrun(&info, o.cmdexec);
else
netexec(&info, o.cmdexec);
continue;
}
FD_SET(socket_n, &read_fds);
FD_SET(STDIN_FILENO, &read_fds);
fdmax = socket_n;
/* stdin -> socket and socket -> stdout */
while (1) {
fd_set fds;
fds = read_fds;
if (o.debug > 1)
logdebug("udp select'ing\n");
fds_ready = fselect(fdmax + 1, &fds, NULL, NULL, NULL);
if (FD_ISSET(STDIN_FILENO, &fds)) {
nbytes = Read(STDIN_FILENO, buf, sizeof(buf));
if (nbytes < 0) {
loguser("%s.\n", strerror(errno));
return 1;
} else if (nbytes == 0) {
return 0;
}
if (o.crlf)
fix_line_endings((char *) buf, &nbytes, &tempbuf, &crlf_state);
if (!o.recvonly) {
if (tempbuf != NULL)
send(socket_n, tempbuf, nbytes, 0);
else
send(socket_n, buf, nbytes, 0);
}
if (tempbuf != NULL) {
free(tempbuf);
tempbuf = NULL;
}
}
if (FD_ISSET(socket_n, &fds)) {
nbytes = recv(socket_n, buf, sizeof(buf), 0);
if (nbytes < 0) {
loguser("%s.\n", socket_strerror(socket_errno()));
close(socket_n);
return 1;
}
if (!o.sendonly)
Write(STDOUT_FILENO, buf, nbytes);
}
zmem(buf, sizeof(buf));
}
}
return 0;
}
int ncat_listen()
{
if (o.httpserver)
return ncat_http_server();
else if (o.udp)
return ncat_listen_dgram(IPPROTO_UDP);
else if (o.sctp)
return ncat_listen_stream(IPPROTO_SCTP);
else
return ncat_listen_stream(IPPROTO_TCP);
/* unreached */
return 1;
}
//---------------
/* Read from recv_fd and broadcast whatever is read to all other descriptors in
read_fds, with the exception of stdin, listen_socket, and recv_fd itself.
Handles EOL translation and chat mode. On read error or end of stream,
closes the socket and removes it from the read_fds list. */
static void read_and_broadcast(int recv_fd)
{
struct fdinfo *fdn;
int pending;
fdn = get_fdinfo(&client_fdlist, recv_fd);
assert(fdn);
/* Loop while ncat_recv indicates data is pending. */
do {
char buf[DEFAULT_TCP_BUF_LEN];
char *chatbuf, *outbuf;
char *tempbuf = NULL;
fd_set broadcastfds;
int n;
/* Behavior differs depending on whether this is stdin or a socket. */
if (recv_fd == STDIN_FILENO) {
n = read(recv_fd, buf, sizeof(buf));
if (n <= 0) {
if (n < 0 && o.verbose)
logdebug("Error reading from stdin: %s\n", strerror(errno));
if (n == 0 && o.debug)
logdebug("EOF on stdin\n");
/* Don't close the file because that allows a socket to be
fd 0. */
FD_CLR(recv_fd, &master_readfds);
/* But mark that we've seen EOF so it doesn't get re-added to
the select list. */
stdin_eof = 1;
return;
}
if (o.crlf)
fix_line_endings((char *) buf, &n, &tempbuf, &crlf_state);
pending = 0;
} else {
/* From a connected socket, not stdin. */
n = ncat_recv(fdn, buf, sizeof(buf), &pending);
if (n <= 0) {
if (o.debug)
logdebug("Closing connection.\n");
#ifdef HAVE_OPENSSL
if (o.ssl && fdn->ssl) {
if (n == 0)
SSL_shutdown(fdn->ssl);
SSL_free(fdn->ssl);
}
#endif
close(recv_fd);
FD_CLR(recv_fd, &master_readfds);
rm_fd(&client_fdlist, recv_fd);
FD_CLR(recv_fd, &master_broadcastfds);
rm_fd(&broadcast_fdlist, recv_fd);
conn_inc--;
if (conn_inc == 0)
FD_CLR(STDIN_FILENO, &master_readfds);
if (o.chat)
chat_announce_disconnect(recv_fd);
return;
}
}
if (o.debug > 1)
logdebug("Handling data from client %d.\n", recv_fd);
chatbuf = NULL;
/* tempbuf is in use if we read from STDIN and fixed EOL */
if (tempbuf == NULL)
outbuf = buf;
else
outbuf = tempbuf;
if (o.chat) {
chatbuf = chat_filter(outbuf, n, recv_fd, &n);
if (chatbuf == NULL) {
if (o.verbose)
logdebug("Error formatting chat message from fd %d\n", recv_fd);
} else {
outbuf = chatbuf;
}
}
/* Send to everyone except the one who sent this message. */
broadcastfds = master_broadcastfds;
FD_CLR(recv_fd, &broadcastfds);
ncat_broadcast(&broadcastfds, &broadcast_fdlist, outbuf, n);
free(chatbuf);
free(tempbuf);
tempbuf = NULL;
} while (pending);
}
/* Announce the new connection and who is already connected. */
static int chat_announce_connect(int fd, const union sockaddr_u *su)
{
char *buf = NULL;
size_t size = 0, offset = 0;
int i, count, ret;
strbuf_sprintf(&buf, &size, &offset,
"<announce> %s is connected as <user%d>.\n", inet_socktop(su), fd);
strbuf_sprintf(&buf, &size, &offset, "<announce> already connected: ");
count = 0;
for (i = 0; i < client_fdlist.fdmax; i++) {
union sockaddr_u su;
socklen_t len = sizeof(su.storage);
if (i == fd || !FD_ISSET(i, &master_broadcastfds))
continue;
if (getpeername(i, &su.sockaddr, &len) == -1)
bye("getpeername for sd %d failed: %s.", strerror(errno));
if (count > 0)
strbuf_sprintf(&buf, &size, &offset, ", ");
strbuf_sprintf(&buf, &size, &offset, "%s as <user%d>", inet_socktop(&su), i);
count++;
}
if (count == 0)
strbuf_sprintf(&buf, &size, &offset, "nobody");
strbuf_sprintf(&buf, &size, &offset, ".\n");
ret = ncat_broadcast(&master_broadcastfds, &broadcast_fdlist, buf, offset);
free(buf);
return ret;
}
static int chat_announce_disconnect(int fd)
{
char buf[128];
int n;
n = Snprintf(buf, sizeof(buf),
"<announce> <user%d> is disconnected.\n", fd);
if (n >= sizeof(buf) || n < 0)
return -1;
return ncat_broadcast(&master_broadcastfds, &broadcast_fdlist, buf, n);
}
/*
* This is stupid. But it's just a bit of fun.
*
* The file descriptor of the sender is prepended to the
* message sent to clients, so you can distinguish
* each other with a degree of sanity. This gives a
* similar effect to an IRC session. But stupider.
*/
static char *chat_filter(char *buf, size_t size, int fd, int *nwritten)
{
char *result = NULL;
size_t n = 0;
const char *p;
int i;
n = 32;
result = (char *) safe_malloc(n);
i = Snprintf(result, n, "<user%d> ", fd);
/* Escape control characters. */
for (p = buf; p - buf < size; p++) {
char repl[32];
int repl_len;
if (isprint((int) (unsigned char) *p) || *p == '\r' || *p == '\n' || *p == '\t') {
repl[0] = *p;
repl_len = 1;
} else {
repl_len = Snprintf(repl, sizeof(repl), "\\%03o", (unsigned char) *p);
}
if (i + repl_len > n) {
n = (i + repl_len) * 2;
result = (char *) safe_realloc(result, n + 1);
}
memcpy(result + i, repl, repl_len);
i += repl_len;
}
/* Trim to length. (Also does initial allocation when str is empty.) */
result = (char *) safe_realloc(result, i + 1);
result[i] = '\0';
*nwritten = i;
return result;
}

90
ncat/ncat_listen.h Normal file
View File

@@ -0,0 +1,90 @@
/***************************************************************************
* ncat_listen.h *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
extern int ncat_listen(void);

801
ncat/ncat_main.c Normal file
View File

@@ -0,0 +1,801 @@
/***************************************************************************
* ncat_main.c -- main function: option parsing and checking, dispatching *
* to mode-specific functions. *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include "nsock.h"
#include "ncat.h"
#include "util.h"
#include "sys_wrap.h"
#include <getopt.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#ifndef WIN32
#include <netdb.h>
#endif
#include <fcntl.h>
#ifdef HAVE_OPENSSL
#include <openssl/ssl.h>
#include <openssl/err.h>
#endif
static int ncat_connect_mode(void);
static int ncat_listen_mode(void);
/* Determines if it's parsing HTTP or SOCKS by looking at defport */
static void parseproxy(char *str, struct sockaddr_storage *ss, unsigned short defport)
{
char *c = strrchr(str, ':'), *ptr;
int httpproxy = (defport == DEFAULT_PROXY_PORT);
unsigned short portno;
size_t sslen;
ptr = str;
if (c)
*c = 0;
if (c && strlen((c + 1)))
portno = (unsigned short) atoi(c + 1);
else
portno = defport;
if (!resolve(ptr, portno, ss, &sslen, o.af)) {
loguser("Could not resolve proxy \"%s\".\n", ptr);
if (o.af == AF_INET6 && httpproxy)
loguser("Did you specify the port number? It's required for IPv6.\n");
exit(EXIT_FAILURE);
}
}
/* These functions implement a simple linked list to hold allow/deny
specifications until the end of option parsing. */
struct host_list_node {
/* If false, then spec is the name of a file containing host patterns. */
int is_filename;
char *spec;
struct host_list_node *next;
};
static void host_list_add_spec(struct host_list_node **list, char *spec)
{
struct host_list_node *node = (struct host_list_node *) safe_malloc(sizeof(*node));
node->is_filename = 0;
node->spec = spec;
node->next = *list;
*list = node;
}
static void host_list_add_filename(struct host_list_node **list, char *filename)
{
struct host_list_node *node = (struct host_list_node *) safe_malloc(sizeof(*node));
node->is_filename = 1;
node->spec = filename;
node->next = *list;
*list = node;
}
static void host_list_free(struct host_list_node *list)
{
struct host_list_node *next;
for ( ; list != NULL; list = next) {
next = list->next;
free(list);
}
}
static void host_list_to_set(struct addrset *set, struct host_list_node *list)
{
struct host_list_node *node;
for (node = list; node != NULL; node = node->next) {
if (node->is_filename) {
FILE *fd;
fd = fopen(node->spec, "r");
if (fd == NULL)
bye("can't open %s: %s.", node->spec, strerror(errno));
if (!addrset_add_file(set, fd, o.af, !o.nodns))
bye("error in hosts file %s.", node->spec);
fclose(fd);
} else {
char *spec, *commalist;
commalist = node->spec;
while ((spec = strtok(commalist, ",")) != NULL) {
commalist = NULL;
if (!addrset_add_spec(set, spec, o.af, !o.nodns))
bye("error in host specification \"%s\".", node->spec);
}
}
}
}
static void print_banner(void)
{
loguser("Version %s ( %s )\n", NCAT_VERSION, NCAT_URL);
}
int main(int argc, char *argv[])
{
/* We have to buffer the lists of hosts to allow and deny until after option
parsing is done. Adding hosts to an addrset can require name resolution,
which may differ as a result of options like -n and -6. */
struct host_list_node *allow_host_list = NULL;
struct host_list_node *deny_host_list = NULL;
int srcport = -1;
char *source = NULL;
char *proxyaddr = NULL;
struct option long_options[] = {
{"4", no_argument, NULL, '4'},
{"6", no_argument, NULL, '6'},
{"crlf", no_argument, NULL, 'C'},
{"g", required_argument, NULL, 'g'},
{"G", required_argument, NULL, 'G'},
{"exec", required_argument, NULL, 'e'},
{"sh-exec", required_argument, NULL, 'c'},
{"max-conns", required_argument, NULL, 'm'},
{"help", no_argument, NULL, 'h'},
{"delay", required_argument, NULL, 'd'},
{"listen", no_argument, NULL, 'l'},
{"output", required_argument, NULL, 'o'},
{"hex-dump", required_argument, NULL, 'x'},
{"append-output", no_argument, NULL, 0},
{"idle-timeout", required_argument, NULL, 'i'},
{"keep-open", no_argument, NULL, 'k'},
{"recv-only", no_argument, &o.recvonly, 1},
{"source-port", required_argument, NULL, 'p'},
{"source", required_argument, NULL, 's'},
{"send-only", no_argument, &o.sendonly, 1},
{"broker", no_argument, NULL, 0},
{"chat", no_argument, NULL, 0},
{"talk", no_argument, NULL, 0},
{"deny", required_argument, NULL, 0},
{"denyfile", required_argument, NULL, 0},
{"allow", required_argument, NULL, 0},
{"allowfile", required_argument, NULL, 0},
{"telnet", no_argument, NULL, 't'},
{"udp", no_argument, NULL, 'u'},
{"sctp", no_argument, &o.sctp, 1},
{"version", no_argument, NULL, 0},
{"verbose", no_argument, NULL, 'v'},
{"wait", required_argument, NULL, 'w'},
{"nodns", no_argument, NULL, 'n'},
{"proxy", required_argument, NULL, 0},
{"proxy-type", required_argument, NULL, 0},
{"proxy-auth", required_argument, NULL, 0},
#ifdef HAVE_OPENSSL
{"ssl", no_argument, &o.ssl, 1},
{"ssl-cert", required_argument, NULL, 0},
{"ssl-key", required_argument, NULL, 0},
{"ssl-verify", no_argument, NULL, 0},
{"ssl-trustfile", required_argument, NULL, 0},
#endif
{0, 0, 0, 0}
};
gettimeofday(&start_time, NULL);
/* Set default options. */
options_init();
#ifdef WIN32
windows_init();
#endif
while (1) {
/* handle command line arguments */
int option_index;
int c = getopt_long(argc, argv, "46Cc:e:g:G:i:km:hp:d:lo:x:ts:uvw:n",
long_options, &option_index);
/* That's the end of the options. */
if (c == -1)
break;
switch (c) {
case '4':
o.af = AF_INET;
break;
case '6':
#ifdef HAVE_IPV6
o.af = AF_INET6;
#else
bye("-6 chosen when IPv6 wasn't compiled in.");
#endif
break;
case 'C':
o.crlf = 1;
break;
case 'c':
o.cmdexec = optarg;
o.shellexec = 1;
break;
case 'e':
o.cmdexec = optarg;
break;
case 'g': {
char *a = strtok(optarg, ",");
do {
union sockaddr_u addr;
size_t sslen;
if (!resolve(a, 0, &addr.storage, &sslen, AF_INET))
bye("Sorry, could not resolve source route hop %s.", a);
o.srcrtes[o.numsrcrtes] = addr.in.sin_addr;
} while (o.numsrcrtes++ <= 8 && (a = strtok(NULL, ",")));
if (o.numsrcrtes > 8)
bye("Sorry, you gave too many source route hops.");
break;
}
case 'G':
o.srcrteptr = atoi(optarg);
if (o.srcrteptr < 4 || (o.srcrteptr % 4) || o.srcrteptr > 28)
bye("Invalid source-route hop pointer %d.", o.srcrteptr);
break;
case 'k':
o.keepopen = 1;
break;
case 'm':
o.conn_limit = atoi(optarg);
break;
case 'd':
o.linedelay = tval2msecs(optarg);
if (o.linedelay <= 0)
bye("Invalid -d delay (must be greater than 0).", optarg);
if (o.linedelay >= 100 * 1000 && tval_unit(optarg) == NULL)
bye("Since April 2010, the default unit for -d is seconds, so your time of \"%s\" is %.1f minutes. Use \"%sms\" for %g milliseconds.", optarg, o.linedelay / 1000.0 / 60, optarg, o.linedelay / 1000.0);
break;
case 'o':
o.normlog = optarg;
break;
case 'x':
o.hexlog = optarg;
break;
case 'p':
srcport = atoi(optarg);
if (srcport < 0 || srcport > 0xffff)
bye("Invalid source port %d.", srcport);
break;
case 'i':
o.idletimeout = tval2msecs(optarg);
if (o.idletimeout <= 0)
bye("Invalid -i timeout (must be greater than 0).");
if (o.linedelay >= 100 * 1000 && tval_unit(optarg) == NULL)
bye("Since April 2010, the default unit for -i is seconds, so your time of \"%s\" is %.1f minutes. Use \"%sms\" for %g milliseconds.", optarg, o.linedelay / 1000.0 / 60, optarg, o.linedelay / 1000.0);
break;
case 's':
source = optarg;
break;
case 'l':
o.listen = 1;
break;
case 'u':
o.udp = 1;
break;
case 'v':
/* One -v activites verbose, after that it's debugging. */
if (o.verbose == 0)
o.verbose++;
else
o.debug++;
break;
case 'n':
o.nodns = 1;
break;
case 'w':
o.conntimeout = tval2msecs(optarg);
if (o.conntimeout <= 0)
bye("Invalid -w timeout (must be greater than 0).");
if (o.linedelay >= 100 * 1000 && tval_unit(optarg) == NULL)
bye("Since April 2010, the default unit for -w is seconds, so your time of \"%s\" is %.1f minutes. Use \"%sms\" for %g milliseconds.", optarg, o.linedelay / 1000.0 / 60, optarg, o.linedelay / 1000.0);
break;
case 't':
o.telnet = 1;
break;
case 0:
if (strcmp(long_options[option_index].name, "version") == 0) {
print_banner();
exit(EXIT_SUCCESS);
}
else if (strcmp(long_options[option_index].name, "proxy") == 0)
{
if (proxyaddr)
bye("You can't specify more than one --proxy.");
proxyaddr = Strdup(optarg);
}
else if (strcmp(long_options[option_index].name, "proxy-type") == 0)
{
if (o.proxytype)
bye("You can't specify more than one --proxy-type.");
o.proxytype = Strdup(optarg);
}
else if (strcmp(long_options[option_index].name, "proxy-auth") == 0)
{
if (o.proxy_auth)
bye("You can't specify more than one --proxy-auth.");
o.proxy_auth = Strdup(optarg);
}
else if (strcmp(long_options[option_index].name, "broker") == 0)
{
o.broker = 1;
/* --broker implies --listen. */
o.listen = 1;
}
else if (strcmp(long_options[option_index].name, "chat") == 0
|| strcmp(long_options[option_index].name, "talk") == 0)
{
/* --talk is an older name for --chat. */
o.chat = 1;
/* --chat implies --broker. */
o.broker = 1;
}
else if (strcmp(long_options[option_index].name, "allow") == 0)
{
o.allow = 1;
host_list_add_spec(&allow_host_list, optarg);
}
else if (strcmp(long_options[option_index].name, "allowfile") == 0)
{
o.allow = 1;
host_list_add_filename(&allow_host_list, optarg);
}
else if (strcmp(long_options[option_index].name, "deny") == 0)
{
host_list_add_spec(&deny_host_list, optarg);
}
else if (strcmp(long_options[option_index].name, "denyfile") == 0)
{
host_list_add_filename(&deny_host_list, optarg);
}
else if (strcmp(long_options[option_index].name, "append-output") == 0)
{
o.append = 1;
}
#ifdef HAVE_OPENSSL
else if (strcmp(long_options[option_index].name, "ssl-cert") == 0)
{
o.ssl = 1;
o.sslcert = Strdup(optarg);
}
else if (strcmp(long_options[option_index].name, "ssl-key") == 0)
{
o.ssl = 1;
o.sslkey = Strdup(optarg);
}
else if (strcmp(long_options[option_index].name, "ssl-verify") == 0)
{
o.sslverify = 1;
o.ssl = 1;
}
else if (strcmp(long_options[option_index].name, "ssl-trustfile") == 0)
{
o.ssl = 1;
if (o.ssltrustfile != NULL)
bye("The --ssl-trustfile option may be given only once.");
o.ssltrustfile = Strdup(optarg);
/* If they list a trustfile assume they want certificate
verification. */
o.sslverify = 1;
}
#endif
break;
case 'h':
printf("%s %s ( %s )\n", NCAT_NAME, NCAT_VERSION, NCAT_URL);
printf(
"Usage: ncat [options] [hostname] [port]\n"
"\n"
"Options taking a time assume seconds. Append 'ms' for milliseconds,\n"
"'s' for seconds, 'm' for minutes, or 'h' for hours (e.g. 500ms).\n"
" -4 Use IPv4 only\n"
" -6 Use IPv6 only\n"
" -C, --crlf Use CRLF for EOL sequence\n"
" -c, --sh-exec <command> Executes the given command via /bin/sh\n"
" -e, --exec <command> Executes the given command\n"
" -g hop1[,hop2,...] Loose source routing hop points (8 max)\n"
" -G <n> Loose source routing hop pointer (4, 8, 12, ...)\n"
" -m, --max-conns <n> Maximum <n> simultaneous connections\n"
" -h, --help Display this help screen\n"
" -d, --delay <time> Wait between read/writes\n"
" -o, --output <filename> Dump session data to a file\n"
" -x, --hex-dump <filename> Dump session data as hex to a file\n"
" -i, --idle-timeout <time> Idle read/write timeout\n"
" -p, --source-port port Specify source port to use\n"
" -s, --source addr Specify source address to use (doesn't affect -l)\n"
" -l, --listen Bind and listen for incoming connections\n"
" -k, --keep-open Accept multiple connections in listen mode\n"
" -n, --nodns Do not resolve hostnames via DNS\n"
" -t, --telnet Answer Telnet negotiations\n"
" -u, --udp Use UDP instead of default TCP\n"
" --sctp Use SCTP instead of default TCP\n"
" -v, --verbose Set verbosity level (can be used up to 3 times)\n"
" -w, --wait <time> Connect timeout\n"
" --append-output Append rather than clobber specified output files\n"
" --send-only Only send data, ignoring received; quit on EOF\n"
" --recv-only Only receive data, never send anything\n"
" --allow Allow only given hosts to connect to Ncat\n"
" --allowfile A file of hosts allowed to connect to Ncat\n"
" --deny Deny given hosts from connecting to Ncat\n"
" --denyfile A file of hosts denied from connecting to Ncat\n"
" --broker Enable Ncat's connection brokering mode\n"
" --chat Start a simple Ncat chat server\n"
" --proxy <addr[:port]> Specify address of host to proxy through\n"
" --proxy-type <type> Specify proxy type (\"http\" or \"socks4\")\n"
" --proxy-auth <auth> Authenticate with HTTP or SOCKS proxy server\n"
#ifdef HAVE_OPENSSL
" --ssl Connect or listen with SSL\n"
" --ssl-cert Specify SSL certificate file (PEM) for listening\n"
" --ssl-key Specify SSL private key (PEM) for listening\n"
" --ssl-verify Verify trust and domain name of certificates\n"
" --ssl-trustfile PEM file containing trusted SSL certificates\n"
#endif
" --version Display Ncat's version information and exit\n"
"\n"
"See the ncat(1) manpage for full options, descriptions and usage examples\n"
);
exit(EXIT_SUCCESS);
case '?':
/* Consider unrecognised parameters/arguments as fatal. */
bye("Try `--help' or man(1) ncat for more information, usage options and help.");
default:
/* We consider an unrecognised option fatal. */
bye("Unrecognised option.");
}
}
if (o.normlog)
o.normlogfd = ncat_openlog(o.normlog, o.append);
if (o.hexlog)
o.hexlogfd = ncat_openlog(o.hexlog, o.append);
if (o.verbose)
print_banner();
if (o.debug)
nbase_set_log(loguser, logdebug);
else
nbase_set_log(loguser, NULL);
/* Will be AF_INET or AF_INET6 when valid */
memset(&targetss.storage, 0, sizeof(targetss.storage));
targetss.storage.ss_family = AF_UNSPEC;
httpconnect.storage = socksconnect.storage = srcaddr.storage = targetss.storage;
/* Clear the listenaddrs array */
int i;
for (i = 0; i < NUM_LISTEN_ADDRS; i++) {
listenaddrs[i].storage = targetss.storage;
}
if (proxyaddr) {
if (!o.proxytype)
o.proxytype = Strdup("http");
if (!strcmp(o.proxytype, "http")) {
/* Parse HTTP proxy address and temporarily store it in httpconnect. If
* the proxy server is given as an IPv6 address (not hostname), the port
* number MUST be specified as well or parsing will break (due to the
* colons in the IPv6 address and host:port separator).
*/
parseproxy(proxyaddr, &httpconnect.storage, DEFAULT_PROXY_PORT);
} else if (!strcmp(o.proxytype, "socks4") || !strcmp(o.proxytype, "4")) {
/* Parse SOCKS proxy address and temporarily store it in socksconnect */
parseproxy(proxyaddr, &socksconnect.storage, DEFAULT_SOCKS4_PORT);
} else {
bye("Invalid proxy type \"%s\".", o.proxytype);
}
free(o.proxytype);
free(proxyaddr);
} else {
if (o.proxytype) {
if (!o.listen)
bye("Proxy type (--proxy-type) specified without proxy address (--proxy).");
if (strcmp(o.proxytype, "http"))
bye("Invalid proxy type \"%s\".", o.proxytype);
}
}
/* Default port */
o.portno = DEFAULT_NCAT_PORT;
/* Resolve the given source address */
if (source) {
if (o.listen)
bye("-l and -s are incompatible. Specify the address and port to bind to like you would a host to connect to.");
if (!resolve(source, 0, &srcaddr.storage, &srcaddrlen, o.af))
bye("Could not resolve source address %s.", source);
}
host_list_to_set(&o.allowset, allow_host_list);
host_list_free(allow_host_list);
host_list_to_set(&o.denyset, deny_host_list);
host_list_free(deny_host_list);
if (optind == argc) {
/* Listen defaults to any address and DEFAULT_NCAT_PORT */
if (!o.listen)
bye("You must specify a host to connect to.");
} else {
/* Resolve hostname if we're given one */
if (strspn(argv[optind], "0123456789") != strlen(argv[optind])) {
o.target = argv[optind];
/* resolve hostname */
if (!resolve(o.target, 0, &targetss.storage, &targetsslen, o.af))
bye("Could not resolve hostname %s.", o.target);
optind++;
} else {
if (!o.listen)
bye("You must specify a host to connect to.");
}
}
/* Whatever's left is the port number; there should be at most one. */
if (optind + 1 < argc || (o.listen && srcport != -1 && optind + 1 == argc)) {
loguser("Got more than one port specification:");
if (o.listen && srcport != -1)
loguser_noprefix(" %d", srcport);
for (; optind < argc; optind++)
loguser_noprefix(" %s", argv[optind]);
loguser_noprefix(". QUITTING.\n");
exit(2);
} else if (optind + 1 == argc) {
long long_port;
errno = 0;
long_port = strtol(argv[optind], NULL, 10);
if (errno != 0 || long_port <= 0 || long_port > 65535)
bye("Invalid port number \"%s\".", argv[optind]);
o.portno = (unsigned short) long_port;
}
if (o.af == AF_INET)
targetss.in.sin_port = htons(o.portno);
#ifdef HAVE_IPV6
else
targetss.in6.sin6_port = htons(o.portno);
#endif
if (srcport != -1) {
if (o.listen) {
/* Treat "ncat -l -p <port>" the same as "ncat -l <port>" for nc
compatibility. */
o.portno = srcport;
} else {
if (srcaddr.storage.ss_family == AF_UNSPEC) {
/* We have a source port but not an explicit source address;
fill in an unspecified address of the same family as the
target. */
srcaddr.storage.ss_family = targetss.storage.ss_family;
if (srcaddr.storage.ss_family == AF_INET)
srcaddr.in.sin_addr.s_addr = INADDR_ANY;
else if (srcaddr.storage.ss_family == AF_INET6)
srcaddr.in6.sin6_addr = in6addr_any;
}
if (srcaddr.storage.ss_family == AF_INET)
srcaddr.in.sin_port = htons(srcport);
#ifdef HAVE_IPV6
else
srcaddr.in6.sin6_port = htons(srcport);
#endif
}
}
/* Since the host we're actually *connecting* to is the proxy server, we
* need to reverse these address structures to avoid any further confusion
*/
if (httpconnect.storage.ss_family != AF_UNSPEC) {
union sockaddr_u tmp = targetss;
targetss = httpconnect;
httpconnect = tmp;
} else if (socksconnect.storage.ss_family != AF_UNSPEC) {
union sockaddr_u tmp = targetss;
targetss = socksconnect;
socksconnect = tmp;
}
if (o.udp) {
/* Don't allow a false sense of security if someone tries SSL over UDP. */
if (o.ssl)
bye("UDP mode does not support SSL.");
if (o.keepopen && o.cmdexec == NULL)
bye("UDP mode does not support the -k or --keep-open options, except with --exec or --sh-exec.");
if (o.broker)
bye("UDP mode does not support connection brokering.\n\
If this feature is important to you, write nmap-dev@insecure.org with a\n\
description of how you intend to use it, as an aid to deciding how UDP\n\
connection brokering should work.");
}
/* Do whatever is necessary to receive \n for line endings on input from
the console. A no-op on Unix. */
set_lf_mode();
if (o.listen)
return ncat_listen_mode();
else
return ncat_connect_mode();
}
/* connect error handling and operations. */
static int ncat_connect_mode(void) {
/*
* allow/deny commands with connect make no sense. If you don't want to
* connect to a host, don't try to.
*/
if (o.allow || o.deny)
bye("Invalid option combination: allow/deny with connect.");
/* o.conn_limit with 'connect' doesn't make any sense. */
if (o.conn_limit != -1)
bye("Invalid option combination: `--max-conns' with connect.");
if (o.chat)
bye("Invalid option combination: `--chat' with connect.");
if (o.keepopen)
bye("Invalid option combination: `--keep-open' with connect.");
return ncat_connect();
}
static int ncat_listen_mode(void) {
/* Can't 'listen' AND 'connect' to a proxy server at the same time. */
if (httpconnect.storage.ss_family != AF_UNSPEC || socksconnect.storage.ss_family != AF_UNSPEC)
bye("Invalid option combination: --proxy and -l.");
if (o.idletimeout != 0)
bye("An idle timeout only works in connect mode.");
if (o.broker && o.cmdexec != NULL)
bye("Invalid option combination: --broker and -e.");
if (o.proxytype != NULL && o.telnet)
bye("Invalid option combination: --telnet has no effect with --proxy-type.");
if (o.conn_limit != -1 && !(o.keepopen || o.broker))
loguser("Warning: Maximum connections ignored, since it does not take "
"effect without -k or --broker.\n");
/* Set the default maximum simultaneous TCP connection limit. */
if (o.conn_limit == -1)
o.conn_limit = DEFAULT_MAX_CONNS;
#ifndef WIN32
/* See if the shell is executable before we get deep into this */
if (o.shellexec && access("/bin/sh", X_OK) == -1)
bye("/bin/sh is not executable, so `-c' won't work.");
#endif
if (targetss.storage.ss_family != AF_UNSPEC) {
listenaddrs[num_listenaddrs++] = targetss;
} else {
size_t ss_len;
int rc;
/* No command-line address. Listen on IPv4 or IPv6 or both. */
/* Try to bind to IPv6 first; on AIX a bound IPv4 socket blocks an IPv6
socket on the same port, despite IPV6_V6ONLY. */
#ifdef HAVE_IPV6
if (o.af == AF_INET6 || o.af == AF_UNSPEC) {
ss_len = sizeof(listenaddrs[num_listenaddrs]);
rc = resolve("::", o.portno, &listenaddrs[num_listenaddrs].storage, &ss_len, AF_INET6);
if (!rc)
bye("Failed to resolve default IPv6 address.");
num_listenaddrs++;
}
#endif
if (o.af == AF_INET || o.af == AF_UNSPEC) {
ss_len = sizeof(listenaddrs[num_listenaddrs]);
rc = resolve("0.0.0.0", o.portno, &listenaddrs[num_listenaddrs].storage, &ss_len, AF_INET);
if (!rc)
bye("Failed to resolve default IPv4 address.");
num_listenaddrs++;
}
}
if (o.proxytype) {
if (strcmp(o.proxytype, "http") == 0)
o.httpserver = 1;
}
/* Fire the listen/select dispatcher for bog-standard listen operations. */
return ncat_listen();
}

357
ncat/ncat_posix.c Normal file
View File

@@ -0,0 +1,357 @@
/***************************************************************************
* ncat_posix.c -- POSIX-specific functions. *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include <assert.h>
#include "ncat.h"
char **cmdline_split(const char *cmdexec);
/* fork and exec a child process with netexec. Close the given file descriptor
in the parent process. Return the child's PID or -1 on error. */
int netrun(struct fdinfo *info, char *cmdexec)
{
int pid;
errno = 0;
pid = fork();
if (pid == 0) {
/* In the child process. */
netexec(info, cmdexec);
}
Close(info->fd);
if (pid == -1 && o.verbose)
logdebug("Error in fork: %s\n", strerror(errno));
return pid;
}
/* Call write in a loop until all the data is written or an error occurs. The
return value is the number of bytes written. If it is less than size, then
there was an error. */
static int write_loop(int fd, char *buf, size_t size)
{
char *p;
int n;
p = buf;
while (p - buf < size) {
n = write(fd, p, size - (p - buf));
if (n == -1) {
if (errno == EINTR)
continue;
else
break;
}
p += n;
}
return p - buf;
}
/* Run the given command line as if with exec. What we actually do is fork the
command line as a subprocess, then loop, relaying data between the socket and
the subprocess. This allows Ncat to handle SSL from the socket and give plain
text to the subprocess, and also allows things like logging and line delays.
Never returns. */
void netexec(struct fdinfo *info, char *cmdexec)
{
int child_stdin[2];
int child_stdout[2];
int pid;
int crlf_state;
char buf[DEFAULT_TCP_BUF_LEN];
int maxfd;
if (o.debug) {
if (o.shellexec)
logdebug("Executing with shell: %s\n", cmdexec);
else
logdebug("Executing: %s\n", cmdexec);
}
if (pipe(child_stdin) == -1 || pipe(child_stdout) == -1)
bye("Can't create child pipes: %s", strerror(errno));
pid = fork();
if (pid == -1)
bye("Error in fork: %s", strerror(errno));
if (pid == 0) {
/* This is the child process. Exec the command. */
close(child_stdin[1]);
close(child_stdout[0]);
/* rearrange stdin and stdout */
Dup2(child_stdin[0], STDIN_FILENO);
Dup2(child_stdout[1], STDOUT_FILENO);
if (o.shellexec) {
execl("/bin/sh", "sh", "-c", cmdexec, (void *) NULL);
} else {
char **cmdargs;
cmdargs = cmdline_split(cmdexec);
execv(cmdargs[0], cmdargs);
}
/* exec failed.*/
die("exec");
}
close(child_stdin[0]);
close(child_stdout[1]);
maxfd = child_stdout[0];
if (info->fd > maxfd)
maxfd = info->fd;
/* This is the parent process. Enter a "caretaker" loop that reads from the
socket and writes to the suprocess, and reads from the subprocess and
writes to the socket. We exit the loop on any read error (or EOF). On a
write error we just close the opposite side of the conversation. */
crlf_state = 0;
for (;;) {
fd_set fds;
int r, n_r, n_w;
FD_ZERO(&fds);
FD_SET(info->fd, &fds);
FD_SET(child_stdout[0], &fds);
r = fselect(maxfd + 1, &fds, NULL, NULL, NULL);
if (r == -1) {
if (errno == EINTR)
continue;
else
break;
}
if (FD_ISSET(info->fd, &fds)) {
int pending;
do {
n_r = ncat_recv(info, buf, sizeof(buf), &pending);
if (n_r <= 0)
goto loop_end;
n_w = write_loop(child_stdin[1], buf, n_r);
} while (pending);
}
if (FD_ISSET(child_stdout[0], &fds)) {
char *crlf = NULL, *wbuf;
n_r = read(child_stdout[0], buf, sizeof(buf));
if (n_r <= 0)
break;
wbuf = buf;
if (o.crlf) {
if (fix_line_endings((char *) buf, &n_r, &crlf, &crlf_state))
wbuf = crlf;
}
n_w = ncat_send(info, wbuf, n_r);
if (crlf != NULL)
free(crlf);
}
}
loop_end:
#ifdef HAVE_OPENSSL
if (info->ssl != NULL) {
SSL_shutdown(info->ssl);
SSL_free(info->ssl);
}
#endif
close(info->fd);
exit(0);
}
/*
* Split a command line into an array suitable for handing to execv.
*
* A note on syntax: words are split on whitespace and '\' escapes characters.
* '\\' will show up as '\' and '\ ' will leave a space, combining two
* words. Examples:
* "ncat\ experiment -l -k" will be parsed as the following tokens:
* "ncat experiment", "-l", "-k".
* "ncat\\ -l -k" will be parsed as "ncat\", "-l", "-k"
* See the test program, test/test-cmdline-split to see additional cases.
*/
char **cmdline_split(const char *cmdexec)
{
const char *ptr;
char *cur_arg, **cmd_args;
int max_tokens = 0, arg_idx = 0, ptr_idx = 0;
/* Figure out the maximum number of tokens needed */
ptr = cmdexec;
while (*ptr) {
// Find the start of the token
while (('\0' != *ptr) && isspace((int) (unsigned char) *ptr)) ptr++;
if ('\0' == *ptr) break;
max_tokens++;
// Find the start of the whitespace again
while (('\0' != *ptr) && !isspace((int) (unsigned char) *ptr)) ptr++;
}
/* The line is not empty so we've got something to deal with */
cmd_args = (char**)safe_malloc(sizeof(char*) * (max_tokens + 1));
cur_arg = (char*)Calloc(sizeof(char), strlen(cmdexec));
/* Get and copy the tokens */
ptr = cmdexec;
while (*ptr) {
while (('\0' != *ptr) && isspace((int) (unsigned char) *ptr)) ptr++;
if ('\0' == *ptr) break;
while (('\0' != *ptr) && !isspace((int) (unsigned char) *ptr)) {
if ('\\' == *ptr) {
ptr++;
if ('\0' == *ptr) break;
cur_arg[ptr_idx] = *ptr;
ptr_idx++;
ptr++;
if ('\\' != *(ptr - 1)) {
while (('\0' != *ptr) && isspace((int) (unsigned char) *ptr)) ptr++;
}
} else {
cur_arg[ptr_idx] = *ptr;
ptr_idx++;
ptr++;
}
}
cur_arg[ptr_idx] = '\0';
cmd_args[arg_idx] = strdup(cur_arg);
cur_arg[0] = '\0';
ptr_idx = 0;
arg_idx++;
}
cmd_args[arg_idx] = NULL;
/* Clean up */
free(cur_arg);
return cmd_args;
}
void set_lf_mode(void)
{
/* Nothing needed. */
}
#ifdef HAVE_OPENSSL
#define NCAT_CA_CERTS_PATH (NCAT_DATADIR "/" NCAT_CA_CERTS_FILE)
int ssl_load_default_ca_certs(SSL_CTX *ctx)
{
int rc;
if (o.debug)
logdebug("Using system default trusted CA certificates and those in %s.\n", NCAT_CA_CERTS_PATH);
/* Load distribution-provided defaults, if any. */
assert(SSL_CTX_set_default_verify_paths(ctx) > 0);
/* Also load the trusted certificates we ship. */
rc = SSL_CTX_load_verify_locations(ctx, NCAT_CA_CERTS_PATH, NULL);
if (rc != 1) {
if (o.debug)
logdebug("Unable to load trusted CA certificates from %s: %s\n",
NCAT_CA_CERTS_PATH, ERR_error_string(ERR_get_error(), NULL));
return -1;
}
return 0;
}
#endif

869
ncat/ncat_proxy.c Normal file
View File

@@ -0,0 +1,869 @@
/***************************************************************************
* ncat_proxy.c -- HTTP proxy server. *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include "base64.h"
#include "http.h"
#include "nsock.h"
#include "ncat.h"
#include "sys_wrap.h"
#ifndef WIN32
#include <unistd.h>
#endif
#ifndef WIN32
/* SIG_CHLD handler */
static void proxyreaper(int signo)
{
while (waitpid(-1, NULL, WNOHANG) > 0);
}
#endif
/* send a '\0'-terminated string. */
static int send_string(struct fdinfo *fdn, const char *s)
{
return fdinfo_send(fdn, s, strlen(s));
}
static void http_server_handler(int c);
static int send_proxy_authenticate(struct fdinfo *fdn, int stale);
static char *http_code2str(int code);
static void fork_handler(int s, int c);
static int handle_connect(struct socket_buffer *client_sock,
struct http_request *request);
static int handle_method(struct socket_buffer *client_sock,
struct http_request *request);
static int check_auth(const struct http_request *request,
const struct http_credentials *credentials, int *stale);
/*
* Simple forking HTTP proxy. It is an HTTP/1.0 proxy with knowledge of
* HTTP/1.1. (The things lacking for HTTP/1.1 are the chunked transfer encoding
* and the expect mechanism.) The proxy supports the CONNECT, GET, HEAD, and
* POST methods. It supports Basic and Digest authentication of clients (use the
* --proxy-auth option).
*
* HTTP/1.1 is defined in RFC 2616. Many comments refer to that document.
* http://tools.ietf.org/html/rfc2616
*
* HTTP authentication is discussed in RFC 2617.
* http://tools.ietf.org/html/rfc2617
*
* The CONNECT method is documented in an Internet draft and is specified as the
* way to proxy HTTPS in RFC 2817, section 5.
* http://tools.ietf.org/html/draft-luotonen-web-proxy-tunneling-01
* http://tools.ietf.org/html/rfc2817#section-5
*
* The CONNECT method is not limited to HTTP, but is potentially capable of
* connecting to any TCP port on any host. The proxy connection is requested
* with an HTTP request, but after that, the proxy does no interpretation of the
* data passing through it. See section 6 of the above mentioned draft for the
* security implications.
*/
int ncat_http_server(void)
{
int c, i, j;
int listen_socket[NUM_LISTEN_ADDRS];
socklen_t sslen;
union sockaddr_u conn;
#ifndef WIN32
Signal(SIGCHLD, proxyreaper);
#endif
#if HAVE_HTTP_DIGEST
http_digest_init_secret();
#endif
#ifdef HAVE_OPENSSL
if (o.ssl)
setup_ssl_listen();
#endif
/* Clear the socket list */
for (i = 0; i < NUM_LISTEN_ADDRS; i++)
listen_socket[i] = -1;
/* set for selecting listening sockets */
fd_set listen_fds;
fd_list_t listen_fdlist;
FD_ZERO(&listen_fds);
init_fdlist(&listen_fdlist, num_listenaddrs);
/* Listen on each address, set up lists for select */
for (i = 0; i < num_listenaddrs; i++) {
listen_socket[i] = do_listen(SOCK_STREAM, IPPROTO_TCP, &listenaddrs[i]);
/* make us not block on accepts in wierd cases. See ncat_listen.c:209 */
unblock_socket(listen_socket[i]);
/* setup select sets and max fd */
FD_SET(listen_socket[i], &listen_fds);
add_fd(&listen_fdlist, listen_socket[i]);
}
for (;;) {
fd_set read_fds;
sslen = sizeof(conn.storage);
/*
* We just select to get a list of sockets which we can talk to
*/
if (o.debug > 1)
logdebug("selecting, fdmax %d\n", listen_fdlist.fdmax);
read_fds = listen_fds;
int fds_ready = fselect(listen_fdlist.fdmax + 1, &read_fds, NULL, NULL, NULL);
if (o.debug > 1)
logdebug("select returned %d fds ready\n", fds_ready);
for (i = 0; i <= listen_fdlist.fdmax && fds_ready >0; i++) {
/* Loop through descriptors until there is something ready */
if (!FD_ISSET(i, &read_fds))
continue;
/* Check each listening socket */
for (j = 0; j < num_listenaddrs; j++) {
if (i == listen_socket[j]) {
fds_ready--;
c = accept(i, &conn.sockaddr, &sslen);
if (c == -1) {
if (errno == EINTR)
continue;
die("accept");
}
if (!allow_access(&conn)) {
Close(c);
continue;
}
if (o.debug > 1)
logdebug("forking handler for %d\n", i);
fork_handler(i, c);
}
}
}
}
return 0;
}
#ifdef WIN32
/* On Windows we don't actually fork but rather start a thread. */
static DWORD WINAPI handler_thread_func(void *data)
{
http_server_handler(*((int *) data));
free(data);
return 0;
}
static void fork_handler(int s, int c)
{
int *data;
HANDLE thread;
data = (int *) safe_malloc(sizeof(int));
*data = c;
thread = CreateThread(NULL, 0, handler_thread_func, data, 0, NULL);
if (thread == NULL) {
if (o.verbose)
logdebug("Error in CreateThread: %d\n", GetLastError());
free(data);
return;
}
CloseHandle(thread);
}
#else
static void fork_handler(int s, int c)
{
int rc;
rc = fork();
if (rc == -1) {
return;
} else if (rc == 0) {
Close(s);
if (!o.debug) {
Close(STDIN_FILENO);
Close(STDOUT_FILENO);
Close(STDERR_FILENO);
}
http_server_handler(c);
exit(0);
} else {
Close(c);
}
}
#endif
/* Is this one of the methods we can handle? */
static int method_is_known(const char *method)
{
return strcmp(method, "CONNECT") == 0
|| strcmp(method, "GET") == 0
|| strcmp(method, "HEAD") == 0
|| strcmp(method, "POST") == 0;
}
static void http_server_handler(int c)
{
int code;
struct socket_buffer sock;
struct http_request request;
char *buf;
socket_buffer_init(&sock, c);
#if HAVE_OPENSSL
if (o.ssl) {
sock.fdn.ssl = new_ssl(sock.fdn.fd);
if (SSL_accept(sock.fdn.ssl) != 1) {
loguser("Failed SSL connection: %s\n",
ERR_error_string(ERR_get_error(), NULL));
fdinfo_close(&sock.fdn);
return;
}
}
#endif
code = http_read_request_line(&sock, &buf);
if (code != 0) {
if (o.verbose)
logdebug("Error reading Request-Line.\n");
send_string(&sock.fdn, http_code2str(code));
fdinfo_close(&sock.fdn);
return;
}
if (o.debug > 1)
logdebug("Request-Line: %s", buf);
code = http_parse_request_line(buf, &request);
free(buf);
if (code != 0) {
if (o.verbose)
logdebug("Error parsing Request-Line.\n");
send_string(&sock.fdn, http_code2str(code));
fdinfo_close(&sock.fdn);
return;
}
if (!method_is_known(request.method)) {
if (o.debug > 1)
logdebug("Bad method: %s.\n", request.method);
http_request_free(&request);
send_string(&sock.fdn, http_code2str(405));
fdinfo_close(&sock.fdn);
return;
}
code = http_read_header(&sock, &buf);
if (code != 0) {
if (o.verbose)
logdebug("Error reading header.\n");
http_request_free(&request);
send_string(&sock.fdn, http_code2str(code));
fdinfo_close(&sock.fdn);
return;
}
if (o.debug > 1)
logdebug("Header:\n%s", buf);
code = http_request_parse_header(&request, buf);
free(buf);
if (code != 0) {
if (o.verbose)
logdebug("Error parsing header.\n");
http_request_free(&request);
send_string(&sock.fdn, http_code2str(code));
fdinfo_close(&sock.fdn);
return;
}
/* Check authentication. */
if (o.proxy_auth) {
struct http_credentials credentials;
int ret, stale;
if (http_header_get_proxy_credentials(request.header, &credentials) == NULL) {
/* No credentials or a parsing error. */
send_proxy_authenticate(&sock.fdn, 0);
http_request_free(&request);
fdinfo_close(&sock.fdn);
return;
}
ret = check_auth(&request, &credentials, &stale);
http_credentials_free(&credentials);
if (!ret) {
/* Password doesn't match. */
/* RFC 2617, section 1.2: "If a proxy does not accept the
credentials sent with a request, it SHOULD return a 407 (Proxy
Authentication Required). */
send_proxy_authenticate(&sock.fdn, stale);
http_request_free(&request);
fdinfo_close(&sock.fdn);
return;
}
}
if (strcmp(request.method, "CONNECT") == 0) {
code = handle_connect(&sock, &request);
} else if (strcmp(request.method, "GET") == 0
|| strcmp(request.method, "HEAD") == 0
|| strcmp(request.method, "POST") == 0) {
code = handle_method(&sock, &request);
} else {
code = 500;
}
http_request_free(&request);
if (code != 0) {
send_string(&sock.fdn, http_code2str(code));
fdinfo_close(&sock.fdn);
return;
}
fdinfo_close(&sock.fdn);
}
static int handle_connect(struct socket_buffer *client_sock,
struct http_request *request)
{
union sockaddr_u su;
size_t sslen = sizeof(su.storage);
int maxfd, s;
char *line;
size_t len;
fd_set m, r;
if (request->uri.port == -1) {
if (o.verbose)
logdebug("No port number in CONNECT URI.\n");
return 400;
}
if (o.debug > 1)
logdebug("CONNECT to %s:%hu.\n", request->uri.host, request->uri.port);
if (!resolve(request->uri.host, request->uri.port, &su.storage, &sslen, o.af)) {
if (o.debug)
logdebug("Can't resolve name %s.\n", request->uri.host);
return 504;
}
s = Socket(su.storage.ss_family, SOCK_STREAM, IPPROTO_TCP);
if (connect(s, &su.sockaddr, sslen) == -1) {
if (o.debug)
logdebug("Can't connect to %s.\n", inet_socktop(&su));
Close(s);
return 504;
}
send_string(&client_sock->fdn, http_code2str(200));
/* Clear out whatever is left in the socket buffer. The client may have
already sent the first part of its request to the origin server. */
line = socket_buffer_remainder(client_sock, &len);
if (send(s, line, len, 0) < 0) {
if (o.debug)
logdebug("Error sending %u leftover bytes: %s.\n", len, strerror(errno));
Close(s);
return 0;
}
maxfd = client_sock->fdn.fd < s ? s : client_sock->fdn.fd;
FD_ZERO(&m);
FD_SET(client_sock->fdn.fd, &m);
FD_SET(s, &m);
errno = 0;
while (!socket_errno() || socket_errno() == EINTR) {
char buf[DEFAULT_TCP_BUF_LEN];
int len, rc, numready;
r = m;
numready = fselect(maxfd + 1, &r, NULL, NULL, NULL);
zmem(buf, sizeof(buf));
if (FD_ISSET(client_sock->fdn.fd, &r)) {
do {
do {
len = fdinfo_recv(&client_sock->fdn, buf, sizeof(buf));
} while (len == -1 && socket_errno() == EINTR);
if (len <= 0)
goto end;
do {
rc = send(s, buf, len, 0);
} while (rc == -1 && socket_errno() == EINTR);
if (rc == -1)
goto end;
} while (fdinfo_pending(&client_sock->fdn));
}
if (FD_ISSET(s, &r)) {
do {
len = recv(s, buf, sizeof(buf), 0);
} while (len == -1 && socket_errno() == EINTR);
if (len <= 0)
goto end;
do {
rc = fdinfo_send(&client_sock->fdn, buf, len);
} while (rc == -1 && socket_errno() == EINTR);
if (rc == -1)
goto end;
}
}
end:
close(s);
return 0;
}
static int do_transaction(struct http_request *request,
struct socket_buffer *client_sock, struct socket_buffer *server_sock);
/* Generic handler for GET, HEAD, and POST methods. */
static int handle_method(struct socket_buffer *client_sock,
struct http_request *request)
{
struct socket_buffer server_sock;
union sockaddr_u su;
size_t sslen = sizeof(su.storage);
int code;
int s;
if (strcmp(request->uri.scheme, "http") != 0) {
if (o.verbose)
logdebug("Unknown scheme in URI: %s.\n", request->uri.scheme);
return 400;
}
if (request->uri.port == -1) {
if (o.verbose)
logdebug("Unknown port in URI.\n");
return 400;
}
if (!resolve(request->uri.host, request->uri.port, &su.storage, &sslen, o.af)) {
if (o.debug)
logdebug("Can't resolve name %s:%d.\n", request->uri.host, request->uri.port);
return 504;
}
/* RFC 2616, section 5.1.2: "In order to avoid request loops, a proxy MUST
be able to recognize all of its server names, including any aliases,
local variations, and the numeric IP address. */
if (request->uri.port == o.portno && addr_is_local(&su)) {
if (o.verbose)
logdebug("Proxy loop detected: %s:%d\n", request->uri.host, request->uri.port);
return 403;
}
s = Socket(su.storage.ss_family, SOCK_STREAM, IPPROTO_TCP);
if (connect(s, &su.sockaddr, sslen) == -1) {
if (o.debug)
logdebug("Can't connect to %s.\n", inet_socktop(&su));
Close(s);
return 504;
}
socket_buffer_init(&server_sock, s);
code = do_transaction(request, client_sock, &server_sock);
fdinfo_close(&server_sock.fdn);
if (code != 0)
return code;
return 0;
}
/* Do a GET, HEAD, or POST transaction. */
static int do_transaction(struct http_request *request,
struct socket_buffer *client_sock, struct socket_buffer *server_sock)
{
char buf[BUFSIZ];
struct http_response response;
char *line;
char *request_str, *response_str;
size_t len;
int code, n;
/* We don't handle the chunked transfer encoding, which in the absence of a
Content-Length is the only way we know the end of a request body. RFC
2616, section 4.4 says, "If a request contains a message-body and a
Content-Length is not given, the server SHOULD respond with 400 (bad
request) if it cannot determine the length of the message, or with 411
(length required) if it wishes to insist on receiving a valid
Content-Length." */
if (strcmp(request->method, "POST") == 0 && request->content_length == 0) {
if (o.debug)
logdebug("POST request with no Content-Length.\n");
return 400;
}
/* The version we use to talk to the server. */
request->version = HTTP_10;
/* Remove headers that only apply to our connection with the client. */
code = http_header_remove_hop_by_hop(&request->header);
if (code != 0) {
if (o.verbose)
logdebug("Error removing hop-by-hop headers.\n");
return code;
}
/* Build the Host header. */
if (request->uri.port == -1 || request->uri.port == 80)
n = Snprintf(buf, sizeof(buf), "%s", request->uri.host);
else
n = Snprintf(buf, sizeof(buf), "%s:%hu", request->uri.host, request->uri.port);
if (n < 0 || n >= sizeof(buf)) {
/* Request Entity Too Large. */
return 501;
}
request->header = http_header_set(request->header, "Host", buf);
request->header = http_header_set(request->header, "Connection", "close");
/* Send the request to the server. */
request_str = http_request_to_string(request, &len);
n = send(server_sock->fdn.fd, request_str, len, 0);
free(request_str);
if (n < 0)
return 504;
/* Send the request body, if any. Count up to Content-Length. */
while (request->bytes_transferred < request->content_length) {
n = socket_buffer_read(client_sock, buf, MIN(sizeof(buf), request->content_length - request->bytes_transferred));
if (n < 0)
return 504;
if (n == 0)
break;
request->bytes_transferred += n;
n = send(server_sock->fdn.fd, buf, n, 0);
if (n < 0)
return 504;
}
if (o.debug && request->bytes_transferred < request->content_length)
logdebug("Received only %lu request body bytes (Content-Length was %lu).\n", request->bytes_transferred, request->content_length);
/* Read the response. */
code = http_read_status_line(server_sock, &line);
if (o.debug > 1)
logdebug("Status-Line: %s", line);
if (code != 0) {
if (o.verbose)
logdebug("Error reading Status-Line.\n");
return 0;
}
code = http_parse_status_line(line, &response);
free(line);
if (code != 0) {
if (o.verbose)
logdebug("Error parsing Status-Line.\n");
return 0;
}
code = http_read_header(server_sock, &line);
if (code != 0) {
if (o.verbose)
logdebug("Error reading header.\n");
return 0;
}
if (o.debug > 1)
logdebug("Response header:\n%s", line);
code = http_response_parse_header(&response, line);
free(line);
if (code != 0) {
if (o.verbose)
logdebug("Error parsing response header.\n");
return 0;
}
/* The version we use to talk to the client. */
response.version = HTTP_10;
/* Remove headers that only apply to our connection with the server. */
code = http_header_remove_hop_by_hop(&response.header);
if (code != 0) {
if (o.verbose)
logdebug("Error removing hop-by-hop headers.\n");
return code;
}
response.header = http_header_set(response.header, "Connection", "close");
/* Send the response to the client. */
response_str = http_response_to_string(&response, &len);
n = fdinfo_send(&client_sock->fdn, response_str, len);
free(response_str);
if (n < 0) {
http_response_free(&response);
return 504;
}
/* If the Content-Length is 0, read until the connection is closed.
Otherwise read until the Content-Length. At this point it's too late to
return our own error code so return 0 in case of any error. */
while (response.content_length == 0
|| response.bytes_transferred < response.content_length) {
size_t remaining = response.content_length - response.bytes_transferred;
size_t count;
count = sizeof(buf);
if (response.content_length > 0 && remaining < count)
count = remaining;
n = socket_buffer_read(server_sock, buf, count);
if (n <= 0)
break;
response.bytes_transferred += n;
n = fdinfo_send(&client_sock->fdn, buf, n);
if (n < 0)
break;
}
http_response_free(&response);
return 0;
}
/* Send a 407 Proxy Authenticate Required response. */
static int send_proxy_authenticate(struct fdinfo *fdn, int stale)
{
char *buf = NULL;
size_t size = 0, offset = 0;
int n;
strbuf_append_str(&buf, &size, &offset, "HTTP/1.0 407 Proxy Authentication Required\r\n");
strbuf_append_str(&buf, &size, &offset, "Proxy-Authenticate: Basic realm=\"Ncat\"\r\n");
#if HAVE_HTTP_DIGEST
{
char *hdr;
hdr = http_digest_proxy_authenticate("Ncat", stale);
strbuf_sprintf(&buf, &size, &offset, "Proxy-Authenticate: %s\r\n", hdr);
free(hdr);
}
#endif
strbuf_append_str(&buf, &size, &offset, "\r\n");
if (o.debug > 1)
logdebug("RESPONSE:\n%s", buf);
n = send_string(fdn, buf);
free(buf);
return n;
}
static char *http_code2str(int code)
{
/* See RFC 2616, section 6.1.1 for status codes. */
switch (code) {
case 200:
return "HTTP/1.0 200 OK\r\n\r\n";
case 400:
return "HTTP/1.0 400 Bad Request\r\n\r\n";
case 403:
return "HTTP/1.0 403 Forbidden\r\n\r\n";
case 405:
/* RFC 2616, section 14.7 for Allow. */
return "\
HTTP/1.0 405 Method Not Allowed\r\n\
Allow: CONNECT, GET, HEAD, POST\r\n\
\r\n";
case 413:
return "HTTP/1.0 413 Request Entity Too Large\r\n\r\n";
case 501:
return "HTTP/1.0 501 Not Implemented\r\n\r\n";
case 504:
return "HTTP/1.0 504 Gateway Timeout\r\n\r\n";
default:
return "HTTP/1.0 500 Internal Server Error\r\n\r\n";
}
return NULL;
}
/* userpass is a user:pass string (the argument to --proxy-auth). value is the
value of the Proxy-Authorization header field. Returns 0 on authentication
failure and nonzero on success. *stale is set to 1 if HTTP Digest credentials
are valid but out of date. */
static int check_auth(const struct http_request *request,
const struct http_credentials *credentials, int *stale)
{
if (o.proxy_auth == NULL)
return 1;
*stale = 0;
if (credentials->scheme == AUTH_BASIC) {
char *expected;
int cmp;
if (credentials->u.basic == NULL)
return 0;
/* We don't decode the received password, we encode the expected
password and compare the encoded strings. */
expected = b64enc((unsigned char *) o.proxy_auth, strlen(o.proxy_auth));
cmp = strcmp(expected, credentials->u.basic);
free(expected);
return cmp == 0;
}
#if HAVE_HTTP_DIGEST
else if (credentials->scheme == AUTH_DIGEST) {
char *username, *password;
char *proxy_auth;
struct timeval nonce_tv, now;
int nonce_age;
int ret;
/* Split up the proxy auth argument. */
proxy_auth = Strdup(o.proxy_auth);
username = strtok(proxy_auth, ":");
password = strtok(NULL, ":");
if (password == NULL) {
free(proxy_auth);
return 0;
}
ret = http_digest_check_credentials(username, "Ncat", password,
request->method, credentials);
free(proxy_auth);
if (!ret)
return 0;
/* The nonce checks out as one we issued and it matches what we expect
given the credentials. Now check if it's too old. */
if (credentials->u.digest.nonce == NULL
|| http_digest_nonce_time(credentials->u.digest.nonce, &nonce_tv) == -1)
return 0;
gettimeofday(&now, NULL);
if (TIMEVAL_AFTER(nonce_tv, now))
return 0;
nonce_age = TIMEVAL_SEC_SUBTRACT(now, nonce_tv);
if (nonce_age > HTTP_DIGEST_NONCE_EXPIRY) {
if (o.verbose)
loguser("Nonce is %d seconds old; rejecting.\n", nonce_age);
*stale = 1;
return 0;
}
/* To prevent replays, here we should additionally check against a list
of recently used nonces, where "recently used nonce" is one that has
been used to successfully authenticate within the last
HTTP_DIGEST_NONCE_EXPIRY seconds. (Older than that and we don't need
to keep it in the list, because the expiry test above will catch it.
This isn't supported because the fork-and-process architecture of the
proxy server makes it hard for us to change state in the parent
process from here in the child. */
return 1;
}
#endif
else {
return 0;
}
}

99
ncat/ncat_proxy.h Normal file
View File

@@ -0,0 +1,99 @@
/***************************************************************************
* ncat_proxy.h *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
/* How long we will honor nonces we issue, in seconds. The client gets back a
407 with stale="true" if the nonce is valid but expired. Nonces are good only
once, so this is really a limit on how long we have to keep nonces on a
"used" list before forgetting them. */
#define HTTP_DIGEST_NONCE_EXPIRY 10
/*
* Simple forking HTTP proxy.
*/
extern int ncat_http_server(void);

614
ncat/ncat_ssl.c Normal file
View File

@@ -0,0 +1,614 @@
/***************************************************************************
* ncat_ssl.c -- SSL support functions. *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include "nbase.h"
#include "ncat_config.h"
#ifdef HAVE_OPENSSL
#include "nsock.h"
#include "ncat.h"
#include <assert.h>
#include <stdio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
/* Required for windows compilation to Eliminate APPLINK errors.
See http://www.openssl.org/support/faq.html#PROG2 */
#ifdef WIN32
#include <openssl/applink.c>
#endif
static SSL_CTX *sslctx;
static int ssl_gen_cert(X509 **cert, EVP_PKEY **key);
/* Parameters for automatic key and certificate generation. */
enum {
DEFAULT_KEY_BITS = 1024,
DEFAULT_CERT_DURATION = 60 * 60 * 24 * 365,
};
#define CERTIFICATE_COMMENT "Automatically generated by Ncat. See http://nmap.org/ncat/."
SSL_CTX *setup_ssl_listen(void)
{
const SSL_METHOD *method;
if (sslctx)
goto done;
SSL_library_init();
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
SSL_load_error_strings();
/* RAND_status initializes the random number generator through a variety of
platform-dependent methods, then returns 1 if there is enough entropy or
0 otherwise. This seems to be a good platform-independent way of seeding
the generator, as well as of refusing to continue without enough
entropy. */
if (!RAND_status())
bye("Failed to seed OpenSSL PRNG (RAND_status returned false).");
if (!(method = SSLv23_server_method()))
bye("SSLv23_server_method(): %s.", ERR_error_string(ERR_get_error(), NULL));
if (!(sslctx = SSL_CTX_new(method)))
bye("SSL_CTX_new(): %s.", ERR_error_string(ERR_get_error(), NULL));
SSL_CTX_set_options(sslctx, SSL_OP_ALL | SSL_OP_NO_SSLv2);
/* Secure ciphers list taken from Nsock. */
if (!SSL_CTX_set_cipher_list(sslctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"))
bye("Unable to set OpenSSL cipher list: %s", ERR_error_string(ERR_get_error(), NULL));
if (o.sslcert == NULL && o.sslkey == NULL) {
X509 *cert;
EVP_PKEY *key;
char digest_buf[SHA1_STRING_LENGTH + 1];
if (o.verbose)
loguser("Generating a temporary %d-bit RSA key. Use --ssl-key and --ssl-cert to use a permanent one.\n", DEFAULT_KEY_BITS);
if (ssl_gen_cert(&cert, &key) == 0)
bye("ssl_gen_cert(): %s.", ERR_error_string(ERR_get_error(), NULL));
if (o.verbose) {
assert(ssl_cert_fp_str_sha1(cert, digest_buf, sizeof(digest_buf)) != NULL);
loguser("SHA-1 fingerprint: %s\n", digest_buf);
}
if (SSL_CTX_use_certificate(sslctx, cert) != 1)
bye("SSL_CTX_use_certificate(): %s.", ERR_error_string(ERR_get_error(), NULL));
if (SSL_CTX_use_PrivateKey(sslctx, key) != 1)
bye("SSL_CTX_use_PrivateKey(): %s.", ERR_error_string(ERR_get_error(), NULL));
X509_free(cert);
EVP_PKEY_free(key);
} else {
if (o.sslcert == NULL || o.sslkey == NULL)
bye("The --ssl-key and --ssl-cert options must be used together.");
if (SSL_CTX_use_certificate_file(sslctx, o.sslcert, SSL_FILETYPE_PEM) != 1)
bye("SSL_CTX_use_certificate_file(): %s.", ERR_error_string(ERR_get_error(), NULL));
if (SSL_CTX_use_PrivateKey_file(sslctx, o.sslkey, SSL_FILETYPE_PEM) != 1)
bye("SSL_CTX_use_Privatekey_file(): %s.", ERR_error_string(ERR_get_error(), NULL));
}
done:
return sslctx;
}
SSL *new_ssl(int fd)
{
SSL *ssl;
if (!(ssl = SSL_new(sslctx)))
bye("SSL_new(): %s.", ERR_error_string(ERR_get_error(), NULL));
if (!SSL_set_fd(ssl, fd))
bye("SSL_set_fd(): %s.", ERR_error_string(ERR_get_error(), NULL));
return ssl;
}
/* Match a (user-supplied) hostname against a (certificate-supplied) name, which
may be a wildcard pattern. A wildcard pattern may contain only one '*', it
must be the entire leftmost component, and there must be at least two
components following it. len is the length of pattern; pattern may contain
null bytes so that len != strlen(pattern). */
static int wildcard_match(const char *pattern, const char *hostname, size_t len) {
if (pattern[0] == '*' && pattern[1] == '.') {
/* A wildcard pattern. */
const char *p, *h, *dot;
/* Skip the wildcard component. */
p = pattern + 2;
/* Ensure there are no more wildcard characters. */
if (memchr(p, '*', len - 2) != NULL)
return 0;
/* Ensure there's at least one more dot, not counting a dot at the
end. */
dot = strchr(p, '.');
if (dot == NULL || *(dot + 1) == '\0') {
if (o.debug > 1) {
logdebug("Wildcard name \"%s\" doesn't have at least two"
" components after the wildcard; rejecting.\n", pattern);
}
return 0;
}
/* Skip the leftmost hostname component. */
h = strchr(hostname, '.');
if (h == NULL)
return 0;
h++;
/* Compare what remains of the pattern and hostname. */
return len == strlen(h) + (p - pattern) && strcmp(p, h) == 0;
} else {
/* Normal string comparison. Check the name length because I'm concerned
about someone somehow embedding a '\0' in the subject and matching
against a shorter name. */
return len == strlen(hostname) && strcmp(pattern, hostname) == 0;
}
}
/* Match a hostname against the contents of a dNSName field of the
subjectAltName extension, if present. This is the preferred place for a
certificate to store its domain name, as opposed to in the commonName field.
It has the advantage that multiple names can be stored, so that one
certificate can match both "example.com" and "www.example.com".
If num_checked is not NULL, the number of dNSName fields that were checked
before returning will be stored in it. This is so you can distinguish between
the check failing because there were names but none matched, or because there
were no names to match. */
static int cert_match_dnsname(X509 *cert, const char *hostname,
unsigned int *num_checked)
{
X509_EXTENSION *ext;
STACK_OF(GENERAL_NAME) *gen_names;
const X509V3_EXT_METHOD *method;
unsigned char *data;
int i;
if (num_checked != NULL)
*num_checked = 0;
i = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1);
if (i < 0)
return 0;
/* If there's more than one subjectAltName extension, forget it. */
if (X509_get_ext_by_NID(cert, NID_subject_alt_name, i) >= 0)
return 0;
ext = X509_get_ext(cert, i);
/* See the function X509V3_EXT_print in the OpenSSL source for this method
of getting a string value from an extension. */
method = X509V3_EXT_get(ext);
if (method == NULL)
return 0;
/* We must copy this address into a temporary variable because ASN1_item_d2i
increments it. We don't want it to corrupt ext->value->data. */
data = ext->value->data;
/* Here we rely on the fact that the internal representation (the "i" in
"i2d") for NID_subject_alt_name is STACK_OF(GENERAL_NAME). Converting it
to a stack of CONF_VALUE with a i2v method is not satisfactory, because a
CONF_VALUE doesn't contain the length of the value so you can't know the
presence of null bytes. */
#if (OPENSSL_VERSION_NUMBER > 0x00907000L)
if (method->it != NULL) {
gen_names = (STACK_OF(GENERAL_NAME) *) ASN1_item_d2i(NULL,
(const unsigned char **) &data,
ext->value->length, ASN1_ITEM_ptr(method->it));
} else {
gen_names = (STACK_OF(GENERAL_NAME) *) method->d2i(NULL,
(const unsigned char **) &data,
ext->value->length);
}
#else
gen_names = (STACK_OF(GENERAL_NAME) *) method->d2i(NULL,
(const unsigned char **) &data,
ext->value->length);
#endif
if (gen_names == NULL)
return 0;
/* Look for a dNSName field with a matching hostname. There may be more than
one dNSName field. */
for (i = 0; i < sk_GENERAL_NAME_num(gen_names); i++) {
GENERAL_NAME *gen_name;
gen_name = sk_GENERAL_NAME_value(gen_names, i);
if (gen_name->type == GEN_DNS) {
if (o.debug > 1)
logdebug("Checking certificate DNS name \"%s\" against \"%s\".\n", ASN1_STRING_data(gen_name->d.dNSName), hostname);
if (num_checked != NULL)
(*num_checked)++;
if (wildcard_match((char *) ASN1_STRING_data(gen_name->d.dNSName), hostname, ASN1_STRING_length(gen_name->d.dNSName)))
return 1;
}
}
return 0;
}
/* Returns the number of contiguous blocks of bytes in pattern that do not
contain the '.' byte. */
static unsigned int num_components(const unsigned char *pattern, size_t len)
{
const unsigned char *p;
unsigned int count;
count = 0;
p = pattern;
for (;;) {
while (p - pattern < len && *p == '.')
p++;
if (p - pattern >= len)
break;
while (p - pattern < len && *p != '.')
p++;
count++;
}
return count;
}
/* Returns true if the a pattern is strictly less specific than the b
pattern. */
static int less_specific(const unsigned char *a, size_t a_len,
const unsigned char *b, size_t b_len)
{
/* Wildcard patterns are always less specific than non-wildcard patterns. */
if (memchr(a, '*', a_len) != NULL && memchr(b, '*', b_len) == NULL)
return 1;
if (memchr(a, '*', a_len) == NULL && memchr(b, '*', b_len) != NULL)
return 0;
return num_components(a, a_len) < num_components(b, b_len);
}
static int most_specific_commonname(X509_NAME *subject, const char **result)
{
ASN1_STRING *best, *cur;
int i;
i = -1;
best = NULL;
while ((i = X509_NAME_get_index_by_NID(subject, NID_commonName, i)) != -1) {
cur = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject, i));
/* We use "not less specific" instead of "more specific" to allow later
entries to supersede earlier ones. */
if (best == NULL
|| !less_specific(ASN1_STRING_data(cur), ASN1_STRING_length(cur),
ASN1_STRING_data(best), ASN1_STRING_length(best))) {
best = cur;
}
}
if (best == NULL) {
*result = NULL;
return -1;
} else {
*result = (char *) ASN1_STRING_data(best);
return ASN1_STRING_length(best);
}
}
/* Match a hostname against the contents of the "most specific" commonName field
of a certificate. The "most specific" term is used in RFC 2818 but is not
defined anywhere that I (David Fifield) can find. This is what it means in
Ncat: wildcard patterns are always less specific than non-wildcard patterns.
If both patterns are wildcard or both are non-wildcard, the one with more
name components is more specific. If two names have the same number of
components, the one that comes later in the certificate is more specific. */
static int cert_match_commonname(X509 *cert, const char *hostname)
{
X509_NAME *subject;
const char *commonname;
int n;
subject = X509_get_subject_name(cert);
if (subject == NULL)
return 0;
n = most_specific_commonname(subject, &commonname);
if (n < 0 || commonname == NULL)
/* No commonName found. */
return 0;
if (wildcard_match(commonname, hostname, n))
return 1;
if (o.verbose)
loguser("Certificate verification error: Connected to \"%s\", but certificate is for \"%s\".\n", hostname, commonname);
return 0;
}
/* Verify a host's name against the name in its certificate after connection.
If the verify mode is SSL_VERIFY_NONE, always returns true. Returns nonzero
on success. */
int ssl_post_connect_check(SSL *ssl, const char *hostname)
{
X509 *cert = NULL;
unsigned int num_checked;
if (SSL_get_verify_mode(ssl) == SSL_VERIFY_NONE)
return 1;
if (hostname == NULL)
return 0;
cert = SSL_get_peer_certificate(ssl);
if (cert == NULL)
return 0;
/* RFC 2818 (HTTP Over TLS): If a subjectAltName extension of type dNSName
is present, that MUST be used as the identity. Otherwise, the (most
specific) Common Name field in the Subject field of the certificate MUST
be used. Although the use of the Common Name is existing practice, it is
deprecated and Certification Authorities are encouraged to use the
dNSName instead. */
if (!cert_match_dnsname(cert, hostname, &num_checked)) {
/* If there were dNSNames, we're done. If not, try the commonNames. */
if (num_checked > 0 || !cert_match_commonname(cert, hostname)) {
X509_free(cert);
return 0;
}
}
X509_free(cert);
return SSL_get_verify_result(ssl) == X509_V_OK;
}
/* Generate a self-signed certificate and matching RSA keypair. References for
this code are the book Network Programming with OpenSSL, chapter 10, section
"Making Certificates"; and apps/req.c in the OpenSSL source. */
static int ssl_gen_cert(X509 **cert, EVP_PKEY **key)
{
RSA *rsa;
X509_NAME *subj;
X509_EXTENSION *ext;
X509V3_CTX ctx;
const char *commonName = "localhost";
char dNSName[128];
int rc;
*cert = NULL;
*key = NULL;
/* Generate a private key. */
*key = EVP_PKEY_new();
if (*key == NULL)
goto err;
do {
rsa = RSA_generate_key(DEFAULT_KEY_BITS, RSA_F4, NULL, NULL);
if (rsa == NULL)
goto err;
rc = RSA_check_key(rsa);
} while (rc == 0);
if (rc == -1)
bye("Error generating RSA key: %s", ERR_error_string(ERR_get_error(), NULL));
if (EVP_PKEY_assign_RSA(*key, rsa) == 0) {
RSA_free(rsa);
goto err;
}
/* Generate a certificate. */
*cert = X509_new();
if (*cert == NULL)
goto err;
if (X509_set_version(*cert, 2) == 0) /* Version 3. */
goto err;
ASN1_INTEGER_set(X509_get_serialNumber(*cert), get_random_u32() & 0x7FFFFFFF);
/* Set the commonName. */
subj = X509_get_subject_name(*cert);
if (o.target != NULL)
commonName = o.target;
if (X509_NAME_add_entry_by_txt(subj, "commonName", MBSTRING_ASC,
(unsigned char *) commonName, -1, -1, 0) == 0) {
goto err;
}
/* Set the dNSName. */
rc = Snprintf(dNSName, sizeof(dNSName), "DNS:%s", commonName);
if (rc < 0 || rc >= sizeof(dNSName))
goto err;
X509V3_set_ctx(&ctx, *cert, *cert, NULL, NULL, 0);
ext = X509V3_EXT_conf(NULL, &ctx, "subjectAltName", dNSName);
if (ext == NULL)
goto err;
if (X509_add_ext(*cert, ext, -1) == 0)
goto err;
/* Set a comment. */
ext = X509V3_EXT_conf(NULL, &ctx, "nsComment", CERTIFICATE_COMMENT);
if (ext == NULL)
goto err;
if (X509_add_ext(*cert, ext, -1) == 0)
goto err;
if (X509_set_issuer_name(*cert, X509_get_subject_name(*cert)) == 0
|| X509_gmtime_adj(X509_get_notBefore(*cert), 0) == 0
|| X509_gmtime_adj(X509_get_notAfter(*cert), DEFAULT_CERT_DURATION) == 0
|| X509_set_pubkey(*cert, *key) == 0) {
goto err;
}
/* Sign it. */
if (X509_sign(*cert, *key, EVP_sha1()) == 0)
goto err;
return 1;
err:
if (*cert != NULL)
X509_free(*cert);
if (*key != NULL)
EVP_PKEY_free(*key);
return 0;
}
/* Calculate a SHA-1 fingerprint of a certificate and format it as a
human-readable string. Returns strbuf or NULL on error. */
char *ssl_cert_fp_str_sha1(const X509 *cert, char *strbuf, size_t len)
{
unsigned char binbuf[SHA1_BYTES];
unsigned int n;
char *p;
unsigned int i;
if (len < SHA1_STRING_LENGTH + 1)
return NULL;
n = sizeof(binbuf);
if (X509_digest(cert, EVP_sha1(), binbuf, &n) != 1)
return NULL;
p = strbuf;
for (i = 0; i < n; i++) {
if (i > 0 && i % 2 == 0)
*p++ = ' ';
Snprintf(p, 3, "%02X", binbuf[i]);
p += 2;
}
assert(p - strbuf <= len);
*p = '\0';
return strbuf;
}
/* Tries to complete an ssl handshake on the socket received by fdinfo struct
if ssl is enabled on that socket. */
int ssl_handshake(struct fdinfo *sinfo)
{
int ret = 0;
int sslerr = 0;
if(sinfo == NULL) {
if (o.debug)
logdebug("ncat_ssl.c: Invoking ssl_handshake() with a NULL parameter "
"is a serious bug. Please fix it.\n");
return -1;
}
if(!o.ssl)
return -1;
/* Initialize the socket too if it isn't. */
if(!sinfo->ssl)
sinfo->ssl = new_ssl(sinfo->fd);
ret = SSL_accept(sinfo->ssl);
if(ret == 1)
return NCAT_SSL_HANDSHAKE_COMPLETED;
sslerr = SSL_get_error(sinfo->ssl, ret);
if(ret == -1) {
if(sslerr == SSL_ERROR_WANT_READ)
return NCAT_SSL_HANDSHAKE_PENDING_READ;
if(sslerr == SSL_ERROR_WANT_WRITE)
return NCAT_SSL_HANDSHAKE_PENDING_WRITE;
}
if (o.verbose) {
loguser("Failed SSL connection from %s: %s\n",
inet_socktop(&sinfo->remoteaddr),
ERR_error_string(ERR_get_error(), NULL));
}
return NCAT_SSL_HANDSHAKE_FAILED;
}
#endif

128
ncat/ncat_ssl.h Normal file
View File

@@ -0,0 +1,128 @@
/***************************************************************************
* ncat_ssl.h *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include "ncat_config.h"
#ifdef HAVE_OPENSSL
#include <openssl/ssl.h>
#include <openssl/err.h>
#define NCAT_CA_CERTS_FILE "ca-bundle.crt"
enum {
SHA1_BYTES = 160 / 8,
/* 40 bytes for hex digits and 9 bytes for ' '. */
SHA1_STRING_LENGTH = SHA1_BYTES * 2 + (SHA1_BYTES / 2 - 1)
};
/* These status variables are returned by ssl_handshake() to describe the
* status of a pending non-blocking ssl handshake(SSL_accept()). */
enum {
NCAT_SSL_HANDSHAKE_COMPLETED = 0,
NCAT_SSL_HANDSHAKE_PENDING_READ = 1,
NCAT_SSL_HANDSHAKE_PENDING_WRITE = 2,
NCAT_SSL_HANDSHAKE_FAILED = 3
};
extern SSL_CTX *setup_ssl_listen(void);
extern SSL *new_ssl(int fd);
extern int ssl_post_connect_check(SSL *ssl, const char *hostname);
extern char *ssl_cert_fp_str_sha1(const X509 *cert, char *strbuf, size_t len);
extern int ssl_load_default_ca_certs(SSL_CTX *ctx);
/* Try to complete an ssl handshake in a non-blocking way for the socket given
* in sinfo. Initialize the socket too with new_ssl() if it hasn't been done
* already. */
extern int ssl_handshake(struct fdinfo *sinfo);
#endif

138
ncat/ncat_win.c Normal file
View File

@@ -0,0 +1,138 @@
/***************************************************************************
* ncat_win.c -- Windows-specific functions. *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include "nbase.h"
#include "ncat.h"
void set_lf_mode(void)
{
/* _O_TEXT (the default setting) converts \r\n to \n on input, making the
terminal look like a Unix terminal. However, use _O_BINARY if stdin is
not a terminal, to avoid breaking data from a pipe or other source. */
if (isatty(STDIN_FILENO))
_setmode(STDIN_FILENO, _O_TEXT);
else
_setmode(STDIN_FILENO, _O_BINARY);
/* Do not translate \n to \r\n on output. */
_setmode(STDOUT_FILENO, _O_BINARY);
}
#ifdef HAVE_OPENSSL
int ssl_load_default_ca_certs(SSL_CTX *ctx)
{
char buf[1024];
char *bundlename;
int n, rc;
size_t size, offset;
/* Get the executable's filename. */
n = GetModuleFileName(GetModuleHandle(0), buf, sizeof(buf));
if (n == 0 || n == sizeof(buf))
return -1;
bundlename = path_get_dirname(buf);
bundlename = (char *) safe_realloc(bundlename, 1024);
offset = strlen(bundlename);
size = offset + 1;
strbuf_sprintf(&bundlename, &size, &offset, "\\%s", NCAT_CA_CERTS_FILE);
if (o.debug)
logdebug("Using trusted CA certificates from %s.\n", bundlename);
rc = SSL_CTX_load_verify_locations(ctx, bundlename, NULL);
if (rc != 1) {
if (o.debug)
logdebug("Unable to load trusted CA certificates from %s: %s\n",
bundlename, ERR_error_string(ERR_get_error(), NULL));
}
free(bundlename);
return rc == 1 ? 0 : -1;
}
#endif

101
ncat/sockaddr_u.h Normal file
View File

@@ -0,0 +1,101 @@
/***************************************************************************
* sockaddr_u.h -- a union containing sockaddr types compatible with C99 *
* strict-aliasing rules. *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id:$ */
#ifndef SOCKADDR_U_H_
#define SOCKADDR_U_H_
union sockaddr_u {
struct sockaddr_storage storage;
struct sockaddr_in in;
struct sockaddr_in6 in6;
struct sockaddr sockaddr;
};
#endif

243
ncat/sys_wrap.c Normal file
View File

@@ -0,0 +1,243 @@
/***************************************************************************
* sys_wrap.c -- Error-checked wrappers around common functions. *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include <limits.h>
#include "sys_wrap.h"
#include "util.h"
void *Calloc(size_t nmemb, size_t size)
{
void *ret;
/* older libcs don't check for int overflow */
smul(nmemb, size);
ret = calloc(nmemb, size);
if (ret == NULL)
die("calloc");
return ret;
}
int Close(int fd)
{
if (close(fd) < 0)
die("close");
return 0;
}
int Connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen)
{
if (connect(sockfd, serv_addr, addrlen) < 0)
die("connect");
return 0;
}
int Dup2(int oldfd, int newfd)
{
int ret;
ret = dup2(oldfd, newfd);
if (ret < 0)
die("dup2");
return ret;
}
int Listen(int s, int backlog)
{
if (listen(s, backlog) < 0)
die("listen");
return 0;
}
int Open(const char *pathname, int flags, mode_t mode)
{
int ret;
ret = open(pathname, flags, mode);
if (ret < 0)
die("open");
return ret;
}
ssize_t Read(int fd, void *buf, size_t count)
{
ssize_t ret;
ret = read(fd, buf, count);
if (ret < 0)
die("read");
return ret;
}
ssize_t Recv(int s, void *buf, size_t len, int flags)
{
ssize_t ret;
ret = recv(s, (char*)buf, len, flags);
if (ret < 0)
die("recv");
return ret;
}
ssize_t Recvfrom(int s, void *buf, size_t len, int flags,
struct sockaddr *from, socklen_t *fromlen)
{
ssize_t ret;
ret = recvfrom(s, (char*)buf, len, flags, from, fromlen);
if (ret < 0)
die("recvfrom");
return ret;
}
int Setsockopt(int s, int level, int optname, const void *optval,
socklen_t optlen)
{
int ret;
ret = setsockopt(s, level, optname, (const char*)optval, optlen);
if (ret < 0)
die("setsockopt");
return ret;
}
sighandler_t Signal(int signum, sighandler_t handler)
{
sighandler_t ret;
ret = signal(signum, handler);
if (ret == SIG_ERR)
die("signal");
return ret;
}
int Socket(int domain, int type, int protocol)
{
int ret;
ret = socket(domain, type, protocol);
if (ret < 0)
die("socket");
return ret;
}
char *Strdup(const char *s)
{
char *ret;
ret = strdup(s);
if (ret == NULL)
die("strdup");
return ret;
}
ssize_t Write(int fd, const void *buf, size_t count)
{
ssize_t ret = write(fd, buf, count);
if (ret < 0) /* we don't bail if < count bytes written */
die("write");
return ret;
}

143
ncat/sys_wrap.h Normal file
View File

@@ -0,0 +1,143 @@
/***************************************************************************
* sys_wrap.h *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#ifndef SYS_WRAP_H
#define SYS_WRAP_H
#include "nbase.h"
#include "util.h"
#ifndef WIN32
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netdb.h>
#include <arpa/inet.h>
#else
#define pid_t int
#define mode_t int
#define uid_t int
#define socklen_t int
#define uint16_t int
#define ssize_t int
#include <WinDef.h>
#endif
#include <sys/stat.h>
#include <stdarg.h>
#include <fcntl.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
/* need an autoconf to check for this */
typedef void (*sighandler_t)(int);
void * Calloc(size_t nmemb, size_t size);
int Close(int fd);
int Connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);
int Dup2(int oldfd, int newfd);
int Listen(int s, int backlog);
int Open(const char *pathname, int flags, mode_t mode);
ssize_t Read(int fd, void *buf, size_t count);
ssize_t Recv(int s, void *buf, size_t len, int flags);
ssize_t Recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);
int Setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen);
sighandler_t Signal(int signum, sighandler_t handler);
int Socket(int domain, int type, int protocol);
char * Strdup(const char *s);
ssize_t Write(int fd, const void *buf, size_t count);
#endif

82
ncat/test/addrset.c Normal file
View File

@@ -0,0 +1,82 @@
/*
Usage: ./addrset [<specification> ...]
This program tests the addrset functions in ncat_hostmatch.c, the
ones that maintain the lists of addresses for --allow and --deny. It
takes as arguments specifications that are added to an addrset. It
then reads whitespace-separated host names or IP addresses from
standard input and echoes only those that are in the addrset.
David Fifield
Example:
$ echo "1.2.3.4 1.0.0.5 1.2.3.8" | ./addrset "1.2.3.10/24"
1.2.3.4
1.2.3.8
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include "ncat_core.h"
static int resolve_name(const char *name, struct addrinfo **result)
{
struct addrinfo hints = { 0 };
hints.ai_protocol = IPPROTO_TCP;
*result = NULL;
return getaddrinfo(name, NULL, &hints, result);
}
int main(int argc, char *argv[])
{
struct addrset set;
char line[1024];
int i;
addrset_init(&set);
options_init();
for (i = 1; i < argc; i++) {
if (!addrset_add_spec(&set, argv[i], o.af, !o.nodns)) {
fprintf(stderr, "Error adding spec \"%s\".\n", argv[i]);
exit(1);
}
}
while (fgets(line, sizeof(line), stdin) != NULL) {
char *s, *hostname;
struct addrinfo *addrs;
s = line;
while ((hostname = strtok(s, " \t\n")) != NULL) {
int rc;
s = NULL;
rc = resolve_name(hostname, &addrs);
if (rc != 0) {
fprintf(stderr, "Error resolving \"%s\": %s.\n", hostname, gai_strerror(rc));
continue;
}
if (addrs == NULL) {
fprintf(stderr, "No addresses found for \"%s\".\n", hostname);
continue;
}
/* Check just the first address returned. */
if (addrset_contains(&set, addrs->ai_addr))
printf("%s\n", hostname);
freeaddrinfo(addrs);
}
}
addrset_free(&set);
return 0;
}

2365
ncat/test/ncat-test.pl Executable file

File diff suppressed because it is too large Load Diff

298
ncat/test/test-addrset.sh Executable file
View File

@@ -0,0 +1,298 @@
#!/usr/bin/env bash
# Automated tests for the addrset functions in ncat_hostmatch.c. This
# program runs various addresses against different host specifications
# and checks that the output is what is expected.
ADDRSET=./addrset
# Takes as arguments a whitespace-separated list of host specifications
# and a space-separated list of expected matching addresses. Tests hosts
# are passed in stdin.
function test_addrset() {
specs=$1
expected=$2
result=$($ADDRSET $specs)
ret=$?
# Change newlines to spaces.
result=$(echo $result)
if [ "$ret" != "0" ]; then
echo "FAIL $ADDRSET returned $ret."
elif [ "$result" != "$expected" ]; then
echo "FAIL \"$result\" !="
echo " \"$expected\"."
else
echo "PASS $specs"
fi
}
# Takes as an argument a host specification with invalid syntax. The
# test passes if addrset returns with a non-zero exit code.
function expect_fail() {
specs=$1
$ADDRSET $specs < /dev/null 2> /dev/null
ret=$?
if [ "$ret" == "0" ]; then
echo "FAIL $ADDRSET $specs was expected to fail, but didn't."
else
echo "PASS $specs"
fi
}
# seq replacement for systems without seq.
function seq() {
low=$1
high=$2
while [ $low -le $high ]; do
echo $low
low=$((low + 1))
done
}
# No specifications.
test_addrset "" "" <<EOF
1.1.1.1
2.2.2.2
EOF
# IPv4 address equality.
(for a in `seq 0 255`; do echo 192.168.0.$a; done) \
| test_addrset "192.168.0.0" "192.168.0.0"
# IPv6 address equality.
(for a in `seq 0 255`; do printf "FE80:0000:0000:0000:0202:E3%02X:FE14:1102\n" $a; done) \
| test_addrset "fe80::202:e3ff:fe14:1102" "FE80:0000:0000:0000:0202:E3FF:FE14:1102"
# IPv4 and IPv6 at once.
test_addrset "1.2.3.4 1:2:3::4" "1.2.3.4 1:2:3::4 1:2:3:0::4" <<EOF
0.0.0.0
1.2.3.4
::
1:2:3::4
1:2:3:0::4
f:e:d:c:b::a
EOF
# Simple IPv4 range.
(for a in `seq 0 255`; do echo 192.168.0.$a; done) \
| test_addrset "192.168.0.1-5" "192.168.0.1 192.168.0.2 192.168.0.3 192.168.0.4 192.168.0.5"
# Addresses outside IPv4 range.
(for a in `seq 0 255`; do echo 192.168.0.$a; done) \
| test_addrset "192.168.1.1-5" ""
# One-element range.
(for a in `seq 0 255`; do echo 192.168.0.$a; done) \
| test_addrset "192.168-168.0.1" "192.168.0.1"
# Double IPv4 ranges.
(for a in `seq 0 255`; do echo 192.168.$a.$a; done) \
| test_addrset "192.168.3-8.1-5" "192.168.3.3 192.168.4.4 192.168.5.5"
# Half-open range.
(for a in `seq 0 255`; do echo 192.168.$a.0; done) \
| test_addrset "192.168.-3.0" "192.168.0.0 192.168.1.0 192.168.2.0 192.168.3.0"
# Half-open range.
(for a in `seq 0 255`; do echo 192.168.$a.0; done) \
| test_addrset "192.168.252-.0" "192.168.252.0 192.168.253.0 192.168.254.0 192.168.255.0"
# Full-open range.
test_addrset "192.168.-.0" "192.168.0.0 192.168.10.0 192.168.100.0 192.168.255.0" <<EOF
192.168.0.0
192.168.10.0
192.168.100.0
192.168.255.0
192.168.0.1
1.2.3.4
EOF
# Comma ranges.
(for a in `seq 0 255`; do echo 192.168.0.$a; done) \
| test_addrset "192.168.0.2,3,5,7,11" "192.168.0.2 192.168.0.3 192.168.0.5 192.168.0.7 192.168.0.11"
# Comma ranges combined with dash ranges.
test_addrset "192-200,202.0.0.1,3-5" "202.0.0.1 202.0.0.5 192.0.0.3" <<EOF
201.0.0.1
202.0.0.1
202.0.0.5
202.0.0.6
192.0.0.3
EOF
# Wildcard octet.
test_addrset "192.168.0.*" "192.168.0.3 192.168.0.200 192.168.0.255" <<EOF
1.2.3.4
192.168.0.3
192.168.0.200
192.161.0.0
192.168.0.255
EOF
# Two wildcards.
test_addrset "192.*.0.*" "192.168.0.3 192.168.0.200 192.161.0.0 192.168.0.255" <<EOF
1.2.3.4
192.168.0.3
192.168.0.200
192.161.0.0
192.168.0.255
EOF
# Many range types.
test_addrset "*.1-10,12.*.4-5,6,7" "1.2.3.4 4.5.6.7 70.10.4.4" <<EOF
1.2.3.4
4.5.6.7
70.11.4.4
70.10.4.4
255.255.255.255
EOF
# IPv4 CIDR netmask.
test_addrset "192.168.0.0/24" "192.168.0.5 192.168.0.90" <<EOF
192.168.0.5
192.168.0.90
192.168.1.5
1.2.3.4
EOF
# /32 netmask.
test_addrset "1.2.3.4/32" "1.2.3.4" <<EOF
192.168.0.10
192.168.0.90
192.168.1.5
1.2.3.4
EOF
# /0 netmask.
test_addrset "5.5.5.5/0" "0.0.0.0 123.123.123.123 255.255.255.255" <<EOF
0.0.0.0
123.123.123.123
255.255.255.255
EOF
# IPv4 range combined with CIDR netmask.
test_addrset "1-5.1-5.1-5.1-5/28" "1.2.3.4 1.2.3.5 1.2.3.7 1.2.3.0" <<EOF
1.2.3.4
1.2.3.5
6.1.2.3
1.2.3.7
1.2.3.0
EOF
# Exhaustive listing of a range with netmask.
(for a in `seq 0 255`; do echo 192.168.0.$a; done) \
| test_addrset "192.168.0.5,30,191/30" \
"192.168.0.4 192.168.0.5 192.168.0.6 192.168.0.7 192.168.0.28 192.168.0.29 192.168.0.30 192.168.0.31 192.168.0.188 192.168.0.189 192.168.0.190 192.168.0.191"
# Exhaustive listing of a range with netmask, different octet.
(for a in `seq 0 255`; do echo 192.168.$a.0; done) \
| test_addrset "192.168.5,30,191.0/22" \
"192.168.4.0 192.168.5.0 192.168.6.0 192.168.7.0 192.168.28.0 192.168.29.0 192.168.30.0 192.168.31.0 192.168.188.0 192.168.189.0 192.168.190.0 192.168.191.0"
# IPv6 CIDR netmask.
test_addrset "1:2::0003/120" "1:2::3 1:2::0 1:2::ff" <<EOF
1:2::3
1:2::0
1:2::ff
1:2::1ff
1:3::3
EOF
# /128 netmask.
test_addrset "1:2::0003/128" "1:2::3" <<EOF
1:2::3
1:2::0
1:2::ff
1:2::1ff
1:3::3
EOF
# /0 netmask.
test_addrset "1:2::0003/0" "1:2::3 1:2::0 1:2::ff 1:2::1ff 1:3::3 ff::00" <<EOF
1:2::3
1:2::0
1:2::ff
1:2::1ff
1:3::3
ff::00
EOF
# Name lookup.
test_addrset "google.com" "google.com" <<EOF
1:2::3:4
1.2.3.4
google.com
EOF
# Name lookup combined with CIDR netmask.
test_addrset "google.com/30" "google.com" <<EOF
1:2::3:4
1.2.3.4
google.com
EOF
# Name lookup combined with /0 CIDR netmask.
test_addrset "google.com/0" "1.2.3.4 google.com" <<EOF
1.2.3.4
google.com
EOF
expect_fail "."
expect_fail "-"
expect_fail ","
expect_fail "1.2.3.4,"
expect_fail ",1.2.3.4"
expect_fail "1.2.3.4.5"
expect_fail "1:2:3:4:5:6:7:8:9"
expect_fail "11::22::33"
expect_fail "256.256.256.256"
expect_fail "FFFFF::FFFFF"
# Backwards range.
expect_fail "10-5.2.3.4"
expect_fail "*10.10.10.10"
expect_fail "5-10-15.10.10.10"
expect_fail "-10-15.10.10.10"
expect_fail "10-15-.10.10.10"
expect_fail ",.6.7.8"
expect_fail "5,.5.5.5"
expect_fail ",5.5.5.5"
expect_fail ",5.5.5.5"
expect_fail "+1.2.3.4"
expect_fail "+1.+2.+3.+4"
expect_fail "1.2.3.4/"
expect_fail "1.2.3.4/33"
expect_fail "1.2.3.4/+24"
expect_fail "1.2.3.4/24abc"
expect_fail "1.2.3.4//24"
expect_fail "1.2.3.4/-0"
expect_fail "FF::FF/129"
# Specifications whose behavior is unspecified but not important; that
# is, if the behavior of these changed it wouldn't matter much to users.
# test_addrset "01.02.03.04" "1.2.3.4" <<EOF
# 1.2.3.4
# 5.6.7.8
# EOF
#
# test_addrset "1" "0.0.0.1" <<EOF
# 1.0.0.0
# 0.0.0.1
# 1.2.3.4
# EOF
#
# test_addrset "1.2" "1.0.0.2" <<EOF
# 1.0.0.2
# 1.2.0.0
# 1.2.3.4
# EOF
#
# test_addrset "1.2.3" "1.2.0.3" <<EOF
# 1.0.2.3
# 1.2.0.3
# 1.2.3.4
# EOF

30
ncat/test/test-cert.pem Normal file
View File

@@ -0,0 +1,30 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQDW0y15CbdbSZHSgmI9sVw346rgRADiP+pTPytRlFHMphGeP+R1
S2E8JdtXTRipskFXMwlMtxvApLRm3EQWIs+Q86zRiQ2InGLv+IkIKPCVwqlmKMYC
ukPQ0ld7l5rWcC1tLRsiStAyGIIt0OtAHFY5PZ/KibqftOtskooc72+0vQIDAQAB
AoGBAJkpJOGH6N8/26SPawV7HzmFqz2LnmmwkhtaDUNzkMJsoGEIQpTR8nhUsUZT
5EKQoX9PFtFIN5QomapAXpa9qOfrW35Zpf4HLYoVoMqDHeJ6/o8E9Dm2Md1kPhhe
VYyKSubvs11EunDfn+tA+MoFZKX0FY5rSeM2Ssj/9oCQ3UrNAkEA/DQhUJs4t5xl
oQtN/hESiMwISlUbC2wi76zmwcf3i5HtONtkMBipZwES52Q7VdVPsbVtsdG/pUa2
6KDnpBuhiwJBANoPAhRWxCB5w3xEFVNJ3A44SGv8duonTkzv7fUll14FqwPCDVbW
jrbbueo75Hn7aCi7+GlBvsPasPg+uvoAO9cCQHTBnXq3oXY/TT1VAnJQbQgvjNb8
t1x+X14d6WZksNFIaU4dIzCw+hvZf2roGCAQdKiMmY/szpAxQJRJiXOL5ykCQQCR
7idTGzoIDdUAjcPDyJMnRQ1aj0u5qnJhVNRoEi85sgtf6Xbp3Y8G2weRtWFTLSfo
0tsM/f2/rtRuXfTdqFhjAkEA87xTa+F4xl4gYs7HzFHsPA/Ov1Ia1HjGwA5DAaZq
2HbEVxUUQc5mUvy5jumOuvj9D26TXj2maCJI65uWJNWzcw==
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIICWTCCAcKgAwIBAgIJANxnVkhhOsU9MA0GCSqGSIb3DQEBBQUAMCgxEjAQBgNV
BAoTCW5jYXQtdGVzdDESMBAGA1UEAxMJbG9jYWxob3N0MB4XDTA5MDUyODIxMTYy
OVoXDTE5MDUyNjIxMTYyOVowKDESMBAGA1UEChMJbmNhdC10ZXN0MRIwEAYDVQQD
Ewlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANbTLXkJt1tJ
kdKCYj2xXDfjquBEAOI/6lM/K1GUUcymEZ4/5HVLYTwl21dNGKmyQVczCUy3G8Ck
tGbcRBYiz5DzrNGJDYicYu/4iQgo8JXCqWYoxgK6Q9DSV3uXmtZwLW0tGyJK0DIY
gi3Q60AcVjk9n8qJup+062ySihzvb7S9AgMBAAGjgYowgYcwHQYDVR0OBBYEFL3K
A6v90YPY7OvXLGvmrnu/8MINMFgGA1UdIwRRME+AFL3KA6v90YPY7OvXLGvmrnu/
8MINoSykKjAoMRIwEAYDVQQKEwluY2F0LXRlc3QxEjAQBgNVBAMTCWxvY2FsaG9z
dIIJANxnVkhhOsU9MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAg+yZ
14y1hz0AKUHN1EzvV/m7D4wfGyZ5YabjoLKc91UB/7zRnNL5YbHKeu/jGkUlP7gT
fYFskAa4yjLx+YDos3kBiRnapZuASlpP+uUkk+tVtL+202dTUaTVa5e1NxLcsx0e
98quMuM82vL+ARLfiqAFR2PZWTdFEiwNSTcnEu8=
-----END CERTIFICATE-----

View File

@@ -0,0 +1,100 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static long test_count = 0;
static long success_count = 0;
char **cmdline_split(const char *cmdexec);
int test_cmdline(const char *line, const char **target_args)
{
char **cmd_args;
int args_match = 1;
test_count++;
cmd_args = cmdline_split(line);
/*
* Make sure that all of the target arguments are have been extracted
* by cmdline_split.
*/
while (*cmd_args && *target_args) {
if (strcmp(*cmd_args, *target_args)) {
args_match = 0;
break;
}
cmd_args++;
target_args++;
}
if ((*cmd_args != NULL) || (*target_args != NULL)) {
/*
* One of the argument list had more arguments than the other.
* Therefore, they do not match
*/
args_match = 0;
}
if (args_match) {
success_count++;
printf("PASS '%s'\n", line);
return 1;
} else {
printf("FAIL '%s'\n", line);
return 0;
}
}
int test_cmdline_fail(const char *line)
{
char **cmd_args;
test_count++;
cmd_args = cmdline_split(line);
if (*cmd_args == NULL) {
success_count++;
printf("PASS '%s'\n", line);
return 1;
} else {
printf("PASS '%s'\n", line);
return 0;
}
}
int main(int argc, char *argv[])
{
int i;
struct {
const char *cmdexec;
const char *args[10];
} TEST_CASES[] = {
{"ncat -l -k", {"ncat", "-l", "-k", NULL}},
{"ncat localhost 793", {"ncat", "localhost", "793", NULL}},
{"./ncat scanme.nmap.org 80", {"./ncat", "scanme.nmap.org", "80",
NULL}},
{"t\\ p\\ s hello world how are you?", {"t p s", "hello", "world", "how", "are",
"you?", NULL}},
{"t\\ p\\ s hello world how\\ are you?", {"t p s", "hello", "world", "how are",
"you?", NULL}},
{"ncat\\", {"ncat", NULL}},
{"a\\nb", {"anb", NULL}},
{" ncat a ", {"ncat", "a", NULL}},
{"\\ncat \\a", {"ncat", "a", NULL}},
{"ncat\\\\ a", {"ncat\\", "a", NULL}},
{"ncat\\", {"ncat", NULL}},
{"ncat\\ \\", {"ncat ", NULL}},
};
for (i = 0; i < sizeof(TEST_CASES)/sizeof(TEST_CASES[0]); i++) {
test_cmdline(TEST_CASES[i].cmdexec,
TEST_CASES[i].args);
}
test_cmdline_fail("");
printf("%ld / %ld tests passed.\n", success_count, test_count);
return success_count == test_count ? 0 : 1;
}

129
ncat/test/test-uri.c Normal file
View File

@@ -0,0 +1,129 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include "ncat_core.h"
#include "http.h"
static long test_count = 0;
static long success_count = 0;
/* Check strings or null pointers for equality. */
int nullstreq(const char *s, const char *t)
{
if (s == NULL) {
if (t == NULL)
return 1;
else
return 0;
} else {
if (t == NULL)
return 0;
else
return strcmp(s, t) == 0;
}
}
int test_uri(const char *uri_s, const char *scheme, const char *host, int port, const char *path)
{
struct uri uri;
int scheme_match, host_match, port_match, path_match;
test_count++;
if (uri_parse(&uri, uri_s) == NULL) {
printf("FAIL %s: couldn't parse.\n", uri_s);
return 0;
}
scheme_match = nullstreq(uri.scheme, scheme);
host_match = nullstreq(uri.host, host);
port_match = uri.port == port;
path_match = nullstreq(uri.path, path);
if (scheme_match && host_match && port_match && path_match) {
printf("PASS %s\n", uri_s);
uri_free(&uri);
success_count++;
return 1;
} else {
printf("FAIL %s:", uri_s);
if (!scheme_match)
printf(" \"%s\" != \"%s\".", uri.scheme, scheme);
if (!host_match)
printf(" \"%s\" != \"%s\".", uri.host, host);
if (!port_match)
printf(" %d != %d.", uri.port, port);
if (!path_match)
printf(" \"%s\" != \"%s\".", uri.path, path);
printf("\n");
uri_free(&uri);
return 0;
}
}
int test_fail(const char *uri_s)
{
struct uri uri;
test_count++;
if (uri_parse(&uri, uri_s) != NULL) {
uri_free(&uri);
printf("FAIL %s: not expected to parse.\n", uri_s);
return 0;
} else {
printf("PASS %s\n", uri_s);
success_count++;
return 0;
}
}
int main(int argc, char *argv[])
{
test_uri("http://www.example.com", "http", "www.example.com", 80, "");
test_uri("HTTP://www.example.com", "http", "www.example.com", 80, "");
test_uri("http://WWW.EXAMPLE.COM", "http", "WWW.EXAMPLE.COM", 80, "");
test_uri("http://www.example.com:100", "http", "www.example.com", 100, "");
test_uri("http://www.example.com:1", "http", "www.example.com", 1, "");
test_uri("http://www.example.com:65535", "http", "www.example.com", 65535, "");
test_uri("http://www.example.com:", "http", "www.example.com", 80, "");
test_uri("http://www.example.com:/", "http", "www.example.com", 80, "/");
test_uri("http://www.example.com/", "http", "www.example.com", 80, "/");
test_uri("http://www.example.com:100/", "http", "www.example.com", 100, "/");
test_uri("http://1.2.3.4", "http", "1.2.3.4", 80, "");
test_uri("http://1.2.3.4:100", "http", "1.2.3.4", 100, "");
test_uri("http://[::ffff]", "http", "::ffff", 80, "");
test_uri("http://[::ffff]:100", "http", "::ffff", 100, "");
test_uri("http://www.example.com/path?query#frag", "http", "www.example.com", 80, "/path?query#frag");
test_uri("http://www.exampl%65.com", "http", "www.example.com", 80, "");
test_uri("http://www.exampl%6a.com", "http", "www.examplj.com", 80, "");
test_uri("http://www.exampl%6A.com", "http", "www.examplj.com", 80, "");
test_uri("http://www.exampl%2523.com", "http", "www.exampl%23.com", 80, "");
test_fail("http://www.example.com:%380");
test_uri("http://www.example.com/a%23b", "http", "www.example.com", 80, "/a%23b");
test_uri("unknown://www.example.com", "unknown", "www.example.com", -1, "");
test_uri("unknown:", "unknown", NULL, -1, "");
test_fail("");
test_fail("/dir/file");
test_fail("http://www.example.com:-1");
test_fail("http://www.example.com:0");
test_fail("http://www.example.com:65536");
/* We explicitly don't support userinfo in the authority. */
test_fail("http://user@www.example.com");
test_fail("http://user:pass@www.example.com");
printf("%ld / %ld tests passed.\n", success_count, test_count);
return success_count == test_count ? 0 : 1;
}

577
ncat/test/test-wildcard.c Normal file
View File

@@ -0,0 +1,577 @@
/*
Usage: ./test-wildcard
This is a test program for the ssl_post_connect_check function. It generates
certificates with a variety of different combinations of commonNames and
dNSNames, then checks that matching names are accepted and non-matching names
are rejected. The SSL transactions happen over OpenSSL BIO pairs.
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include "ncat_core.h"
#define KEY_BITS 1024
static int tests_run = 0, tests_passed = 0;
/* A length-delimited string. */
struct lstr {
size_t len;
const char *s;
};
/* Make an anonymous struct lstr. */
#define LSTR(s) { sizeof(s) - 1, (s) }
/* Variable-length arrays of struct lstr are terminated with a special sentinel
value. */
#define LSTR_SENTINEL { -1, NULL }
const struct lstr lstr_sentinel = LSTR_SENTINEL;
int is_sentinel(const struct lstr *name) {
return name->len == -1;
}
int ssl_post_connect_check(SSL *ssl, const char *hostname);
static struct lstr *check(SSL *ssl, const struct lstr names[]);
static int ssl_ctx_trust_cert(SSL_CTX *ctx, X509 *cert);
static int gen_cert(X509 **cert, EVP_PKEY **key,
const struct lstr commonNames[], const struct lstr dNSNames[]);
static void print_escaped(const char *s, size_t len);
static void print_array(const struct lstr array[]);
static int arrays_equal(const struct lstr a[], const struct lstr b[]);
/* Returns positive on success, 0 on failure. The various arrays must be
NULL-terminated. */
static int test(const struct lstr commonNames[], const struct lstr dNSNames[],
const struct lstr test_names[], const struct lstr expected[])
{
SSL_CTX *server_ctx, *client_ctx;
SSL *server_ssl, *client_ssl;
BIO *server_bio, *client_bio;
X509 *cert;
EVP_PKEY *key;
struct lstr *results;
int need_accept, need_connect;
int passed;
tests_run++;
assert(gen_cert(&cert, &key, commonNames, dNSNames) == 1);
assert(BIO_new_bio_pair(&server_bio, 0, &client_bio, 0) == 1);
server_ctx = SSL_CTX_new(SSLv23_server_method());
assert(server_ctx != NULL);
client_ctx = SSL_CTX_new(SSLv23_client_method());
assert(client_ctx != NULL);
SSL_CTX_set_verify(client_ctx, SSL_VERIFY_PEER, NULL);
SSL_CTX_set_verify_depth(client_ctx, 1);
ssl_ctx_trust_cert(client_ctx, cert);
server_ssl = SSL_new(server_ctx);
assert(server_ssl != NULL);
SSL_set_accept_state(server_ssl);
SSL_set_bio(server_ssl, server_bio, server_bio);
assert(SSL_use_certificate(server_ssl, cert) == 1);
assert(SSL_use_PrivateKey(server_ssl, key) == 1);
client_ssl = SSL_new(client_ctx);
assert(client_ssl != NULL);
SSL_set_connect_state(client_ssl);
SSL_set_bio(client_ssl, client_bio, client_bio);
passed = 0;
need_accept = 1;
need_connect = 1;
do {
int rc, err;
if (need_accept) {
rc = SSL_accept(server_ssl);
err = SSL_get_error(server_ssl, rc);
if (rc == 1) {
need_accept = 0;
} else {
if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) {
printf("SSL_accept: %s \n",
ERR_error_string(ERR_get_error(), NULL));
goto end;
}
}
}
if (need_connect) {
rc = SSL_connect(client_ssl);
err = SSL_get_error(client_ssl, rc);
if (rc == 1) {
need_connect = 0;
} else {
if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) {
printf("SSL_connect: %s \n",
ERR_error_string(ERR_get_error(), NULL));
goto end;
}
}
}
} while (need_accept || need_connect);
results = check(client_ssl, test_names);
if (arrays_equal(results, expected)) {
tests_passed++;
passed = 1;
printf("PASS CN");
print_array(commonNames);
printf(" DNS");
print_array(dNSNames);
printf("\n");
} else {
printf("FAIL CN");
print_array(commonNames);
printf(" DNS");
print_array(dNSNames);
printf("\n");
printf(" got ");
print_array(results);
printf("\n");
printf("expected ");
print_array(expected);
printf("\n");
}
free(results);
end:
X509_free(cert);
EVP_PKEY_free(key);
BIO_destroy_bio_pair(server_bio);
SSL_CTX_free(server_ctx);
SSL_CTX_free(client_ctx);
SSL_free(server_ssl);
SSL_free(client_ssl);
return passed;
}
/* Returns a sentinel-terminated malloc-allocated array of names that match ssl
with ssl_post_connect_check. */
static struct lstr *check(SSL *ssl, const struct lstr names[])
{
const struct lstr *name;
struct lstr *results = NULL;
size_t size = 0, capacity = 0;
if (names == NULL)
return NULL;
for (name = names; !is_sentinel(name); name++) {
if (ssl_post_connect_check(ssl, name->s)) {
if (size >= capacity) {
capacity = (size + 1) * 2;
results = safe_realloc(results, (capacity + 1) * sizeof(results[0]));
}
results[size++] = *name;
}
}
results = safe_realloc(results, (size + 1) * sizeof(results[0]));
results[size] = lstr_sentinel;
return results;
}
/* Make a certificate object trusted by an SSL_CTX. I coulnd't find a way to do
this directly, so the certificate is written in PEM format to a temporary
file and then loaded with SSL_CTX_load_verify_locations. Returns 1 on success
and 0 on failure. */
static int ssl_ctx_trust_cert(SSL_CTX *ctx, X509 *cert)
{
char name[] = "ncat-test-XXXXXX";
int fd;
FILE *fp;
int rc;
fd = mkstemp(name);
if (fd == -1)
return 0;
fp = fdopen(fd, "w");
if (fp == NULL) {
close(fd);
return 0;
}
if (PEM_write_X509(fp, cert) == 0) {
fclose(fp);
return 0;
}
fclose(fp);
rc = SSL_CTX_load_verify_locations(ctx, name, NULL);
if (rc == 0) {
fprintf(stderr, "SSL_CTX_load_verify_locations: %s \n",
ERR_error_string(ERR_get_error(), NULL));
}
if (unlink(name) == -1)
fprintf(stderr, "unlink(\"%s\"): %s\n", name, strerror(errno));
return rc;
}
static int set_dNSNames(X509 *cert, const struct lstr dNSNames[])
{
STACK_OF(GENERAL_NAME) *gen_names;
GENERAL_NAME *gen_name;
X509_EXTENSION *ext;
const struct lstr *name;
if (dNSNames == NULL || is_sentinel(&dNSNames[0]))
return 1;
/* We break the abstraction here a bit because the normal way of setting
a list of values, using an i2v method, uses a stack of CONF_VALUE that
doesn't contain the length of each value. We rely on the fact that
the internal representation (the "i" in "i2d") for
NID_subject_alt_name is STACK_OF(GENERAL_NAME). */
gen_names = sk_GENERAL_NAME_new_null();
if (gen_names == NULL)
return 0;
for (name = dNSNames; !is_sentinel(name); name++) {
gen_name = GENERAL_NAME_new();
if (gen_name == NULL)
goto stack_err;
gen_name->type = GEN_DNS;
gen_name->d.dNSName = M_ASN1_IA5STRING_new();
if (gen_name->d.dNSName == NULL)
goto name_err;
if (ASN1_STRING_set(gen_name->d.dNSName, name->s, name->len) == 0)
goto name_err;
if (sk_GENERAL_NAME_push(gen_names, gen_name) == 0)
goto name_err;
}
ext = X509V3_EXT_i2d(NID_subject_alt_name, 0, gen_names);
if (ext == NULL)
goto stack_err;
if (X509_add_ext(cert, ext, -1) == 0) {
X509_EXTENSION_free(ext);
goto stack_err;
}
X509_EXTENSION_free(ext);
sk_GENERAL_NAME_pop_free(gen_names, GENERAL_NAME_free);
return 1;
name_err:
GENERAL_NAME_free(gen_name);
stack_err:
sk_GENERAL_NAME_pop_free(gen_names, GENERAL_NAME_free);
return 0;
}
static int gen_cert(X509 **cert, EVP_PKEY **key,
const struct lstr commonNames[], const struct lstr dNSNames[])
{
RSA *rsa;
int rc;
*cert = NULL;
*key = NULL;
/* Generate a private key. */
*key = EVP_PKEY_new();
if (*key == NULL)
goto err;
do {
rsa = RSA_generate_key(KEY_BITS, RSA_F4, NULL, NULL);
if (rsa == NULL)
goto err;
rc = RSA_check_key(rsa);
} while (rc == 0);
if (rc == -1)
goto err;
if (EVP_PKEY_assign_RSA(*key, rsa) == 0) {
RSA_free(rsa);
goto err;
}
/* Generate a certificate. */
*cert = X509_new();
if (*cert == NULL)
goto err;
if (X509_set_version(*cert, 2) == 0) /* Version 3. */
goto err;
ASN1_INTEGER_set(X509_get_serialNumber(*cert), get_random_u32() & 0x7FFFFFFF);
/* Set the commonNames. */
if (commonNames != NULL) {
X509_NAME *subj;
const struct lstr *name;
subj = X509_get_subject_name(*cert);
for (name = commonNames; !is_sentinel(name); name++) {
if (X509_NAME_add_entry_by_txt(subj, "commonName", MBSTRING_ASC,
(unsigned char *) name->s, name->len, -1, 0) == 0) {
goto err;
}
}
}
/* Set the dNSNames. */
if (set_dNSNames(*cert, dNSNames) == 0)
goto err;
if (X509_set_issuer_name(*cert, X509_get_subject_name(*cert)) == 0
|| X509_gmtime_adj(X509_get_notBefore(*cert), 0) == 0
|| X509_gmtime_adj(X509_get_notAfter(*cert), 60) == 0
|| X509_set_pubkey(*cert, *key) == 0) {
goto err;
}
/* Sign it. */
if (X509_sign(*cert, *key, EVP_sha1()) == 0)
goto err;
return 1;
err:
if (*cert != NULL)
X509_free(*cert);
if (*key != NULL)
EVP_PKEY_free(*key);
return 0;
}
static void print_escaped(const char *s, size_t len)
{
int c;
for ( ; len > 0; len--) {
c = (unsigned char) *s++;
if (isprint(c) && !isspace(c))
putchar(c);
else
printf("\\%03o", c);
}
}
static void print_array(const struct lstr array[])
{
const struct lstr *p;
if (array == NULL) {
printf("[]");
return;
}
printf("[");
for (p = array; !is_sentinel(p); p++) {
if (p != array)
printf(" ");
print_escaped(p->s, p->len);
}
printf("]");
}
static int lstr_equal(const struct lstr *a, const struct lstr *b)
{
return a->len == b->len && memcmp(a->s, b->s, a->len) == 0;
}
static int arrays_equal(const struct lstr a[], const struct lstr b[])
{
if (a == NULL)
return b == NULL;
if (b == NULL)
return a == NULL;
while (!is_sentinel(a) && !is_sentinel(b)) {
if (!lstr_equal(a, b))
return 0;
a++;
b++;
}
return is_sentinel(a) && is_sentinel(b);
}
/* This is just a constant used to give a fixed length to the arrays that are
conceptually variable-length in the test cases. Increase it if some array
grows too big. */
#define ARR_LEN 10
const struct lstr test_names[] = {
LSTR("a.com"), LSTR("www.a.com"), LSTR("sub.www.a.com"),
LSTR("www.example.com"), LSTR("example.co.uk"), LSTR("*.*.com"),
LSTR_SENTINEL
};
/* These tests just check that matching a single string works properly. */
struct {
const struct lstr name[ARR_LEN];
const struct lstr expected[ARR_LEN];
} single_tests[] = {
{ { LSTR_SENTINEL },
{ LSTR_SENTINEL } },
{ { LSTR("a.com"), LSTR_SENTINEL },
{ LSTR("a.com"), LSTR_SENTINEL } },
{ { LSTR("www.a.com"), LSTR_SENTINEL },
{ LSTR("www.a.com"), LSTR_SENTINEL } },
{ { LSTR("*.a.com"), LSTR_SENTINEL },
{ LSTR("www.a.com"), LSTR_SENTINEL } },
{ { LSTR("w*.a.com"), LSTR_SENTINEL },
{ LSTR_SENTINEL } },
{ { LSTR("*w.a.com"), LSTR_SENTINEL },
{ LSTR_SENTINEL } },
{ { LSTR("www.*.com"), LSTR_SENTINEL },
{ LSTR_SENTINEL } },
{ { LSTR("*.com"), LSTR_SENTINEL },
{ LSTR_SENTINEL } },
{ { LSTR("*.com."), LSTR_SENTINEL },
{ LSTR_SENTINEL } },
{ { LSTR("*.*.com"), LSTR_SENTINEL },
{ LSTR_SENTINEL } },
{ { LSTR("a.com\0evil.com"), LSTR_SENTINEL },
{ LSTR_SENTINEL } },
};
/* These test different combinations of commonName and dNSName. */
struct {
const struct lstr common[ARR_LEN];
const struct lstr dns[ARR_LEN];
const struct lstr expected[ARR_LEN];
} double_tests[] = {
/* Should not match any commonName if any dNSNames exist. */
{ { LSTR("a.com"), LSTR_SENTINEL },
{ LSTR("example.co.uk"), LSTR_SENTINEL },
{ LSTR("example.co.uk"), LSTR_SENTINEL } },
{ { LSTR("a.com"), LSTR_SENTINEL },
{ LSTR("b.com"), LSTR_SENTINEL },
{ LSTR_SENTINEL } },
/* Should check against all of the dNSNames. */
{ { LSTR_SENTINEL },
{ LSTR("a.com"), LSTR("example.co.uk"), LSTR("b.com"), LSTR_SENTINEL },
{ LSTR("a.com"), LSTR("example.co.uk"), LSTR_SENTINEL } },
};
const struct lstr specificity_test_names[] = {
LSTR("a.com"),
LSTR("sub.b.com"), LSTR("sub.c.com"), LSTR("sub.d.com"),
LSTR("sub.sub.e.com"), LSTR("sub.sub.f.com"), LSTR("sub.sub.g.com"),
LSTR_SENTINEL
};
/* Validation should check only the "most specific" commonName if multiple
exist. This "most specific" term is used in RFCs 2818, 4261, and 5018 at
least, but is not defined anywhere that I can find. Let's interpret it as the
greatest number of name elements, with wildcard names considered less
specific than all non-wildcard names. For ties, the name that comes later is
considered more specific. */
struct {
const struct lstr patterns[ARR_LEN];
const struct lstr expected_forward;
const struct lstr expected_backward;
} specificity_tests[] = {
{ { LSTR("a.com"), LSTR("*.b.com"), LSTR("sub.c.com"), LSTR("sub.d.com"), LSTR("*.sub.e.com"), LSTR("*.sub.f.com"), LSTR("sub.sub.g.com"), LSTR_SENTINEL },
LSTR("sub.sub.g.com"), LSTR("sub.sub.g.com") },
{ { LSTR("a.com"), LSTR("*.b.com"), LSTR("sub.c.com"), LSTR("sub.d.com"), LSTR("*.sub.e.com"), LSTR("*.sub.f.com"), LSTR_SENTINEL },
LSTR("sub.d.com"), LSTR("sub.c.com") },
{ { LSTR("a.com"), LSTR("*.b.com"), LSTR("sub.c.com"), LSTR("*.sub.e.com"), LSTR("*.sub.f.com"), LSTR_SENTINEL },
LSTR("sub.c.com"), LSTR("sub.c.com") },
{ { LSTR("a.com"), LSTR("*.b.com"), LSTR("*.sub.e.com"), LSTR("*.sub.f.com"), LSTR_SENTINEL },
LSTR("a.com"), LSTR("a.com") },
{ { LSTR("*.b.com"), LSTR("*.sub.e.com"), LSTR("*.sub.f.com"), LSTR_SENTINEL },
LSTR("sub.sub.f.com"), LSTR("sub.sub.e.com") },
{ { LSTR("*.b.com"), LSTR("*.sub.e.com"), LSTR_SENTINEL },
LSTR("sub.sub.e.com"), LSTR("sub.sub.e.com") },
};
#define NELEMS(a) (sizeof(a) / sizeof(a[0]))
void reverse(struct lstr a[])
{
struct lstr tmp;
unsigned int i, j;
i = 0;
for (j = 0; !is_sentinel(&a[j]); j++)
;
if (j == 0)
return;
j--;
while (i < j) {
tmp = a[i];
a[i] = a[j];
a[j] = tmp;
i++;
j--;
}
}
void test_specificity(const struct lstr patterns[],
const struct lstr test_names[],
const struct lstr expected_forward[],
const struct lstr expected_backward[])
{
struct lstr scratch[ARR_LEN];
unsigned int i;
for (i = 0; i < ARR_LEN && !is_sentinel(&patterns[i]); i++)
scratch[i] = patterns[i];
assert(i < ARR_LEN);
scratch[i] = lstr_sentinel;
test(scratch, NULL, test_names, expected_forward);
reverse(scratch);
test(scratch, NULL, test_names, expected_backward);
return;
}
int main(void)
{
unsigned int i;
SSL_library_init();
ERR_load_crypto_strings();
SSL_load_error_strings();
/* Test single pattens in both the commonName and dNSName positions. */
for (i = 0; i < NELEMS(single_tests); i++)
test(single_tests[i].name, NULL, test_names, single_tests[i].expected);
for (i = 0; i < NELEMS(single_tests); i++)
test(NULL, single_tests[i].name, test_names, single_tests[i].expected);
for (i = 0; i < NELEMS(double_tests); i++) {
test(double_tests[i].common, double_tests[i].dns,
test_names, double_tests[i].expected);
}
for (i = 0; i < NELEMS(specificity_tests); i++) {
struct lstr expected_forward[2], expected_backward[2];
/* Put the expected names in arrays for the test. */
expected_forward[0] = specificity_tests[i].expected_forward;
expected_forward[1] = lstr_sentinel;
expected_backward[0] = specificity_tests[i].expected_backward;
expected_backward[1] = lstr_sentinel;
test_specificity(specificity_tests[i].patterns,
specificity_test_names, expected_forward, expected_backward);
}
printf("%d / %d tests passed.\n", tests_passed, tests_run);
return tests_passed == tests_run ? 0 : 1;
}

657
ncat/util.c Normal file
View File

@@ -0,0 +1,657 @@
/***************************************************************************
* util.c -- Various utility functions. *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#include "sys_wrap.h"
#include "util.h"
#include "ncat.h"
#include "nbase.h"
#include "sockaddr_u.h"
#include <assert.h>
#include <stdio.h>
#ifdef WIN32
#include <iphlpapi.h>
#endif
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
/* safely add 2 size_t */
size_t sadd(size_t l, size_t r)
{
size_t t;
t = l + r;
if (t < l)
bye("integer overflow %lu + %lu.", (u_long)l, (u_long)r);
return t;
}
/* safely multiply 2 size_t */
size_t smul(size_t l, size_t r)
{
size_t t;
t = l * r;
if (l && t / l != r)
bye("integer overflow %lu * %lu.", (u_long)l, (u_long)r);
return t;
}
#ifdef WIN32
void windows_init()
{
WORD werd;
WSADATA data;
werd = MAKEWORD( 2, 2 );
if ( (WSAStartup(werd, &data)) !=0 )
bye("Failed to start WinSock.");
}
#endif
/* Use this to print debug or diagnostic messages to avoid polluting the user
stream. */
void loguser(const char *fmt, ...)
{
va_list ap;
fprintf(stderr, "%s: ", NCAT_NAME);
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
/* Log a user message without the "Ncat: " prefix, to allow building up a line
with a series of strings. */
void loguser_noprefix(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
void logdebug(const char *fmt, ...)
{
va_list ap;
fprintf(stderr, "NCAT DEBUG: ");
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
/* Exit status 2 indicates a program error other than a network error. */
void die(char *err)
{
perror(err);
exit(2);
}
/* adds newline for you */
void bye(const char *fmt, ...)
{
va_list ap;
fprintf(stderr, "%s: ", NCAT_NAME);
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fprintf(stderr, " QUITTING.\n");
exit(2);
}
/* zero out some mem, bzero() is deprecated */
void zmem(void *mem, size_t n)
{
memset(mem, 0, n);
}
/* Append n bytes starting at s to a malloc-allocated buffer. Reallocates the
buffer and updates the variables to make room if necessary. */
int strbuf_append(char **buf, size_t *size, size_t *offset, const char *s, size_t n)
{
assert(*offset <= *size);
if (n >= *size - *offset) {
*size += n + 1;
*buf = (char*) safe_realloc(*buf, *size);
}
memcpy(*buf + *offset, s, n);
*offset += n;
(*buf)[*offset] = '\0';
return n;
}
/* Append a '\0'-terminated string as with strbuf_append. */
int strbuf_append_str(char **buf, size_t *size, size_t *offset, const char *s)
{
return strbuf_append(buf, size, offset, s, strlen(s));
}
/* Do a sprintf at the given offset into a malloc-allocated buffer. Reallocates
the buffer and updates the variables to make room if necessary. */
int strbuf_sprintf(char **buf, size_t *size, size_t *offset, const char *fmt, ...)
{
va_list va;
int n;
assert(*offset <= *size);
if (*buf == NULL) {
*size = 1;
*buf = (char*) safe_malloc(*size);
}
for (;;) {
va_start(va, fmt);
n = Vsnprintf(*buf + *offset, *size - *offset, fmt, va);
va_end(va);
if (n < 0)
*size = MAX(*size, 1) * 2;
else if (n >= *size - *offset)
*size += n + 1;
else
break;
*buf = (char*) safe_realloc(*buf, *size);
}
*offset += n;
return n;
}
/* Make a new allocated null-terminated string from the bytes [start, end). */
char *mkstr(const char *start, const char *end)
{
char *s;
assert(end >= start);
s = (char *) safe_malloc(end - start + 1);
memcpy(s, start, end - start);
s[end - start] = '\0';
return s;
}
/* Return true if the given address is a local one. */
int addr_is_local(const union sockaddr_u *su)
{
struct addrinfo hints = { 0 }, *addrs, *addr;
char hostname[128];
/* Check loopback addresses. */
if (su->storage.ss_family == AF_INET) {
if ((ntohl(su->in.sin_addr.s_addr) & 0xFF000000UL) == 0x7F000000UL)
return 1;
if (ntohl(su->in.sin_addr.s_addr) == 0x00000000UL)
return 1;
}
#ifdef HAVE_IPV6
else if (su->storage.ss_family == AF_INET6) {
if (memcmp(&su->in6.sin6_addr, &in6addr_any, sizeof(su->in6.sin6_addr)) == 0
|| memcmp(&su->in6.sin6_addr, &in6addr_loopback, sizeof(su->in6.sin6_addr)) == 0)
return 1;
}
#endif
/* Check addresses assigned to the local host name. */
if (gethostname(hostname, sizeof(hostname)) == -1)
return 0;
hints.ai_family = su->storage.ss_family;
if (getaddrinfo(hostname, NULL, &hints, &addrs) != 0)
return 0;
for (addr = addrs; addr != NULL; addr = addr->ai_next) {
union sockaddr_u addr_su;
if (addr->ai_family != su->storage.ss_family)
continue;
if (addr->ai_addrlen > sizeof(addr_su)) {
bye("getaddrinfo returned oversized address (%u > %u)",
addr->ai_addrlen, sizeof(addr_su));
}
memcpy(&addr_su, addr->ai_addr, addr->ai_addrlen);
if (su->storage.ss_family == AF_INET) {
if (su->in.sin_addr.s_addr == addr_su.in.sin_addr.s_addr)
break;
} else if (su->storage.ss_family == AF_INET6) {
if (memcmp(&su->in6.sin6_addr, &addr_su.in6.sin6_addr, sizeof(su->in6.sin6_addr)) == 0)
break;
}
}
if (addr != NULL) {
freeaddrinfo(addrs);
return 1;
} else {
return 0;
}
}
/* Converts an IP address given in a sockaddr_u to an IPv4 or
IPv6 IP address string. Since a static buffer is returned, this is
not thread-safe and can only be used once in calls like printf()
*/
const char *inet_socktop(const union sockaddr_u *su) {
static char buf[INET6_ADDRSTRLEN + 1];
void *addr;
if (su->storage.ss_family == AF_INET)
addr = (void *) &su->in.sin_addr;
#if HAVE_IPV6
else if (su->storage.ss_family == AF_INET6)
addr = (void *) &su->in6.sin6_addr;
#endif
else
addr = NULL;
if (inet_ntop(su->storage.ss_family, addr, buf, sizeof(buf)) == NULL) {
bye("Failed to convert address to presentation format! Error: %s.",
strerror(socket_errno()));
}
return buf;
}
/* Returns the port number in HOST BYTE ORDER based on the su's family */
unsigned short inet_port(const union sockaddr_u *su)
{
if (su->storage.ss_family == AF_INET)
return ntohs(su->in.sin_port);
#if HAVE_IPV6
else if (su->storage.ss_family == AF_INET6)
return ntohs(su->in6.sin6_port);
#endif
bye("Invalid address family passed to inet_port().");
return 0;
}
int do_listen(int type, int proto, const union sockaddr_u *srcaddr_u)
{
int sock = 0, option_on = 1;
size_t sa_len;
if (type != SOCK_STREAM && type != SOCK_DGRAM)
return -1;
/* We need a socket that can be inherited by child processes in
ncat_exec_win.c, for --exec and --sh-exec. inheritable_socket is from
nbase. */
sock = inheritable_socket(srcaddr_u->storage.ss_family, type, proto);
Setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &option_on, sizeof(int));
/* IPPROTO_IPV6 is defined in Visual C++ only when _WIN32_WINNT >= 0x501.
Nbase's nbase_winunix.h defines _WIN32_WINNT to a lower value for
compatibility with older versions of Windows. This code disables IPv6 sockets
that also receive IPv4 connections. This is the default on Windows anyway so
it doesn't make a difference.
http://support.microsoft.com/kb/950688
http://msdn.microsoft.com/en-us/library/bb513665
*/
#ifdef IPPROTO_IPV6
if (srcaddr_u->storage.ss_family == AF_INET6) {
int set = 1;
/* Tell it to not try and bind to IPV4 */
if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &set, sizeof(set))== -1)
die("Unable to set IPV6 socket to bind only to IPV6");
}
#endif
#ifdef HAVE_SOCKADDR_SA_LEN
sa_len = srcaddr_u->sockaddr.sa_len;
#else
sa_len = sizeof(*srcaddr_u);
#endif
if (bind(sock, &srcaddr_u->sockaddr, sa_len) < 0) {
bye("bind to %s:%hu: %s.", inet_socktop(srcaddr_u),
inet_port(srcaddr_u), socket_strerror(socket_errno()));
}
if (type == SOCK_STREAM)
Listen(sock, BACKLOG);
if (o.verbose)
loguser("Listening on %s:%hu\n", inet_socktop(srcaddr_u), inet_port(srcaddr_u));
return sock;
}
int do_connect(int type)
{
int sock = 0;
if (type != SOCK_STREAM && type != SOCK_DGRAM)
return -1;
/* We need a socket that can be inherited by child processes in
ncat_exec_win.c, for --exec and --sh-exec. inheritable_socket is from
nbase. */
sock = inheritable_socket(targetss.storage.ss_family, type, 0);
if (srcaddr.storage.ss_family != AF_UNSPEC) {
size_t sa_len;
#ifdef HAVE_SOCKADDR_SA_LEN
sa_len = srcaddr.sockaddr.sa_len;
#else
sa_len = sizeof(srcaddr);
#endif
if (bind(sock, &srcaddr.sockaddr, sa_len) < 0) {
bye("bind to %s:%hu: %s.", inet_socktop(&srcaddr),
inet_port(&srcaddr), socket_strerror(socket_errno()));
}
}
if (sock != -1) {
if (connect(sock, &targetss.sockaddr, (int) targetsslen)!= -1)
return sock;
else if (socket_errno()==EINPROGRESS||socket_errno()==EAGAIN)
return sock;
}
return -1 ;
}
unsigned char *buildsrcrte(struct in_addr dstaddr, struct in_addr routes[],
int numroutes, int ptr, size_t *len)
{
int x;
unsigned char *opts, *p;
*len = (numroutes + 1) * sizeof(struct in_addr) + 4;
if (numroutes > 8)
bye("Bad number of routes passed to buildsrcrte().");
opts = (unsigned char *) safe_malloc(*len);
p = opts;
zmem(opts, *len);
*p++ = 0x01; /* IPOPT_NOP, for alignment */
*p++ = 0x83; /* IPOPT_LSRR */
*p++ = (char) (*len - 1); /* subtract nop */
*p++ = (char) ptr;
for (x = 0; x < numroutes; x++) {
memcpy(p, &routes[x], sizeof(routes[x]));
p += sizeof(routes[x]);
}
memcpy(p, &dstaddr, sizeof(dstaddr));
return opts;
}
int allow_access(const union sockaddr_u *su)
{
/* A host not in the allow set is denied, but only if the --allow or
--allowfile option was given. */
if (o.allow && !addrset_contains(&o.allowset, &su->sockaddr))
return 0;
if (addrset_contains(&o.denyset, &su->sockaddr))
return 0;
return 1;
}
/*
* ugly code to maintain our list of fds so we can have proper fdmax for
* select(). really this should be generic list code, not this silly bit of
* stupidity. -sean
*/
/* add an fdinfo to our list */
int add_fdinfo(fd_list_t *fdl, struct fdinfo *s)
{
if (fdl->nfds >= fdl->maxfds)
return -1;
fdl->fds[fdl->nfds] = *s;
fdl->nfds++;
if (s->fd > fdl->fdmax)
fdl->fdmax = s->fd;
if (o.debug > 1)
logdebug("Added fd %d to list, nfds %d, maxfd %d\n", s->fd, fdl->nfds, fdl->fdmax);
return 0;
}
/* Add a descriptor to the list. Use this when you are only adding to the list
* for the side effect of increasing fdmax, and don't care about fdinfo
* members. */
int add_fd(fd_list_t *fdl, int fd)
{
struct fdinfo info = { 0 };
info.fd = fd;
return add_fdinfo(fdl, &info);
}
/* remove a descriptor from our list */
int rm_fd(fd_list_t *fdl, int fd)
{
int x = 0, last = fdl->nfds;
/* make sure we have a list */
if (last == 0)
bye("Program bug: Trying to remove fd from list with no fds.");
/* find the fd in the list */
for (x = 0; x < last; x++)
if (fdl->fds[x].fd == fd)
break;
/* make sure we found it */
if (x == last)
bye("Program bug: fd (%d) not on list.", fd);
/* remove it, does nothing if (last == 1) */
if (o.debug > 1)
logdebug("Swapping fd[%d] (%d) with fd[%d] (%d)\n",
x, fdl->fds[x].fd, last - 1, fdl->fds[last - 1].fd);
fdl->fds[x] = fdl->fds[last - 1];
fdl->nfds--;
/* was it the max */
if (fd == fdl->fdmax)
fdl->fdmax = get_maxfd(fdl);
if (o.debug > 1)
logdebug("Removed fd %d from list, nfds %d, maxfd %d\n", fd, fdl->nfds, fdl->fdmax);
return 0;
}
/* find the max descriptor in our list */
int get_maxfd(fd_list_t *fdl)
{
int x = 0, max = -1, nfds = fdl->nfds;
for (x = 0; x < nfds; x++)
if (fdl->fds[x].fd > max)
max = fdl->fds[x].fd;
return max;
}
struct fdinfo *get_fdinfo(const fd_list_t *fdl, int fd)
{
int x;
for (x = 0; x < fdl->nfds; x++)
if (fdl->fds[x].fd == fd)
return &fdl->fds[x];
return NULL;
}
void init_fdlist(fd_list_t *fdl, int maxfds)
{
fdl->fds = (struct fdinfo *) Calloc(maxfds, sizeof(struct fdinfo));
fdl->nfds = 0;
fdl->fdmax = -1;
fdl->maxfds = maxfds;
if (o.debug > 1)
logdebug("Initialized fdlist with %d maxfds\n", maxfds);
}
void free_fdlist(fd_list_t *fdl)
{
free(fdl->fds);
fdl->nfds = 0;
fdl->fdmax = -1;
}
/* If any changes need to be made to EOL sequences to comply with --crlf
* then dst will be populated with the modified src, len will be adjusted
* accordingly and the return will be non-zero.
*
* state is used to keep track of line endings that span more than one call to
* this function. On the first call, state should be a pointer to a int
* containing 0. Thereafter, keep passing the same pointer. Separate logical
* streams should use separate state pointers.
*
* Returns 0 if changes were not made - len and dst will remain untouched.
*/
int fix_line_endings(char *src, int *len, char **dst, int *state)
{
int fix_count;
int i,j;
int num_bytes = *len;
int prev_state = *state;
/* *state is true iff the last byte of the previous block was \r. */
if (num_bytes > 0)
*state = (src[num_bytes - 1] == '\r');
/* get count of \n without matching \r */
fix_count = 0;
for (i = 0; i < num_bytes; i++) {
if (src[i] == '\n' && ((i == 0) ? !prev_state : src[i-1] != '\r'))
fix_count++;
}
if (fix_count <= 0 ) return 0;
/* now insert matching \r */
*dst = (char *) safe_malloc(num_bytes + fix_count);
j = 0;
for (i = 0; i < num_bytes; i++) {
if (src[i] == '\n' && ((i == 0) ? !prev_state : src[i-1] != '\r')) {
memcpy(*dst + j, "\r\n", 2);
j += 2;
} else {
memcpy(*dst + j, src + i, 1);
j++;
}
}
*len += fix_count;
return 1;
}

174
ncat/util.h Normal file
View File

@@ -0,0 +1,174 @@
/***************************************************************************
* util.h *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id$ */
#ifndef UTIL_H_
#define UTIL_H_
#include "ncat_config.h"
#include "nbase.h"
#ifndef WIN32
#include <sys/types.h>
#include <netinet/in.h>
#endif
#ifdef HAVE_OPENSSL
#include <openssl/ssl.h>
#endif
/* add/multiply unsigned values safely */
size_t sadd(size_t, size_t);
size_t smul(size_t, size_t);
#ifdef WIN32
void windows_init();
#endif
#include "sockaddr_u.h"
void loguser(const char *fmt, ...);
void loguser_noprefix(const char *fmt, ...);
void logdebug(const char *fmt, ...);
/* handle errors */
void die(char *);
void bye(const char *, ...);
/* zero out some memory, bzero() is deprecated */
void zmem(void *, size_t);
int strbuf_append(char **buf, size_t *size, size_t *offset, const char *s, size_t n);
int strbuf_append_str(char **buf, size_t *size, size_t *offset, const char *s);
int strbuf_sprintf(char **buf, size_t *size, size_t *offset, const char *fmt, ...);
char *mkstr(const char *start, const char *end);
int addr_is_local(const union sockaddr_u *su);
const char *inet_socktop(const union sockaddr_u *su);
unsigned short inet_port(const union sockaddr_u *su);
int do_listen(int, int, const union sockaddr_u *);
int do_connect(int);
unsigned char *buildsrcrte(struct in_addr dstaddr, struct in_addr routes[],
int numroutes, int ptr, size_t *len);
int allow_access(const union sockaddr_u *su);
struct fdinfo {
int fd;
union sockaddr_u remoteaddr;
#ifdef HAVE_OPENSSL
SSL *ssl;
#endif
};
typedef struct fd_list {
struct fdinfo *fds;
int nfds, maxfds, fdmax;
} fd_list_t;
int add_fdinfo(fd_list_t *, struct fdinfo *);
int add_fd(fd_list_t *fdl, int fd);
int rm_fd(fd_list_t *, int);
void free_fdlist(fd_list_t *);
void init_fdlist(fd_list_t *, int);
int get_maxfd(fd_list_t *);
struct fdinfo *get_fdinfo(const fd_list_t *, int);
int fix_line_endings(char *src, int *len, char **dst, int *state);
#endif

1885
nping/ArgParser.cc Normal file

File diff suppressed because it is too large Load Diff

110
nping/ArgParser.h Normal file
View File

@@ -0,0 +1,110 @@
/***************************************************************************
* ArgParser.h -- The ArgParser Class is the one in charge of command line *
* argument parsing. Essentially it contains method parseArguments() that *
* takes the usual argc and *argv[] parameters and fills the general *
* NpingOps class with all the information needed for the execution of *
* Nping. *
* *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
* linked combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* 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 v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
class ArgParser {
public:
ArgParser();
~ArgParser();
int parseArguments(int argc, char *argv[]);
void printVersion(void);
void printUsage(void);
int parseAdvertEntry(char *str, struct in_addr *addr, u32 *pref);
int atoICMPType(char *opt, u8 *type);
int atoICMPCode(char *opt, u8 *code);
int atoARPOpCode(char *opt, u16 *code);
int atoEtherType(char *opt, u16 *type);
int parseICMPTimestamp(char *optarg, u32 *dst);
}; /* End of class ArgParser*/

Some files were not shown because too many files have changed in this diff Show More