Initial revision

This commit is contained in:
fishwaldo 2002-08-31 09:28:34 +00:00
commit b669fe6604
12 changed files with 6200 additions and 0 deletions

12
.gitattributes vendored Normal file
View file

@ -0,0 +1,12 @@
* text=auto !eol
/Makefile.in -text
/README.opsb -text
/config.status -text
/configure -text
/configure.in -text
/install-sh -text
/modconfig.h.in -text
/opsb.c -text
/opsb.h -text
/opsb_help.c -text
/proxy.c -text

38
Makefile.in Normal file
View file

@ -0,0 +1,38 @@
#Neostats Module Makefile!
CC=@CC@
CFLAGS=@CFLAGS@
LDFLAGS= @LIBS@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
DIRECTORY=@DIRINST@/dl/
INCLUDES=-I@DIRINST@/include/ -I.
SOURCES= opsb.c proxy.c opsb_help.c
OBJECTS= opsb.o proxy.o opsb_help.o
TARGET= opsb.so
DOCS=README.opsb
DATA=
all: module
.c.o:
$(CC) -c $(CFLAGS) $(INCLUDES) $<
module: $(OBJECTS)
$(LD) -shared -o $(TARGET) $(LDFLAGS) $(OBJECTS)
clean:
/bin/rm -rf $(TARGET) *.o Makefile *.log modconfig.h
install: module
$(INSTALL) -m 644 $(TARGET) $(DIRECTORY)
$(INSTALL) -m 644 $(DOCS) $(DIRECTORY)/docs/
$(INSTALL) -m 644 $(DATA) $(DIRECTORY)../data/
$(OBJECTS): Makefile
opsb.c: opsb.h opsb.c
proxy.c: proxy.c opsb.h
opsb_help.c: opsb_help.c

136
README.opsb Normal file
View file

@ -0,0 +1,136 @@
Open Proxy Scanning Bot Version 1.0 Beta1 - fish@dynam.ac
+++++++++++++++++++++++++++++++++++++++++
Thanks for Downloading opsb. opsb is a bot for the NeoStats IRC services
package (www.neostats.net) that allows you to check and ban users
connecting to your network using In-Secure proxy servers.
Insecure proxy servers are often used to
launch attacks against IRC networks, or users, and are difficult to detect
by regular irc means.
Opsb actually scans each user as they connect to the network, and attempts
to determine if the user is coming from a open proxy.
Currently the open proxies that we scan for are:
HTTP proxies on ports 80, 8080, 3128
Socks4 and Socks5 proxies on ports 1080
wingate or cisco routers on ports 23
opsb also checks the Blitzed DNS blacklist for proxies that have already
been reported as open. More information on the blitzed DNS blacklist can
be found at http://www.blitzed.org/opm/. This means that you can ban users
that come from known proxies.
opsb is ideal for larger networks where you want one server to
do all the scanning instead of
individual servers running their own proxy scanner.
==============================================================================
Requirements
==============================================================================
1) NeoStats 2.5.0 Beta5 or Higher installed
2) A shell to run from
3) CN lines to a server on your network
4) Knowledge of unices
==============================================================================
Installation
==============================================================================
Installation is faily straight forward.
1) Make sure you have a working copy of NeoStats installed.
You can obtain Neostats from www.neostats.net
Please make sure that you have it configured correctly and installed
and it links to your network correctly.
*NOTE*
You must have done "make install" in the neostats directory. This
will install NeoStats, by default to ~/NeoStats/
*BSD USERS*
neostats has a bug with make install. Please refer to the forums
on the neostats site for more information
2) Configure opsb.
to configure opsb, run ./configure <--with-neostats=<DIR>>
from the directory where you untared opsb (typically ~/opsb-1.0-beta1/)
You must specify the --with-neostats option if the configure
script can not find the NeoStats directory
3) Make
Run "make" (or gmake if you use bsd) in the opsb directory. This
should compile opsb for you.
4) Make install
run "make install" or "gmake install" if you use bsd to install
opsb into the NeoStats Directory.
5) (optionally) Configure Neostats to load opsb on startup
This is done by adding the line "LOAD_MODULE opsb"
to the neostats.cfg file
6) Load and Configure opsb.
Start up NeoStats, or load the module via IRC.
All configuration of opsb is done via IRC, there is no config file
as such.
Read Below for more Information.
7) You done!
==============================================================================
Configuration
==============================================================================
All of opsb configurable options are set via IRC. The defaults will
probably not be correct for your network, hence, opsb will broadcast a
message warning you of this till you configure it.
What you should change from defaults:
/msg opsb set targetip <ip address>
this sets the IP address that opsb tries to
make proxies connect to. By default it is set to the server that NeoStats
is linked to. This might not always be a good idea, so you should set the
IP address to a server on your network.
/msg opsb set targetport <port>
This is the port number that opsb tries to
make proxies connect to. You should set this to a Common IRC port such
as 6667. Defaults to the port that NeoStats connects to.
/msg opsb set bantime <seconds>
By Default, opsb will akill a host that is a open proxy for 1 day.
You may wish to change this option
/msg opsb set cachetime <seconds>
opsb will cache the results of the scans that were not successfull
(ie, IP addresses that are *NOT* open proxies) so that if a
user re-connects within the cache time, they will not be scanned again. it
is default to 1 hour.
/msg opsb exclude add <serviceshostname> 1
opsb scans every user that joins the network, including users that
come from your services host. (such as ChanServ or
Reserved Nicks). You *SHOULD* add a exclusion, so that users from your
services server are not scanned. servershostname is the name of your
services as seen on IRC. (eg, in /map or /links)
The "1" specifies a IRC server, a 0 specifies a true internet hostname.
There are many other options that you configure, though you should consult
the help interface to what they do (/msg opsb help set and /msg opsb
help exclude). In 99% of the cases, it is not necessary to
change these settings, unless you are absolutly sure of what you are
doing, or one of the NeoStats helpers advises you to.
==============================================================================
More Information and Support
==============================================================================
You can get more help with opsb by visiting
http://www.neostats.net/forums/
If your question is *NOT* answered there, then you can visit us at
irc://irc.irc-chat.org/#neostats. We will *NOT* answer questions that have
already been answered in this file, or on the forums, so make sure you
read both carefully.
opsb is written and maintained by fish <fish@dynam.ac>

795
config.status Executable file
View file

@ -0,0 +1,795 @@
#! /bin/sh
# Generated by configure.
# Run this file to recreate the current configuration.
# Compiler output produced by configure, useful for debugging
# configure, is in config.log if it exists.
debug=false
SHELL=${CONFIG_SHELL-/bin/sh}
## --------------------- ##
## M4sh Initialization. ##
## --------------------- ##
# Be Bourne compatible
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
emulate sh
NULLCMD=:
elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
set -o posix
fi
# NLS nuisances.
# Support unset when possible.
if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
as_unset=unset
else
as_unset=false
fi
(set +x; test -n "`(LANG=C; export LANG) 2>&1`") &&
{ $as_unset LANG || test "${LANG+set}" != set; } ||
{ LANG=C; export LANG; }
(set +x; test -n "`(LC_ALL=C; export LC_ALL) 2>&1`") &&
{ $as_unset LC_ALL || test "${LC_ALL+set}" != set; } ||
{ LC_ALL=C; export LC_ALL; }
(set +x; test -n "`(LC_TIME=C; export LC_TIME) 2>&1`") &&
{ $as_unset LC_TIME || test "${LC_TIME+set}" != set; } ||
{ LC_TIME=C; export LC_TIME; }
(set +x; test -n "`(LC_CTYPE=C; export LC_CTYPE) 2>&1`") &&
{ $as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set; } ||
{ LC_CTYPE=C; export LC_CTYPE; }
(set +x; test -n "`(LANGUAGE=C; export LANGUAGE) 2>&1`") &&
{ $as_unset LANGUAGE || test "${LANGUAGE+set}" != set; } ||
{ LANGUAGE=C; export LANGUAGE; }
(set +x; test -n "`(LC_COLLATE=C; export LC_COLLATE) 2>&1`") &&
{ $as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set; } ||
{ LC_COLLATE=C; export LC_COLLATE; }
(set +x; test -n "`(LC_NUMERIC=C; export LC_NUMERIC) 2>&1`") &&
{ $as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set; } ||
{ LC_NUMERIC=C; export LC_NUMERIC; }
(set +x; test -n "`(LC_MESSAGES=C; export LC_MESSAGES) 2>&1`") &&
{ $as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set; } ||
{ LC_MESSAGES=C; export LC_MESSAGES; }
# Name of the executable.
as_me=`(basename "$0") 2>/dev/null ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
X"$0" : 'X\(//\)$' \| \
X"$0" : 'X\(/\)$' \| \
. : '\(.\)' 2>/dev/null ||
echo X/"$0" |
sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
/^X\/\(\/\/\)$/{ s//\1/; q; }
/^X\/\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
# PATH needs CR, and LINENO needs CR and PATH.
# Avoid depending upon Character Ranges.
as_cr_letters='abcdefghijklmnopqrstuvwxyz'
as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
as_cr_Letters=$as_cr_letters$as_cr_LETTERS
as_cr_digits='0123456789'
as_cr_alnum=$as_cr_Letters$as_cr_digits
# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
echo "#! /bin/sh" >conftest.sh
echo "exit 0" >>conftest.sh
chmod +x conftest.sh
if (PATH=".;."; conftest.sh) >/dev/null 2>&1; then
PATH_SEPARATOR=';'
else
PATH_SEPARATOR=:
fi
rm -f conftest.sh
fi
as_lineno_1=$LINENO
as_lineno_2=$LINENO
as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
test "x$as_lineno_1" != "x$as_lineno_2" &&
test "x$as_lineno_3" = "x$as_lineno_2" || {
# Find who we are. Look in the path if we contain no path at all
# relative or not.
case $0 in
*[\\/]* ) as_myself=$0 ;;
*) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
done
;;
esac
# We did not find ourselves, most probably we were run as `sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
as_myself=$0
fi
if test ! -f "$as_myself"; then
{ { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
{ (exit 1); exit 1; }; }
fi
case $CONFIG_SHELL in
'')
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for as_base in sh bash ksh sh5; do
case $as_dir in
/*)
if ("$as_dir/$as_base" -c '
as_lineno_1=$LINENO
as_lineno_2=$LINENO
as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
test "x$as_lineno_1" != "x$as_lineno_2" &&
test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
CONFIG_SHELL=$as_dir/$as_base
export CONFIG_SHELL
exec "$CONFIG_SHELL" "$0" ${1+"$@"}
fi;;
esac
done
done
;;
esac
# Create $as_me.lineno as a copy of $as_myself, but with $LINENO
# uniformly replaced by the line number. The first 'sed' inserts a
# line-number line before each line; the second 'sed' does the real
# work. The second script uses 'N' to pair each line-number line
# with the numbered line, and appends trailing '-' during
# substitution so that $LINENO is not a special case at line end.
# (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
# second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
sed '=' <$as_myself |
sed '
N
s,$,-,
: loop
s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
t loop
s,-$,,
s,^['$as_cr_digits']*\n,,
' >$as_me.lineno &&
chmod +x $as_me.lineno ||
{ { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
{ (exit 1); exit 1; }; }
# Don't try to exec as it changes $[0], causing all sort of problems
# (the dirname of $[0] is not the place where we might find the
# original and so on. Autoconf is especially sensible to this).
. ./$as_me.lineno
# Exit status is that of the last command.
exit
}
case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
*c*,-n*) ECHO_N= ECHO_C='
' ECHO_T=' ' ;;
*c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
*) ECHO_N= ECHO_C='\c' ECHO_T= ;;
esac
if expr a : '\(a\)' >/dev/null 2>&1; then
as_expr=expr
else
as_expr=false
fi
rm -f conf$$ conf$$.exe conf$$.file
echo >conf$$.file
if ln -s conf$$.file conf$$ 2>/dev/null; then
# We could just check for DJGPP; but this test a) works b) is more generic
# and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
if test -f conf$$.exe; then
# Don't use ln at all; we don't have any links
as_ln_s='cp -p'
else
as_ln_s='ln -s'
fi
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
as_ln_s='cp -p'
fi
rm -f conf$$ conf$$.exe conf$$.file
as_executable_p="test -f"
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
# Sed expression to map a string onto a valid variable name.
as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
# IFS
# We need space, tab and new line, in precisely that order.
as_nl='
'
IFS=" $as_nl"
# CDPATH.
$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=$PATH_SEPARATOR; export CDPATH; }
exec 6>&1
# Open the log real soon, to keep \$[0] and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. Logging --version etc. is OK.
exec 5>>config.log
{
echo
sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
## Running $as_me. ##
_ASBOX
} >&5
cat >&5 <<_CSEOF
This file was extended by $as_me, which was
generated by GNU Autoconf 2.53. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
CONFIG_LINKS = $CONFIG_LINKS
CONFIG_COMMANDS = $CONFIG_COMMANDS
$ $0 $@
_CSEOF
echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
echo >&5
config_files=" Makefile"
config_headers=" modconfig.h"
ac_cs_usage="\
\`$as_me' instantiates files from templates according to the
current configuration.
Usage: $0 [OPTIONS] [FILE]...
-h, --help print this help, then exit
-V, --version print version number, then exit
-d, --debug don't remove temporary files
--recheck update $as_me by reconfiguring in the same conditions
--file=FILE[:TEMPLATE]
instantiate the configuration file FILE
--header=FILE[:TEMPLATE]
instantiate the configuration header FILE
Configuration files:
$config_files
Configuration headers:
$config_headers
Report bugs to <bug-autoconf@gnu.org>."
ac_cs_version="\
config.status
configured by ./configure, generated by GNU Autoconf 2.53,
with options \"\"
Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
srcdir=.
INSTALL="/usr/bin/install -c"
# If no file are specified by the user, then we need to provide default
# value. By we need to know if files were specified by the user.
ac_need_defaults=:
while test $# != 0
do
case $1 in
--*=*)
ac_option=`expr "x$1" : 'x\([^=]*\)='`
ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
shift
set dummy "$ac_option" "$ac_optarg" ${1+"$@"}
shift
;;
-*);;
*) # This is not an option, so the user has probably given explicit
# arguments.
ac_need_defaults=false;;
esac
case $1 in
# Handling of the options.
-recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
echo "running /bin/sh ./configure " " --no-create --no-recursion"
exec /bin/sh ./configure --no-create --no-recursion ;;
--version | --vers* | -V )
echo "$ac_cs_version"; exit 0 ;;
--he | --h)
# Conflict between --help and --header
{ { echo "$as_me:$LINENO: error: ambiguous option: $1
Try \`$0 --help' for more information." >&5
echo "$as_me: error: ambiguous option: $1
Try \`$0 --help' for more information." >&2;}
{ (exit 1); exit 1; }; };;
--help | --hel | -h )
echo "$ac_cs_usage"; exit 0 ;;
--debug | --d* | -d )
debug=: ;;
--file | --fil | --fi | --f )
shift
CONFIG_FILES="$CONFIG_FILES $1"
ac_need_defaults=false;;
--header | --heade | --head | --hea )
shift
CONFIG_HEADERS="$CONFIG_HEADERS $1"
ac_need_defaults=false;;
# This is an error.
-*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
Try \`$0 --help' for more information." >&5
echo "$as_me: error: unrecognized option: $1
Try \`$0 --help' for more information." >&2;}
{ (exit 1); exit 1; }; } ;;
*) ac_config_targets="$ac_config_targets $1" ;;
esac
shift
done
for ac_config_target in $ac_config_targets
do
case "$ac_config_target" in
# Handling of arguments.
"Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"modconfig.h" ) CONFIG_HEADERS="$CONFIG_HEADERS modconfig.h" ;;
*) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
{ (exit 1); exit 1; }; };;
esac
done
# If the user did not use the arguments to specify the items to instantiate,
# then the envvar interface is used. Set only those that are not.
# We use the long form for the default assignment because of an extremely
# bizarre bug on SunOS 4.1.3.
if $ac_need_defaults; then
test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
fi
# Create a temporary directory, and hook for its removal unless debugging.
$debug ||
{
trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
trap '{ (exit 1); exit 1; }' 1 2 13 15
}
# Create a (secure) tmp directory for tmp files.
: ${TMPDIR=/tmp}
{
tmp=`(umask 077 && mktemp -d -q "$TMPDIR/csXXXXXX") 2>/dev/null` &&
test -n "$tmp" && test -d "$tmp"
} ||
{
tmp=$TMPDIR/cs$$-$RANDOM
(umask 077 && mkdir $tmp)
} ||
{
echo "$me: cannot create a temporary directory in $TMPDIR" >&2
{ (exit 1); exit 1; }
}
#
# CONFIG_FILES section.
#
# No need to generate the scripts if there are no CONFIG_FILES.
# This happens for instance when ./config.status config.h
if test -n "$CONFIG_FILES"; then
# Protect against being on the right side of a sed subst in config.status.
sed 's/,@/@@/; s/@,/@@/; s/,;t t$/@;t t/; /@;t t$/s/[\\&,]/\\&/g;
s/@@/,@/; s/@@/@,/; s/@;t t$/,;t t/' >$tmp/subs.sed <<\CEOF
s,@SHELL@,/bin/sh,;t t
s,@PATH_SEPARATOR@,:,;t t
s,@PACKAGE_NAME@,,;t t
s,@PACKAGE_TARNAME@,,;t t
s,@PACKAGE_VERSION@,,;t t
s,@PACKAGE_STRING@,,;t t
s,@PACKAGE_BUGREPORT@,,;t t
s,@exec_prefix@,${prefix},;t t
s,@prefix@,/home/fish/NeoStats/,;t t
s,@program_transform_name@,s,x,x,,;t t
s,@bindir@,${exec_prefix}/bin,;t t
s,@sbindir@,${exec_prefix}/sbin,;t t
s,@libexecdir@,${exec_prefix}/libexec,;t t
s,@datadir@,${prefix}/share,;t t
s,@sysconfdir@,${prefix}/etc,;t t
s,@sharedstatedir@,${prefix}/com,;t t
s,@localstatedir@,${prefix}/var,;t t
s,@libdir@,${exec_prefix}/lib,;t t
s,@includedir@,${prefix}/include,;t t
s,@oldincludedir@,/usr/include,;t t
s,@infodir@,${prefix}/info,;t t
s,@mandir@,${prefix}/man,;t t
s,@build_alias@,,;t t
s,@host_alias@,,;t t
s,@target_alias@,,;t t
s,@DEFS@,-DHAVE_CONFIG_H,;t t
s,@ECHO_C@,,;t t
s,@ECHO_N@,-n,;t t
s,@ECHO_T@,,;t t
s,@LIBS@,,;t t
s,@CC@,gcc,;t t
s,@CFLAGS@, -O2 -Wall,;t t
s,@LDFLAGS@,,;t t
s,@CPPFLAGS@,,;t t
s,@ac_ct_CC@,gcc,;t t
s,@EXEEXT@,,;t t
s,@OBJEXT@,o,;t t
s,@INSTALL_PROGRAM@,${INSTALL},;t t
s,@INSTALL_SCRIPT@,${INSTALL},;t t
s,@INSTALL_DATA@,${INSTALL} -m 644,;t t
s,@DIRINST@,/home/fish/NeoStats/,;t t
CEOF
# Split the substitutions into bite-sized pieces for seds with
# small command number limits, like on Digital OSF/1 and HP-UX.
ac_max_sed_lines=48
ac_sed_frag=1 # Number of current file.
ac_beg=1 # First line for current file.
ac_end=$ac_max_sed_lines # Line after last line for current file.
ac_more_lines=:
ac_sed_cmds=
while $ac_more_lines; do
if test $ac_beg -gt 1; then
sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
else
sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
fi
if test ! -s $tmp/subs.frag; then
ac_more_lines=false
else
# The purpose of the label and of the branching condition is to
# speed up the sed processing (if there are no `@' at all, there
# is no need to browse any of the substitutions).
# These are the two extra sed commands mentioned above.
(echo ':t
/@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
if test -z "$ac_sed_cmds"; then
ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
else
ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
fi
ac_sed_frag=`expr $ac_sed_frag + 1`
ac_beg=$ac_end
ac_end=`expr $ac_end + $ac_max_sed_lines`
fi
done
if test -z "$ac_sed_cmds"; then
ac_sed_cmds=cat
fi
fi # test -n "$CONFIG_FILES"
for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
# Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
case $ac_file in
- | *:- | *:-:* ) # input from stdin
cat >$tmp/stdin
ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
*:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
* ) ac_file_in=$ac_file.in ;;
esac
# Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
ac_dir=`(dirname "$ac_file") 2>/dev/null ||
$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$ac_file" : 'X\(//\)[^/]' \| \
X"$ac_file" : 'X\(//\)$' \| \
X"$ac_file" : 'X\(/\)' \| \
. : '\(.\)' 2>/dev/null ||
echo X"$ac_file" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
/^X\(\/\/\)$/{ s//\1/; q; }
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
{ case "$ac_dir" in
[\\/]* | ?:[\\/]* ) as_incr_dir=;;
*) as_incr_dir=.;;
esac
as_dummy="$ac_dir"
for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do
case $as_mkdir_dir in
# Skip DOS drivespec
?:) as_incr_dir=$as_mkdir_dir ;;
*)
as_incr_dir=$as_incr_dir/$as_mkdir_dir
test -d "$as_incr_dir" ||
mkdir "$as_incr_dir" ||
{ { echo "$as_me:$LINENO: error: cannot create \"$ac_dir\"" >&5
echo "$as_me: error: cannot create \"$ac_dir\"" >&2;}
{ (exit 1); exit 1; }; }
;;
esac
done; }
ac_builddir=.
if test "$ac_dir" != .; then
ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
# A "../" for each directory in $ac_dir_suffix.
ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
else
ac_dir_suffix= ac_top_builddir=
fi
case $srcdir in
.) # No --srcdir option. We are building in place.
ac_srcdir=.
if test -z "$ac_top_builddir"; then
ac_top_srcdir=.
else
ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
fi ;;
[\\/]* | ?:[\\/]* ) # Absolute path.
ac_srcdir=$srcdir$ac_dir_suffix;
ac_top_srcdir=$srcdir ;;
*) # Relative path.
ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
ac_top_srcdir=$ac_top_builddir$srcdir ;;
esac
# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
# absolute.
ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd`
ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
case $INSTALL in
[\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
*) ac_INSTALL=$ac_top_builddir$INSTALL ;;
esac
if test x"$ac_file" != x-; then
{ echo "$as_me:$LINENO: creating $ac_file" >&5
echo "$as_me: creating $ac_file" >&6;}
rm -f "$ac_file"
fi
# Let's still pretend it is `configure' which instantiates (i.e., don't
# use $as_me), people would be surprised to read:
# /* config.h. Generated by config.status. */
if test x"$ac_file" = x-; then
configure_input=
else
configure_input="$ac_file. "
fi
configure_input=$configure_input"Generated from `echo $ac_file_in |
sed 's,.*/,,'` by configure."
# First look for the input files in the build tree, otherwise in the
# src tree.
ac_file_inputs=`IFS=:
for f in $ac_file_in; do
case $f in
-) echo $tmp/stdin ;;
[\\/$]*)
# Absolute (can't be DOS-style, as IFS=:)
test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
echo "$as_me: error: cannot find input file: $f" >&2;}
{ (exit 1); exit 1; }; }
echo $f;;
*) # Relative
if test -f "$f"; then
# Build tree
echo $f
elif test -f "$srcdir/$f"; then
# Source tree
echo $srcdir/$f
else
# /dev/null tree
{ { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
echo "$as_me: error: cannot find input file: $f" >&2;}
{ (exit 1); exit 1; }; }
fi;;
esac
done` || { (exit 1); exit 1; }
sed "/^[ ]*VPATH[ ]*=/{
s/:*\$(srcdir):*/:/;
s/:*\${srcdir}:*/:/;
s/:*@srcdir@:*/:/;
s/^\([^=]*=[ ]*\):*/\1/;
s/:*$//;
s/^[^=]*=[ ]*$//;
}
:t
/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
s,@configure_input@,$configure_input,;t t
s,@srcdir@,$ac_srcdir,;t t
s,@abs_srcdir@,$ac_abs_srcdir,;t t
s,@top_srcdir@,$ac_top_srcdir,;t t
s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
s,@builddir@,$ac_builddir,;t t
s,@abs_builddir@,$ac_abs_builddir,;t t
s,@top_builddir@,$ac_top_builddir,;t t
s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
s,@INSTALL@,$ac_INSTALL,;t t
" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
rm -f $tmp/stdin
if test x"$ac_file" != x-; then
mv $tmp/out $ac_file
else
cat $tmp/out
rm -f $tmp/out
fi
done
#
# CONFIG_HEADER section.
#
# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
# NAME is the cpp macro being defined and VALUE is the value it is being given.
#
# ac_d sets the value in "#define NAME VALUE" lines.
ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)'
ac_dB='[ ].*$,\1#\2'
ac_dC=' '
ac_dD=',;t'
# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
ac_uB='$,\1#\2define\3'
ac_uC=' '
ac_uD=',;t'
for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
# Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
case $ac_file in
- | *:- | *:-:* ) # input from stdin
cat >$tmp/stdin
ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
*:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
* ) ac_file_in=$ac_file.in ;;
esac
test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
echo "$as_me: creating $ac_file" >&6;}
# First look for the input files in the build tree, otherwise in the
# src tree.
ac_file_inputs=`IFS=:
for f in $ac_file_in; do
case $f in
-) echo $tmp/stdin ;;
[\\/$]*)
# Absolute (can't be DOS-style, as IFS=:)
test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
echo "$as_me: error: cannot find input file: $f" >&2;}
{ (exit 1); exit 1; }; }
echo $f;;
*) # Relative
if test -f "$f"; then
# Build tree
echo $f
elif test -f "$srcdir/$f"; then
# Source tree
echo $srcdir/$f
else
# /dev/null tree
{ { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
echo "$as_me: error: cannot find input file: $f" >&2;}
{ (exit 1); exit 1; }; }
fi;;
esac
done` || { (exit 1); exit 1; }
# Remove the trailing spaces.
sed 's/[ ]*$//' $ac_file_inputs >$tmp/in
# Handle all the #define templates only if necessary.
if egrep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then
# If there are no defines, we may have an empty if/fi
:
cat >$tmp/defines.sed <<CEOF
/^[ ]*#[ ]*define/!b
t clr
: clr
${ac_dA}PACKAGE_NAME${ac_dB}PACKAGE_NAME${ac_dC}""${ac_dD}
${ac_dA}PACKAGE_TARNAME${ac_dB}PACKAGE_TARNAME${ac_dC}""${ac_dD}
${ac_dA}PACKAGE_VERSION${ac_dB}PACKAGE_VERSION${ac_dC}""${ac_dD}
${ac_dA}PACKAGE_STRING${ac_dB}PACKAGE_STRING${ac_dC}""${ac_dD}
${ac_dA}PACKAGE_BUGREPORT${ac_dB}PACKAGE_BUGREPORT${ac_dC}""${ac_dD}
CEOF
sed -f $tmp/defines.sed $tmp/in >$tmp/out
rm -f $tmp/in
mv $tmp/out $tmp/in
fi # egrep
# Handle all the #undef templates
cat >$tmp/undefs.sed <<CEOF
/^[ ]*#[ ]*undef/!b
t clr
: clr
${ac_uA}PACKAGE_NAME${ac_uB}PACKAGE_NAME${ac_uC}""${ac_uD}
${ac_uA}PACKAGE_TARNAME${ac_uB}PACKAGE_TARNAME${ac_uC}""${ac_uD}
${ac_uA}PACKAGE_VERSION${ac_uB}PACKAGE_VERSION${ac_uC}""${ac_uD}
${ac_uA}PACKAGE_STRING${ac_uB}PACKAGE_STRING${ac_uC}""${ac_uD}
${ac_uA}PACKAGE_BUGREPORT${ac_uB}PACKAGE_BUGREPORT${ac_uC}""${ac_uD}
s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
CEOF
sed -f $tmp/undefs.sed $tmp/in >$tmp/out
rm -f $tmp/in
mv $tmp/out $tmp/in
# Let's still pretend it is `configure' which instantiates (i.e., don't
# use $as_me), people would be surprised to read:
# /* config.h. Generated by config.status. */
if test x"$ac_file" = x-; then
echo "/* Generated by configure. */" >$tmp/config.h
else
echo "/* $ac_file. Generated by configure. */" >$tmp/config.h
fi
cat $tmp/in >>$tmp/config.h
rm -f $tmp/in
if test x"$ac_file" != x-; then
if cmp -s $ac_file $tmp/config.h 2>/dev/null; then
{ echo "$as_me:$LINENO: $ac_file is unchanged" >&5
echo "$as_me: $ac_file is unchanged" >&6;}
else
ac_dir=`(dirname "$ac_file") 2>/dev/null ||
$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$ac_file" : 'X\(//\)[^/]' \| \
X"$ac_file" : 'X\(//\)$' \| \
X"$ac_file" : 'X\(/\)' \| \
. : '\(.\)' 2>/dev/null ||
echo X"$ac_file" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
/^X\(\/\/\)$/{ s//\1/; q; }
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
{ case "$ac_dir" in
[\\/]* | ?:[\\/]* ) as_incr_dir=;;
*) as_incr_dir=.;;
esac
as_dummy="$ac_dir"
for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do
case $as_mkdir_dir in
# Skip DOS drivespec
?:) as_incr_dir=$as_mkdir_dir ;;
*)
as_incr_dir=$as_incr_dir/$as_mkdir_dir
test -d "$as_incr_dir" ||
mkdir "$as_incr_dir" ||
{ { echo "$as_me:$LINENO: error: cannot create \"$ac_dir\"" >&5
echo "$as_me: error: cannot create \"$ac_dir\"" >&2;}
{ (exit 1); exit 1; }; }
;;
esac
done; }
rm -f $ac_file
mv $tmp/config.h $ac_file
fi
else
cat $tmp/config.h
rm -f $tmp/config.h
fi
done
{ (exit 0); exit 0; }

3112
configure vendored Executable file

File diff suppressed because it is too large Load diff

66
configure.in Normal file
View file

@ -0,0 +1,66 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(opsb.c)
AC_CONFIG_HEADER(modconfig.h)
PACKAGE=opsb
VERSION=1.0
DIRINST=~/NeoStats/
AC_PREFIX_DEFAULT(~/NeoStats/)
CFLAGS="$CFLAGS -O2 -Wall"
dnl Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL
AC_MSG_CHECKING(Location of NeoStats...)
AC_ARG_WITH(neostats,
[ --with-neostats=DIR Location of NeoStats installation],
[DIRINST=$withval])
AC_MSG_RESULT($DIRINST)
AC_CHECK_FILE($DIRINST/include/dl.h,
[INCLUDEDIR="$DIRINST/include/"],
[AC_MSG_ERROR(Can't find existing NeoStats Installation please supply with --with-neostats option)])
dnl check if we are running with Debug....
AC_MSG_CHECKING(Whether to Enable Debuging...)
AC_ARG_ENABLE(debug,
[ --enable-debug - Enable Debuging],
[ case "$enableval" in
yes)
CFLAGS="$CFLAGS -ggdb"
AC_MSG_RESULT(yes - Watch your Log Files)
;;
*)
AC_MSG_RESULT(no)
;;
esac],
AC_MSG_RESULT(no)
)
AC_SUBST(DIRINST)
AC_SUBST(CFLAGS)
AC_OUTPUT(Makefile)
echo "(*----------------------------------------------------------*)"
echo "(| Important Instructions |)"
echo "(*----------------------------------------------------------*)"
echo "(| To compile your module, please type 'make' |)"
echo "(| If make completes without errors, then you |)"
echo "(| Must 'make install', but please be sure that NeoStats |)"
echo "(| Is not currently running with a module of the same name |)"
echo "(| Running, otherwise Make install will not work |)"
echo "(| !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |)"
echo "(| If you are running a BSD, make install may produce a |)"
echo "(| Error, if that is the case, then please manually copy |)"
echo "(| opsb.so to the NeoStats/dl directory |)"
echo "(| !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |)"
echo "(*----------------------------------------------------------*)"
echo "(| For Support please visit: |)"
echo "(| IRC: /server irc.irc-chat.org |)"
echo "(| #neostats channel |)"
echo "(| WWW: http://www.neostats.net/boards/ |)"
echo "(*----------------------------------------------------------*)"
echo "(|This Module was written by: |)"
echo "(| fish (fish@dynam.ac) |)"
echo "(*----------------------------------------------------------*)"

251
install-sh Executable file
View file

@ -0,0 +1,251 @@
#!/bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
chmodcmd=""
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0

0
modconfig.h.in Normal file
View file

989
opsb.c Normal file
View file

@ -0,0 +1,989 @@
/* NetStats - IRC Statistical Services Copyright (c) 1999 Adam Rutter,
** Justin Hammond http://codeworks.kamserve.com
*
** Based from GeoStats 1.1.0 by Johnathan George net@lite.net
*
** NetStats CVS Identification
** $Id: opsb.c,v 1.1 2002/08/31 09:28:35 fishwaldo Exp $
*/
#include <stdio.h>
#include <fnmatch.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include "dl.h"
#include "stats.h"
#include "opsb.h"
const char opsbversion_date[] = __DATE__;
const char opsbversion_time[] = __TIME__;
void reportdns(char *data, adns_answer *a);
void dnsblscan(char *data, adns_answer *a);
static int ScanNick(char **av, int ac);
int startscan(scaninfo *scandata);
int do_set(User *u, char **av, int ac);
void savecache();
void loadcache();
void unconf();
extern const char *opsb_help[];
extern const char *opsb_help_oper[];
extern const char *opsb_help_lookup[];
extern const char *opsb_help_info[];
extern const char *opsb_help_check[];
extern const char *opsb_help_status[];
extern const char *opsb_help_set[];
extern const char *opsb_help_exclude[];
Module_Info my_info[] = { {
"OPSB",
"A Open Proxy Scanning Bot",
"1.0Beta1"
} };
int new_m_version(char *origin, char **av, int ac) {
snumeric_cmd(351,origin, "Module OPSB Loaded, Version: %s %s %s",my_info[0].module_version,opsbversion_date,opsbversion_time);
return 0;
}
Functions my_fn_list[] = {
{ MSG_VERSION, new_m_version, 1 },
#ifdef HAVE_TOKEN_SUP
{ TOK_VERSION, new_m_version, 1 },
#endif
{ NULL, NULL, 0 }
};
int findscan(const void *key1, const void *key2) {
const scaninfo *chan1 = key1;
return (strcasecmp(chan1->who, key2));
}
int __Bot_Message(char *origin, char **argv, int argc)
{
User *u, *u2;
lnode_t *lnode;
scaninfo *scandata;
exemptinfo *exempts;
int lookuptype, i;
u = finduser(origin);
if (!u) {
log("Unable to find user %s (opsb)", origin);
return -1;
}
if (!strcasecmp(argv[1], "help")) {
if (argc == 2) {
privmsg_list(u->nick, s_opsb, opsb_help);
if (UserLevel(u) >= 50)
privmsg_list(u->nick, s_opsb, opsb_help_oper);
} else if (!strcasecmp(argv[2], "lookup")) {
privmsg_list(u->nick, s_opsb, opsb_help_lookup);
} else if (!strcasecmp(argv[2], "info")) {
privmsg_list(u->nick, s_opsb, opsb_help_info);
} else if ((!strcasecmp(argv[2], "check") && UserLevel(u) >= 50)) {
privmsg_list(u->nick, s_opsb, opsb_help_check);
} else if ((!strcasecmp(argv[2], "status") && UserLevel(u) >= 50)) {
privmsg_list(u->nick, s_opsb, opsb_help_status);
} else if ((!strcasecmp(argv[2], "set") && UserLevel(u) >= 100)) {
privmsg_list(u->nick, s_opsb, opsb_help_set);
} else if ((!strcasecmp(argv[2], "exclude") && UserLevel(u) > 100)) {
privmsg_list(u->nick, s_opsb, opsb_help_exclude);
} else {
prefmsg(u->nick, s_opsb, "Invalid Syntax. /msg %s help for more info", s_opsb);
}
return 1;
} else if (!strcasecmp(argv[1], "info")) {
privmsg_list(u->nick, s_opsb, opsb_help_info);
return 1;
} else if (!strcasecmp(argv[1], "status")) {
if (UserLevel(u) < 50) {
prefmsg(u->nick, s_opsb, "Access Denied");
chanalert(s_opsb, "%s tried to view status, but is not a operator", u->nick);
return 1;
}
send_status(u);
return 1;
} else if (!strcasecmp(argv[1], "lookup")) {
if (argc < 3) {
prefmsg(u->nick, s_opsb, "Invalid Syntax. /msg %s help lookup for more help", s_opsb);
return 0;
}
scandata = malloc(sizeof(scaninfo));
scandata->dnsstate = REPORT_DNS;
strncpy(scandata->who, u->nick, MAXNICK);
strncpy(scandata->lookup, argv[2], MAXHOST);
/* if the lists are full, don't add it, and alert the user */
if (list_isfull(opsbl)) {
if (list_isfull(opsbq)) {
prefmsg(u->nick, s_opsb, "Too Busy. Try again Later");
free(scandata);
return 0;
}
prefmsg(u->nick, s_opsb, "OPSB list is full, queuing your request");
lnode = lnode_create(scandata);
list_append(opsbq, lnode);
}
if (inet_aton(scandata->lookup, NULL) > 0) {
lookuptype = adns_r_ptr;
} else {
if (argc == 4) {
if (!strcasecmp(argv[3], "txt"))
lookuptype = adns_r_txt;
else if (!strcasecmp(argv[3], "rp"))
lookuptype = adns_r_rp;
else if (!strcasecmp(argv[3], "ns"))
lookuptype = adns_r_ns;
else if (!strcasecmp(argv[3], "soa"))
lookuptype = adns_r_soa;
else
lookuptype = adns_r_a;
} else {
lookuptype = adns_r_a;
}
}
if (dns_lookup(scandata->lookup, lookuptype, reportdns, scandata->who) != 1) {
prefmsg(u->nick, s_opsb, "DnsLookup Failed.");
free(scandata);
return 0;
}
lnode = lnode_create(scandata);
list_append(opsbl, lnode);
} else if (!strcasecmp(argv[1], "check")) {
if (UserLevel(u) < 50) {
prefmsg(u->nick, s_opsb, "Access Denied");
chanalert(s_opsb, "%s tried to use check, but does not have access", u->nick);
return 0;
}
if (argc < 3) {
prefmsg(u->nick, s_opsb, "Invalid Syntax. /msg %s help check for more info", s_opsb);
return 0;
}
if ((list_find(opsbl, argv[2], findscan)) || (list_find(opsbq, argv[2], findscan))) {
prefmsg(u->nick, s_opsb, "Already Scanning (or in queue) %s. Not Scanning again", argv[2]);
return 0;
}
scandata = malloc(sizeof(scaninfo));
scandata->u = u;
if ((u2 = finduser(argv[2])) != NULL) {
/* don't scan users from my server */
if (!strcasecmp(u2->server->name, me.name)) {
prefmsg(u->nick, s_opsb, "Error, Can not scan NeoStats Bots");
return -1;
}
strncpy(scandata->who, u2->nick, MAXHOST);
strncpy(scandata->lookup, u2->hostname, MAXHOST);
strncpy(scandata->server, u2->server->name, MAXHOST);
scandata->ipaddr.s_addr = u2->ipaddr.s_addr;
if (scandata->ipaddr.s_addr > 0) {
scandata->dnsstate = DO_OPM_LOOKUP;
} else {
if (inet_aton(u2->hostname, &scandata->ipaddr) > 0)
scandata->dnsstate = DO_OPM_LOOKUP;
else {
scandata->dnsstate = GET_NICK_IP;
scandata->ipaddr.s_addr = 0;
}
}
} else {
strncpy(scandata->who, argv[2], MAXHOST);
strncpy(scandata->lookup, argv[2], MAXHOST);
bzero(scandata->server, MAXHOST);
if (inet_aton(argv[2], &scandata->ipaddr) > 0) {
scandata->dnsstate = DO_OPM_LOOKUP;
} else {
scandata->dnsstate = GET_NICK_IP;
scandata->ipaddr.s_addr = 0;
}
}
prefmsg(u->nick, s_opsb, "Checking %s for open Proxies", argv[2]);
if (!startscan(scandata))
prefmsg(u->nick, s_opsb, "Check Failed");
return 1;
} else if (!strcasecmp(argv[1], "EXCLUDE")) {
if (argc < 3) {
prefmsg(u->nick, s_opsb, "Syntax Error. /msg %s help exclude", s_opsb);
return 0;
}
if (!strcasecmp(argv[2], "LIST")) {
lnode = list_first(exempt);
i = 1;
prefmsg(u->nick, s_opsb, "Exception List:");
while (lnode) {
exempts = lnode_get(lnode);
prefmsg(u->nick, s_opsb, "%d) %s %s", i, exempts->host, (exempts->server ? "(Server)" : "(Client)"));
++i;
lnode = list_next(exempt, lnode);
}
prefmsg(u->nick, s_opsb, "End of List.");
chanalert(s_opsb, "%s requested Exception List", u->nick);
} else if (!strcasecmp(argv[2], "ADD")) {
if (argc < 5) {
prefmsg(u->nick, s_opsb, "Syntax Error. /msg %s help exclude", s_opsb);
return 0;
}
if (list_isfull(exempt)) {
prefmsg(u->nick, s_opsb, "Error, Exception list is full", s_opsb);
return 0;
}
if (!index(argv[3], '.')) {
prefmsg(u->nick, s_opsb, "Host field does not contain a vaild host");
return 0;
}
exempts = malloc(sizeof(exemptinfo));
snprintf(exempts->host, MAXHOST, "%s", argv[3]);
if (atoi(argv[4]) > 0)
exempts->server = 1;
else
exempts->server = 0;
lnode = lnode_create(exempts);
list_append(exempt, lnode);
prefmsg(u->nick, s_opsb, "Added %s (%s) exception to list", exempts->host, (exempts->server ? "(Server)" : "(Client)"));
chanalert(s_opsb, "%s added %s (%s) exception to list", u->nick, exempts->host, (exempts->server ? "(Server)" : "(Client)"));
} else if (!strcasecmp(argv[2], "DEL")) {
if (argc < 3) {
prefmsg(u->nick, s_opsb, "Syntax Error. /msg %s help exclude", s_opsb);
return 0;
}
if (atoi(argv[3]) != 0) {
lnode = list_first(exempt);
i = 1;
while (lnode) {
if (i == atoi(argv[3])) {
/* delete the entry */
exempts = lnode_get(lnode);
list_delete(exempt, lnode);
prefmsg(u->nick, s_opsb, "Deleted %s %s out of exception list", exempts->host, (exempts->server ? "(Server)" : "(Client)"));
chanalert(s_opsb, "%s deleted %s %s out of exception list", u->nick, exempts->host, (exempts->server ? "(Server)" : "(Client)"));
free(exempts);
return 1;
}
++i;
lnode = list_next(exempt, lnode);
}
/* if we get here, then we can't find the entry */
prefmsg(u->nick, s_opsb, "Error, Can't find entry %d. /msg %s exclude list", atoi(argv[3]), s_opsb);
return 0;
} else {
prefmsg(u->nick, s_opsb, "Error, Out of Range");
return 0;
}
} else {
prefmsg(u->nick, s_opsb, "Syntax Error. /msg %s help exclude", s_opsb);
return 0;
}
} else if (!strcasecmp(argv[1], "SET")) {
if (argc < 3) {
prefmsg(u->nick, s_opsb, "Syntax Error. /msg %s help set", s_opsb);
return 0;
}
do_set(u, argv, argc);
if (opsb.confed == 1)
savecache();
} else {
prefmsg(u->nick, s_opsb, "Syntax Error. /msg %s help", s_opsb);
}
return 1;
}
int do_set(User *u, char **av, int ac) {
char *buf;
if (UserLevel(u) < 100) {
prefmsg(u->nick, s_opsb, "Access Denied");
chanalert(s_opsb, "%s tried to set, but doesn't have access");
return 0;
}
if (!strcasecmp(av[2], "TARGETIP")) {
if (!inet_addr(av[3])) {
prefmsg(u->nick, s_opsb, "Invalid IP address (Can not be hostname) in TARGETIP");
return 0;
}
snprintf(opsb.targethost, MAXHOST, "%s", av[3]);
prefmsg(u->nick, s_opsb, "Target IP set to %s", av[3]);
chanalert(s_opsb, "%s changed the target ip to %s", u->nick, av[3]);
opsb.confed = 1;
return 1;
} else if (!strcasecmp(av[2], "TARGETPORT")) {
if (!atoi(av[3])) {
prefmsg(u->nick, s_opsb, "Invalid Port (Must be numeric) in TARGETPORT");
return 0;
}
opsb.targetport = atoi(av[3]);
prefmsg(u->nick, s_opsb, "Target PORT set to %d", opsb.targetport);
chanalert(s_opsb, "%s changed the target port to %d", u->nick, opsb.targetport);
opsb.confed = 1;
return 1;
} else if (!strcasecmp(av[2], "OPMDOMAIN")) {
if (!index(av[3], '.')) {
prefmsg(u->nick, s_opsb, "Invalid Domain name in OPMDOMAIN");
return 0;
}
snprintf(opsb.opmdomain, MAXHOST, "%s", av[3]);
prefmsg(u->nick, s_opsb, "OPM Domain changed to %s", opsb.opmdomain);
chanalert(s_opsb, "%s changed the opm domain to %s", u->nick, opsb.opmdomain);
opsb.confed = 1;
return 1;
} else if (!strcasecmp(av[2], "MAXBYTES")) {
if (!atoi(av[3])) {
prefmsg(u->nick, s_opsb, "Invalid setting (Must be numeric)");
return 0;
}
opsb.maxbytes = atoi(av[3]);
prefmsg(u->nick, s_opsb, "Max Bytes set to %d", opsb.maxbytes);
chanalert(s_opsb, "%s changed the Max Bytes setting to %d", u->nick, opsb.maxbytes);
opsb.confed = 1;
return 1;
} else if (!strcasecmp(av[2], "TIMEOUT")) {
if (!atoi(av[3]) || (atoi(av[3]) > 120)) {
prefmsg(u->nick, s_opsb, "Setting must be numeric, and below 120");
return 0;
}
opsb.timeout = atoi(av[3]);
prefmsg(u->nick, s_opsb, "Timeout set to %d", opsb.timeout);
chanalert(s_opsb, "%s changed the timeout to %d", u->nick, opsb.timeout);
opsb.confed = 1;
return 1;
} else if (!strcasecmp(av[2], "OPENSTRING")) {
buf = joinbuf(av, ac, 3);
snprintf(opsb.lookforstring, 512, "%s", buf);
free(buf);
prefmsg(u->nick, s_opsb, "OPENSTRING changed to %s", opsb.lookforstring);
chanalert(s_opsb, "%s changed OPENSTRING to %s", u->nick, opsb.lookforstring);
opsb.confed = 1;
return 0;
} else if (!strcasecmp(av[2], "SPLITTIME")) {
if (!atoi(av[3])) {
prefmsg(u->nick, s_opsb, "Error, Setting must be numeric");
return 0;
}
opsb.timedif = atoi(av[3]);
prefmsg(u->nick, s_opsb, "SPLITTIME changed to %d", opsb.timedif);
chanalert(s_opsb, "%s changed the split time to %d", u->nick, opsb.timedif);
opsb.confed = 1;
return 0;
} else if (!strcasecmp(av[2], "SCANMSG")) {
buf = joinbuf(av, ac, 3);
snprintf(opsb.scanmsg, 512, "%s", buf);
free(buf);
prefmsg(u->nick, s_opsb, "ScanMessage changed to %s", opsb.scanmsg);
chanalert(s_opsb, "%s changed the scan message to %s", u->nick, opsb.scanmsg);
opsb.confed = 1;
return 0;
} else if (!strcasecmp(av[2], "BANTIME")) {
if (!atoi(av[3])) {
prefmsg(u->nick, s_opsb, "Error, Bantime must be numeric (in Seconds)");
return 0;
}
opsb.bantime = atoi(av[3]);
prefmsg(u->nick, s_opsb, "Ban time changed to %d", opsb.bantime);
chanalert(s_opsb, "%s changed ban time to %d", u->nick, opsb.bantime);
opsb.confed = 1;
return 0;
} else if (!strcasecmp(av[2], "CACHETIME")) {
if (!atoi(av[3])) {
prefmsg(u->nick, s_opsb, "Error, CacheTime must be numeric (in Seconds)");
return 0;
}
opsb.cachetime = atoi(av[3]);
prefmsg(u->nick, s_opsb, "CacheTime set to %d", opsb.cachetime);
chanalert(s_opsb, "%s changed cachetime to %d", u->nick, opsb.cachetime);
opsb.confed = 1;
return 0;
} else {
prefmsg(u->nick, s_opsb, "TargetIP: %s", opsb.targethost);
prefmsg(u->nick, s_opsb, "TargetPort: %d", opsb.targetport);
prefmsg(u->nick, s_opsb, "OPM Domain: %s", opsb.opmdomain);
prefmsg(u->nick, s_opsb, "Max Bytes: %d", opsb.maxbytes);
prefmsg(u->nick, s_opsb, "TimeOut: %d", opsb.timeout);
prefmsg(u->nick, s_opsb, "Target String: %s", opsb.lookforstring);
prefmsg(u->nick, s_opsb, "Split Time: %d", opsb.timedif);
prefmsg(u->nick, s_opsb, "ScanMessage: %s", opsb.scanmsg);
prefmsg(u->nick, s_opsb, "Ban Time: %d", opsb.bantime);
prefmsg(u->nick, s_opsb, "Configured: %s", (opsb.confed ? "Yes" : "No"));
return 0;
}
}
int Online(char **av, int ac) {
struct sockaddr_in sa;
socklen_t ulen = sizeof(struct sockaddr_in);
if (init_bot(s_opsb,"opsb",me.name,"Proxy Scanning Bot", "+xd", my_info[0].module_name) == -1 ) {
/* Nick was in use!!!! */
s_opsb = strcat(s_opsb, "_");
init_bot(s_opsb,"opsb",me.name,"Proxy Scanning Bot", "+xd", my_info[0].module_name);
}
loadcache();
if (opsb.confed == 0) add_mod_timer("unconf", "Un_configured_warn", "opsb", 60);
unconf();
if (opsb.confed == 0) {
getpeername(servsock, (struct sockaddr *)&sa, (socklen_t*)&ulen);
snprintf(opsb.targethost, MAXHOST, "%s", inet_ntoa(sa.sin_addr));
}
add_mod_timer("cleanlist", "CleanProxyList", "opsb", 1);
add_mod_timer("savecache", "SaveProxyCache", "opsb", 600);
chanalert(s_opsb, "Open Proxy Scanning bot has started (Concurrent Scans: %d Sockets %d)", opsb.socks, opsb.socks *7);
return 1;
};
void unconf() {
if (opsb.confed == 1) return;
chanalert(s_opsb, "Warning, OPSB is configured with default Settings. Please Update this ASAP");
globops(s_opsb, "Warning, OPSB is configred with default Settings, Please Update this ASAP");
}
void checkqueue() {
lnode_t *scannode;
scaninfo *scandata;
/* exit, if the list is full */
if (list_isfull(opsbl) || list_isempty(opsbq))
return;
scannode = list_first(opsbq);
scandata = lnode_get(scannode);
list_delete(opsbq, scannode);
lnode_destroy(scannode);
startscan(scandata);
}
void addtocache(unsigned long ipaddr) {
lnode_t *cachenode;
C_entry *ce;
/* pop off the oldest entry */
if (list_isfull(cache)) {
#ifdef DEBUG
log("OPSB: Deleting Tail of Cache: %d", list_count(cache));
#endif
cachenode = list_del_last(cache);
ce = lnode_get(cachenode);
lnode_destroy(cachenode);
free(ce);
}
cachenode = list_first(cache);
while (cachenode) {
ce = lnode_get(cachenode);
if (ce->ip == ipaddr) {
#ifdef DEBUG
log("OPSB: Not adding %ld to cache as it already exists", ipaddr);
#endif
// return;
}
cachenode = list_next(cache, cachenode);
}
ce = malloc(sizeof(C_entry));
ce->ip = ipaddr;
ce->when = time(NULL);
cachenode = lnode_create(ce);
list_prepend(cache, cachenode);
}
int checkcache(scaninfo *scandata) {
lnode_t *node, *node2;
C_entry *ce;
exemptinfo *exempts;
node = list_first(exempt);
while (node) {
exempts = lnode_get(node);
if ((exempts->server == 1) && (scandata->server)) {
/* match a server */
if (fnmatch(exempts->host, scandata->server, 0) == 0) {
#ifdef DEBUG
log("OPSB: User %s exempt. Matched server entry %s in Exemptions", scandata->who, exempts->host);
#endif
if (scandata->u) prefmsg(scandata->u->nick, s_opsb,"%s Matches a Server Exception %s", scandata->who, exempts->host);
return 1;
}
} else {
if (fnmatch(exempts->host, scandata->lookup, 0) == 0) {
#ifdef DEBUG
log("OPSB: User %s exempt. Matched host entry %s in exemptions", scandata->who, exempts->host);
#endif
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "%s Matches a Host Exception %s", scandata->who, exempts->host);
return 2;
}
}
node = list_next(exempt, node);
}
node = list_first(cache);
while (node) {
ce = lnode_get(node);
/* delete any old cache entries */
if ((time(NULL) - ce->when) > opsb.cachetime) {
#ifdef DEBUG
log("OPSB: Deleting old cache entry %ld", ce->ip);
#endif
node2 = list_next(cache, node);
list_delete(cache, node);
lnode_destroy(node);
free(ce);
node = node2;
break;
}
if (ce->ip == scandata->ipaddr.s_addr) {
#ifdef DEBUG
log("OPSB: user %s is already in Cache", scandata->who);
#endif
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "User %s is already in Cache", scandata->who);
return 3;
}
node = list_next(cache, node);
}
return 0;
}
void savecache() {
lnode_t *node;
unsigned long *ip;
exemptinfo *exempts;
FILE *fp = fopen("data/opsb.db", "w");
if (!fp) {
log("OPSB: warning, Can not open cache file for writting");
chanalert(s_opsb, "Warning, Can not open cache file for writting");
return;
}
fprintf(fp, "%s\n", opsb.opmdomain);
fprintf(fp, "%s\n", opsb.targethost);
fprintf(fp, "%s\n", opsb.lookforstring);
fprintf(fp, "%d\n", opsb.targetport);
fprintf(fp, "%d\n", opsb.maxbytes);
fprintf(fp, "%d\n", opsb.timeout);
fprintf(fp, "%d\n", opsb.timedif);
fprintf(fp, "%s\n", opsb.scanmsg);
fprintf(fp, "%d\n", opsb.bantime);
fprintf(fp, "%d\n", opsb.confed);
fprintf(fp, "%d\n", opsb.cachetime);
/* exempts next */
node = list_first(exempt);
while (node) {
exempts = lnode_get(node);
fprintf(fp, "%s %d\n", exempts->host, exempts->server);
node = list_next(exempt, node);
}
fprintf(fp, "#CACHE\n");
node = list_first(cache);
while (node) {
ip = lnode_get(node);
if (*ip < 1) break;
fprintf(fp, "%ld\n", *ip);
node = list_next(cache, node);
}
fclose(fp);
}
void loadcache() {
lnode_t *node;
unsigned long ip;
exemptinfo *exempts = NULL;
char buf[512];
int gotcache = 0;
FILE *fp = fopen("data/opsb.db", "r");
char *tmp;
if (!fp) {
log("OPSB: Warning, Can not open Cache file for Reading");
chanalert(s_opsb, "Warning, Can not open Cache file for Reading");
return;
}
fgets(buf, 512, fp);
snprintf(opsb.opmdomain, MAXHOST, "%s", strtok(buf, "\n"));
fgets(buf, 512, fp);
snprintf(opsb.targethost, MAXHOST, "%s", strtok(buf, "\n"));
fgets(buf, 512, fp);
snprintf(opsb.lookforstring, 512, "%s", strtok(buf, "\n"));
fgets(buf, 512, fp);
opsb.targetport = atoi(buf);
fgets(buf, 512, fp);
opsb.maxbytes = atoi(buf);
fgets(buf, 512, fp);
opsb.timeout = atoi(buf);
fgets(buf, 512, fp);
opsb.timedif = atoi(buf);
fgets(buf, 512, fp);
snprintf(opsb.scanmsg, 512, "%s", strtok(buf, "\n"));
fgets(buf, 512, fp);
opsb.bantime = atoi(buf);
fgets(buf, 512, fp);
opsb.confed = atoi(buf);
fgets(buf, 512, fp);
opsb.cachetime = atoi(buf);
while (fgets(buf, 512, fp)) {
if (!strcasecmp("#CACHE\n", buf)) {
gotcache = 1;
}
if (gotcache == 0) {
if (list_isfull(exempt))
break;
exempts = malloc(sizeof(exemptinfo));
snprintf(exempts->host, MAXHOST, "%s", strtok(buf, " "));
exempts->server = atoi(strtok(NULL, " "));
node = lnode_create(exempts);
list_prepend(exempt, node);
} else {
if (list_isfull(cache))
break;
tmp = strtok(buf, "\n");
ip = strtol(tmp, (char **)NULL, 10);
if (ip > 0) addtocache(ip);
}
}
fclose(fp);
}
EventFnList my_event_list[] = {
{ "ONLINE", Online},
{ "SIGNON", ScanNick},
{ NULL, NULL}
};
Module_Info *__module_get_info() {
return my_info;
};
Functions *__module_get_functions() {
return my_fn_list;
};
EventFnList *__module_get_events() {
return my_event_list;
};
/* this function kicks of a scan of a user that just signed on the network */
static int ScanNick(char **av, int ac) {
User *u;
scaninfo *scandata;
lnode_t *scannode;
u = finduser(av[0]);
if (!u) {
log("OPSB: Ehhh, Can't find user %s", av[0]);
return -1;
}
/* don't scan users from my own server */
if (!strcasecmp(u->server->name, me.name)) {
return -1;
}
if (time(NULL) - u->TS > opsb.timedif) {
#ifdef DEBUG
log("Netsplit Nick %s, Not Scanning", av[0]);
#endif
return -1;
}
scannode = list_find(opsbl, av[0], findscan);
if (!scannode) scannode = list_find(opsbq, av[0], findscan);
if (scannode) {
log("ScanNick(): Not scanning %s as we are already scanning them", av[0]);
return -1;
}
prefmsg(u->nick, s_opsb, "%s", opsb.scanmsg);
scandata = malloc(sizeof(scaninfo));
scandata->u = NULL;
strncpy(scandata->who, u->nick, MAXHOST);
strncpy(scandata->lookup, u->hostname, MAXHOST);
strncpy(scandata->server, u->server->name, MAXHOST);
scandata->ipaddr.s_addr = u->ipaddr.s_addr;
if (scandata->ipaddr.s_addr > 0) {
scandata->dnsstate = DO_OPM_LOOKUP;
} else {
if (inet_aton(u->hostname, &scandata->ipaddr) > 0)
scandata->dnsstate = DO_OPM_LOOKUP;
else {
scandata->dnsstate = GET_NICK_IP;
scandata->ipaddr.s_addr = 0;
}
}
if (!startscan(scandata))
chanalert(s_opsb, "Warning Can't scan %s", u->nick);
return 1;
}
/* this function is the entry point for all scans. Any scan you want to kick off is started with this function. */
/* this includes moving scans from the queue to the active list */
int startscan(scaninfo *scandata) {
lnode_t *scannode;
unsigned char a, b, c, d;
char *buf;
int buflen;
int i;
i = checkcache(scandata);
if ((i > 0) && (!scandata->u)) {
free(scandata);
return 1;
}
switch(scandata->dnsstate) {
case GET_NICK_IP:
if (list_isfull(opsbl)) {
if (list_isfull(opsbq)) {
chanalert(s_opsb, "Warning, Both Current and queue lists are full. Not Adding additional scans");
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "To Busy. Try again later");
free(scandata);
return 0;
}
scannode = lnode_create(scandata);
list_append(opsbq, scannode);
#ifdef DEBUG
log("DNS: Added %s to dns queue", scandata->who);
#endif
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "Your Request has been added to the Queue");
return 1;
}
if (dns_lookup(scandata->lookup, adns_r_a, dnsblscan, scandata->who) != 1) {
log("DNS: startscan() GET_NICK_IP dns_lookup() failed");
free(scandata);
checkqueue();
return 0;
}
scannode = lnode_create(scandata);
list_append(opsbl, scannode);
#ifdef DEBUG
log("DNS: Added getnickip to DNS active list");
#endif
return 1;
break;
case DO_OPM_LOOKUP:
if (list_isfull(opsbl)) {
if(list_isfull(opsbq)) {
chanalert(s_opsb, "Warning, Both Current and Queue lists are full, Not adding Scan");
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "Too Busy. Try again Later");
free(scandata);
return 0;
}
scannode = lnode_create(scandata);
list_append(opsbq, scannode);
#ifdef DEBUG
log("DNS: Added OPM lookup to queue", scandata->who);
#endif
return 1;
}
d = (unsigned char) (scandata->ipaddr.s_addr >> 24) & 0xFF;
c = (unsigned char) (scandata->ipaddr.s_addr >> 16) & 0xFF;
b = (unsigned char) (scandata->ipaddr.s_addr >> 8) & 0xFF;
a = (unsigned char) scandata->ipaddr.s_addr & 0xFF;
/* Enough for a reversed IP and the zone. */
buflen = 18 + strlen(opsb.opmdomain);
buf = malloc(buflen * sizeof(*buf));
snprintf(buf, buflen, "%d.%d.%d.%d.%s", d, c, b, a, opsb.opmdomain);
if (dns_lookup(buf, adns_r_a, dnsblscan, scandata->who) != 1) {
log("DNS: startscan() DO_OPM_LOOKUP dns_lookup() failed");
free(scandata);
checkqueue();
return 0;
}
scannode = lnode_create(scandata);
list_append(opsbl, scannode);
#ifdef DEBUG
log("DNS: Added OPM %s lookup to DNS active list", buf);
#endif
free(buf);
start_proxy_scan(scannode);
++opsb.scanned;
return 1;
break;
default:
log("Warning, Unknown Status in startscan()");
free(scandata);
return -1;
}
}
/* this function is called when either checking the opm list, or when we are trying to resolve the hostname */
void dnsblscan(char *data, adns_answer *a) {
lnode_t *scannode;
scaninfo *scandata;
char *show;
int len, ri;
scannode = list_find(opsbl, data, findscan);
if (!scannode) {
log("dnsblscan(): Ehhh, Something is wrong here");
return;
}
scandata = lnode_get(scannode);
if (a) {
switch(scandata->dnsstate) {
case GET_NICK_IP:
if (a->nrrs < 1) {
chanalert(s_opsb, "No Record for %s. Aborting Scan", scandata->lookup);
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "No A record for %s. Aborting Scan", scandata->lookup);
list_delete(opsbl, scannode);
lnode_destroy(scannode);
free(scandata);
checkqueue();
break;
}
adns_rr_info(a->type, 0, 0, &len, 0, 0);
ri = adns_rr_info(a->type, 0, 0, 0, a->rrs.bytes, &show);
if (!ri) {
#ifdef DEBUG
log("DNS: Got IP for %s -> %s", scandata->who, show);
#endif
if (a->nrrs > 1) {
chanalert(s_opsb, "Warning, More than one IP address for %s. Using %s only", scandata->lookup, show);
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "Warning, More than one IP address for %s. Using %s only", scandata->lookup, show);
}
if (inet_aton(show, &scandata->ipaddr) > 0) {
scandata->dnsstate = DO_OPM_LOOKUP;
list_delete(opsbl, scannode);
lnode_destroy(scannode);
startscan(scandata);
break;
} else {
log("DNS: dnsblscan() GETNICKIP failed-> %s", show);
checkqueue();
}
}
log("DNS: dnsblscan GETNICKIP rr_info failed");
list_delete(opsbl, scannode);
lnode_destroy(scannode);
free(scandata);
checkqueue();
break;
case DO_OPM_LOOKUP:
if (a->nrrs > 0) {
/* TODO: print out what type of open proxy it is based on IP address returned */
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "%s apears in DNS blacklist", scandata->lookup);
scandata->dnsstate = OPMLIST;
do_ban(scandata);
checkqueue();
} else
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "%s does not appear in DNS black list", scandata->lookup);
break;
default:
log("Warning, Unknown Status in dnsblscan()");
return;
}
return;
}
}
/* this function is to send the results to the user after a lookup command */
void reportdns(char *data, adns_answer *a) {
lnode_t *dnslookup;
scaninfo *dnsinfo;
char *show;
int i, len, ri;
dnslookup = list_find(opsbl, data, findscan);
if (!dnslookup) {
log("reportdns(): Ehhh, something wrong here");
return;
}
dnsinfo = lnode_get(dnslookup);
if (a) {
adns_rr_info(a->type, 0, 0, &len, 0, 0);
for(i = 0; i < a->nrrs; i++) {
ri = adns_rr_info(a->type, 0, 0, 0, a->rrs.bytes +i*len, &show);
if (!ri) {
prefmsg(data, s_opsb, "%s resolves to %s", dnsinfo->lookup, show);
} else {
prefmsg(data, s_opsb, "DNS error %s", adns_strerror(ri));
}
free(show);
}
if (a->nrrs < 1) {
prefmsg(data, s_opsb, "%s Does not resolve", dnsinfo->lookup);
}
} else {
prefmsg(data, s_opsb, "A unknown error occured");
}
list_delete(opsbl, dnslookup);
lnode_destroy(dnslookup);
free(dnsinfo);
checkqueue();
}
void _init() {
s_opsb = "opsb";
globops(me.name, "OPSB Module Loaded");
/* we have to be carefull here. Currently, we have 7 sockets that get opened per connection. Soooo.
* we check that MAX_SCANS is not greater than the maxsockets available / 7
* this way, we *shouldn't* get problems with running out of sockets
*/
if (MAX_SCANS > me.maxsocks / 7) {
opsbl = list_create(me.maxsocks /7);
opsb.socks = me.maxsocks /7;
} else {
opsbl = list_create(MAX_SCANS);
opsb.socks = MAX_SCANS;
}
/* queue can be anything we want */
opsbq = list_create(MAX_QUEUE);
/* scan cache is MAX_QUEUE size (why not?) */
cache = list_create(2);
exempt = list_create(MAX_EXEMPTS);
sprintf(opsb.opmdomain, "%s", "opm.blitzed.org");
sprintf(opsb.targethost, "%s", me.uplink);
opsb.targetport = me.port;
opsb.maxbytes = 500;
opsb.timeout = 30;
opsb.timedif = 30;
opsb.open = 0;
opsb.scanned = 0;
opsb.confed = 0;
opsb.cachetime = 3600;
opsb.bantime = 86400;
snprintf(opsb.lookforstring, 512, "*** Looking up your hostname...");
snprintf(opsb.scanmsg, 512, "Your Host is being Scanned for Open Proxies");
}
void _fini() {
globops(me.name, "OPSB Module Unloaded");
};

133
opsb.h Normal file
View file

@ -0,0 +1,133 @@
/* NetStats - IRC Statistical Services Copyright (c) 1999 Adam Rutter,
** Justin Hammond http://codeworks.kamserve.com
*
** Based from GeoStats 1.1.0 by Johnathan George net@lite.net
*
** NetStats CVS Identification
** $Id: opsb.h,v 1.1 2002/08/31 09:28:35 fishwaldo Exp $
*/
#ifndef OPSB_H
#define OPSB_H
typedef struct proxy_types {
char *type;
int port;
int (*scan)(int sock);
int nofound;
int noopen;
} proxy_types;
char *s_opsb;
/* max scans in the max concurrent scans at any one time */
#define MAX_SCANS 100
/* max queue is the max amount of scans that may be concurrent and queued. */
#define MAX_QUEUE MAX_SCANS * 100
/* max no of exempt entries */
#define MAX_EXEMPTS 20
struct scanq {
char who[MAXHOST];
int state;
int dnsstate;
char lookup[MAXHOST];
char server[MAXHOST];
struct in_addr ipaddr;
User *u;
int doreport;
list_t *socks;
time_t started;
};
typedef struct scanq scaninfo;
struct opsb {
char opmdomain[MAXHOST];
int init;
char targethost[MAXHOST];
char lookforstring[512];
int targetport;
int maxbytes;
int timeout;
int socks;
int timedif;
int open;
int scanned;
char scanmsg[512];
int bantime;
int confed;
int cachetime;
} opsb;
struct sockinfo {
int sock;
int (*function)(int sock);
int flags;
int type;
int bytes;
};
typedef struct sockinfo socklist;
/* this is the list of items to be queued */
list_t *opsbq;
/* this is the list of currently active scans */
list_t *opsbl;
struct cache_entry {
unsigned long ip;
time_t when;
};
typedef struct cache_entry C_entry;
/* this is a list of cached scans */
list_t *cache;
struct exempts {
char host[MAXHOST];
int server;
};
typedef struct exempts exemptinfo;
/* this is the list of exempted hosts/servers */
list_t *exempt;
/* these are some state flags */
#define REPORT_DNS 0x0001
#define GET_NICK_IP 0x0002
#define DO_OPM_LOOKUP 0x0004
#define DOING_SCAN 0x0008
#define GOTOPENPROXY 0x0010
#define OPMLIST 0x0020
/* this is some socklist flags */
#define CONNECTING 0x0001
#define SOCKCONNECTED 0x0002
#define UNCONNECTED 0x0004
#define OPENPROXY 0x0008
/* opsb.c */
int findscan(const void *key1, const void *key2);
void do_ban(scaninfo *scandata);
void checkqueue();
void addtocache(unsigned long ipaddr);
/* proxy.c */
void start_proxy_scan(lnode_t *scannode);
void send_status(User *u);
#endif /* OPSB_H */

121
opsb_help.c Normal file
View file

@ -0,0 +1,121 @@
/* NeoStats - IRC Statistical Services Copryight (c) 1999-2002 NeoStats Group.
*
** Module: opsb
** Author: Fish
** $Id: opsb_help.c,v 1.1 2002/08/31 09:28:35 fishwaldo Exp $
*/
#include "stats.h"
const char *opsb_help[] = {
"\2Open Proxy Scanning Bot HELP\2",
"",
" This bot scans the network for insecure clients. For more info",
" \2/msg opsb info\2",
"",
"COMMANDS:",
" LOOKUP INFO",
"",
NULL
};
const char *opsb_help_oper[] = {
"OPERTATOR COMMANDS:",
" CHECK STATUS SET EXCLUDE CACHETIME",
"",
NULL
};
const char *opsb_help_lookup[] = {
"Usage: \2LOOKUP <ip or Hostname> <flag>\2",
"",
"This command allows you to lookup DNS records on the Internet",
"Different types of Records can be looked up by specifing different flags",
"",
"The Flags are:",
" txt - Lookup Text Records",
" rp - Lookup the Responsible Person for this record",
" ns - Lookup the NameServers for this record",
" soa - Lookup the SOA for this Record",
"",
"If you do not specify a flag, it defaults to looking up either the IP address for Hostnames, or",
"The Hostname for IP addresses",
"",
NULL
};
const char *opsb_help_info[] = {
"\2Open Proxy Scanning Bot Information\2",
"",
"This bot is intended to scan clients connecting to this network for insecure proxies",
"Insecure proxies are often used to attack networks or channel with \2clone\2 bots",
"This check scans the following ports:",
" 3128, 8080, 80 23 and 1080",
"if you have Firewall, or IDS software, please ignore any errors that this scan may generate",
"",
"If you have any futher questions, please contact network adminstration staff",
NULL
};
const char *opsb_help_check[] = {
"Usage: \2CHECK <nickname/IP/hostname>\2",
"",
"This option will scan either a user connected to your Network",
"Or a IP address or Hostname for Insecure proxies, and report the status to you",
"If a Insecure proxy is found, the host will be banned from the network",
"",
NULL
};
const char *opsb_help_status[] = {
"Usage: \2STATUS\2",
"",
"View Detailed information about the state of the Open Proxy Scanning Bot",
"",
NULL
};
const char *opsb_help_set[] = {
"Usage: \2SET <OPTIONS> <SETTING>\2",
"",
"This command will set various options relating to OPSB.",
"The Settings take effect imediatly",
"The Options are:",
" \2TARGETIP\2 - Change the IP address we try to make the proxies connect to",
" This should be set to a IP address of on of your IRC Servers.",
" \2TARGETPORT\2 - Change the Port number we try to make proxies connect to",
" This should be a port that runs on your IRCD",
" \2CACHETIME\2 - This sets the amount of time (in Seconds) that a entry will be cached",
"\2Advanced Settings\2 - These settings should not be changed unless you know the effects in full",
" \2OPMDOMAIN\2 - Change the Domain we use to Lookup for Blacklists.",
" \2MAXBYTES\2 - This is the maximum number of bytes we recieve from a proxy before disconnecting it",
" \2TIMEOUT\2 - This is the ammount of time we wait for a proxy to respond to our servers before",
" Disconnecting, and assuming its not a open Proxy",
" \2OPENSTRING\2 - This is the string we expect to see if there is a successfull Open Proxy",
" \2SPLITTIME\2 - This is used to determine if users connecting to the network are part of a Netjoin",
" (when two servers link together)",
" \2SCANMSG\2 - This is the message sent to a user when we scan their hosts",
" \2BANTIME\2 - This is how long the user will be banned from the network for",
"",
NULL
};
const char *opsb_help_exclude[] = {
"Usage: \2EXCLUDE <LIST/ADD/DEL>\2",
"",
"This command lets you view or manipulate the exception list.",
"Exception lists are used to exclude users, or servers from scanning",
"You should at least add a server entry for your services irc name, to stop",
"OPSB from scanning Nickserv, Chanserv etc",
"The Options are:",
" \2LIST\2 - This will list the current exceptions and the positions in the list",
" If you wish to remove a entry, you must exaime the list position first",
" \2ADD <hostname> <1/0>\2",
" - This option will add a entry of <hostname> to the exception list",
" a Value of 1 after the hostname indicates a Servername (eg, services.irc-chat.net)",
" a Value of 0 after the hostname indicates a hostname (eg, *.adsl.home.com)",
" Wildcards such as * and ? may be used in the hostname portion",
" \2DEL <NUM>\2 - This will delete entry numbered <NUM> in the list from the exclusions"
"",
NULL
};

547
proxy.c Normal file
View file

@ -0,0 +1,547 @@
/* NetStats - IRC Statistical Services Copyright (c) 1999 Adam Rutter,
** Justin Hammond http://codeworks.kamserve.com
*
** Based from GeoStats 1.1.0 by Johnathan George net@lite.net
*
** NetStats CVS Identification
** $Id: proxy.c,v 1.1 2002/08/31 09:28:36 fishwaldo Exp $
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <fcntl.h>
#include "dl.h"
#include "stats.h"
#include "opsb.h"
int proxy_connect(unsigned long ipaddr, int port, char *who);
int http_proxy(int sock);
int sock4_proxy(int sock);
int sock5_proxy(int sock);
int cisco_proxy(int sock);
int wingate_proxy(int sock);
#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
#endif
proxy_types proxy_list[] = {
{"http", 80, http_proxy, 0, 0},
{"http", 8080, http_proxy, 0, 0},
{"http", 3128, http_proxy, 0, 0},
{"socks4", 1080, sock4_proxy, 0, 0},
{"socks5", 1080, sock5_proxy, 0, 0},
{"Cisco", 23, cisco_proxy, 0, 0},
{"Wingate", 23, wingate_proxy, 0, 0},
{NULL, 0, NULL, 0, 0}
};
#define NUM_PROXIES 7
void do_ban(scaninfo *scandata) {
lnode_t *socknode;
socklist *sockdata;
int doneban = 0;
FILE *fp;
++opsb.open;
/* ban based on proxy detection first */
socknode = list_first(scandata->socks);
while (socknode) {
sockdata = lnode_get(socknode);
if ((sockdata->flags != OPENPROXY) || (doneban == 1)) {
socknode = list_next(scandata->socks, socknode);
break;
}
log("OPSB: Banning %s (%s) for Open Proxy - %s(%d)", scandata->who, inet_ntoa(scandata->ipaddr), proxy_list[sockdata->type].type, proxy_list[sockdata->type].port);
chanalert(s_opsb, "Banning %s (%s) for Open Proxy - %s(%d)", scandata->who, inet_ntoa(scandata->ipaddr), proxy_list[sockdata->type].type, proxy_list[sockdata->type].port);
globops(s_opsb, "Banning %s (%s) for Open Proxy - %s(%d)", scandata->who, inet_ntoa(scandata->ipaddr), proxy_list[sockdata->type].type, proxy_list[sockdata->type].port);
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "Banning %s (%s) for Open Proxy - %s(%d)", scandata->who, inet_ntoa(scandata->ipaddr), proxy_list[sockdata->type].type, proxy_list[sockdata->type].port);
sakill_cmd(inet_ntoa(scandata->ipaddr), "*", s_opsb, opsb.bantime, "Open Proxy found on your host. Please visit the following website for more info: www.blitzed.org/proxy?ip=%s", inet_ntoa(scandata->ipaddr));
if (doneban != 1) {
if ((fp = fopen("logs/opsb.log", "a")) == NULL) return;
fprintf(fp, "%s: %s\n", proxy_list[sockdata->type].type, inet_ntoa(scandata->ipaddr));
fclose(fp);
} else {
doneban = 1;
}
socknode = list_next(scandata->socks, socknode);
}
if (doneban == 1)
return;
if (scandata->dnsstate == OPMLIST) {
log("OPSB: Banning %s (%s) as its listed in %s", scandata->who, inet_ntoa(scandata->ipaddr), opsb.opmdomain);
chanalert(s_opsb, "Banning %s (%s) as its listed in %s", scandata->who, inet_ntoa(scandata->ipaddr), opsb.opmdomain);
globops(s_opsb, "Banning %s (%s) as its listed in %s", scandata->who, inet_ntoa(scandata->ipaddr), opsb.opmdomain);
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "Banning %s (%s) as its listed in %s", scandata->who, inet_ntoa(scandata->ipaddr), opsb.opmdomain);
sakill_cmd(inet_ntoa(scandata->ipaddr), "*", s_opsb, opsb.bantime, "Your host is listed as a Open Proxy. Please visit the following website for more info: www.blitzed.org/proxy?ip=%s", inet_ntoa(scandata->ipaddr));
}
}
scaninfo *find_scandata(char *sockname) {
char *buf, *cmd;
lnode_t *scannode;
buf = sstrdup(sockname);
cmd = strtok(buf, " ");
scannode = list_find(opsbl, cmd, findscan);
if (scannode)
return lnode_get(scannode);
else
return NULL;
}
void cleanlist() {
lnode_t *scannode;
scaninfo *scandata;
lnode_t *socknode, *scannode2;
socklist *sockdata;
char sockname[64];
int savescan, timedout = 0, finished;
scannode = list_first(opsbl);
while (scannode) {
timedout = 0;
scandata = lnode_get(scannode);
/* check if this scan has timed out */
if (time(NULL) - scandata->started > opsb.timeout) timedout = 1;
/* savescan is a flag if we should save this entry into the cache file */
savescan = 1;
if (scandata->dnsstate == OPMLIST) savescan = 0;
/* if this is not valid, exit */
if (!scandata->socks) break;
/* check for open sockets */
socknode = list_first(scandata->socks);
finished = 1;
while (socknode) {
sockdata = lnode_get(socknode);
/* if it was a open proxy, don't save the cache */
if (sockdata->flags == OPENPROXY) savescan = 0;
/* if this still has sockets connected, set finished flaged to 0 to not delete scans */
if ((sockdata->flags == SOCKCONNECTED) || (sockdata->flags == CONNECTING)) finished = 0;
if (timedout == 1) {
if ((sockdata->flags == SOCKCONNECTED) || (sockdata->flags == CONNECTING)) {
/* it still has open socks */
snprintf(sockname, 64, "%s %d", scandata->who, sockdata->type);
sockdata->flags = UNCONNECTED;
#ifdef DEBUG
log("Closing Socket %s in cleanlist function for timeout()", sockname);
#endif
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "Timeout Connecting to Proxy %s on port %d", proxy_list[sockdata->type].type, proxy_list[sockdata->type].port);
sock_disconnect(sockname);
free(sockdata);
}
}
socknode = list_next(scandata->socks, socknode);
}
if (timedout == 1 || finished == 1) {
#ifdef DEBUG
if (timedout == 1) log("Deleting Old Scannode %s out of active list (Timeout)", scandata->who );
if (finished == 1) log("Deleting Old Scannode %s out of active list (Finished)", scandata->who );
#endif
if (savescan == 1)
addtocache(scandata->ipaddr.s_addr);
/* destory all the nodes in the sock list */
list_destroy_nodes(scandata->socks);
scannode2 = list_next(opsbl, scannode);
list_delete(opsbl, scannode);
lnode_destroy(scannode);
scandata->u = NULL;
free(scandata);
scannode = scannode2;
} else {
scannode = list_next(opsbl, scannode);
}
}
checkqueue();
}
void send_status(User *u) {
int i;
lnode_t *node, *socknode;
scaninfo *scandata;
socklist *sockinfo;
prefmsg(u->nick, s_opsb, "Proxy Results:");
prefmsg(u->nick, s_opsb, "Hosts Scanned: %d Hosts found Open: %d Exceptions %d", opsb.scanned, opsb.open, list_count(exempt));
prefmsg(u->nick, s_opsb, "Cache Entries: %d", list_count(cache));
for (i = 0; i < NUM_PROXIES; i++) {
prefmsg(u->nick, s_opsb, "Proxy %s (%d) Found %d Open %d", proxy_list[i].type, proxy_list[i].port, proxy_list[i].nofound, proxy_list[i].noopen);
}
prefmsg(u->nick, s_opsb, "Currently Scanning %d Proxies (%d in queue):", list_count(opsbl), list_count(opsbq));
node = list_first(opsbl);
while (node) {
scandata = lnode_get(node);
if (scandata->u)
prefmsg(u->nick, s_opsb, "Scanning %s by request of %s", scandata->lookup, scandata->u->nick);
else
prefmsg(u->nick, s_opsb, "Scanning %s (%s)", scandata->lookup, inet_ntoa(scandata->ipaddr));
switch(scandata->dnsstate) {
case REPORT_DNS:
prefmsg(u->nick, s_opsb, "Looking up IP Address");
break;
case GET_NICK_IP:
prefmsg(u->nick, s_opsb, "Looking up IP address for Scan");
break;
case DO_OPM_LOOKUP:
prefmsg(u->nick, s_opsb, "Looking up DNS blacklist");
break;
default:
prefmsg(u->nick, s_opsb, "Unknown State (DNS)");
}
switch(scandata->state) {
case DOING_SCAN:
prefmsg(u->nick, s_opsb, "Scanning for Open Proxies");
break;
case GOTOPENPROXY:
prefmsg(u->nick, s_opsb, "Contains a Open Proxy");
break;
default:
prefmsg(u->nick, s_opsb, "Unknown State (Scan)");
}
socknode = list_first(scandata->socks);
while (socknode) {
sockinfo = lnode_get(socknode);
switch (sockinfo->flags) {
case CONNECTING:
prefmsg(u->nick, s_opsb, " %s(%d) - Connecting", proxy_list[sockinfo->type].type, proxy_list[sockinfo->type].port);
break;
case SOCKCONNECTED:
prefmsg(u->nick, s_opsb, " %s(%d) - Connected", proxy_list[sockinfo->type].type, proxy_list[sockinfo->type].port);
break;
case UNCONNECTED:
prefmsg(u->nick, s_opsb, " %s(%d) - Disconnected", proxy_list[sockinfo->type].type, proxy_list[sockinfo->type].port);
break;
case OPENPROXY:
prefmsg(u->nick, s_opsb, " %s(%d) - Open Proxy", proxy_list[sockinfo->type].type, proxy_list[sockinfo->type].port);
break;
default:
prefmsg(u->nick, s_opsb, " %s(%d) - Unknown", proxy_list[sockinfo->type].type, proxy_list[sockinfo->type].port);
}
socknode = list_next(scandata->socks, socknode);
}
node = list_next(opsbl, node);
}
}
void start_proxy_scan(lnode_t *scannode) {
scaninfo *scandata;
socklist *sockdata;
lnode_t *socknode;
char *sockname;
int i, j;
scandata = lnode_get(scannode);
if (scandata->u) chanalert(s_opsb, "Starting proxy scan on %s (%s) by Request of %s", scandata->who, scandata->lookup, scandata->u->nick);
scandata->socks = list_create(NUM_PROXIES);
scandata->state = DOING_SCAN;
for (i = 0; i < NUM_PROXIES; i++) {
#ifdef DEBUG
log("OPSB proxy_connect(): host %ul (%s), port %d", scandata->ipaddr,inet_ntoa(scandata->ipaddr), proxy_list[i].port);
#endif
sockname = malloc(64);
sprintf(sockname, "%s %d", scandata->who, i);
j = proxy_connect(scandata->ipaddr.s_addr, proxy_list[i].port, sockname);
free(sockname);
if (j > 0) {
/* its ok */
sockdata = malloc(sizeof(socklist));
sockdata->sock = j;
sockdata->function = proxy_list[i].scan;
sockdata->flags = CONNECTING;
sockdata->type = i;
sockdata->bytes = 0;
socknode = lnode_create(sockdata);
list_append(scandata->socks, socknode);
}
}
/* this is so we can timeout scans */
scandata->started = time(NULL);
}
int http_proxy(int sock) {
char *buf;
int i;
buf = malloc(512);
i = snprintf(buf, 512, "CONNECT %s:%d HTTP/1.0\r\n\r\n", opsb.targethost, opsb.targetport);
#ifdef DEBUG
log("sending http request");
#endif
i= send(sock, buf, i, MSG_NOSIGNAL);
free(buf);
return i;
}
int sock4_proxy(int sock) {
struct in_addr addr;
unsigned long laddr;
char *buf;
int len;
if (inet_aton(opsb.targethost, &addr) == 0) {
log("OPSB socks4_proxy() : %s is not a valid IP",
opsb.targethost);
return 0;
}
laddr = htonl(addr.s_addr);
buf = malloc(512);
len = snprintf(buf, 512, "%c%c%c%c%c%c%c%c%c", 4, 1,
(((unsigned short) opsb.targetport) >> 8) & 0xFF,
(((unsigned short) opsb.targetport) & 0xff),
(char) (laddr >> 24) & 0xFF, (char) (laddr >> 16) & 0xFF,
(char) (laddr >> 8) & 0xFF, (char) laddr & 0xFF, 0);
len = send(sock, buf, len, MSG_NOSIGNAL);
free(buf);
return(len);
}
int sock5_proxy(int sock) {
struct in_addr addr;
unsigned long laddr;
int len;
char *buf;
if (inet_aton(opsb.targethost, &addr) == 0) {
log("OPSB socks5_proxy() : %s is not a valid IP",
opsb.targethost);
}
laddr = htonl(addr.s_addr);
buf = malloc(512);
/* Form authentication string */
/* Version 5, 1 number of methods, 0 method (no auth). */
len = snprintf(buf, 512, "%c%c%c", 5, 1, 0);
len = send(sock, buf, len, MSG_NOSIGNAL);
if (len < 0) {
free(buf);
return len;
}
/* Form request string */
len = snprintf(buf, 512, "%c%c%c%c%c%c%c%c%c%c", 5, 1, 0, 1,
(char) (laddr >> 24) & 0xFF, (char) (laddr >> 16) & 0xFF,
(char) (laddr >> 8) & 0xFF, (char) laddr & 0xFF,
(((unsigned short) opsb.targetport) >> 8) & 0xFF,
(((unsigned short) opsb.targetport) & 0xFF)
);
len = send(sock, buf, len, MSG_NOSIGNAL);
return(len);
}
int cisco_proxy(int sock) {
char *buf;
int i;
buf = malloc(512);
i = snprintf(buf, 512, "cisco\r\n");
i = send(sock, buf, i, MSG_NOSIGNAL);
if (i < 0)
return i;
i = snprintf(buf, 512, "telnet %s %d\r\n", opsb.targethost, opsb.targetport);
i = send(sock, buf, i, MSG_NOSIGNAL);
free(buf);
return i;
}
int wingate_proxy(int sock) {
char *buf;
int i;
buf = malloc(512);
i = snprintf(buf, 512, "%s:%d\r\n", opsb.targethost, opsb.targetport);
i = send(sock, buf, i, MSG_NOSIGNAL);
free(buf);
return i;
}
/* proxy read function */
int proxy_read(int socknum, char *sockname) {
char *buf;
int i = 0;
scaninfo *scandata;
lnode_t *socknode;
socklist *sockdata = NULL;
scandata = find_scandata(sockname);
if (!scandata) {
log("ehh, wtf, can find scan data");
return 1;
}
socknode = list_first(scandata->socks);
while (socknode) {
sockdata = lnode_get(socknode);
if (sockdata->sock == socknum) {
i = 1;
break;
}
socknode = list_next(scandata->socks, socknode);
}
if (i == 0) {
log("ehh can't find socket info for proxy_read()");
return 1;
}
buf = malloc(512);
bzero(buf, 512);
i = recv(socknum, buf, 512, 0);
if (i < 0) {
#ifdef DEBUG
log("OPSB proxy_read(): %d has the following error: %s", socknum, strerror(errno));
#endif
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "No %s Proxy Server on port %d", proxy_list[sockdata->type].type, proxy_list[sockdata->type].port);
sock_disconnect(sockname);
sockdata->flags = UNCONNECTED;
free(buf);
return -1;
} else {
if (i > 0) {
#ifdef DEBUG
log("OPSB proxy_read(): Got this: %s (%d)",buf, i);
#endif
/* we check if this might be a normal http server */
do_ban(scandata);
if (strstr(buf, "Method Not Allowed")) {
#ifdef DEBUG
log("closing socket %d due to ok HTTP server", socknum);
#endif
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "No Open %s Proxy Server on port %d", proxy_list[sockdata->type].type, proxy_list[sockdata->type].port);
sockdata->flags = UNCONNECTED;
sock_disconnect(sockname);
free(buf);
return -1;
}
/* this looks for the ban string */
if (strstr(buf, opsb.lookforstring)) {
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "Open %s Proxy Server on port %d", proxy_list[sockdata->type].type, proxy_list[sockdata->type].port);
++proxy_list[sockdata->type].noopen;
scandata->state = GOTOPENPROXY;
sockdata->flags = OPENPROXY;
do_ban(scandata);
sock_disconnect(sockname);
free(buf);
return -1;
}
sockdata->bytes += i;
/* avoid reading too much data */
if (sockdata->bytes > opsb.maxbytes) {
#ifdef DEBUG
log("OPSB proxy_read(): Closing %d due to too much data", socknum);
#endif
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "No Open %s Proxy Server on port %d", proxy_list[sockdata->type].type, proxy_list[sockdata->type].port);
sock_disconnect(sockname);
sockdata->flags = UNCONNECTED;
free(buf);
return -1;
}
}
}
free(buf);
return 1;
}
/* proxy write function */
int proxy_write(int socknum, char *sockname) {
int i = 0;
scaninfo *scandata;
lnode_t *socknode;
socklist *sockdata = NULL;
scandata = find_scandata(sockname);
if (!scandata) {
log("ehh, wtf, can find scan data");
return 1;
}
socknode = list_first(scandata->socks);
while (socknode) {
sockdata = lnode_get(socknode);
if (sockdata->sock == socknum) {
i = 1;
break;
}
socknode = list_next(scandata->socks, socknode);
}
if (i == 0) {
log("ehhh, can't find socket for proxy_write()");
return 1;
}
if (sockdata->flags == CONNECTING || sockdata->flags == SOCKCONNECTED) {
if (sockdata->flags == CONNECTING)
i = (int)sockdata->function(socknum);
else
i = send(socknum, "", 1, MSG_NOSIGNAL);
if (i < 0) {
#ifdef DEBUG
log("OPSB proxy_write(): %d has the following error: %s", socknum, strerror(errno));
#endif
if (scandata->u) prefmsg(scandata->u->nick, s_opsb, "No %s Proxy Server on port %d", proxy_list[sockdata->type].type, proxy_list[sockdata->type].port);
sock_disconnect(sockname);
sockdata->flags = UNCONNECTED;
return -1;
} else {
if (sockdata->flags != SOCKCONNECTED) ++proxy_list[sockdata->type].nofound;
sockdata->flags = SOCKCONNECTED;
}
}
return 1;
}
/* proxy error function */
int proxy_err(int socknum, char *sockname) {
return 1;
}
/* proxy connect function trys to connect a socket to a remote proxy
* its set non blocking, so both the send and recieve functions must be used
* to tell if the connection is successfull or not
* it also registers the socket with the core neostats socket functions
*/
int proxy_connect(unsigned long ipaddr, int port, char *who)
{
int s;
s = sock_connect(SOCK_STREAM, ipaddr, port, who, "opsb", "proxy_read", "proxy_write", "proxy_err");
return s;
}