1
0
mirror of https://git.FreeBSD.org/ports.git synced 2024-11-23 00:43:28 +00:00

- Fix doormand to work on FreeBSD

- Replace broken ipf* script
- RCng script

PR:		ports/81615
Submitted by:	Lupe Christoph <lupe@lupe-christoph.de> (maintainer)
This commit is contained in:
Pav Lucistnik 2005-05-30 16:31:51 +00:00
parent ff008ae301
commit ca5a2552a5
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=136446
9 changed files with 409 additions and 11 deletions

View File

@ -7,6 +7,7 @@
PORTNAME= doorman
PORTVERSION= 0.8
PORTREVISION= 1
CATEGORIES= security
MASTER_SITES= ${MASTER_SITE_SOURCEFORGE}
MASTER_SITE_SUBDIR= doorman
@ -18,13 +19,14 @@ COMMENT= A Port Knocking implementation, both daemon and client
BUILD_DEPENDS= lsof:${PORTSDIR}/sysutils/lsof
RUN_DEPENDS= ${BUILD_DEPENDS}
IGNORE= does not work correctly, issues with the pcap library. Patches are under development
PKGMESSAGE= ${WRKDIR}/pkg-message
PATCH_STRIP= -p1
# Default to db4
WITH_BDB_VER?= 4
.include <bsd.port.pre.mk>
.if ${WITH_BDB_VER} == 2
LIB_DEPENDS= db2.0:${PORTSDIR}/databases/db2
.elif ${WITH_BDB_VER} == 3
@ -39,11 +41,21 @@ LIB_DEPENDS= db-4.2.2:${PORTSDIR}/databases/db42
.error WITH_BDB_VER must be one between 2, 3, 4, 41 and 42
.endif
# doormand does not work with the FreeBSD 4.x version of libpcap.
# Require the ports version.
.if ${OSVERSION} < 500000
BUILD_DEPENDS+= ${LOCALBASE}/lib/libpcap.a:${PORTSDIR}/net/libpcap
.endif
INSTALL_TARGET= installdirs install-exec install-data
MAN1= knock.1
MAN5= knockcf.5 doormand.cf.5 guestlist.5
MAN8= doormand.8
GNU_CONFIGURE= yes
SUB_FILES= pkg-message
USE_RC_SUBR= doorman.sh
pre-everything::
@${ECHO_MSG}
@ -55,10 +67,20 @@ pre-everything::
@${ECHO_MSG} " CURRENTLY BUILDING WITH db${WITH_BDB_VER} "
@${ECHO_MSG}
pre-install:
@${SED} 's#%%PREFIX%%#${PREFIX}#' ${MASTERDIR}/pkg-message >${PKGMESSAGE}
post-install:
${RM} -f ${PREFIX}/etc/doormand/ipf_add
${INSTALL_SCRIPT} ${FILESDIR}/ipf_add.atend ${PREFIX}/etc/doormand/ipf_add.atend
${INSTALL_SCRIPT} ${FILESDIR}/ipf_add.before_block ${PREFIX}/etc/doormand/ipf_add.before_block
${INSTALL_SCRIPT} ${FILESDIR}/ipf_delete ${PREFIX}/etc/doormand/ipf_delete
@for man in ${MAN1}; do \
${INSTALL_MAN} -C ${WRKSRC}/$$man ${PREFIX}/man/man1; \
done
@for man in ${MAN5}; do \
${INSTALL_MAN} -C ${WRKSRC}/$$man ${PREFIX}/man/man5; \
done
@for man in ${MAN8}; do \
${INSTALL_MAN} -C ${WRKSRC}/$$man ${PREFIX}/man/man8; \
done
@${CAT} ${PKGMESSAGE}
.include <bsd.port.mk>
.include <bsd.port.post.mk>

View File

@ -0,0 +1,30 @@
#!/bin/sh
#
# PROVIDE: doorman
# REQUIRE: LOGIN
# KEYWORD: FreeBSD
#
# Add the following lines to /etc/rc.conf to enable doorman:
# doorman_enable (bool): Set to "NO" by default.
# Set it to "YES" to enable doorman
# doorman_config (path): Set to "%%PREFIX%%/etc/doormand/doormand.cf" by default.
#
. %%RC_SUBR%%
name="doorman"
rcvar=`set_rcvar`
[ -z "$doorman_enable" ] && doorman_enable="NO"
[ -z "$doorman_config" ] && doorman_config="%%PREFIX%%/etc/doormand/doormand.cf"
[ -f "$doorman_config" ] || (echo "$doorman_config" does not exist.; exit)
command=%%PREFIX%%/sbin/doormand
pidfile=/var/run/doormand.pid
command_args="-p $pidfile -f $doorman_config"
load_rc_config $name
run_rc_command "$1"

View File

@ -0,0 +1,73 @@
#!/bin/sh
#
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#
# WARNING!
#
# This script has not been tested. The author does not run this kind
# of firewall rules and is too lazy to build a firewall that does
# just for testing.
#
# If you use this script and either find it *does* work (surprise!)
# or have modifications that make it work, please send mail to
# tke FreeBSD port maintainer. (See port Makefile).
#
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# *********************************************************************
# This script is used with IPFilter if the ruleset (/etc/ipf.rules)
# does not contain explicit drop rules that mask a rule added at the end.
#
# The script will add it's rules at the end.
#
# Note that it does not use locking, so concurrent accesses may
# interfere with each other.
# *********************************************************************
#
# file "ipf_add.atend"
# IPFilter add script, called by "doormand".
# This add "pass in quick" rules to the firewall.
#
# Called with five arguments:
#
# $1 : name of the interface (e.g. ne0)
# $2 : source IP; i.e. dotted-decimal address of the 'knock' client
# $3 : source port; when this script is called for the first time
# for a connection (man 8 doormand), this argument will be set
# to a single "0" (0x30) character. This means that the source
# port is not yet known, and a broad rule allowing any source
# port is required.
# $4 : destination IP; that is, the IP address of the interface
# in argument 1.
# $5 : The port number of the requested service (e.g. 22 for ssh, etc.)
#
# This script expects the IPFilter ruleset to have two rules like this:
inblock="block in log quick on $1 from any to any"
outblock="block out log quick on $1 from any to any"
# The new rules will be inserted just before these blocking rules.
if [ $3 = 0 ]; then
inrule="pass in quick on $1 proto TCP from $2 to $4 port = $5"
outrule="pass out quick on $1 proto TCP from $4 port = $5 to $2"
else
inrule="pass in quick on $1 proto TCP from $2 port = $3 to $4 port = $5"
outrule="pass out quick on $1 proto TCP from $4 port = $5 to $2 port = $3"
fi
#
# acquire lock (not implemented)
#
# Insert new rules.
ret=`(echo $inrule; echo $outrule) | /sbin/ipf -f - 2>&1`
#
# release lock (not implemented)
#
if [ -z "$ret" ]; then
echo 0
else
echo -1 3 $ret
fi

View File

@ -0,0 +1,67 @@
#!/bin/sh
#
# *********************************************************************
# This script is used with IPFilter if the ruleset (/etc/ipf.rules)
# contains an explicit drop rule that masks a rule added at the end.
# It expects block rules for both input and output filters. This
# works e.g. with rule sets generated by fwbuilder.
#
# The script will insert it's rule before the drop rule. The drop rules
# are expected to look like the $inblock and $outblock variables
# defined below.
#
# Note that it does not use locking, so concurrent accesses may
# interfere with each other.
# *********************************************************************
#
# file "ipf_add.before_block"
# IPFilter add script, called by "doormand".
# This add two "pass in quick" rules to the firewall.
#
# Called with five arguments:
#
# $1 : name of the interface (e.g. ne0)
# $2 : source IP; i.e. dotted-decimal address of the 'knock' client
# $3 : source port; when this script is called for the first time
# for a connection (man 8 doormand), this argument will be set
# to a single "0" (0x30) character. This means that the source
# port is not yet known, and a broad rule allowing any source
# port is required.
# $4 : destination IP; that is, the IP address of the interface
# in argument 1.
# $5 : The port number of the requested service (e.g. 22 for ssh, etc.)
#
# This script expects the IPFilter ruleset to have two rules like this:
inblock="block in log quick on $1 from any to any"
outblock="block out log quick on $1 from any to any"
# The new rules will be inserted just before these blocking rules.
if [ $3 = 0 ]; then
inrule="pass in quick on $1 proto TCP from $2 to $4 port = $5"
outrule="pass out quick on $1 proto TCP from $4 port = $5 to $2"
else
inrule="pass in quick on $1 proto TCP from $2 port = $3 to $4 port = $5"
outrule="pass out quick on $1 proto TCP from $4 port = $5 to $2 port = $3"
fi
#
# acquire lock (not implemented)
#
# Find the rule numbers of the block rules.
inruleno=`ipfstat -in | sed -n -e "s/@\([0-9]*\) $inblock/\1/p"`
outruleno=`ipfstat -on | sed -n -e "s/@\([0-9]*\) $outblock/\1/p"`
# Insert new rules.
ret=`(echo @$inruleno $inrule; echo @$outruleno $outrule) | /sbin/ipf -f - 2>&1`
#
# release lock (not implemented)
#
if [ -z "$ret" ]; then
echo 0
else
echo -1 3 $ret
fi

View File

@ -0,0 +1,38 @@
#!/bin/sh
#
# file "ipf_delete"
# IPFilter firewall-delete script, called by "doormand".
# This removes the "pass in quick" rules from the firewall
# that were added by one of the ipf_add scripts.
#
# Called with five arguments:
#
# $1 : name of the interface (e.g. ne0)
# $2 : source IP; i.e. dotted-decimal address of the 'knock' client
# $3 : source port; when this script is called for the first time
# to delete a broad firewall rule, this argument will be set
# to a single "0" (0x30) character. This means that the source
# port was not known, and a broad rule allowing any source
# port was set.
# $4 : destination IP; that is, the IP address of the interface
# in argument 1.
# $5 : The port number of the requested service (e.g. 22 for ssh, etc.)
#
#
if [ $3 = 0 ]; then
inrule="pass in quick on $1 proto TCP from $2 to $4 port = $5"
outrule="pass out quick on $1 proto TCP from $4 port = $5 to $2"
else
inrule="pass in quick on $1 proto TCP from $2 port = $3 to $4 port = $5"
outrule="pass out quick on $1 proto TCP from $4 port = $5 to $2 port = $3"
fi
ret=`(echo @$inruleno $inrule; echo @$outruleno $outrule) | /sbin/ipf -r -f - 2>&1`
if [ -z "$ret" ]
then
echo 0
else
echo -1 3 $ret
fi

View File

@ -0,0 +1,165 @@
--- doorman-0.8.orig/doormand.c Thu Jul 29 21:24:02 2004
+++ doorman-0.8/doormand.c Sun May 29 09:05:31 2005
@@ -397,7 +397,11 @@
int datalink_header_lengths[] = {
// hdr len code data link type
// ------- --- ---------------------------
+#ifdef __FreeBSD__
+ 4, // 0 no link-layer encapsulation
+#else
0, // 0 no link-layer encapsulation
+#endif
14, // 1 Ethernet (10Mb)
-1, // 2 Experimental Ethernet (3Mb)
-1, // 3 Amateur Radio AX.25
@@ -557,6 +561,14 @@
// more readable.
//
+/*
+// lsof on FreeBSD produces one more field.
+// This should be rewritten to use a regular expression, anyway.
+//
+// And who said using C++ style comments in C was good for portability?!?
+*/
+
+#ifdef __FreeBSD__
#define LSOF()\
sprintf (cmd, "lsof -Pn -iTCP@%s:%s", interface_ip_str, dport_string) ;\
\
@@ -578,6 +590,7 @@
if ((p1 = token (&p2, " ")) == NULL) continue ;\
if ((p1 = token (&p2, " ")) == NULL) continue ;\
if ((p1 = token (&p2, " ")) == NULL) continue ;\
+ if ((p1 = token (&p2, " ")) == NULL) continue ;\
if ((p1 = token (&p2, " :")) == NULL) continue ;\
local_ip = inet_addr(p1) ;\
if ((p1 = token (&p2, "-")) == NULL) continue ;\
@@ -602,7 +615,53 @@
}\
}\
pclose(f) ;
-
+#else
+#define LSOF()\
+sprintf (cmd, "lsof -Pn -iTCP@%s:%s", interface_ip_str, dport_string) ;\
+\
+f = popen (cmd, "r") ;\
+if (f == NULL) {\
+ croak (errno, "Can't execute '%s'; exiting.", cmd) ;\
+}\
+\
+fgets(buffer, 254, f) ; /* throw away the first line. */ \
+while (fgets(buffer, 254, f)) {\
+ p2 = buffer ;\
+ if ((p1 = token (&p2, " ")) == NULL) continue ;\
+ dname = p1 ;\
+ if ((p1 = token (&p2, " ")) == NULL) continue ;\
+ pid = p1 ;\
+ if ((p1 = token (&p2, " ")) == NULL) continue ;\
+ uname = p1 ;\
+ if ((p1 = token (&p2, " ")) == NULL) continue ;\
+ if ((p1 = token (&p2, " ")) == NULL) continue ;\
+ if ((p1 = token (&p2, " ")) == NULL) continue ;\
+ if ((p1 = token (&p2, " ")) == NULL) continue ;\
+ if ((p1 = token (&p2, " :")) == NULL) continue ;\
+ local_ip = inet_addr(p1) ;\
+ if ((p1 = token (&p2, "-")) == NULL) continue ;\
+ local_port = atoi(p1) ;\
+ if ((p1 = token (&p2, "->:")) == NULL) continue ;\
+ aptr = p1 ;\
+ remote_ip = inet_addr(p1) ;\
+ if ((p1 = token (&p2, " ")) == NULL) continue ;\
+ pptr = p1 ;\
+ remote_port = atoi(p1) ;\
+ if ((p1 = token (&p2, " ()")) == NULL) continue ;\
+ status = p1 ;\
+\
+ if ((saddr == remote_ip) &&\
+ (daddr == local_ip) &&\
+ (sport == remote_port) &&\
+ (dport == local_port) && \
+ (strcmp(status, "ESTABLISHED") == 0))\
+ {\
+ connected = TRUE ;\
+ break ;\
+ }\
+}\
+pclose(f) ;
+#endif
@@ -647,7 +706,11 @@
snprintf (cmd, 254, "tcp and dst port %s and src %s and dst %s",
dport_string, src_addr, interface_ip_str) ;
DEBUG "open a secondary pcap: '%s'", cmd) ;
+#ifdef __FreeBSD__
+ hdr_len = open_a_pcap (device, 1000, &cap, cmd) ;
+#else
hdr_len = open_a_pcap (device, 0, &cap, cmd) ;
+#endif
// set broad firewall rule
sprintf (G_fw_broad_rule, " %s %s 0 %s %s",
@@ -659,7 +722,22 @@
for (;;) {
+#ifdef __FreeBSD__
+ {
+ int ret = 0;
+ struct pcap_pkthdr * packet_hdr_p;
+
+ while (ret == 0) {
+ ret = pcap_next_ex (cap, &packet_hdr_p, (const u_char **)&p) ;
+ packet_hdr = *packet_hdr_p;
+ if (ret < 0) {
+ p = NULL;
+ }
+ }
+ }
+#else
p = (unsigned char*)pcap_next (cap, &packet_hdr) ;
+#endif
if (p == NULL) {
WARNX "manage_firewall got null from 'pcap_next'. Exiting.") ;
exit (1) ;
@@ -1222,9 +1300,13 @@
croak (errno, "Can't get interface address of %s", device) ;
}
+#ifdef __FreeBSD__
+ hdr_len = open_a_pcap (device, 1000, &G_cap, "udp and port %d and dst %s",
+ port, interface_ip) ;
+#else
hdr_len = open_a_pcap (device, 0, &G_cap, "udp and port %d and dst %s",
port, interface_ip) ;
-
+#endif
if (G_reconfigure) {
G_reconfigure = FALSE ;
NOTICE "reconfigured.") ;
@@ -1252,7 +1334,22 @@
char src_addr_buff[16] ;
errno = 0 ;
+#ifdef __FreeBSD__
+ {
+ int ret = 0;
+ struct pcap_pkthdr * packet_hdr_p;
+
+ while (ret == 0) {
+ ret = pcap_next_ex (G_cap, &packet_hdr_p, (const u_char **)&p) ;
+ packet_hdr = *packet_hdr_p;
+ if (ret < 0) {
+ p = NULL;
+ }
+ }
+ }
+#else
p = (unsigned char *)pcap_next (G_cap, &packet_hdr) ;
+#endif
if (G_reconfigure) {
if (daemonize) err_closelog() ;
goto reconfigure ;

View File

@ -9,4 +9,9 @@ To configure Doorman, please edit the files guestlist and doormand.cf found in
or by visiting the Doorman website at http://doorman.sourceforge.net.
The doormand daemon will *not* be started automatically. To allow it
to start, put this line in /etc/rc.conf:
doorman_enable="YES"
******************************************************************************

View File

@ -4,6 +4,3 @@ the secret knock!
WWW: http://doorman.sourceforge.net/
Author: Bruce Ward <bward2@users.sourceforge.net>
- Aaron Dalton
aaron@daltons.ca

View File

@ -3,7 +3,8 @@ etc/doormand/doormand.cf.EXAMPLE
etc/doormand/guestlist.EXAMPLE
etc/doormand/ipchains_add
etc/doormand/ipchains_delete
etc/doormand/ipf_add
etc/doormand/ipf_add.atend
etc/doormand/ipf_add.before_block
etc/doormand/ipf_delete
etc/doormand/ipfw_add
etc/doormand/ipfw_delete
@ -12,4 +13,4 @@ etc/doormand/iptables_delete
etc/doormand/pfctl_add
etc/doormand/pfctl_delete
sbin/doormand
@dirrm etc/doormand
@unexec rmdir %D/etc/doormand 2>/dev/null || true