diff --git a/ChangeLog b/ChangeLog index 1c65ab3..766fadf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ VERSION DESCRIPTION ----------------------------------------------------------------------------- +0.9 - Permit ignoring duplicate packets. 0.8 - Multiple fixes (#67, #77) - IPv6 support (Sebastien Valat) 0.7.8 - Fix for Issue #33, #34 and #35 contributed by Alexander diff --git a/configure.ac b/configure.ac index 1d6acb0..8e00387 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ AC_PREREQ(2.60) -AC_INIT([knock], [0.8], [https://github.com/jvinet/knock/issues]) +AC_INIT([knock], [0.9], [https://github.com/jvinet/knock/issues]) AM_INIT_AUTOMAKE([dist-xz no-dist-gzip foreign subdir-objects]) AC_CONFIG_HEADER([config.h]) diff --git a/doc/knockd.1.in b/doc/knockd.1.in index b69ca06..c928b39 100644 --- a/doc/knockd.1.in +++ b/doc/knockd.1.in @@ -196,6 +196,13 @@ interfere with (and thus invalidate) the knock. Separate multiple flags with commas (eg, TCPFlags = syn,ack,urg). Flags can be explicitly excluded by a "!" (eg, TCPFlags = syn,!ack). .TP +.B "AllowDupes" +Ignore packets (that is, don't invalidate the entire knock), if the packet is a +duplicate of the sequence stage we've just seen. This may be the case if our +firewall is configured to drop packets (rather than respond with a rst), so we +may receive multiple/duplicate TCP syn packets from the knocker, for a single +stage. +.TP .B "Target = " Use the specified IP address instead of the address determined for the \fBInterface\fP when matching the \fBSequence\fP. diff --git a/src/knock.c b/src/knock.c index 851f80a..a48f4b5 100644 --- a/src/knock.c +++ b/src/knock.c @@ -35,7 +35,7 @@ #include #include -static char version[] = "0.8"; +static char version[] = "0.9"; #define PROTO_TCP 1 #define PROTO_UDP 2 diff --git a/src/knockd.c b/src/knockd.c index eff10bc..6ac1a56 100644 --- a/src/knockd.c +++ b/src/knockd.c @@ -63,7 +63,7 @@ extern int daemon(int, int); #endif -static char version[] = "0.8"; +static char version[] = "0.9"; #define SEQ_TIMEOUT 25 /* default knock timeout in seconds */ #define CMD_TIMEOUT 10 /* default timeout in seconds between start and stop commands */ @@ -97,6 +97,7 @@ typedef struct opendoor { FILE *one_time_sequences_fd; char *pcap_filter_exp; char *pcap_filter_expv6; + int allowdupes; } opendoor_t; PMList *doors = NULL; @@ -624,6 +625,7 @@ int parseconfig(char *configfile) door->one_time_sequences_fd = NULL; door->pcap_filter_exp = NULL; door->pcap_filter_expv6 = NULL; + door->allowdupes = 0; doors = list_add(doors, door); } } else { @@ -644,6 +646,14 @@ int parseconfig(char *configfile) if(!strcmp(key, "USESYSLOG")) { o_usesyslog = 1; dprint("config: usesyslog\n"); + } else if(!strcmp(key, "ALLOWDUPES")) { + if(door == NULL) { + fprintf(stderr, "config: line %d: \"%s\" can only be used within a Door section\n", + linenum, key); + return(1); + } + door->allowdupes = 1; + dprint("config: %s: allowdupes: %d\n", door->name, door->allowdupes); } else { fprintf(stderr, "config: line %d: syntax error\n", linenum); return(1); @@ -1825,8 +1835,18 @@ void sniff(u_char* arg, const struct pcap_pkthdr* hdr, const u_char* packet) } else { /* invalidate the knock sequence, it will be removed in the * next sniff() call. + * + * ... unless it matches a previous stage, in which case assume it's a dupe and ignore */ - attempt->stage = -1; + + if(attempt->door->allowdupes && + attempt->stage > 0 && + ip_proto == attempt->door->protocol[attempt->stage - 1] && + dport == attempt->door->sequence[attempt->stage - 1]) { + dprint("got attempt, ip %s, matching previous stage - assuming duplicate packet\n", attempt->src); + } else { + attempt->stage = -1; + } } } else { /* did they hit the first port correctly? */