summaryrefslogtreecommitdiff
path: root/net/knock
diff options
context:
space:
mode:
authoradam <adam@pkgsrc.org>2010-11-30 12:35:12 +0000
committeradam <adam@pkgsrc.org>2010-11-30 12:35:12 +0000
commita8f7e55b832967682f8f836fd873a9a228bee1d5 (patch)
treeecb1734a9d1ea31a9d77699e1cc63040a8bba748 /net/knock
parent2882e2092f57715a23614ea70e021e2357939e84 (diff)
downloadpkgsrc-a8f7e55b832967682f8f836fd873a9a228bee1d5.tar.gz
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.
Diffstat (limited to 'net/knock')
-rw-r--r--net/knock/DESCR7
-rw-r--r--net/knock/Makefile34
-rw-r--r--net/knock/PLIST6
-rw-r--r--net/knock/distinfo7
-rw-r--r--net/knock/patches/patch-aa270
-rw-r--r--net/knock/patches/patch-ab29
6 files changed, 353 insertions, 0 deletions
diff --git a/net/knock/DESCR b/net/knock/DESCR
new file mode 100644
index 00000000000..070d9398b36
--- /dev/null
+++ b/net/knock/DESCR
@@ -0,0 +1,7 @@
+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.
diff --git a/net/knock/Makefile b/net/knock/Makefile
new file mode 100644
index 00000000000..6a523e66af8
--- /dev/null
+++ b/net/knock/Makefile
@@ -0,0 +1,34 @@
+# $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"
diff --git a/net/knock/PLIST b/net/knock/PLIST
new file mode 100644
index 00000000000..1b5e731952c
--- /dev/null
+++ b/net/knock/PLIST
@@ -0,0 +1,6 @@
+@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
diff --git a/net/knock/distinfo b/net/knock/distinfo
new file mode 100644
index 00000000000..223e10c5820
--- /dev/null
+++ b/net/knock/distinfo
@@ -0,0 +1,7 @@
+$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
diff --git a/net/knock/patches/patch-aa b/net/knock/patches/patch-aa
new file mode 100644
index 00000000000..20e5632b5b3
--- /dev/null
+++ b/net/knock/patches/patch-aa
@@ -0,0 +1,270 @@
+$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);
diff --git a/net/knock/patches/patch-ab b/net/knock/patches/patch-ab
new file mode 100644
index 00000000000..153c1c0e906
--- /dev/null
+++ b/net/knock/patches/patch-ab
@@ -0,0 +1,29 @@
+$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