Tue Nov 30 12:35:13 2010 UTC ()
knockd is a port-knock server. It listens to all traffic on an ethernet (or PPP)
interface, looking for special "knock" sequences of port-hits. A client makes
these port-hits by sending a TCP (or UDP) packet to a port on the server. This
port need not be open - since knockd listens at the link-layer level, it sees
all traffic even if it's destined for a closed port. When the server detects
a specific sequence of port-hits, it runs a command defined in its configuration
file. This can be used to open up holes in a firewall for quick access.

Status:

Vendor Tag:	TNF
Release Tags:	pkgsrc-base


(adam)
diff -r0 -r1.1.1.1 pkgsrc/net/knock/DESCR
diff -r0 -r1.1.1.1 pkgsrc/net/knock/distinfo
diff -r0 -r1.1.1.1 pkgsrc/net/knock/Makefile
diff -r0 -r1.1.1.1 pkgsrc/net/knock/PLIST
diff -r0 -r1.1.1.1 pkgsrc/net/knock/patches/patch-aa
diff -r0 -r1.1.1.1 pkgsrc/net/knock/patches/patch-ab

File Added: pkgsrc/net/knock/DESCR
knockd is a port-knock server. It listens to all traffic on an ethernet (or PPP)
interface, looking for special "knock" sequences of port-hits. A client makes
these port-hits by sending a TCP (or UDP) packet to a port on the server. This
port need not be open - since knockd listens at the link-layer level, it sees
all traffic even if it's destined for a closed port. When the server detects
a specific sequence of port-hits, it runs a command defined in its configuration
file. This can be used to open up holes in a firewall for quick access.

File Added: pkgsrc/net/knock/distinfo
$NetBSD: distinfo,v 1.1.1.1 2010/11/30 12:35:12 adam Exp $

SHA1 (knock-0.5.tar.gz) = 26f3b2f2d698bc6978390ef6e93c628361605059
RMD160 (knock-0.5.tar.gz) = 089ea289a51478a89945c46469b378c3b33fff6d
Size (knock-0.5.tar.gz) = 83990 bytes
SHA1 (patch-aa) = 3defe3f7982e6d79f4daecd7b5039a48ab9aec1d
SHA1 (patch-ab) = daaa6370019a55937d72fdf1d8f09747a4b38de9

File Added: pkgsrc/net/knock/Makefile
# $NetBSD: Makefile,v 1.1.1.1 2010/11/30 12:35:12 adam Exp $

DISTNAME=	knock-0.5
CATEGORIES=	net
MASTER_SITES=	http://www.zeroflux.org/proj/knock/files/

MAINTAINER=	adam@NetBSD.org
HOMEPAGE=	http://www.zeroflux.org/projects/knock/
COMMENT=	Port knocking server
LICENSE=	gnu-gpl-v2

PKG_DESTDIR_SUPPORT=	user-destdir

USE_LANGUAGES=		c c++
USE_TOOLS+=		gmake
GNU_CONFIGURE=		yes
CONFIGURE_ARGS+=	--sysconfdir=${PKG_SYSCONFDIR}

BUILD_DEFS+=	VARBASE

EGDIR=		${PREFIX}/share/examples/knock
CONF_FILES=	${EGDIR}/knockd.conf ${PKG_SYSCONFDIR}/knockd.conf

INSTALLATION_DIRS=	${EGDIR}

SUBST_CLASSES+=		paths
SUBST_STAGE.paths=	pre-configure
SUBST_MESSAGE.paths=	Fixing absolute paths.
SUBST_FILES.paths=	src/knockd.c
SUBST_SED.paths=	-e 's,"/etc,"${PKG_SYSCONFDIR},g'
SUBST_SED.paths+=	-e 's,"/var,"${VARBASE},g'

.include "../../net/libpcap/buildlink3.mk"
.include "../../mk/bsd.pkg.mk"

File Added: pkgsrc/net/knock/PLIST
@comment $NetBSD: PLIST,v 1.1.1.1 2010/11/30 12:35:12 adam Exp $
bin/knock
man/man1/knock.1
man/man1/knockd.1
sbin/knockd
share/examples/knock/knockd.conf

File Added: pkgsrc/net/knock/patches/Attic/patch-aa
$NetBSD: patch-aa,v 1.1.1.1 2010/11/30 12:35:12 adam Exp $

--- src/knockd.c.orig	2005-06-27 05:11:34.000000000 +0000
+++ src/knockd.c
@@ -28,18 +28,20 @@
 #include <ctype.h>
 #include <string.h>
 #include <fcntl.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
 #include <netinet/in.h>
+#include <netinet/in_systm.h>
 #include <netinet/if_ether.h>
 #include <netinet/ip.h>
 #include <netinet/tcp.h>
 #include <netinet/udp.h>
 #include <netinet/ip_icmp.h>
-#include <net/if.h>
-#include <bits/time.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/ioctl.h>
 #include <arpa/inet.h>
 #include <netdb.h>
 #include <getopt.h>
@@ -193,7 +195,7 @@ int main(int argc, char **argv)
 		}
 	}
 
-	cap = pcap_open_live(o_int, 65535, 0, 0, pcapErr);
+	cap = pcap_open_live(o_int, 65535, 0, 1000, pcapErr);
 	if(strlen(pcapErr)) {
 		fprintf(stderr, "could not open %s: %s\n", o_int, pcapErr);
 	}
@@ -1161,8 +1163,8 @@ int exec_cmd(char* command, char* name){
 void sniff(u_char* arg, const struct pcap_pkthdr* hdr, const u_char* packet)
 {
 	/* packet structs */
-	struct ethhdr* eth = NULL;
-	struct iphdr* ip   = NULL;
+	struct ether_header* eth = NULL;
+	struct ip* ip   = NULL;
 	struct tcphdr* tcp = NULL;
 	struct udphdr* udp = NULL;
 	char proto[8];
@@ -1179,23 +1181,23 @@ void sniff(u_char* arg, const struct pca
 	knocker_t *attempt = NULL;
 
 	if(lltype == DLT_EN10MB) {
-		eth = (struct ethhdr*)packet;
-		if(ntohs(eth->h_proto) != ETH_P_IP) {
+		eth = (struct ether_header*)packet;
+		if(ntohs(eth->ether_type) != ETHERTYPE_IP) {
 			return;
 		}
-		ip = (struct iphdr*)(packet + sizeof(struct ethhdr));
+		ip = (struct ip*)(packet + sizeof(struct ether_header));
 	} else if(lltype == DLT_LINUX_SLL) {
-		ip = (struct iphdr*)((u_char*)packet + 16);
+		ip = (struct ip*)((u_char*)packet + 16);
 	} else if(lltype == DLT_RAW) {
-		ip = (struct iphdr*)((u_char*)packet);
+		ip = (struct ip*)((u_char*)packet);
 	}
 	
-	if(ip->version != 4) {
+	if(ip->ip_v != 4) {
 		/* no IPv6 yet */
 		dprint("packet is not IPv4, ignoring...\n");
 		return;
 	}
-	if(ip->protocol == IPPROTO_ICMP) {
+	if(ip->ip_p == IPPROTO_ICMP) {
 		/* we don't do ICMP */
 		return;
 	}
@@ -1207,23 +1209,23 @@ void sniff(u_char* arg, const struct pca
 		fprintf(stderr, "error: could not understand IP address: %s\n", myip);
 		return;
 	}
-	if(ip->daddr != inaddr.s_addr) {
+	if(ip->ip_dst.s_addr != inaddr.s_addr) {
 		dprint("packet destined for another host, ignoring...\n");
 		return;
 	}
 	
 	sport = dport = 0;
-	if(ip->protocol == IPPROTO_TCP) {
+	if(ip->ip_p == IPPROTO_TCP) {
 		strncpy(proto, "tcp", sizeof(proto));
-		tcp = (struct tcphdr*)((u_char*)ip + (ip->ihl * 4));
-		sport = ntohs(tcp->source);
-		dport = ntohs(tcp->dest);
+		tcp = (struct tcphdr*)((u_char*)ip + (ip->ip_hl * 4));
+		sport = ntohs(tcp->th_sport);
+		dport = ntohs(tcp->th_dport);
 	}
-	if(ip->protocol == IPPROTO_UDP) {
+	if(ip->ip_p == IPPROTO_UDP) {
 		strncpy(proto, "udp", sizeof(proto));
-		udp = (struct udphdr*)((u_char*)ip + (ip->ihl * 4));
-		sport = ntohs(udp->source);
-		dport = ntohs(udp->dest);
+		udp = (struct udphdr*)((u_char*)ip + (ip->ip_hl * 4));
+		sport = ntohs(udp->uh_sport);
+		dport = ntohs(udp->uh_dport);
 	}
 
 	/* get the date/time */
@@ -1234,10 +1236,10 @@ void sniff(u_char* arg, const struct pca
 			pkt_tm->tm_sec);
 
 	/* convert IPs from binary to string */
-	inaddr.s_addr = ip->saddr;
+	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->daddr;
+	inaddr.s_addr = ip->ip_dst.s_addr;
 	strncpy(dstIP, inet_ntoa(inaddr), sizeof(dstIP)-1);
 	dstIP[sizeof(dstIP)-1] = '\0';
 
@@ -1297,69 +1299,69 @@ void sniff(u_char* arg, const struct pca
 		/* if tcp, check the flags to ignore the packets we don't want
 		 * (don't even use it to cancel sequences)
 		 */
-		if(ip->protocol == IPPROTO_TCP) {
+		if(ip->ip_p == IPPROTO_TCP) {
 			if(attempt->door->flag_fin != DONT_CARE) {
-				if(attempt->door->flag_fin == SET && tcp->fin != 1) {
+				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->fin == 1) {
+				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->syn != 1) {
+				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->syn == 1) {
+				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->rst != 1) {
+				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->rst == 1) {
+				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->psh != 1) {
+				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->psh == 1) {
+				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->ack != 1) {
+				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->ack == 1) {
+				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->urg != 1) {
+				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->urg == 1) {
+				if(attempt->door->flag_urg == NOT_SET && (tcp->th_flags & TH_URG)) {
 					dprint("packet is not !URG, ignoring...\n");
 					flagsmatch = 0;
 				}
 			}
 		}
-		if(flagsmatch && ip->protocol == attempt->door->protocol[attempt->stage] &&
+		if(flagsmatch && ip->ip_p == attempt->door->protocol[attempt->stage] &&
 				dport == attempt->door->sequence[attempt->stage]) {
 			/* level up! */
 			attempt->stage++;
@@ -1451,34 +1453,34 @@ void sniff(u_char* arg, const struct pca
 		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(ip->protocol == IPPROTO_TCP){
+			if(ip->ip_p == IPPROTO_TCP){
 				if(door->flag_fin != DONT_CARE) {
-					if(door->flag_fin == SET && tcp->fin != 1) {dprint("packet is not FIN, ignoring...\n");continue;}
-					if(door->flag_fin == NOT_SET && tcp->fin == 1) {dprint("packet is not !FIN, ignoring...\n");continue;}
+					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->syn != 1) {dprint("packet is not SYN, ignoring...\n");continue;}
-					if(door->flag_syn == NOT_SET && tcp->syn == 1) {dprint("packet is not !SYN, ignoring...\n");continue;}
+					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->rst != 1) {dprint("packet is not RST, ignoring...\n");continue;}
-					if(door->flag_rst == NOT_SET && tcp->rst == 1) {dprint("packet is not !RST, ignoring...\n");continue;}
+					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->psh != 1) {dprint("packet is not PSH, ignoring...\n");continue;}
-					if(door->flag_psh == NOT_SET && tcp->psh == 1) {dprint("packet is not !PSH, ignoring...\n");continue;}
+					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->ack != 1) {dprint("packet is not ACK, ignoring...\n");continue;}
-					if(door->flag_ack == NOT_SET && tcp->ack == 1) {dprint("packet is not !ACK, ignoring...\n");continue;}
+					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->urg != 1) {dprint("packet is not URG, ignoring...\n");continue;}
-					if(door->flag_urg == NOT_SET && tcp->urg == 1) {dprint("packet is not !URG, ignoring...\n");continue;}
+					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->protocol == door->protocol[0] && dport == door->sequence[0]) {
+			if(ip->ip_p == door->protocol[0] && dport == door->sequence[0]) {
 				struct hostent *he;
 				/* create a new entry */
 				attempt = (knocker_t*)malloc(sizeof(knocker_t));
@@ -1490,7 +1492,7 @@ void sniff(u_char* arg, const struct pca
 				strcpy(attempt->src, srcIP);
 				/* try a reverse lookup if enabled  */
 				if (o_lookup) {
-					inaddr.s_addr = ip->saddr;
+					inaddr.s_addr = ip->ip_src.s_addr;
 					he = gethostbyaddr((void *)&inaddr, sizeof(inaddr), AF_INET);
 					if(he) {
 						attempt->srchost = strdup(he->h_name);

File Added: pkgsrc/net/knock/patches/Attic/patch-ab
$NetBSD: patch-ab,v 1.1.1.1 2010/11/30 12:35:12 adam Exp $

--- Makefile.in.orig	2010-11-30 10:30:02.000000000 +0000
+++ Makefile.in
@@ -28,6 +28,7 @@ VERSION = 0.5
 BINDIR  = @bindir@
 SBINDIR = @sbindir@
 MANDIR  = @mandir@
+DATADIR = @datadir@
 
 INSTALL = @INSTALL@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
@@ -68,11 +68,11 @@ dist: distclean
 	(cd ..; tar czvf knock-$(VERSION).tar.gz knock-$(VERSION))
 
 install: all
-	$(INSTALL) -D -m0755 knockd $(DESTDIR)$(SBINDIR)/knockd
-	$(INSTALL) -D -m0755 knock $(DESTDIR)$(BINDIR)/knock
-	$(INSTALL) -D -m0644 $(MANSRC)knockd.1 $(DESTDIR)$(MANDIR)/man1/knockd.1
-	$(INSTALL) -D -m0644 $(MANSRC)knock.1 $(DESTDIR)$(MANDIR)/man1/knock.1
-	$(INSTALL) -D -m0644 knockd.conf $(DESTDIR)/etc/knockd.conf
+	${BSD_INSTALL_PROGRAM} knockd $(DESTDIR)$(SBINDIR)/knockd
+	${BSD_INSTALL_PROGRAM} knock $(DESTDIR)$(BINDIR)/knock
+	${BSD_INSTALL_MAN} $(MANSRC)knockd.1 $(DESTDIR)$(MANDIR)/man1/knockd.1
+	${BSD_INSTALL_MAN} $(MANSRC)knock.1 $(DESTDIR)$(MANDIR)/man1/knock.1
+	${BSD_INSTALL_DATA} knockd.conf $(DESTDIR)$(DATADIR)/examples/knock/knockd.conf
 
 clean:
 	rm -f *~ $(OBJDIR)*.o $(MANSRC)*.1