Add send (rfc3971 implementation)

git-svn-id: svn://svn.openwrt.org/openwrt/packages@13020 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
florian 2008-10-21 17:03:18 +00:00
parent 321c337d72
commit f851fd4589
5 changed files with 563 additions and 0 deletions

55
ipv6/send/Makefile Normal file
View File

@ -0,0 +1,55 @@
#
# Copyright (C) 2008 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
# $Id: $
include $(TOPDIR)/rules.mk
PKG_NAME:=send
PKG_VERSION:=0.2-4
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)d_$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://rfc.1924.fr/debian-mobisend/pool/main/s/sendd/
PKG_MD5SUM:=57907178cad20fe3a21e2e449de1dc13
PKG_BUILD_DIR:=$(BUILD_DIR)/sendd-0.2
include $(INCLUDE_DIR)/package.mk
define Package/send
SECTION:=ipv6
CATEGORY:=IPv6
TITLE:=Secure Neighbor Discovery implementation
URL:=http://rfc.1924.fr/debian-mobisend.html
DEPENDS:=+kmod-ipv6 +ip6tables +libnetfilter-queue +libopenssl +libreadline +libncurses
endef
define Package/send/description
DoCoMo's Open Source SEND project provides an implementation of RFC 3971
Secure Neighbor Discovery (SEND). SEND cryptographically secures the
IPv6 neighbor discovery protocol, countering the threats discussed in
RFC 3756 (IPv6 Neighbor Discovery (ND) Trust Models and Threats).
endef
define Package/send/conffiles
/etc/sendd/sendd.conf
/etc/sendd/params.conf
endef
MAKE_FLAGS += \
CC="$(TARGET_CC)" \
CFLAGS="$(TARGET_CFLAGS) -I$(STAGING_DIR)/usr/include/libnetfilter_queue -I$(STAGING_DIR)/usr/include -I$(STAGING_DIR)/include" \
LDFLAGS="$(TARGET_LDFLAGS) -lnfnetlink" \
define Package/send/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/sendd/sendd $(1)/usr/sbin/
$(INSTALL_DIR) $(1)/etc/sendd/
$(INSTALL_CONF) $(PKG_BUILD_DIR)/examples/sendd.conf $(1)/etc/sendd/
$(INSTALL_CONF) $(PKG_BUILD_DIR)/examples/params.conf $(1)/etc/sendd/
endef
$(eval $(call BuildPackage,send))

View File

@ -0,0 +1,396 @@
Index: sendd-0.2/Makefile.config
===================================================================
--- sendd-0.2.orig/Makefile.config 2008-05-27 16:53:49.238160776 +0200
+++ sendd-0.2/Makefile.config 2008-05-27 16:53:52.866156255 +0200
@@ -19,7 +19,7 @@
#CC=gcc-4.0
# Where to install
-prefix=/usr
+prefix=$(DESTDIR)/usr
# Set to "y" to build MT versions of sendd and cgatool
USE_THREADS=n
Index: sendd-0.2/README
===================================================================
--- sendd-0.2.orig/README 2008-05-27 16:53:49.246168775 +0200
+++ sendd-0.2/README 2008-05-27 16:53:52.866156255 +0200
@@ -20,7 +20,7 @@
o CONFIG_NETFILTER, CONFIG_IPV6, CONFIG_IP6_NF_QUEUE, CONFIG_IP6_NF_IPTABLES,
CONFIG_IP6_NF_FILTER enabled in your kernel config.
o netfilter ip6tables command
- o netfilter libipq development library and headers
+ o netfilter libnetfilter_queue development library and headers
FreeBSD:
o NETGRAPH, NETGRAPH_BPF, NETGRAPH_ETHER, NETGRAPH_SOCKET enabled in
Index: sendd-0.2/cgatool/Makefile
===================================================================
--- sendd-0.2.orig/cgatool/Makefile 2008-05-27 16:53:49.278164104 +0200
+++ sendd-0.2/cgatool/Makefile 2008-05-27 16:53:52.866156255 +0200
@@ -25,7 +25,7 @@
ifeq ($(USE_CONSOLE),y)
ifeq ($(USE_READLINE),y)
-LDLIBS += -lreadline -lncurses
+LDLIBS += -lreadline
endif
endif
Index: sendd-0.2/sendd/Makefile
===================================================================
--- sendd-0.2.orig/sendd/Makefile 2008-05-27 16:53:49.286173430 +0200
+++ sendd-0.2/sendd/Makefile 2008-05-27 16:53:52.878156241 +0200
@@ -37,7 +37,7 @@
ifeq ($(USE_CONSOLE),y)
ifeq ($(USE_READLINE),y)
-LDLIBS += -lreadline -lncurses
+LDLIBS += -lreadline
endif
endif
Index: sendd-0.2/sendd/os-linux/Makefile
===================================================================
--- sendd-0.2.orig/sendd/os-linux/Makefile 2008-05-27 16:53:49.294197424 +0200
+++ sendd-0.2/sendd/os-linux/Makefile 2008-05-27 16:53:52.910156597 +0200
@@ -1,23 +1,5 @@
OBJS += os/addr.o os/ipq.o os/rand.o os/snd_linux.o
-OSLIBS= -ldl -lipq
+OSLIBS= -lnetfilter_queue
-OSEXTRA= os/sendd os/snd_upd_fw
-
-ETCINIT= /etc/init.d
-EXTRAINSTALL= $(ETCINIT)/sendd $(ETCINIT)/snd_upd_fw $(ETCINIT)/snd_fw_functions.sh
-EXTRAUNINSTALL=$(EXTRAINSTALL)
-EXTRACLEAN= os/sendd os/snd_upd_fw os/snd_fw_functions.sh
-
-$(ETCINIT)/%: os/%
- install $< $@
-
-os/%: os/%.in
- sed "s/@etcinit@/\/etc\/init.d/g" $< > $@
-
-os/%: os/%.in2
- @./os/find_ip6tables.sh
-
-# Sometimes libipq.h is installed in include/libipq.h, other times it is
-# installed in include/libipq/libipq.h. This rule helps cpp to find it.
-os/ipq.o: CPPFLAGS += -I/usr/include/libipq -I/usr/local/include/libipq
+os/ipq.o: CPPFLAGS += -I/usr/include/libnetfilter_queue
Index: sendd-0.2/sendd/os-linux/ipq.c
===================================================================
--- sendd-0.2.orig/sendd/os-linux/ipq.c 2008-05-27 16:53:49.306181136 +0200
+++ sendd-0.2/sendd/os-linux/ipq.c 2008-05-27 16:55:57.602168158 +0200
@@ -33,7 +33,7 @@
#include <sys/select.h>
#include <netinet/in.h>
#include <linux/netfilter.h>
-#include <libipq.h>
+#include <libnetfilter_queue.h>
#include "config.h"
#include <applog.h>
@@ -42,122 +42,170 @@
#include "../sendd_local.h"
#include "snd_linux.h"
-static struct ipq_handle *qh;
-
extern unsigned if_nametoindex(const char *);
-static inline void
-process_pkt(ipq_packet_msg_t *pkt, struct sbuff *b)
-{
+struct nfq_handle *h = NULL;
+struct nfq_q_handle *qh = NULL;
+
+/* This is the default queue number used in our init script */
+#define SND_DEFAULT_NFQUEUE_NUMBER 13
+
+/* The sbuff is must be made available to the callback function that will
+ handle the packet */
+struct callback_data {
+ struct sbuff *b;
+};
+
+struct callback_data process_pkt_data;
+
+/* nfqueue callback */
+static int process_pkt(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
+ struct nfq_data *nfa, void *data)
+{
+ struct callback_data * d = (struct callback_data *)data;
+ struct nfqnl_msg_packet_hdr *ph;
+ struct sbuff *b = d->b;
+ char *pkt_data;
int in, ifidx;
- b->data = pkt->payload;
- b->len = pkt->data_len;
+ b->len = nfq_get_payload(nfa, &pkt_data);
+ if (b->len == -1) {
+ applog(LOG_ERR, "%s: nfq_get_payload() failed.", __FUNCTION__);
+ return 0;
+ }
+ b->data = (unsigned char *)pkt_data;
- if (*(pkt->indev_name)) {
+ if ((ifidx = nfq_get_indev(nfa)) && ifidx != 0)
in = 1;
- ifidx = if_nametoindex(pkt->indev_name);
- } else if (*(pkt->outdev_name)) {
+ else if ((ifidx = nfq_get_outdev(nfa)) && ifidx != 0)
in = 0;
- ifidx = if_nametoindex(pkt->outdev_name);
- } else {
+ else {
applog(LOG_ERR, "%s: pkt has neither indev nor outdev",
__FUNCTION__);
snd_put_buf(b);
- return;
+ return 0;
}
- snd_recv_pkt(b, ifidx, in, pkt);
-}
+ /* Grab packet header to get its id later */
+ ph = nfq_get_msg_packet_hdr(nfa); /* FIXME Check return value */
-static void
-ipq_recv_pkt(void)
-{
- int r;
- struct sbuff *b = snd_get_buf();
+ snd_recv_pkt(b, ifidx, in, (void *)ph);
- if (b == NULL) {
- return;
- }
- if ((r = ipq_read(qh, b->head, b->rem, -1)) < 0) {
- applog(LOG_ERR, "%s: ipq_read(): %s", __FUNCTION__,
- ipq_errstr());
- goto fail;
- } else if (r == 0) {
- /* timeout */
- goto fail;
- }
-
- switch ((r = ipq_message_type(b->head))) {
- case NLMSG_ERROR:
- applog(LOG_ERR, "%s: nlmsg error: %s", __FUNCTION__,
- strerror(ipq_get_msgerr(b->head)));
- goto fail;
- case IPQM_PACKET:
- process_pkt(ipq_get_packet(b->head), b);
- return;
- default:
- break;
- }
-
-fail:
- snd_put_buf(b);
+ return 1;
}
void
-linux_ipq_add_fds(fd_set *fds, int *maxfd)
+linux_nfq_add_fds(fd_set *fds, int *maxfd)
{
- FD_SET(qh->fd, fds);
- *maxfd = sendd_max(*maxfd, qh->fd);
+ int fd = nfnl_fd(nfq_nfnlh(h));
+
+ FD_SET(fd, fds);
+ *maxfd = sendd_max(*maxfd, fd);
}
void
-linux_ipq_dispatch_fds(fd_set *fds)
+linux_nfq_dispatch_fds(fd_set *fds)
{
- if (FD_ISSET(qh->fd, fds)) {
- ipq_recv_pkt();
+ int fd = nfnl_fd(nfq_nfnlh(h));
+ int r;
+
+ if (FD_ISSET(fd, fds)) {
+ struct sbuff *b = snd_get_buf();
+
+ if (b == NULL) {
+ return;
+ }
+
+ if ((r = recv(fd, b->head, b->rem, 0)) && r <= 0) {
+ if (r < 0) /* not a timeout */
+ applog(LOG_ERR, "%s: recv failed.",
+ __FUNCTION__);
+ snd_put_buf(b);
+ return;
+ }
+
+ process_pkt_data.b = b; /* make sbuff available to
+ callback function */
+ nfq_handle_packet(h, (char *)b->head, r);
}
}
void
os_specific_deliver_pkt(void *p, struct sbuff *b, int drop, int changed)
{
- ipq_packet_msg_t *pkt = p;
- void *newpkt = NULL;
+ struct nfqnl_msg_packet_hdr *ph = (struct nfqnl_msg_packet_hdr *)p;
+ unsigned char *newpkt = NULL;
int plen = 0;
+ uint32_t id = 0;
+
+ if (ph)
+ id = ntohl(ph->packet_id);
if (changed && !drop) {
- newpkt = sbuff_data(b);
+ newpkt = (unsigned char *)b->data;
plen = b->len;
}
- ipq_set_verdict(qh, pkt->packet_id, drop ? NF_DROP : NF_ACCEPT,
- plen, newpkt);
+ nfq_set_verdict(qh, id, drop ? NF_DROP : NF_ACCEPT, plen, newpkt);
snd_put_buf(b);
}
int
-linux_ipq_init(void)
+linux_nfq_init(void)
{
- if ((qh = ipq_create_handle(0, PF_INET6)) == NULL) {
- applog(LOG_ERR, "%s: ipq_create_handle() failed: %s",
- __FUNCTION__, ipq_errstr());
- return (-1);
- }
- if (ipq_set_mode(qh, IPQ_COPY_PACKET, SND_MAX_PKT) < 0) {
- applog(LOG_ERR, "%s: ipq_set_mode() failed: %s",
- __FUNCTION__, ipq_errstr());
- if (errno == ECONNREFUSED) {
- applog(LOG_ERR, "%s: perhaps you need to modprobe "
- "ip6_queue?", __FUNCTION__);
- }
- return (-1);
+ struct nfnl_handle *nh;
+ u_int16_t nfqueue_num = SND_DEFAULT_NFQUEUE_NUMBER;
+
+ /* Get netfilter queue connection handle */
+ h = nfq_open();
+ if (!h) {
+ applog(LOG_ERR, "%s: nfq_open() failed.", __FUNCTION__);
+ return -1;
+ }
+
+ /* Unbinding existing nfqueue handlers for AF_INET6. We ignore the
+ return value: http://www.spinics.net/lists/netfilter/msg42063.html.
+ Note that this call is required, otherwise, nfq_bind_pf() fails. */
+ nfq_unbind_pf(h, PF_INET6);
+
+ if (nfq_bind_pf(h, PF_INET6) < 0) {
+ applog(LOG_ERR, "%s: nfq_bind_pf failed.\n", __FUNCTION__);
+ return -1;
+ }
+
+ /* Binding this socket to queue number nfqueue_num and installing
+ our packet handler */
+ qh = nfq_create_queue(h, nfqueue_num,
+ (nfq_callback *) &process_pkt,
+ (void *)&process_pkt_data);
+ if (!qh) {
+ applog(LOG_ERR, "%s: nfq_create_queue() failed.\n",
+ __FUNCTION__);
+ return -1;
+ }
+
+ /* Asking for entire copy of queued packets */
+ if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0) { /* XXX was SND_MAX_PKT */
+ fprintf(stderr, "nfq_set_mode() failed.\n");
+ return -1;
}
- return (0);
+
+ /* XXX - Check if we have an interest in setting queue length */
+
+ /* The netlink handle associated with our queue connection handle */
+ nh = nfq_nfnlh(h);
+
+ return 0;
}
void
-linux_ipq_fini(void)
+linux_nfq_fini(void)
{
- ipq_destroy_handle(qh);
+ /* Remove the binding for our queue handler*/
+ if (qh != NULL)
+ nfq_destroy_queue(qh);
+
+ /* Close connection associated with our connection handler */
+ if (h != NULL)
+ nfq_close(h);
}
Index: sendd-0.2/sendd/os-linux/snd_linux.c
===================================================================
--- sendd-0.2.orig/sendd/os-linux/snd_linux.c 2008-05-27 16:53:49.314164060 +0200
+++ sendd-0.2/sendd/os-linux/snd_linux.c 2008-05-27 16:53:52.914160667 +0200
@@ -40,13 +40,13 @@
void
os_specific_add_fds(fd_set *fds, int *maxfd)
{
- linux_ipq_add_fds(fds, maxfd);
+ linux_nfq_add_fds(fds, maxfd);
}
void
os_specific_dispatch_fds(fd_set *fds)
{
- linux_ipq_dispatch_fds(fds);
+ linux_nfq_dispatch_fds(fds);
}
int
@@ -59,7 +59,7 @@
os_specific_init(void)
{
if (linux_rand_init() < 0 ||
- linux_ipq_init() < 0) {
+ linux_nfq_init() < 0) {
return (-1);
}
return (0);
@@ -68,6 +68,6 @@
void
os_specific_fini(void)
{
- linux_ipq_fini();
+ linux_nfq_fini();
linux_rand_fini();
}
Index: sendd-0.2/sendd/os-linux/snd_linux.h
===================================================================
--- sendd-0.2.orig/sendd/os-linux/snd_linux.h 2008-05-27 16:53:49.330169232 +0200
+++ sendd-0.2/sendd/os-linux/snd_linux.h 2008-05-27 16:53:52.914160667 +0200
@@ -33,10 +33,10 @@
#ifndef _SEND_LINUX_H
#define _SEND_LINUX_H
-extern void linux_ipq_add_fds(fd_set *, int *);
-extern void linux_ipq_dispatch_fds(fd_set *);
-extern int linux_ipq_init(void);
-extern void linux_ipq_fini(void);
+extern void linux_nfq_add_fds(fd_set *, int *);
+extern void linux_nfq_dispatch_fds(fd_set *);
+extern int linux_nfq_init(void);
+extern void linux_nfq_fini(void);
extern void linux_rand_fini(void);
extern int linux_rand_init(void);

View File

@ -0,0 +1,59 @@
This patch allows one to specify a maximum number of bits
for the CGA and RSA key size. RFC specifies that an implementation
may optionnaly honor this setting (5.1.3). This is particularly
useful on embedded systems where both the entropy and the processing
power are limited.
Index: sendd-0.2/sendd/config.c
===================================================================
diff -urN sendd-0.2/sendd/config.c sendd-0.2.new/sendd/config.c
--- sendd-0.2/sendd/config.c 2008-04-18 16:21:46.000000000 +0200
+++ sendd-0.2.new/sendd/config.c 2008-09-09 15:41:11.000000000 +0200
@@ -82,6 +82,7 @@
SND_CFS(snd_cga_params, NULL, 1),
SND_CFIB(snd_full_secure, 1, 0),
SND_CFII(snd_min_key_bits, 1024, "bits", 0),
+ SND_CFII(snd_max_key_bits, 2048, "bits", 0),
SND_CFII(snd_nonce_cache_gc_intvl, 2, "seconds", 0),
SND_CFII(snd_pfx_cache_gc_intvl, 40, "seconds", 0),
SND_CFS(snd_pkixip_conf, NULL, 0),
Index: sendd-0.2/sendd/sig_rfc3971.c
===================================================================
diff -urN sendd-0.2/sendd/sig_rfc3971.c sendd-0.2.new/sendd/sig_rfc3971.c
--- sendd-0.2/sendd/sig_rfc3971.c 2008-04-18 16:21:46.000000000 +0200
+++ sendd-0.2.new/sendd/sig_rfc3971.c 2008-09-10 11:14:35.000000000 +0200
@@ -147,7 +147,7 @@
EVP_MD_CTX ctx[1];
EVP_PKEY *pub;
int rv = -1;
- int i, real_slen, min_bits;
+ int i, real_slen, min_bits, max_bits;
DEFINE_TIMESTAMP_VARS();
DBG_HEXDUMP(&dbg_cryptox, "key: ", key, klen);
@@ -164,6 +164,12 @@
"minimum: %d)", EVP_PKEY_bits(pub), min_bits);
return (-1);
}
+ max_bits = snd_conf_get_int(snd_max_key_bits);
+ if (EVP_PKEY_bits(pub) > max_bits) {
+ DBG(&dbg_snd, "Peer key too strong: %d bits (configured "
+ "maximum: %d)", EVP_PKEY_bits(pub), max_bits);
+ return (-1);
+ }
real_slen = EVP_PKEY_size(pub);
if (real_slen < slen) {
Index: sendd-0.2/sendd/snd_config.h
===================================================================
diff -urN sendd-0.2/sendd/snd_config.h sendd-0.2.new/sendd/snd_config.h
--- sendd-0.2/sendd/snd_config.h 2008-04-18 16:21:46.000000000 +0200
+++ sendd-0.2.new/sendd/snd_config.h 2008-09-09 15:09:45.000000000 +0200
@@ -42,6 +42,7 @@
snd_cga_params,
snd_full_secure,
snd_min_key_bits,
+ snd_max_key_bits,
snd_nonce_cache_gc_intvl,
snd_pfx_cache_gc_intvl,
snd_pkixip_conf,

View File

@ -0,0 +1,22 @@
This patch aligns the structure describing the RSA signature
option to 8 bytes. Before that, send was padding with N bytes
(4 on 32-bits architectures) using a cast in sendd/proto_sig.c :
so = (struct snd_opt_sig *)(nd_so);
which would align to the number of bytes representing a pointer
on your architecture.
Index: sendd-0.2/sendd/snd_proto.h
============================================================
--- sendd-0.2/sendd/snd_proto.h 2008-04-18 16:21:46.000000000 +0200
+++ sendd-0.2.new/sendd/snd_proto.h 2008-10-05 16:08:34.000000000 +0200
@@ -69,7 +69,7 @@
uint32_t reserved; /* opt hdr + reserved */
uint8_t keyhash[SND_KEYHASH_LEN];
uint8_t sig[0];
-};
+} __attribute__((aligned(8)));
struct snd_opt_timestamp {
uint8_t type;

View File

@ -0,0 +1,31 @@
We should always link with libncurses. This is not noticeable
when building the debian packages because we install libncurses5
runtime library as a dependency.
Index: sendd-0.2/cgatool/Makefile
===================================================================
--- sendd-0.2/cgatool/Makefile 2008-10-05 16:26:28.000000000 +0200
+++ sendd-0.2.new/cgatool/Makefile 2008-10-21 18:03:28.000000000 +0200
@@ -17,7 +17,7 @@
LDFLAGS= -L../libs/.libs
endif
-LDLIBS += -lcrypto
+LDLIBS += -lcrypto -lncurses
ifeq ($(USE_THREADS),y)
LDLIBS += -lpthread
Index: sendd-0.2/sendd/Makefile
===================================================================
diff -urN sendd-0.2/sendd/Makefile sendd-0.2.new/sendd/Makefile
--- sendd-0.2/sendd/Makefile 2008-05-27 17:04:08.000000000 +0200
+++ sendd-0.2.new/sendd/Makefile 2008-10-21 18:49:05.000000000 +0200
@@ -28,7 +28,7 @@
LDFLAGS= -L../libs/.libs
endif
-LDLIBS += -lcrypto
+LDLIBS += -lcrypto -lncurses
LDLIBS += $(OSLIBS)
ifeq ($(USE_THREADS),y)