Index: Makefile =================================================================== RCS file: /home/pcvs/ports/security/knock/Makefile,v retrieving revision 1.8 diff -u -r1.8 Makefile --- Makefile 18 Mar 2011 10:04:52 -0000 1.8 +++ Makefile 19 Sep 2011 09:30:19 -0000 @@ -6,15 +6,19 @@ # PORTNAME= knock -PORTVERSION= 0.5.20051124 +PORTVERSION= 0.5 PORTREVISION= 1 +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 +26,6 @@ OPTIONS= SERVER "Install knockd server" on \ CLIENT "Install knock client" on -RUNDIR= /var/run -SUB_LIST= RUNDIR=${RUNDIR} - .include .if defined(WITH_SERVER) @@ -46,14 +47,15 @@ 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) Index: distinfo =================================================================== RCS file: /home/pcvs/ports/security/knock/distinfo,v retrieving revision 1.2 diff -u -r1.2 distinfo --- distinfo 3 Jul 2011 14:02:52 -0000 1.2 +++ distinfo 19 Sep 2011 09:30:19 -0000 @@ -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 Index: files/knockd.sh.in =================================================================== RCS file: /home/pcvs/ports/security/knock/files/knockd.sh.in,v retrieving revision 1.2 diff -u -r1.2 knockd.sh.in --- files/knockd.sh.in 27 Mar 2010 00:14:44 -0000 1.2 +++ files/knockd.sh.in 19 Sep 2011 09:30:19 -0000 @@ -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" Index: files/patch-Makefile.in =================================================================== RCS file: files/patch-Makefile.in diff -N files/patch-Makefile.in --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ files/patch-Makefile.in 19 Sep 2011 09:30:19 -0000 @@ -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 Index: files/patch-config.h.in =================================================================== RCS file: files/patch-config.h.in diff -N files/patch-config.h.in --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ files/patch-config.h.in 19 Sep 2011 09:30:19 -0000 @@ -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 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 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 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 header file. */ + #undef HAVE_NETDB_H + + /* Define to 1 if you have the header file. */ + #undef HAVE_NETINET_IN_H + +-/* Define to 1 if you have the 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 header file. */ + #undef HAVE_STDINT_H +@@ -43,12 +62,15 @@ + /* Define to 1 if you have the 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 header file. */ + #undef HAVE_STRINGS_H + +@@ -61,6 +83,9 @@ + /* Define to 1 if you have the header file. */ + #undef HAVE_SYSLOG_H + ++/* Define to 1 if you have the header file. */ ++#undef HAVE_SYS_IOCTL_H ++ + /* Define to 1 if you have the header file. */ + #undef HAVE_SYS_SOCKET_H + +@@ -124,6 +149,9 @@ + /* Define to `int' if does not define. */ + #undef pid_t + ++/* Define to rpl_realloc if the replacement function should be used. */ ++#undef realloc ++ + /* Define to `unsigned' if does not define. */ + #undef size_t + Index: files/patch-doc__knock.1.in =================================================================== RCS file: files/patch-doc__knock.1.in diff -N files/patch-doc__knock.1.in --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ files/patch-doc__knock.1.in 19 Sep 2011 09:30:19 -0000 @@ -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 , \-\-delay " ++Wait 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 Index: files/patch-doc__knockd.1.in =================================================================== RCS file: files/patch-doc__knockd.1.in diff -N files/patch-doc__knockd.1.in --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ files/patch-doc__knockd.1.in 19 Sep 2011 09:30:19 -0000 @@ -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 = " + 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 = [:][,[:] ...]" +@@ -158,7 +158,7 @@ + \fBNote\fP: Do not edit the file while knockd is running! + .TP + .B "Seq_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 = " +-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. Index: files/patch-knockd.conf =================================================================== RCS file: /home/pcvs/ports/security/knock/files/patch-knockd.conf,v retrieving revision 1.1 diff -u -r1.1 patch-knockd.conf --- files/patch-knockd.conf 12 Jul 2006 18:03:24 -0000 1.1 +++ files/patch-knockd.conf 19 Sep 2011 09:30:19 -0000 @@ -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 Index: files/patch-src__knock.c =================================================================== RCS file: files/patch-src__knock.c diff -N files/patch-src__knock.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ files/patch-src__knock.c 19 Sep 2011 09:30:19 -0000 @@ -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 +- * ++ * + * 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 + #include + #include +-#include + #include ++#include ++#if defined(__FreeBSD__) || defined(__APPLE__) ++#include ++#endif + #include + #include + #include ++#include + #include + #include + #include + +-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] [port[:proto]] ...\n"); + printf("options:\n"); + printf(" -u, --udp make all ports hits use UDP (default is TCP)\n"); ++ printf(" -d, --delay wait milliseconds between port hits\n"); + printf(" -v, --verbose be verbose\n"); + printf(" -V, --version display version\n"); + printf(" -h, --help this help\n"); Index: files/patch-src__knockd.c =================================================================== RCS file: files/patch-src__knockd.c diff -N files/patch-src__knockd.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ files/patch-src__knockd.c 19 Sep 2011 09:30:19 -0000 @@ -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 +- * ++ * + * 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 + #include + #include ++#if defined(__FreeBSD__) || defined(__APPLE__) ++#include ++#include ++#include ++#endif + #include + #include + #include +@@ -35,8 +40,9 @@ + #include + #include + #include ++#if !defined(__FreeBSD__) && !defined(__APPLE__) + #include +-#include ++#endif + #include + #include + #include +@@ -48,7 +54,7 @@ + #include + #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);