Compare commits

...

15 Commits
v1.6 ... v1.7

Author SHA1 Message Date
Jan Engelhardt
598c7ede37 Xtables-addons 1.7 2008-12-25 20:10:38 +01:00
Jan Engelhardt
2f66755226 Merge branch 'ipp2p' 2008-12-10 16:51:34 +01:00
Jan Engelhardt
d01a5f3d17 ipp2p: ensure better array bounds checking 2008-12-10 16:50:45 +01:00
Jan Engelhardt
bbda3e53da Merge branch 'SYSRQ' 2008-12-10 16:03:13 +01:00
Jan Engelhardt
22e73ea31f xt_SYSRQ: src: prefix variables 2008-12-10 16:02:21 +01:00
Jan Engelhardt
6b37f201d7 xt_SYSRQ: make new code compile for kernel <= 2.6.23 2008-12-10 15:45:43 +01:00
John Haxby
94ecf3847b xt_SYSRQ: improve security
I want to be able to use SYSRQ to reboot, crash or partially diagnose
machines that become unresponsive for one reason or another. These
machines, typically, are blades or rack mounted machines that do not
have a PS/2 connection for a keyboard and the old method of wheeling
round a "crash trolley" that has a monitor and a keyboard on it no
longer works: USB keyboards rarely, if ever, work because by the time
the machine is responding only to a ping, udev is incapable of
setting up a new keyboard.

This patch extends the xt_SYSRQ module to avoid both disclosing the
sysrq password and preventing replay. This is done by changing the
request packet from the simple "<key><password>" to a slightly more
complex "<key>,<seqno>,<salt>,<hash>". The hash is the sha1 checksum
of "<key>,<seqno>,<salt>,<password>". A request can be constructed in
a small shell script (see manpage).

Verification of the hash in xt_SYSRQ follows much the same process.
The sequence number, seqno, is initialised to the current time (in
seconds) when the xt_SYSRQ module is loaded and is updated each time
a valid request is received. A request with a sequence number less
than the current sequence number or a wrong hash is silently ignored.
(Using the time for the sequence number assumes (requires) that time
doesn't go backwards on a reboot and that the requester and victim
have reasonably synchronized clocks.)

The random salt is there to prevent pre-computed dictionary attacks
difficult: dictionary attacks are still feasible if you capture a
packet because the hash is computed quickly -- taking perhaps several
milliseconds to compute a more complex hash in xt_SYSRQ when the
machine is unresponsive is probably not the best thing you could do.
However, cracking, say, a random 32 character password would take
some time and is probably beyond what the people in the target
untrustworthy environment are prepared to do or have the resources
for. It almost goes without saying that no two victim machines should
use the same password.

Finally, the module allocates all the resources it need at module
initialisation time on the assumption that if things are going badly
resource allocation is going to be troublesome.
2008-12-02 19:45:22 +01:00
Jan Engelhardt
ee968691d7 ipp2p: fix newline inspection in kazaa
LFCR looks suspect, it should most likely be CRLF.
2008-11-26 00:47:36 +01:00
Jan Engelhardt
22db3bcb9c ipp2p: kazaa code cleanup 2008-11-26 00:46:44 +01:00
Jan Engelhardt
7da803e908 doc: add manpages for xt_ECHO and xt_TEE 2008-11-24 17:42:32 +01:00
Jan Engelhardt
bd99e950f5 ipset: enable building of new modules
Whoops, modules need to be listed in GNUmakefile.in!
(Needed for out-of-srcdir builds.)
2008-11-20 23:08:33 +01:00
Jan Engelhardt
fdb7f34bc8 build: use new vars from automake-tranquility-3 2008-11-20 21:17:42 +01:00
Jan Engelhardt
85e3c24167 build: do not unconditionally install ipset
build_ipset=n was not completely respected and the ipset userspace
parts were still installed. This is now fixed.
2008-11-20 20:19:55 +01:00
Jan Engelhardt
aab8dd360f src: avoid use of _init
Xtables-addons's extensions will always be built as modules, so it is
safe to use __attribute__((constructor)).
2008-11-20 20:00:26 +01:00
Jan Engelhardt
a8f60d0d4b xt_ECHO: compile fix 2008-11-19 17:38:45 +01:00
30 changed files with 377 additions and 103 deletions

13
INSTALL
View File

@@ -65,6 +65,19 @@ If you want to enable debugging, use
much easier.)
Build-time options
==================
V= controls the kernel's make verbosity.
V=0 "silent" (output filename)
V=1 "verbose" (entire gcc command line)
VU= controls the Xt-a make verbosity.
VU=0 output filename
VU=1 output filename and source file
VU=2 entire gcc command line
Note to distribution packagers
==============================

View File

@@ -1,12 +1,13 @@
# -*- Makefile -*-
ACLOCAL_AMFLAGS = -I m4
AUTOMAKE_OPTIONS = foreign subdir-objects
SUBDIRS = extensions extensions/ipset
SUBDIRS = extensions
man_MANS := xtables-addons.8
xtables-addons.8: ${srcdir}/xtables-addons.8.in extensions/matches.man extensions/targets.man
${AM_VERBOSE_GEN} sed -e '/@MATCHES@/ r extensions/matches.man' -e '/@TARGET@/ r extensions/targets.man' $< >$@;
${am__verbose_GEN}sed -e '/@MATCHES@/ r extensions/matches.man' -e '/@TARGET@/ r extensions/targets.man' $< >$@;
extensions/%:
${MAKE} ${AM_MAKEFLAGS} -C $(@D) $(@F)

View File

@@ -1,8 +1,9 @@
AC_INIT([xtables-addons], [1.6])
AC_INIT([xtables-addons], [1.7])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
AC_PROG_INSTALL
AM_INIT_AUTOMAKE
AM_INIT_AUTOMAKE([-Wall])
AC_PROG_CC
AM_PROG_CC_C_O
AC_DISABLE_STATIC
@@ -63,4 +64,5 @@ AC_SUBST([kinclude_CFLAGS])
AC_SUBST([kbuilddir])
AC_SUBST([ksourcedir])
AC_SUBST([xtlibdir])
AC_OUTPUT([Makefile extensions/GNUmakefile extensions/ipset/GNUmakefile])
AC_CONFIG_FILES([Makefile extensions/GNUmakefile extensions/ipset/GNUmakefile])
AC_OUTPUT

View File

@@ -30,15 +30,17 @@ xtables_CFLAGS := @xtables_CFLAGS@
AM_CFLAGS := ${regular_CFLAGS} -I${top_srcdir}/include ${xtables_CFLAGS} ${kinclude_CFLAGS}
AM_DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
ifeq (${V},)
AM_LIBTOOL_SILENT = --silent
AM_VERBOSE_CC = @echo " CC " $@;
AM_VERBOSE_CCLD = @echo " CCLD " $@;
AM_VERBOSE_CXX = @echo " CXX " $@;
AM_VERBOSE_CXXLD = @echo " CXXLD " $@;
AM_VERBOSE_AR = @echo " AR " $@;
AM_VERBOSE_GEN = @echo " GEN " $@;
endif
VU := 0
am__1verbose_CC_0 = @echo " CC " $@;
am__1verbose_CCLD_0 = @echo " CCLD " $@;
am__1verbose_GEN_0 = @echo " GEN " $@;
am__1verbose_CC_1 = @echo " CC " $@ "<-" $<;
am__1verbose_CCLD_1 = @echo " CCLD " $@ "<-" $^;
am__1verbose_GEN_1 = @echo " GEN " $@ "<-" $<;
am__verbose_CC = ${am__1verbose_CC_${VU}}
am__verbose_CCLD = ${am__1verbose_CCLD_${VU}}
am__verbose_GEN = ${am__1verbose_GEN_${VU}}
#
# Wildcard module list
@@ -53,22 +55,30 @@ include ${srcdir}/Mbuild
#
# Building blocks
#
targets := ${obj-m}
targets_install := ${obj-m}
targets := $(filter-out %/,${obj-m})
targets_install := ${targets}
subdirs_list := $(filter %/,${obj-m})
.SECONDARY:
.PHONY: all install clean distclean FORCE
all: modules user matches.man targets.man
all: subdirs modules user matches.man targets.man
subdirs:
@for i in ${subdirs_list}; do ${MAKE} -C $$i; done;
subdirs-install:
@for i in ${subdirs_list}; do ${MAKE} -C $$i install; done;
user: ${targets}
install: modules_install ${targets_install}
install: modules_install subdirs-install ${targets_install}
@mkdir -p "${DESTDIR}${xtlibdir}";
install -pm0755 ${targets_install} "${DESTDIR}${xtlibdir}/";
clean: clean_modules
@for i in ${subdirs_list}; do make -C $$i clean; done;
rm -f *.oo *.so;
distclean: clean
@@ -96,10 +106,10 @@ clean_modules:
# Shared libraries
#
lib%.so: lib%.oo
${AM_VERBOSE_CCLD} ${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $<;
${am__verbose_CCLD}${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $<;
lib%.oo: ${srcdir}/lib%.c
${AM_VERBOSE_CC} ${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -D_INIT=lib$*_init -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
${am__verbose_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -D_INIT=lib$*_init -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
#
@@ -116,8 +126,7 @@ wlist_targets := $(patsubst ${srcdir}/libxt_%.man,%,${wcman_targets})
rm -f $@.tmp;
man_run = \
${AM_VERBOSE_GEN} \
for ext in $(1); do \
${am__verbose_GEN}for ext in $(1); do \
f="${srcdir}/libxt_$$ext.man"; \
if [ -f "$$f" ]; then \
echo ".SS $$ext"; \

View File

@@ -11,5 +11,6 @@ obj-${build_condition} += libxt_condition.so
obj-${build_fuzzy} += libxt_fuzzy.so
obj-${build_geoip} += libxt_geoip.so
obj-${build_ipp2p} += libxt_ipp2p.so
obj-${build_ipset} += ipset/
obj-${build_portscan} += libxt_portscan.so
obj-${build_quota2} += libxt_quota2.so

View File

@@ -32,20 +32,20 @@ xtables_CFLAGS := @xtables_CFLAGS@
AM_CFLAGS := ${regular_CFLAGS} -I${top_srcdir}/include ${xtables_CFLAGS} ${kinclude_CFLAGS} -DIPSET_LIB_DIR=\"${xtlibdir}\"
AM_DEPFLAGS = -Wp,-MMD,$(@D)/.$(@F).d,-MT,$@
ifeq (${V},)
AM_LIBTOOL_SILENT = --silent
AM_VERBOSE_CC = @echo " CC " $@;
AM_VERBOSE_CCLD = @echo " CCLD " $@;
AM_VERBOSE_CXX = @echo " CXX " $@;
AM_VERBOSE_CXXLD = @echo " CXXLD " $@;
AM_VERBOSE_AR = @echo " AR " $@;
AM_VERBOSE_GEN = @echo " GEN " $@;
endif
VU := 0
am__1verbose_CC_0 = @echo " CC " $@;
am__1verbose_CCLD_0 = @echo " CCLD " $@;
am__1verbose_CC_1 = @echo " CC " $@ "<-" $<;
am__1verbose_CCLD_1 = @echo " CCLD " $@ "<-" $^;
am__verbose_CC = ${am__1verbose_CC_${VU}}
am__verbose_CCLD = ${am__1verbose_CCLD_${VU}}
#
# Building blocks
#
targets := $(addsuffix .so,$(addprefix libipset_,iphash ipmap ipporthash iptree iptreemap macipmap nethash portmap))
targets := $(addsuffix .so,$(addprefix libipset_, \
iphash ipmap ipporthash ipportiphash ipportnethash iptree \
iptreemap macipmap nethash portmap setlist))
.SECONDARY:
@@ -69,16 +69,16 @@ distclean: clean
ipset: ipset.o
${AM_VERBOSE_CCLD} ${CCLD} ${AM_LDFLAGS} ${LDFLAGS} -o $@ $< -ldl -rdynamic;
${am__verbose_CCLD}${CCLD} ${AM_LDFLAGS} ${LDFLAGS} -o $@ $< -ldl -rdynamic;
#
# Shared libraries
#
lib%.so: lib%.oo
${AM_VERBOSE_CCLD} ${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $<;
${am__verbose_CCLD}${CCLD} ${AM_LDFLAGS} -shared ${LDFLAGS} -o $@ $<;
libipset_%.oo: ${srcdir}/ipset_%.c
${AM_VERBOSE_CC} ${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
${am__verbose_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} -DPIC -fPIC ${CFLAGS} -o $@ -c $<;
%.o: %.c
${AM_VERBOSE_CC} ${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} ${CFLAGS} -o $@ -c $<;
${am__verbose_CC}${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} ${CFLAGS} -o $@ -c $<;

View File

@@ -106,8 +106,7 @@ static struct xtables_target chaos_tg_reg = {
.extra_opts = chaos_tg_opts,
};
void _init(void);
void _init(void)
static __attribute__((constructor)) void chaos_tg_ldr(void)
{
xtables_register_target(&chaos_tg_reg);
}

View File

@@ -41,8 +41,7 @@ static struct xtables_target delude_tg_reg = {
.final_check = delude_tg_check,
};
void _init(void);
void _init(void)
static __attribute__((constructor)) void delude_tg_ldr(void)
{
xtables_register_target(&delude_tg_reg);
}

View File

@@ -95,7 +95,7 @@ static struct xtables_target dhcpaddr_tg_reg = {
.extra_opts = dhcpaddr_tg_opts,
};
static void _init(void)
static __attribute__((constructor)) void dhcpaddr_tg_ldr(void)
{
xtables_register_target(&dhcpaddr_tg_reg);
}

View File

@@ -37,7 +37,7 @@ static struct xtables_target echo_tg_reg = {
.final_check = echo_tg_check,
};
static void _init(void)
static __attribute__((constructor)) void echo_tg_ldr(void)
{
xtables_register_target(&echo_tg_reg);
}

View File

@@ -0,0 +1,4 @@
The \fBECHO\fP target will send back all packets it received. It serves as an
examples for an Xtables target.
.PP
ECHO takes no options.

View File

@@ -68,7 +68,7 @@ static int ipmark_tg_parse(int c, char **argv, int invert, unsigned int *flags,
exit_error(PARAMETER_PROBLEM, "Bad addr value `%s' - should be `src' or `dst'", optarg);
*flags |= FL_ADDR_USED;
return true;
case '2':
param_act(P_ONLY_ONCE, "IPMARK", "and-mask", *flags & FL_AND_MASK_USED);
param_act(P_NO_INVERT, "IPMARK", "and-mask", invert);
@@ -175,7 +175,7 @@ static struct xtables_target ipmark_tg6_reg = {
.extra_opts = ipmark_tg_opts,
};
static void _init(void)
static __attribute__((constructor)) void ipmark_tg_ldr(void)
{
xtables_register_target(&ipmark_tg4_reg);
xtables_register_target(&ipmark_tg6_reg);

View File

@@ -111,8 +111,7 @@ static struct xtables_target logmark_tg_reg = {
.extra_opts = logmark_tg_opts,
};
void _init(void);
void _init(void)
static __attribute__((constructor)) void logmark_tg_ldr(void)
{
xtables_register_target(&logmark_tg_reg);
}

View File

@@ -43,7 +43,7 @@ static struct xtables_target sysrq_tg6_reg = {
.final_check = sysrq_tg_check,
};
static void _init(void)
static __attribute__((constructor)) void sysrq_tg_ldr(void)
{
xtables_register_target(&sysrq_tg4_reg);
xtables_register_target(&sysrq_tg6_reg);

View File

@@ -1,17 +1,19 @@
The SYSRQ target allows to remotely trigger sysrq on the local machine over the
network. This can be useful when vital parts of the machine hang, for example
an oops in a filesystem causing locks to be not released and processes to get
stuck as a result -- if still possible, use /proc/sysrq-trigger. Even when
stuck as a result - if still possible, use /proc/sysrq-trigger. Even when
processes are stuck, interrupts are likely to be still processed, and as such,
sysrq can be triggered through incoming network packets.
.PP
This xt_SYSRQ implementation does not use any encryption, so you should change
the SYSRQ password after use unless you have made sure it was transmitted
securely and no one sniffed the network, e.g. by use of an IPsec tunnel whose
endpoint is at the machine where you want to trigger the sysrq. Also, you
should limit as to who can issue commands using \fB-s\fP and/or \fB-m mac\fP,
and also that the destination is correct using \fB-d\fP (to protect against
potential broadcast packets), noting that it is still short of MAC/IP spoofing:
The xt_SYSRQ implementation uses a salted hash and a sequence number to prevent
network sniffers from either guessing the password or replaying earlier
requests. The initial sequence number comes from the time of day so you will
have a small window of vulnerability should time go backwards at a reboot.
However, the file /sys/module/xt_SYSREQ/seqno can be used to both query and
update the current sequence number. Also, you should limit as to who can issue
commands using \fB-s\fP and/or \fB-m mac\fP, and also that the destination is
correct using \fB-d\fP (to protect against potential broadcast packets), noting
that it is still short of MAC/IP spoofing:
.IP
-A INPUT -s 10.10.25.1 -m mac --mac-source aa:bb:cc:dd:ee:ff -d 10.10.25.7
-p udp --dport 9 -j SYSRQ
@@ -20,28 +22,59 @@ potential broadcast packets), noting that it is still short of MAC/IP spoofing:
ipsec --proto esp --tunnel-src 10.10.25.1 --tunnel-dst 10.10.25.7
-p udp --dport 9 -j SYSRQ
.PP
You should also limit the rate at which connections can be received to limit
the CPU time taken by illegal requests, for example:
.IP
-A INPUT 0s 10.10.25.1 -m mac --mac-source aa:bb:cc:dd:ee:ff -d 10.10.25.7
-p udp --dport 9 -m limit --limit 5/minute -j SYSRQ
.PP
This extension does not take any options. The \fB-p udp\fP options are
required.
.PP
The SYSRQ password can be changed through
/sys/module/xt_SYSRQ/parameters/password; note you need to use `echo -n` to
not add a newline to the password, i.e.
/sys/module/xt_SYSRQ/parameters/password, for example:
.IP
echo -n "password" >/sys/.../password
echo -n "password" >/sys/module/xt_SYSRQ/parameters/password
.PP
Alternatively, the password may be specified at modprobe time, but this is
insecure as people can possible see it through ps(1). You can use an option
line in /etc/modprobe.d/sysrq if it is properly guarded, that is, only readable
by root.
line in e.g. /etc/modprobe.d/xt_sysrq if it is properly guarded, that is, only
readable by root.
.IP
options xt_SYSRQ password=cookies
.PP
To trigger SYSRQ from a remote host, just use netcat or socat, specifying the
action (only one) as first character, followed by the password:
The hash algorithm can also be specified as a module option, for example, to
use SHA-256 instead of the default SHA-1:
.IP
echo -n "scookies" | socat stdin udp-sendto:10.10.25.7:9
.IP
echo -n "scookies" | netcat -u 10.10.25.7 9
options xt_SYSRQ hash=sha256
.PP
See the Linux docs for possible sysrq keys. Important ones are:
re(b)oot, power(o)ff, (s)ync filesystems, (u)mount and remount readonly.
The xt_SYSRQ module is normally silent unless a successful request is received,
but the \fIdebug\fP module parameter can be used to find exactly why a
seemingly correct request is not being processed.
.PP
To trigger SYSRQ from a remote host, just use netcat or socat:
.PP
.nf
sysrq_key="s" # the SysRq key(s)
password="password"
seqno="$(date +%s)"
salt="$(dd bs=12 count=1 if=/dev/urandom 2>/dev/null |
openssl enc -base64)"
req="$sysrq_key,$seqno,$salt"
req="$req,$(echo -n "$req,$password" | sha1sum | cut -c1-40)"
echo "$req" | socat stdin udp-sendto:10.10.25.7:9
# or
echo "$req" | netcat -uw1 10.10.25.7 9
.fi
.PP
See the Linux docs for possible sysrq keys. Important ones are: re(b)oot,
power(o)ff, (s)ync filesystems, (u)mount and remount readonly. More than one
sysrq key can be used at once, but bear in mind that, for example, a sync may
not complete before a subsequent reboot or poweroff.
.PP
The hashing scheme should be enough to prevent mis-use of SYSRQ in many
environments, but it is not perfect: take reasonable precautions to
protect your machines. Most importantly ensure that each machine has a
different password; there is scant protection for a SYSRQ packet being
applied to a machine that happens to have the same password.

View File

@@ -32,7 +32,7 @@ static struct xtables_target tarpit_tg_reg = {
.final_check = tarpit_tg_check,
};
static void _init(void)
static __attribute__((constructor)) void tarpit_tg_ldr(void)
{
xtables_register_target(&tarpit_tg_reg);
}

View File

@@ -108,7 +108,7 @@ static struct xtables_target tee_tg_reg = {
.extra_opts = tee_tg_opts,
};
static void _init(void)
static __attribute__((constructor)) void tee_tg_ldr(void)
{
xtables_register_target(&tee_tg_reg);
}

8
extensions/libxt_TEE.man Normal file
View File

@@ -0,0 +1,8 @@
The \fBTEE\fP target will clone a packet and redirect this clone to another
machine on the \fBlocal\fP network segment. In other words, the nexthop
must be the target, or you will have to configure the nexthop to forward it
further if so desired.
.TP
\fB--gw\fP \fIipaddr\fP
Send the cloned packet to the host reachable at the given IP address.
Use of 0.0.0.0 (for IPv4 packets) or :: (IPv6) is invalid.

View File

@@ -92,7 +92,7 @@ static struct xtables_match condition_mt_reg = {
.extra_opts = condition_opts,
};
static void _init(void)
static __attribute__((constructor)) void condition_mt_ldr(void)
{
xtables_register_match(&condition_mt_reg);
}

View File

@@ -96,7 +96,7 @@ static struct xtables_match dhcpaddr_mt_reg = {
.extra_opts = dhcpaddr_mt_opts,
};
static void _init(void)
static __attribute__((constructor)) void dhcpaddr_mt_ldr(void)
{
xtables_register_match(&dhcpaddr_mt_reg);
}

View File

@@ -112,7 +112,7 @@ static struct xtables_match fuzzy_mt_reg = {
.extra_opts = fuzzy_mt_opts,
};
static void _init(void)
static __attribute__((constructor)) void fuzzy_mt_ldr(void)
{
xtables_register_match(&fuzzy_mt_reg);
}

View File

@@ -272,7 +272,7 @@ static struct xtables_match geoip_match = {
.extra_opts = geoip_opts,
};
static void _init(void)
static __attribute__((constructor)) void geoip_mt_ldr(void)
{
xtables_register_match(&geoip_match);
}

View File

@@ -242,7 +242,7 @@ static struct xtables_match ipp2p_mt_reg = {
.extra_opts = ipp2p_mt_opts,
};
static void _init(void)
static __attribute__((constructor)) void ipp2p_mt_ldr(void)
{
xtables_register_match(&ipp2p_mt_reg);
}

View File

@@ -116,8 +116,7 @@ static struct xtables_match portscan_mt_reg = {
.extra_opts = portscan_mt_opts,
};
void _init(void);
void _init(void)
static __attribute__((constructor)) void portscan_mt_ldr(void)
{
xtables_register_match(&portscan_mt_reg);
}

View File

@@ -133,7 +133,7 @@ static struct xtables_match quota_mt2_reg = {
.extra_opts = quota_mt2_opts,
};
static void _init(void)
static __attribute__((constructor)) void quota2_mt_ldr(void)
{
xtables_register_match(&quota_mt2_reg);
}

View File

@@ -32,6 +32,8 @@ echo_tg4(struct sk_buff **poldskb, const struct xt_target_param *par)
unsigned int addr_type, data_len;
void *payload;
printk(KERN_INFO "dst_out=%p\n", (*poldskb)->dst->output);
/* This allows us to do the copy operation in fewer lines of code. */
if (skb_linearize(*poldskb) < 0)
return NF_DROP;
@@ -75,10 +77,10 @@ echo_tg4(struct sk_buff **poldskb, const struct xt_target_param *par)
addr_type = RTN_UNSPEC;
#ifdef CONFIG_BRIDGE_NETFILTER
if (hooknum != NF_INET_FORWARD || (newskb->nf_bridge != NULL &&
if (par->hooknum != NF_INET_FORWARD || (newskb->nf_bridge != NULL &&
newskb->nf_bridge->mask & BRNF_BRIDGED))
#else
if (hooknum != NF_INET_FORWARD)
if (par->hooknum != NF_INET_FORWARD)
#endif
addr_type = RTN_LOCAL;

View File

@@ -3,7 +3,6 @@
* Copyright © Jan Engelhardt <jengelh [at] medozas de>, 2008
*
* Based upon the ipt_SYSRQ idea by Marek Zalem <marek [at] terminus sk>
* xt_SYSRQ does not use hashing or timestamps.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -19,15 +18,145 @@
#include <linux/netfilter_ipv4/ip_tables.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
#include <linux/netfilter/x_tables.h>
#include <linux/crypto.h>
#include <linux/scatterlist.h>
#include <net/ip.h>
#include "compat_xtables.h"
static bool sysrq_once;
static char sysrq_password[64];
static char sysrq_hash[16] = "sha1";
static long sysrq_seqno;
static int sysrq_debug;
module_param_string(password, sysrq_password, sizeof(sysrq_password),
S_IRUSR | S_IWUSR);
module_param_string(hash, sysrq_hash, sizeof(sysrq_hash), S_IRUSR);
module_param_named(seqno, sysrq_seqno, long, S_IRUSR | S_IWUSR);
module_param_named(debug, sysrq_debug, int, S_IRUSR | S_IWUSR);
MODULE_PARM_DESC(password, "password for remote sysrq");
MODULE_PARM_DESC(hash, "hash algorithm, default sha1");
MODULE_PARM_DESC(seqno, "sequence number for remote sysrq");
MODULE_PARM_DESC(debug, "debugging: 0=off, 1=on");
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static struct crypto_hash *sysrq_tfm;
static int sysrq_digest_size;
static unsigned char *sysrq_digest_password;
static unsigned char *sysrq_digest;
static char *sysrq_hexdigest;
/*
* The data is of the form "<requests>,<seqno>,<salt>,<hash>" where <requests>
* is a series of sysrq requests; <seqno> is a sequence number that must be
* greater than the last sequence number; <salt> is some random bytes; and
* <hash> is the hash of everything up to and including the preceding ","
* together with the password.
*
* For example
*
* salt=$RANDOM
* req="s,$(date +%s),$salt"
* echo "$req,$(echo -n $req,secret | sha1sum | cut -c1-40)"
*
* You will want a better salt and password than that though :-)
*/
static unsigned int sysrq_tg(const void *pdata, uint16_t len)
{
const char *data = pdata;
int i, n;
struct scatterlist sg[2];
struct hash_desc desc;
int ret;
long new_seqno = 0;
if (*sysrq_password == '\0') {
if (!sysrq_once)
printk(KERN_INFO KBUILD_MODNAME ": No password set\n");
sysrq_once = true;
return NF_DROP;
}
if (len == 0)
return NF_DROP;
for (i = 0; sysrq_password[i] != '\0' &&
sysrq_password[i] != '\n'; ++i)
/* loop */;
sysrq_password[i] = '\0';
i = 0;
for (n = 0; n < len - 1; ++n) {
if (i == 1 && '0' <= data[n] && data[n] <= '9')
new_seqno = 10L * new_seqno + data[n] - '0';
if (data[n] == ',' && ++i == 3)
break;
}
++n;
if (i != 3) {
if (sysrq_debug)
printk(KERN_WARNING KBUILD_MODNAME
": badly formatted request\n");
return NF_DROP;
}
if (sysrq_seqno >= new_seqno) {
if (sysrq_debug)
printk(KERN_WARNING KBUILD_MODNAME
": old sequence number ignored\n");
return NF_DROP;
}
desc.tfm = sysrq_tfm;
desc.flags = 0;
ret = crypto_hash_init(&desc);
if (ret != 0)
goto hash_fail;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
sg_init_table(sg, 2);
#endif
sg_set_buf(&sg[0], data, n);
strcpy(sysrq_digest_password, sysrq_password);
i = strlen(sysrq_digest_password);
sg_set_buf(&sg[1], sysrq_digest_password, i);
ret = crypto_hash_digest(&desc, sg, n + i, sysrq_digest);
if (ret != 0)
goto hash_fail;
for (i = 0; i < sysrq_digest_size; ++i) {
sysrq_hexdigest[2*i] =
"0123456789abcdef"[(sysrq_digest[i] >> 4) & 0xf];
sysrq_hexdigest[2*i+1] =
"0123456789abcdef"[sysrq_digest[i] & 0xf];
}
sysrq_hexdigest[2*sysrq_digest_size] = '\0';
if (len - n < sysrq_digest_size) {
if (sysrq_debug)
printk(KERN_INFO KBUILD_MODNAME ": Short digest,"
" expected %s\n", sysrq_hexdigest);
return NF_DROP;
}
if (strncmp(data + n, sysrq_hexdigest, sysrq_digest_size) != 0) {
if (sysrq_debug)
printk(KERN_INFO KBUILD_MODNAME ": Bad digest,"
" expected %s\n", sysrq_hexdigest);
return NF_DROP;
}
/* Now we trust the requester */
sysrq_seqno = new_seqno;
for (i = 0; i < len && data[i] != ','; ++i) {
printk(KERN_INFO KBUILD_MODNAME ": SysRq %c\n", data[i]);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
handle_sysrq(data[i], NULL);
#else
handle_sysrq(data[i], NULL, NULL);
#endif
}
return NF_ACCEPT;
hash_fail:
printk(KERN_WARNING KBUILD_MODNAME ": digest failure\n");
return NF_DROP;
}
#else
static unsigned int sysrq_tg(const void *pdata, uint16_t len)
{
const char *data = pdata;
@@ -57,6 +186,7 @@ static unsigned int sysrq_tg(const void *pdata, uint16_t len)
#endif
return NF_ACCEPT;
}
#endif
static unsigned int
sysrq_tg4(struct sk_buff **pskb, const struct xt_target_param *par)
@@ -73,9 +203,11 @@ sysrq_tg4(struct sk_buff **pskb, const struct xt_target_param *par)
udph = (void *)iph + ip_hdrlen(skb);
len = ntohs(udph->len) - sizeof(struct udphdr);
printk(KERN_INFO KBUILD_MODNAME ": " NIPQUAD_FMT ":%u -> :%u len=%u\n",
NIPQUAD(iph->saddr), htons(udph->source), htons(udph->dest),
len);
if (sysrq_debug)
printk(KERN_INFO KBUILD_MODNAME
": " NIPQUAD_FMT ":%u -> :%u len=%u\n",
NIPQUAD(iph->saddr), htons(udph->source),
htons(udph->dest), len);
return sysrq_tg((void *)udph + sizeof(struct udphdr), len);
}
@@ -94,14 +226,17 @@ sysrq_tg6(struct sk_buff **pskb, const struct xt_target_param *par)
udph = udp_hdr(skb);
len = ntohs(udph->len) - sizeof(struct udphdr);
printk(KERN_INFO KBUILD_MODNAME ": " NIP6_FMT ":%hu -> :%hu len=%u\n",
NIP6(iph->saddr), ntohs(udph->source),
ntohs(udph->dest), len);
if (sysrq_debug)
printk(KERN_INFO KBUILD_MODNAME
": " NIP6_FMT ":%hu -> :%hu len=%u\n",
NIP6(iph->saddr), ntohs(udph->source),
ntohs(udph->dest), len);
return sysrq_tg(udph + sizeof(struct udphdr), len);
}
static bool sysrq_tg_check(const struct xt_tgchk_param *par)
{
if (par->target->family == NFPROTO_IPV4) {
const struct ipt_entry *entry = par->entryinfo;
@@ -146,11 +281,64 @@ static struct xt_target sysrq_tg_reg[] __read_mostly = {
static int __init sysrq_tg_init(void)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
struct timeval now;
sysrq_tfm = crypto_alloc_hash(sysrq_hash, 0, CRYPTO_ALG_ASYNC);
if (IS_ERR(sysrq_tfm)) {
printk(KERN_WARNING KBUILD_MODNAME
": Error: Could not find or load %s hash\n",
sysrq_hash);
sysrq_tfm = NULL;
goto fail;
}
sysrq_digest_size = crypto_hash_digestsize(sysrq_tfm);
sysrq_digest = kmalloc(sysrq_digest_size, GFP_KERNEL);
if (sysrq_digest == NULL) {
printk(KERN_WARNING KBUILD_MODNAME
": Cannot allocate digest\n");
goto fail;
}
sysrq_hexdigest = kmalloc(2 * sysrq_digest_size + 1, GFP_KERNEL);
if (sysrq_hexdigest == NULL) {
printk(KERN_WARNING KBUILD_MODNAME
": Cannot allocate hexdigest\n");
goto fail;
}
sysrq_digest_password = kmalloc(sizeof(sysrq_password), GFP_KERNEL);
if (sysrq_digest_password == NULL) {
printk(KERN_WARNING KBUILD_MODNAME
": Cannot allocate password digest space\n");
goto fail;
}
do_gettimeofday(&now);
sysrq_seqno = now.tv_sec;
return xt_register_targets(sysrq_tg_reg, ARRAY_SIZE(sysrq_tg_reg));
fail:
if (sysrq_tfm)
crypto_free_hash(sysrq_tfm);
if (sysrq_digest)
kfree(sysrq_digest);
if (sysrq_hexdigest)
kfree(sysrq_hexdigest);
if (sysrq_digest_password)
kfree(sysrq_digest_password);
return -EINVAL;
#else
printk(KERN_WARNING "xt_SYSRQ does not provide crypto for <= 2.6.18\n");
return xt_register_targets(sysrq_tg_reg, ARRAY_SIZE(sysrq_tg_reg));
#endif
}
static void __exit sysrq_tg_exit(void)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
crypto_free_hash(sysrq_tfm);
kfree(sysrq_digest);
kfree(sysrq_hexdigest);
kfree(sysrq_digest_password);
#endif
return xt_unregister_targets(sysrq_tg_reg, ARRAY_SIZE(sysrq_tg_reg));
}

View File

@@ -597,27 +597,42 @@ search_all_gnu(const unsigned char *payload, const unsigned int plen)
}
/* check for KaZaA download commands and other typical data */
/* plen is guaranteed to be >= 5 (see @matchlist) */
static unsigned int
search_all_kazaa(const unsigned char *payload, const unsigned int plen)
{
if (payload[plen-2] == 0x0d && payload[plen-1] == 0x0a) {
if (memcmp(payload, "GIVE ", 5) == 0)
return IPP2P_KAZAA * 100 + 1;
uint16_t c, end, rem;
if (memcmp(payload, "GET /", 5) == 0) {
uint16_t c = 8;
const uint16_t end = plen - 22;
while (c < end) {
if (payload[c] == 0x0a &&
payload[c+1] == 0x0d &&
(memcmp(&payload[c+2], "X-Kazaa-Username: ", 18) == 0 ||
memcmp(&payload[c+2], "User-Agent: PeerEnabler/", 24) == 0))
return IPP2P_KAZAA * 100 + 2;
c++;
}
}
if (plen >= 5) {
printk(KERN_WARNING KBUILD_MODNAME ": %s: plen (%u) < 5\n",
__func__, plen);
return 0;
}
if (payload[plen-2] != 0x0d || payload[plen-1] != 0x0a)
return 0;
if (memcmp(payload, "GIVE ", 5) == 0)
return IPP2P_KAZAA * 100 + 1;
if (memcmp(payload, "GET /", 5) != 0)
return 0;
end = plen - 18;
rem = plen - 5;
for (c = 5; c < end; ++c, --rem) {
if (payload[c] != 0x0d)
continue;
if (payload[c+1] != 0x0a)
continue;
if (rem >= 18 &&
memcmp(&payload[c+2], "X-Kazaa-Username: ", 18) == 0)
return IPP2P_KAZAA * 100 + 2;
if (rem >= 24 &&
memcmp(&payload[c+2], "User-Agent: PeerEnabler/", 24) == 0)
return IPP2P_KAZAA * 100 + 2;
}
return 0;
}

2
m4/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/libtool.m4
/lt*.m4

View File

@@ -1,4 +1,4 @@
.TH xtables\-addons 8 2008\-11\-18
.TH xtables\-addons 8 "v1.7 (2008\-12\-25)" "" "v1.7 (2008\-12\-25)"
.SH NAME
Xtables\-addons - additional extensions for iptables, ip6tables, etc.
.SH TARGETS