aboutsummaryrefslogtreecommitdiffstats
path: root/security/knock
diff options
context:
space:
mode:
authorsbz <sbz@FreeBSD.org>2011-09-26 16:26:18 +0800
committersbz <sbz@FreeBSD.org>2011-09-26 16:26:18 +0800
commit5046e1b76fe061bf8406be4d6be981dd6b44bc9b (patch)
treeda3dd2b1e4f07685e4df5579fb329af74aa971a2 /security/knock
parentacf8efe121be97f1d4a6098a5b14372ba32abd8d (diff)
downloadfreebsd-ports-gnome-5046e1b76fe061bf8406be4d6be981dd6b44bc9b.tar.gz
freebsd-ports-gnome-5046e1b76fe061bf8406be4d6be981dd6b44bc9b.tar.zst
freebsd-ports-gnome-5046e1b76fe061bf8406be4d6be981dd6b44bc9b.zip
- Add LICENSE
- Add support for tun devices [1] - Update MASTER_SITES - Make happy portlint - Bump PORTEPOCH PR: ports/159078 [1] Submitted by: Lung-Pin Chang <changlp at cs.nctu.edu.tw> Approved by: jadawin@ (mentor)
Diffstat (limited to 'security/knock')
-rw-r--r--security/knock/Makefile23
-rw-r--r--security/knock/distinfo4
-rw-r--r--security/knock/files/knockd.sh.in20
-rw-r--r--security/knock/files/patch-Makefile.in20
-rw-r--r--security/knock/files/patch-config.h.in89
-rw-r--r--security/knock/files/patch-doc__knock.1.in15
-rw-r--r--security/knock/files/patch-doc__knockd.1.in58
-rw-r--r--security/knock/files/patch-knockd.conf4
-rw-r--r--security/knock/files/patch-src__knock.c132
-rw-r--r--security/knock/files/patch-src__knockd.c520
10 files changed, 866 insertions, 19 deletions
diff --git a/security/knock/Makefile b/security/knock/Makefile
index d19ed024fd1c..c07025d6e0fa 100644
--- a/security/knock/Makefile
+++ b/security/knock/Makefile
@@ -6,15 +6,18 @@
#
PORTNAME= knock
-PORTVERSION= 0.5.20051124
-PORTREVISION= 1
+PORTVERSION= 0.5
+PORTEPOCH= 1
CATEGORIES= security
-MASTER_SITES= ${MASTER_SITE_LOCAL}
-MASTER_SITE_SUBDIR= shaun
+MASTER_SITES= http://www.zeroflux.org/proj/knock/files/ \
+ ${MASTER_SITE_LOCAL:S,%SUBDIR%,sbz,}
MAINTAINER= sbz@FreeBSD.org
COMMENT= A flexible port-knocking server and client
+LICENSE= GPLv2
+LICENSE_FILE= ${WRKSRC}/COPYING
+
GNU_CONFIGURE= yes
CFLAGS+= -I${LOCALBASE}/include
@@ -22,9 +25,6 @@ CFLAGS+= -I${LOCALBASE}/include
OPTIONS= SERVER "Install knockd server" on \
CLIENT "Install knock client" on
-RUNDIR= /var/run
-SUB_LIST= RUNDIR=${RUNDIR}
-
.include <bsd.port.pre.mk>
.if defined(WITH_SERVER)
@@ -46,14 +46,15 @@ IGNORE= at least one component must be selected for installation
post-patch:
@${REINPLACE_CMD} -e "s#%%PREFIX%%#${PREFIX}#g" \
- -e "s#%%RUNDIR%%#${RUNDIR}#g" \
-e "s#eth0#fxp0#g" \
${WRKSRC}/src/knockd.c
@${REINPLACE_CMD} -e "s/#VERSION#/${PORTVERSION}/g" \
- -e "s#eth0#fxp0#g" \
- ${WRKSRC}/doc/knock.1.in \
- ${WRKSRC}/doc/knockd.1.in
+ -e "s#eth0#fxp0#g" \
+ ${WRKSRC}/doc/knock.1.in \
+ ${WRKSRC}/doc/knockd.1.in \
+ ${WRKSRC}/src/knockd.c \
+ ${WRKSRC}/src/knock.c
do-install:
.if defined(WITH_SERVER)
diff --git a/security/knock/distinfo b/security/knock/distinfo
index c975d87a078f..e311b633ed71 100644
--- a/security/knock/distinfo
+++ b/security/knock/distinfo
@@ -1,2 +1,2 @@
-SHA256 (knock-0.5.20051124.tar.gz) = 15aa6a5d152a7cdb5b52d1e9de9e77d7f52156ce3e5d5c80dd9b76e40f6a84aa
-SIZE (knock-0.5.20051124.tar.gz) = 86607
+SHA256 (knock-0.5.tar.gz) = c4c141166a10c45b139e5e656d0c98bbb99567abb35163863fc1df1a025cde15
+SIZE (knock-0.5.tar.gz) = 83990
diff --git a/security/knock/files/knockd.sh.in b/security/knock/files/knockd.sh.in
index be858ca7d255..65b9e35b6cce 100644
--- a/security/knock/files/knockd.sh.in
+++ b/security/knock/files/knockd.sh.in
@@ -3,18 +3,30 @@
# PROVIDE: knockd
# REQUIRE: DAEMON
# BEFORE: LOGIN
+#
+# Add the following lines to /etc/rc.conf to enable knockd:
+#
+# knockd_enable (bool): Set it to "YES" to enable knockd
+# Default is "NO".
+# knockd_conf (path): Set full path to config file.
+# Default is "%%PREFIX%%/etc/knockd.conf".
+# knockd_flags (arguments): Set command arguments of knockd daemon
+# Default is "-d".
. /etc/rc.subr
name="knockd"
rcvar=`set_rcvar`
+
load_rc_config $name
-knockd_enable=${knockd_enable:-"NO"}
-knockd_flags=${knockd_flags:-"-d"}
+: ${knockd_enable="NO"}
+: ${knockd_conf="%%PREFIX%%/etc/knockd.conf"}
+: ${knockd_flags="-d"}
command="%%PREFIX%%/bin/knockd"
-pidfile="%%RUNDIR%%/knockd.pid"
-required_files="%%PREFIX%%/etc/knockd.conf"
+command_args=${knockd_flags}
+pidfile="/var/run/knockd.pid"
+required_files=${knockd_conf}
run_rc_command "$1"
diff --git a/security/knock/files/patch-Makefile.in b/security/knock/files/patch-Makefile.in
new file mode 100644
index 000000000000..0a36bf5117c9
--- /dev/null
+++ b/security/knock/files/patch-Makefile.in
@@ -0,0 +1,20 @@
+--- ./Makefile.in.orig 2005-06-27 07:11:34.000000000 +0200
++++ ./Makefile.in 2011-08-17 13:19:00.000000000 +0200
+@@ -15,7 +15,7 @@
+ #
+ # You should have received a copy of the GNU General Public License
+ # along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ # USA.
+ #
+
+@@ -48,7 +48,7 @@
+ $(SRCDIR)knock.c \
+ $(SRCDIR)list.c
+
+-all: knockd knock man
++all: knockd knock
+
+ knockd: $(OBJDIR)knockd.o $(OBJDIR)list.o
+ $(CXX) $(OBJDIR)knockd.o $(OBJDIR)list.o -o $@ $(LDFLAGS) -lpcap
diff --git a/security/knock/files/patch-config.h.in b/security/knock/files/patch-config.h.in
new file mode 100644
index 000000000000..847da6a1cc65
--- /dev/null
+++ b/security/knock/files/patch-config.h.in
@@ -0,0 +1,89 @@
+--- ./config.h.in.orig 2004-04-19 09:22:07.000000000 +0200
++++ ./config.h.in 2011-08-17 13:19:00.000000000 +0200
+@@ -3,12 +3,24 @@
+ /* Define to 1 if you have the <arpa/inet.h> header file. */
+ #undef HAVE_ARPA_INET_H
+
++/* Define to 1 if you have the `bzero' function. */
++#undef HAVE_BZERO
++
+ /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+ #undef HAVE_DOPRNT
+
++/* Define to 1 if you have the <fcntl.h> header file. */
++#undef HAVE_FCNTL_H
++
+ /* Define to 1 if you have the `fork' function. */
+ #undef HAVE_FORK
+
++/* Define to 1 if you have the `gethostbyaddr' function. */
++#undef HAVE_GETHOSTBYADDR
++
++/* Define to 1 if you have the `gethostbyname' function. */
++#undef HAVE_GETHOSTBYNAME
++
+ /* Define to 1 if you have the `inet_ntoa' function. */
+ #undef HAVE_INET_NTOA
+
+@@ -28,14 +40,21 @@
+ /* Define to 1 if you have the <memory.h> header file. */
+ #undef HAVE_MEMORY_H
+
++/* Define to 1 if you have the `memset' function. */
++#undef HAVE_MEMSET
++
+ /* Define to 1 if you have the <netdb.h> header file. */
+ #undef HAVE_NETDB_H
+
+ /* Define to 1 if you have the <netinet/in.h> header file. */
+ #undef HAVE_NETINET_IN_H
+
+-/* Define to 1 if you have the <pcap.h> header file. */
+-#undef HAVE_PCAP_H
++/* Define to 1 if your system has a GNU libc compatible `realloc' function,
++ and to 0 otherwise. */
++#undef HAVE_REALLOC
++
++/* Define to 1 if you have the `socket' function. */
++#undef HAVE_SOCKET
+
+ /* Define to 1 if you have the <stdint.h> header file. */
+ #undef HAVE_STDINT_H
+@@ -43,12 +62,15 @@
+ /* Define to 1 if you have the <stdlib.h> header file. */
+ #undef HAVE_STDLIB_H
+
+-/* Define to 1 if you have the `strcasecmp' function. */
+-#undef HAVE_STRCASECMP
++/* Define to 1 if you have the `strchr' function. */
++#undef HAVE_STRCHR
+
+ /* Define to 1 if you have the `strdup' function. */
+ #undef HAVE_STRDUP
+
++/* Define to 1 if you have the `strerror' function. */
++#undef HAVE_STRERROR
++
+ /* Define to 1 if you have the <strings.h> header file. */
+ #undef HAVE_STRINGS_H
+
+@@ -61,6 +83,9 @@
+ /* Define to 1 if you have the <syslog.h> header file. */
+ #undef HAVE_SYSLOG_H
+
++/* Define to 1 if you have the <sys/ioctl.h> header file. */
++#undef HAVE_SYS_IOCTL_H
++
+ /* Define to 1 if you have the <sys/socket.h> header file. */
+ #undef HAVE_SYS_SOCKET_H
+
+@@ -124,6 +149,9 @@
+ /* Define to `int' if <sys/types.h> does not define. */
+ #undef pid_t
+
++/* Define to rpl_realloc if the replacement function should be used. */
++#undef realloc
++
+ /* Define to `unsigned' if <sys/types.h> does not define. */
+ #undef size_t
+
diff --git a/security/knock/files/patch-doc__knock.1.in b/security/knock/files/patch-doc__knock.1.in
new file mode 100644
index 000000000000..aea05e8af562
--- /dev/null
+++ b/security/knock/files/patch-doc__knock.1.in
@@ -0,0 +1,15 @@
+--- ./doc/knock.1.in.orig 2005-06-27 07:10:30.000000000 +0200
++++ ./doc/knock.1.in 2011-08-17 13:28:24.000000000 +0200
+@@ -15,6 +15,12 @@
+ If you want each port to use a different protocol (TCP or UDP), then you
+ can specify the protocol on a per-port basis. See the example below.
+ .TP
++.B "\-d <t>, \-\-delay <t>"
++Wait <t> milliseconds between each port hit. This can be used in situations
++where a router mistakes your stream of SYN packets as a port scan and blocks
++them. If the packet rate is slowed with --delay, then the router should let
++the packets through.
++.TP
+ .B "\-v, \-\-verbose"
+ Output verbose status messages.
+ .TP
diff --git a/security/knock/files/patch-doc__knockd.1.in b/security/knock/files/patch-doc__knockd.1.in
new file mode 100644
index 000000000000..09a23f5d0056
--- /dev/null
+++ b/security/knock/files/patch-doc__knockd.1.in
@@ -0,0 +1,58 @@
+--- ./doc/knockd.1.in.orig 2005-06-29 20:45:17.000000000 +0200
++++ ./doc/knockd.1.in 2011-08-17 13:29:55.000000000 +0200
+@@ -60,13 +60,13 @@
+ sequence = 7000,8000,9000
+ seq_timeout = 10
+ tcpflags = syn
+- command = /usr/sbin/iptables -A INPUT -s %IP% -j ACCEPT
++ command = /usr/sbin/iptables -A INPUT -s %IP% --dport 22 -j ACCEPT
+
+ [closeSSH]
+ sequence = 9000,8000,7000
+ seq_timeout = 10
+ tcpflags = syn
+- command = /usr/sbin/iptables -D INPUT -s %IP% -j ACCEPT
++ command = /usr/sbin/iptables -D INPUT -s %IP% --dport 22 -j ACCEPT
+
+ .fi
+ .RE
+@@ -115,7 +115,7 @@
+ start_command = /usr/sbin/iptables -A INPUT -s %IP% -p tcp --dport 25 -j ACCEPT
+ cmd_timeout = 5
+ stop_command = /usr/sbin/iptables -D INPUT -s %IP% -p tcp --dport 25 -j ACCEPT
+-
++
+ .fi
+ .RE
+ .SH CONFIGURATION: GLOBAL DIRECTIVES
+@@ -132,7 +132,7 @@
+ .TP
+ .B "Interface = <interface_name>"
+ Network interface to listen on. Only its name has to be given, not the path to
+-the device (eg, "eth0" and not "/dev/eth0"). Default: eth0.
++the device (eg, "fxp0" and not "/dev/fxp0"). Default: fxp0.
+ .SH CONFIGURATION: KNOCK/EVENT DIRECTIVES
+ .TP
+ .B "Sequence = <port1>[:<tcp|udp>][,<port2>[:<tcp|udp>] ...]"
+@@ -158,7 +158,7 @@
+ \fBNote\fP: Do not edit the file while knockd is running!
+ .TP
+ .B "Seq_Timeout = <timeout>"
+-Time to wait for a sequence to complete in seconds. If the time elapses
++Time to wait (in seconds) for a sequence to complete in seconds. If the time elapses
+ before the knock is complete, it is discarded.
+ .TP
+ .B "TCPFlags = fin|syn|rst|psh|ack|urg"
+@@ -183,10 +183,10 @@
+ directive is optional, only required if \fBStop_Command\fP is used.
+ .TP
+ .B "Stop_Command = <command>"
+-Specify the command to be executed when \fBCmd_Timeout\fP seconds have passed
++Specify the command to be executed when \fBCmd_Timeout\fP seconds have passed
+ since \fBStart_Command\fP has been executed. All instances of \fB%IP%\fP will
+ be replaced with the knocker's IP address. This directive is optional.
+-.SH SECURITY NOTES
++.SH SECURITY NOTES
+ Using the \fB-l\fP or \fB--lookup\fP commandline option to resolve DNS names
+ for log entries may be a security risk! An attacker may find out the first port
+ of a sequence if he can monitor the DNS traffic of the host running knockd.
diff --git a/security/knock/files/patch-knockd.conf b/security/knock/files/patch-knockd.conf
index d0223778d320..1bd5062b1919 100644
--- a/security/knock/files/patch-knockd.conf
+++ b/security/knock/files/patch-knockd.conf
@@ -1,5 +1,5 @@
---- knockd.conf.orig Thu May 6 22:56:03 2004
-+++ knockd.conf Fri Mar 17 23:39:01 2006
+--- ./knockd.conf.orig 2004-05-07 00:56:03.000000000 +0200
++++ ./knockd.conf 2011-08-17 13:19:00.000000000 +0200
@@ -1,15 +1,16 @@
[options]
logfile = /var/log/knockd.log
diff --git a/security/knock/files/patch-src__knock.c b/security/knock/files/patch-src__knock.c
new file mode 100644
index 000000000000..d69598407cdb
--- /dev/null
+++ b/security/knock/files/patch-src__knock.c
@@ -0,0 +1,132 @@
+--- ./src/knock.c.orig 2005-06-27 07:11:34.000000000 +0200
++++ ./src/knock.c 2011-08-17 13:21:28.000000000 +0200
+@@ -1,8 +1,8 @@
+ /*
+ * knock.c
+- *
++ *
+ * Copyright (c) 2004-2005 by Judd Vinet <jvinet@zeroflux.org>
+- *
++ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+@@ -15,7 +15,7 @@
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+
+@@ -23,16 +23,20 @@
+ #include <stdlib.h>
+ #include <stdarg.h>
+ #include <netdb.h>
+-#include <sys/socket.h>
+ #include <sys/types.h>
++#include <sys/socket.h>
++#if defined(__FreeBSD__) || defined(__APPLE__)
++#include <netinet/in.h>
++#endif
+ #include <arpa/inet.h>
+ #include <unistd.h>
+ #include <string.h>
++#include <netinet/in.h>
+ #include <resolv.h>
+ #include <getopt.h>
+ #include <fcntl.h>
+
+-static char version[] = "0.5";
++static char version[] = "#VERSION#";
+
+ #define PROTO_TCP 1
+ #define PROTO_UDP 2
+@@ -44,6 +48,7 @@
+
+ int o_verbose = 0;
+ int o_udp = 0;
++int o_delay = 0;
+
+ int main(int argc, char** argv)
+ {
+@@ -55,12 +60,13 @@
+ {
+ {"verbose", no_argument, 0, 'v'},
+ {"udp", no_argument, 0, 'u'},
++ {"delay", required_argument, 0, 'd'},
+ {"help", no_argument, 0, 'h'},
+ {"version", no_argument, 0, 'V'},
+ {0, 0, 0, 0}
+ };
+
+- while((opt = getopt_long(argc, argv, "vuhV", opts, &optidx))) {
++ while((opt = getopt_long(argc, argv, "vud:hV", opts, &optidx))) {
+ if(opt < 0) {
+ break;
+ }
+@@ -68,6 +74,7 @@
+ case 0: break;
+ case 'v': o_verbose = 1; break;
+ case 'u': o_udp = 1; break;
++ case 'd': o_delay = (int)atoi(optarg); break;
+ case 'V': ver();
+ case 'h': /* fallthrough */
+ default: usage();
+@@ -77,6 +84,11 @@
+ usage();
+ }
+
++ if(o_delay < 0) {
++ fprintf(stderr, "error: delay cannot be negative\n");
++ exit(1);
++ }
++
+ host = gethostbyname(argv[optind++]);
+ if(host == NULL) {
+ fprintf(stderr, "Cannot resolve hostname\n");
+@@ -98,16 +110,16 @@
+ } else {
+ port = atoi(arg);
+ }
+-
++
+ if(o_udp || proto == PROTO_UDP) {
+- sd = socket(PF_INET, SOCK_DGRAM, 0);
++ sd = socket(PF_INET, SOCK_DGRAM, 0);
+ if(sd == -1) {
+ fprintf(stderr, "Cannot open socket\n");
+ exit(1);
+ }
+ } else {
+ int flags;
+- sd = socket(PF_INET, SOCK_STREAM, 0);
++ sd = socket(PF_INET, SOCK_STREAM, 0);
+ if(sd == -1) {
+ fprintf(stderr, "Cannot open socket\n");
+ exit(1);
+@@ -121,13 +133,13 @@
+ addr.sin_port = htons(port);
+ if(o_udp || proto == PROTO_UDP) {
+ vprint("hitting udp %s:%u\n", inet_ntoa(addr.sin_addr), port);
+- connect(sd, (struct sockaddr*)&addr, sizeof(struct sockaddr));
+- send(sd, NULL, 0, MSG_DONTWAIT);
++ sendto(sd, "", 1, 0, (struct sockaddr*)&addr, sizeof(addr));
+ } else {
+ vprint("hitting tcp %s:%u\n", inet_ntoa(addr.sin_addr), port);
+ connect(sd, (struct sockaddr*)&addr, sizeof(struct sockaddr));
+ }
+ close(sd);
++ usleep(1000*o_delay);
+ }
+
+ return(0);
+@@ -148,6 +160,7 @@
+ printf("usage: knock [options] <host> <port[:proto]> [port[:proto]] ...\n");
+ printf("options:\n");
+ printf(" -u, --udp make all ports hits use UDP (default is TCP)\n");
++ printf(" -d, --delay <t> wait <t> milliseconds between port hits\n");
+ printf(" -v, --verbose be verbose\n");
+ printf(" -V, --version display version\n");
+ printf(" -h, --help this help\n");
diff --git a/security/knock/files/patch-src__knockd.c b/security/knock/files/patch-src__knockd.c
new file mode 100644
index 000000000000..4325e6c745e0
--- /dev/null
+++ b/security/knock/files/patch-src__knockd.c
@@ -0,0 +1,520 @@
+--- ./src/knockd.c.orig 2005-06-27 07:11:34.000000000 +0200
++++ ./src/knockd.c 2011-08-17 13:24:16.000000000 +0200
+@@ -1,8 +1,8 @@
+ /*
+ * knockd.c
+- *
++ *
+ * Copyright (c) 2004-2005 by Judd Vinet <jvinet@zeroflux.org>
+- *
++ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+@@ -15,7 +15,7 @@
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+
+@@ -28,6 +28,11 @@
+ #include <ctype.h>
+ #include <string.h>
+ #include <fcntl.h>
++#if defined(__FreeBSD__) || defined(__APPLE__)
++#include <limits.h>
++#include <sys/socket.h>
++#include <netinet/in_systm.h>
++#endif
+ #include <netinet/in.h>
+ #include <netinet/if_ether.h>
+ #include <netinet/ip.h>
+@@ -35,8 +40,9 @@
+ #include <netinet/udp.h>
+ #include <netinet/ip_icmp.h>
+ #include <net/if.h>
++#if !defined(__FreeBSD__) && !defined(__APPLE__)
+ #include <bits/time.h>
+-#include <sys/socket.h>
++#endif
+ #include <sys/types.h>
+ #include <sys/wait.h>
+ #include <sys/ioctl.h>
+@@ -48,7 +54,7 @@
+ #include <errno.h>
+ #include "list.h"
+
+-static char version[] = "0.5";
++static char version[] = "#VERSION#";
+
+ #define SEQ_TIMEOUT 25 /* default knock timeout in seconds */
+ #define CMD_TIMEOUT 10 /* default timeout in seconds between start and stop commands */
+@@ -131,7 +137,7 @@
+ int o_daemon = 0;
+ int o_lookup = 0;
+ char o_int[32] = ""; /* default (eth0) is set after parseconfig() */
+-char o_cfg[PATH_MAX] = "/etc/knockd.conf";
++char o_cfg[PATH_MAX] = "%%PREFIX%%/etc/knockd.conf";
+ char o_pidfile[PATH_MAX] = "/var/run/knockd.pid";
+ char o_logfile[PATH_MAX] = "";
+
+@@ -193,7 +199,11 @@
+ }
+ }
+
++#if defined(__FreeBSD__) || defined(__APPLE__)
++ cap = pcap_open_live(o_int, 65535, 0, 1, pcapErr);
++#else
+ cap = pcap_open_live(o_int, 65535, 0, 0, pcapErr);
++#endif
+ if(strlen(pcapErr)) {
+ fprintf(stderr, "could not open %s: %s\n", o_int, pcapErr);
+ }
+@@ -212,7 +222,10 @@
+ case DLT_RAW:
+ dprint("raw interface detected, no encapsulation\n");
+ break;
+- default:
++ case DLT_NULL:
++ dprint("tun interface detected. pppoe on freebsd\n");
++ break;
++ default:
+ fprintf(stderr, "error: unsupported link-layer type: %d\n", lltype);
+ cleanup(1);
+ break;
+@@ -301,9 +314,9 @@
+ struct tm *tm;
+ t = time(NULL);
+ tm = localtime(&t);
+-
+- fprintf(logfd, "[%04d-%02d-%02d %02d:%02d] %s\n", tm->tm_year+1900,
+- tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, msg);
++
++ fprintf(logfd, "[%04d-%02d-%02d %02d:%02d:%02d] %s\n", tm->tm_year+1900,
++ tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, msg);
+ fflush(logfd);
+ }
+ }
+@@ -420,7 +433,7 @@
+ if(pch != str) {
+ memmove(str, pch, (strlen(pch) + 1));
+ }
+-
++
+ pch = (char*)(str + (strlen(str) - 1));
+ while(isspace(*pch)) {
+ pch--;
+@@ -503,7 +516,7 @@
+ dprint("config: usesyslog\n");
+ } else {
+ fprintf(stderr, "config: line %d: syntax error\n", linenum);
+- return(1);
++ return(1);
+ }
+ } else {
+ trim(ptr);
+@@ -681,7 +694,7 @@
+ return(1);
+ }
+ dprint_sequence(door, "new sequence for door %s: ", door->name);
+-
++
+ return(0);
+ }
+
+@@ -694,7 +707,7 @@
+ {
+ char line[PATH_MAX+1];
+ int pos;
+-
++
+ pos = ftell(door->one_time_sequences_fd);
+ while(fgets(line, PATH_MAX, door->one_time_sequences_fd)) {
+ trim(line);
+@@ -746,7 +759,7 @@
+
+ rewind(door->one_time_sequences_fd);
+ pseudo_door.one_time_sequences_fd = door->one_time_sequences_fd;
+-
++
+ pos = get_next_one_time_sequence(&pseudo_door);
+ while(pos >= 0) {
+ if(door->seqcount == pseudo_door.seqcount) {
+@@ -769,10 +782,10 @@
+ void generate_pcap_filter()
+ {
+ /* NOTE: We're doing string manipulations in a daemon -- use defensive programming! */
+-
++
+ PMList *lp;
+ opendoor_t *door;
+- char *buffer = NULL; /* temporary buffer to create the individual filter strings */
++ char *buffer = NULL; /* temporary buffer to create the individual filter strings */
+ size_t bufsize = 0; /* size of buffer */
+ char port_str[10]; /* used by snprintf to convert unsigned short --> string */
+ short head_set = 0; /* flag indicating if protocol head is set (i.e. "((tcp dst port") */
+@@ -781,7 +794,7 @@
+ unsigned int i;
+ short modified_filters = 0; /* flag indicating if at least one filter has changed --> recompile the filter */
+ struct bpf_program bpf_prog; /* compiled BPF filter program */
+-
++
+ /* generate subfilters for each door having a NULL pcap_filter_exp
+ *
+ * Example filter for one single door:
+@@ -796,11 +809,11 @@
+
+ /* if we get here at least one door had a pcap_filter_exp == NULL */
+ modified_filters = 1;
+-
++
+ head_set = 0;
+ tcp_present = 0;
+ udp_present = 0;
+-
++
+ /* allocate memory for buffer if needed.
+ * The first allocation will be 200 Bytes (should be large enough for common sequences). If there is
+ * not enough space, a call to realloc_strcat() will eventually increase its size. The buffer will be
+@@ -913,7 +926,7 @@
+ if(udp_present) {
+ bufsize = realloc_strcat(&buffer, ")", bufsize); /* close parentheses of UDP ports */
+ }
+-
++
+ /* test if in any of the precedent calls to realloc_strcat() failed. We can do this safely here because
+ * realloc_strcat() returns 0 on failure and if a buffer size of 0 is passed to it, the function does
+ * nothing but returning 0 again. Because we never read buffer in the above code, it is secure to test
+@@ -930,7 +943,7 @@
+ perror("malloc");
+ cleanup(1);
+ }
+- strcpy(door->pcap_filter_exp, buffer);
++ strcpy(door->pcap_filter_exp, buffer);
+
+ buffer[0] = '\0'; /* "clear" the buffer */
+ }
+@@ -941,7 +954,7 @@
+ * Note that we don't check if a port is included in multiple doors, we simply concatenate the individual door
+ * filters and rely on pcap's optimization capabilities.
+ *
+- * Example filter for two doors with sequences 8000:tcp,4000:udp,8001:tcp,4001:udp,8002:tcp (syn) and
++ * Example filter for two doors with sequences 8000:tcp,4000:udp,8001:tcp,4001:udp,8002:tcp (syn) and
+ * 1234:tcp,4567:tcp,8901:tcp (syn,ack) :
+ * dst host the.hosts.ip.address and (
+ * ((tcp dst port 8000 or 8001 or 8002) and tcp[tcpflags] & tcp-syn != 0) or (udp dst port 4000 or 4001)
+@@ -1005,7 +1018,7 @@
+
+ needed_size = strlen(*dest) + strlen(src) + 1; /* '+ 1' for '\0' */
+ new_size = size;
+-
++
+ while(needed_size > new_size) {
+ new_size *= 2;
+ }
+@@ -1018,7 +1031,7 @@
+
+ /* now dest is large enough to strcat() the src */
+ strcat(*dest, src);
+-
++
+ return new_size;
+ }
+
+@@ -1059,7 +1072,11 @@
+ }
+ buf[0] = '\0';
+
++#if defined(__FreeBSD__) || defined(__APPLE__)
+ s = socket(AF_INET, SOCK_DGRAM, 0);
++#else
++ s = socket(PF_PACKET, SOCK_DGRAM, 0);
++#endif
+ if(s < 0) {
+ return(NULL);
+ }
+@@ -1161,12 +1178,17 @@
+ void sniff(u_char* arg, const struct pcap_pkthdr* hdr, const u_char* packet)
+ {
+ /* packet structs */
++#if defined(__FreeBSD__) || defined(__APPLE__)
++ struct ether_header* eth = NULL;
++ struct ip* ip = NULL;
++#else
+ struct ethhdr* eth = NULL;
+ struct iphdr* ip = NULL;
++#endif
+ struct tcphdr* tcp = NULL;
+ struct udphdr* udp = NULL;
+ char proto[8];
+- /* TCP/IP data */
++ /* TCP/IP data */
+ struct in_addr inaddr;
+ unsigned short sport, dport;
+ char srcIP[16], dstIP[16];
+@@ -1179,23 +1201,46 @@
+ knocker_t *attempt = NULL;
+
+ if(lltype == DLT_EN10MB) {
++#if defined(__FreeBSD__) || defined(__APPLE__)
++ eth = (struct ether_header*)packet;
++ if(ntohs(eth->ether_type) != ETHERTYPE_IP) {
++ return;
++ }
++
++ ip = (struct ip*)(packet + sizeof(struct ether_header));
++ } else if(lltype == DLT_LINUX_SLL) {
++ ip = (struct ip*)((u_char*)packet + 16);
++ } else if(lltype == DLT_RAW) {
++ ip = (struct ip*)((u_char*)packet);
++ } else if(lltype == DLT_NULL) {
++ ip = (struct ip*)((u_char*)packet + 4);
++ }
++
++ if(ip->ip_v != 4) {
++#else
+ eth = (struct ethhdr*)packet;
+ if(ntohs(eth->h_proto) != ETH_P_IP) {
+ return;
+ }
++
+ ip = (struct iphdr*)(packet + sizeof(struct ethhdr));
+ } else if(lltype == DLT_LINUX_SLL) {
+ ip = (struct iphdr*)((u_char*)packet + 16);
+ } else if(lltype == DLT_RAW) {
+ ip = (struct iphdr*)((u_char*)packet);
+ }
+-
++
+ if(ip->version != 4) {
++#endif
+ /* no IPv6 yet */
+ dprint("packet is not IPv4, ignoring...\n");
+ return;
+ }
++#if defined(__FreeBSD__) || defined(__APPLE__)
++ if(ip->ip_p == IPPROTO_ICMP) {
++#else
+ if(ip->protocol == IPPROTO_ICMP) {
++#endif
+ /* we don't do ICMP */
+ return;
+ }
+@@ -1207,12 +1252,30 @@
+ fprintf(stderr, "error: could not understand IP address: %s\n", myip);
+ return;
+ }
++#if defined(__FreeBSD__) || defined(__APPLE__)
++ if(ip->ip_dst.s_addr != inaddr.s_addr) {
++#else
+ if(ip->daddr != inaddr.s_addr) {
++#endif
+ dprint("packet destined for another host, ignoring...\n");
+ return;
+ }
+-
++
+ sport = dport = 0;
++
++#if defined(__FreeBSD__) || defined(__APPLE__)
++ if(ip->ip_p == IPPROTO_TCP) {
++ strncpy(proto, "tcp", sizeof(proto));
++ tcp = (struct tcphdr*)((u_char*)ip + (ip->ip_hl *4));
++ sport = ntohs(tcp->th_sport);
++ dport = ntohs(tcp->th_dport);
++ }
++ if(ip->ip_p == IPPROTO_UDP) {
++ strncpy(proto, "udp", sizeof(proto));
++ udp = (struct udphdr*)((u_char*)ip + (ip->ip_hl * 4));
++ sport = ntohs(udp->uh_sport);
++ dport = ntohs(udp->uh_dport);
++#else
+ if(ip->protocol == IPPROTO_TCP) {
+ strncpy(proto, "tcp", sizeof(proto));
+ tcp = (struct tcphdr*)((u_char*)ip + (ip->ihl * 4));
+@@ -1224,6 +1287,7 @@
+ udp = (struct udphdr*)((u_char*)ip + (ip->ihl * 4));
+ sport = ntohs(udp->source);
+ dport = ntohs(udp->dest);
++#endif
+ }
+
+ /* get the date/time */
+@@ -1234,10 +1298,17 @@
+ pkt_tm->tm_sec);
+
+ /* convert IPs from binary to string */
++#if defined(__FreeBSD__) || defined(__APPLE__)
++ inaddr.s_addr = ip->ip_src.s_addr;
++ strncpy(srcIP, inet_ntoa(inaddr), sizeof(srcIP)-1);
++ srcIP[sizeof(srcIP)-1] = '\0';
++ inaddr.s_addr = ip->ip_dst.s_addr;
++#else
+ inaddr.s_addr = ip->saddr;
+ strncpy(srcIP, inet_ntoa(inaddr), sizeof(srcIP)-1);
+ srcIP[sizeof(srcIP)-1] = '\0';
+ inaddr.s_addr = ip->daddr;
++#endif
+ strncpy(dstIP, inet_ntoa(inaddr), sizeof(dstIP)-1);
+ dstIP[sizeof(dstIP)-1] = '\0';
+
+@@ -1297,6 +1368,73 @@
+ /* if tcp, check the flags to ignore the packets we don't want
+ * (don't even use it to cancel sequences)
+ */
++#if defined(__FreeBSD__) || defined(__APPLE__)
++ if(ip->ip_p == IPPROTO_TCP) {
++ if(attempt->door->flag_fin != DONT_CARE) {
++ if(attempt->door->flag_fin == SET && !(tcp->th_flags & TH_FIN)) {
++ dprint("packet is not FIN, ignoring...\n");
++ flagsmatch = 0;
++ }
++ if(attempt->door->flag_fin == NOT_SET && (tcp->th_flags & TH_FIN)) {
++ dprint("packet is not !FIN, ignoring...\n");
++ flagsmatch = 0;
++ }
++ }
++ if(attempt->door->flag_syn != DONT_CARE) {
++ if(attempt->door->flag_syn == SET && !(tcp->th_flags & TH_SYN)) {
++ dprint("packet is not SYN, ignoring...\n");
++ flagsmatch = 0;
++ }
++ if(attempt->door->flag_syn == NOT_SET && (tcp->th_flags & TH_SYN)) {
++ dprint("packet is not !SYN, ignoring...\n");
++ flagsmatch = 0;
++ }
++ }
++ if(attempt->door->flag_rst != DONT_CARE) {
++ if(attempt->door->flag_rst == SET && !(tcp->th_flags & TH_RST)) {
++ dprint("packet is not RST, ignoring...\n");
++ flagsmatch = 0;
++ }
++ if(attempt->door->flag_rst == NOT_SET && (tcp->th_flags & TH_RST)) {
++ dprint("packet is not !RST, ignoring...\n");
++ flagsmatch = 0;
++ }
++ }
++ if(attempt->door->flag_psh != DONT_CARE) {
++ if(attempt->door->flag_psh == SET && !(tcp->th_flags & TH_PUSH)) {
++ dprint("packet is not PSH, ignoring...\n");
++ flagsmatch = 0;
++ }
++ if(attempt->door->flag_psh == NOT_SET && (tcp->th_flags & TH_PUSH)) {
++ dprint("packet is not !PSH, ignoring...\n");
++ flagsmatch = 0;
++ }
++ }
++ if(attempt->door->flag_ack != DONT_CARE) {
++ if(attempt->door->flag_ack == SET && !(tcp->th_flags & TH_ACK)) {
++ dprint("packet is not ACK, ignoring...\n");
++ flagsmatch = 0;
++ }
++ if(attempt->door->flag_ack == NOT_SET && !(tcp->th_flags & TH_ACK)) {
++ dprint("packet is not !ACK, ignoring...\n");
++ flagsmatch = 0;
++ }
++ }
++ if(attempt->door->flag_urg != DONT_CARE) {
++ if(attempt->door->flag_urg == SET && !(tcp->th_flags & TH_URG)) {
++ dprint("packet is not URG, ignoring...\n");
++ flagsmatch = 0;
++ }
++ if(attempt->door->flag_urg == NOT_SET && !(tcp->th_flags & TH_URG)) {
++ dprint("packet is not !URG, ignoring...\n");
++ flagsmatch = 0;
++ }
++ }
++ }
++ if(flagsmatch && ip->ip_p == attempt->door->protocol[attempt->stage] &&
++ dport == attempt->door->sequence[attempt->stage]) {
++
++#else
+ if(ip->protocol == IPPROTO_TCP) {
+ if(attempt->door->flag_fin != DONT_CARE) {
+ if(attempt->door->flag_fin == SET && tcp->fin != 1) {
+@@ -1361,6 +1499,7 @@
+ }
+ if(flagsmatch && ip->protocol == attempt->door->protocol[attempt->stage] &&
+ dport == attempt->door->sequence[attempt->stage]) {
++#endif
+ /* level up! */
+ attempt->stage++;
+ if(attempt->srchost) {
+@@ -1387,7 +1526,7 @@
+ size_t cmd_len = 0;
+
+ setsid();
+-
++
+ /* parse start and stop command and check if the parsed commands fit in the given buffer. Don't
+ * execute any command if one of them has been truncated */
+ cmd_len = parse_cmd(parsed_start_cmd, sizeof(parsed_start_cmd), attempt->door->start_command, attempt->src);
+@@ -1419,7 +1558,7 @@
+ }
+ exec_cmd(parsed_stop_cmd, attempt->door->name);
+ }
+-
++
+ exit(0); /* exit child */
+ }
+ }
+@@ -1451,6 +1590,36 @@
+ for(lp = doors; lp; lp = lp->next) {
+ opendoor_t *door = (opendoor_t*)lp->data;
+ /* if we're working with TCP, try to match the flags */
++#if defined(__FreeBSD__) || defined(__APPLE__)
++ if(ip->ip_p == IPPROTO_TCP){
++ if(door->flag_fin != DONT_CARE) {
++ if(door->flag_fin == SET && !(tcp->th_flags & TH_FIN)) {dprint("packet is not FIN, ignoring...\n");continue;}
++ if(door->flag_fin == NOT_SET && (tcp->th_flags & TH_FIN)) {dprint("packet is not !FIN, ignoring...\n");continue;}
++ }
++ if(door->flag_syn != DONT_CARE) {
++ if(door->flag_syn == SET && !(tcp->th_flags & TH_SYN)) {dprint("packet is not SYN, ignoring...\n");continue;}
++ if(door->flag_syn == NOT_SET && (tcp->th_flags & TH_SYN)) {dprint("packet is not !SYN, ignoring...\n");continue;}
++ }
++ if(door->flag_rst != DONT_CARE) {
++ if(door->flag_rst == SET && !(tcp->th_flags & TH_RST)) {dprint("packet is not RST, ignoring...\n");continue;}
++ if(door->flag_rst == NOT_SET && (tcp->th_flags & TH_RST)) {dprint("packet is not !RST, ignoring...\n");continue;}
++ }
++ if(door->flag_psh != DONT_CARE) {
++ if(door->flag_psh == SET && !(tcp->th_flags & TH_PUSH)) {dprint("packet is not PSH, ignoring...\n");continue;}
++ if(door->flag_psh == NOT_SET && (tcp->th_flags & TH_PUSH)) {dprint("packet is not !PSH, ignoring...\n");continue;}
++ }
++ if(door->flag_ack != DONT_CARE) {
++ if(door->flag_ack == SET && !(tcp->th_flags & TH_ACK)) {dprint("packet is not ACK, ignoring...\n");continue;}
++ if(door->flag_ack == NOT_SET && (tcp->th_flags & TH_ACK)) {dprint("packet is not !ACK, ignoring...\n");continue;}
++ }
++ if(door->flag_urg != DONT_CARE) {
++ if(door->flag_urg == SET && !(tcp->th_flags & TH_URG)) {dprint("packet is not URG, ignoring...\n");continue;}
++ if(door->flag_urg == NOT_SET && (tcp->th_flags & TH_URG)) {dprint("packet is not !URG, ignoring...\n");continue;}
++ }
++ }
++
++ if(ip->ip_p == door->protocol[0] && dport == door->sequence[0]) {
++#else
+ if(ip->protocol == IPPROTO_TCP){
+ if(door->flag_fin != DONT_CARE) {
+ if(door->flag_fin == SET && tcp->fin != 1) {dprint("packet is not FIN, ignoring...\n");continue;}
+@@ -1479,6 +1648,7 @@
+ }
+
+ if(ip->protocol == door->protocol[0] && dport == door->sequence[0]) {
++#endif
+ struct hostent *he;
+ /* create a new entry */
+ attempt = (knocker_t*)malloc(sizeof(knocker_t));
+@@ -1490,7 +1660,11 @@
+ strcpy(attempt->src, srcIP);
+ /* try a reverse lookup if enabled */
+ if (o_lookup) {
++#if defined(__FreeBSD__) || defined(__APPLE__)
++ inaddr.s_addr = ip->ip_src.s_addr;
++#else
+ inaddr.s_addr = ip->saddr;
++#endif
+ he = gethostbyaddr((void *)&inaddr, sizeof(inaddr), AF_INET);
+ if(he) {
+ attempt->srchost = strdup(he->h_name);