From 7ec5099b5f5c79419a54a6cdedea618d98b60569 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 5 Nov 2003 10:44:19 +0000 Subject: Commit initial version git-svn-id: file:///home/lennart/svn/public/seppl/trunk@2 91a2fd9b-5dcb-0310-a70a-d71e310228e6 --- Makefile.am | 1 + bootstrap.sh | 46 ++++++ conf/Makefile.am | 31 ++++ conf/seppl.init.in | 106 ++++++++++++ configure.ac | 148 +++++++++++++++++ kernel/Makefile.in | 61 +++++++ kernel/ipt_CRYPT.c | 190 +++++++++++++++++++++ kernel/ipt_CRYPT.h | 32 ++++ kernel/ipt_DECRYPT.c | 197 ++++++++++++++++++++++ kernel/ipt_DECRYPT.h | 28 ++++ kernel/seppl.c | 429 ++++++++++++++++++++++++++++++++++++++++++++++++ kernel/seppl.h | 60 +++++++ kernel/seppl_protocol.h | 27 +++ kernel/test.sh | 39 +++++ libs/Makefile.am | 28 ++++ libs/libipt_CRYPT.c | 114 +++++++++++++ libs/libipt_DECRYPT.c | 75 +++++++++ utils/Makefile.am | 22 +++ utils/seppl-gen-key | 110 +++++++++++++ utils/seppl-ls | 198 ++++++++++++++++++++++ utils/seppl_common.py | 105 ++++++++++++ 21 files changed, 2047 insertions(+) create mode 100644 Makefile.am create mode 100755 bootstrap.sh create mode 100644 conf/Makefile.am create mode 100755 conf/seppl.init.in create mode 100644 configure.ac create mode 100644 kernel/Makefile.in create mode 100644 kernel/ipt_CRYPT.c create mode 100644 kernel/ipt_CRYPT.h create mode 100644 kernel/ipt_DECRYPT.c create mode 100644 kernel/ipt_DECRYPT.h create mode 100644 kernel/seppl.c create mode 100644 kernel/seppl.h create mode 100644 kernel/seppl_protocol.h create mode 100755 kernel/test.sh create mode 100644 libs/Makefile.am create mode 100644 libs/libipt_CRYPT.c create mode 100644 libs/libipt_DECRYPT.c create mode 100644 utils/Makefile.am create mode 100755 utils/seppl-gen-key create mode 100755 utils/seppl-ls create mode 100644 utils/seppl_common.py diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..ae9033f --- /dev/null +++ b/Makefile.am @@ -0,0 +1 @@ +SUBDIRS=kernel libs utils conf diff --git a/bootstrap.sh b/bootstrap.sh new file mode 100755 index 0000000..148356b --- /dev/null +++ b/bootstrap.sh @@ -0,0 +1,46 @@ +#!/bin/sh +# $Id: bootstrap.sh 58 2003-10-20 21:57:59Z lennart $ + +# This file is part of seppl. +# +# seppl 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 +# (at your option) any later version. +# +# seppl is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with seppl; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + +run_versioned() { + local P + type -p "$1-$2" &> /dev/null && P="$1-$2" || local P="$1" + + shift 2 + "$P" "$@" +} + +if [ "x$1" = "xam" ] ; then + set -ex + run_versioned automake 1.7 -a -c + ./config.status +else + set -ex + rm -rf autom4te.cache + rm -f config.cache + + run_versioned aclocal 1.7 + libtoolize -c --force + autoheader + run_versioned automake 1.7 -a -c + autoconf -Wall + + ./configure --sysconfdir=/etc "$@" + + make clean +fi diff --git a/conf/Makefile.am b/conf/Makefile.am new file mode 100644 index 0000000..98667e2 --- /dev/null +++ b/conf/Makefile.am @@ -0,0 +1,31 @@ +# $Id: Makefile.am 40 2003-10-27 18:32:45Z lennart $ +# +# This file is part of seppl. +# +# seppl 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 +# (at your option) any later version. +# +# seppl is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with seppl; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + +noinst_DATA = seppl.init +EXTRA_DIST = seppl.init.in +CLEANFILES = seppl.init + +seppl.init: seppl.init.in Makefile + sed -e 's,@sysconfdir\@,$(sysconfdir),g' -e 's,@sbindir\@,$(sbindir),g' $< > $@ + chmod 755 $@ + +install-data-local: seppl.init + $(INSTALL) -b -D -m755 seppl.init ${DESTDIR}/${sysconfdir}/init.d/seppl + +uninstall-local: + rm -f ${DESTDIR}/${sysconfdir}/init.d/seppl diff --git a/conf/seppl.init.in b/conf/seppl.init.in new file mode 100755 index 0000000..79ee4d5 --- /dev/null +++ b/conf/seppl.init.in @@ -0,0 +1,106 @@ +#! /bin/sh + +# $Id: Makefile.am 40 2003-10-27 18:32:45Z lennart $ +# +# This file is part of seppl. +# +# seppl 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 +# (at your option) any later version. +# +# seppl is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with seppl; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin + +PROCFILE="/proc/net/seppl_keyring" +SEPPLLS="@sbindir@/seppl-ls" +KEYDIR="@sysconfdir@/seppl" + +test -d "$KEYDIR" || exit 1 +test -x "$SEPPLLS" || exit 1 + +load_keys() { + echo -n "Configuring SEPPL keys: " + for K in "$KEYDIR"/* ; do + if test -f "$K" ; then + if ( "$SEPPLLS" -f $K > "$PROCFILE" ) 2> /dev/null ; then + echo -n "$K " + else + echo "failed" + exit 1 + fi + fi + done + echo "." +} + +clear_keys() { + echo -n "Clearing SEPPL keys: " + ( echo "clear" > "$PROCFILE" ) 2> /dev/null + if test -s "$PROCFILE" ; then + echo "failure" + exit 1 + fi + echo "success" +} + + +load_modules() { + echo -n "Loading SEPPL module: " + modprobe seppl &> /dev/null + if ! test -f "$PROCFILE" ; then + echo "failure" + exit 1 + fi + echo "success" +} + +unload_modules() { + echo -n "Unloading SEPPL modules: " + modprobe -r ipt_CRYPT &> /dev/null + modprobe -r ipt_DECRYPT &> /dev/null + modprobe -r seppl &> /dev/null + if test -f "$PROCFILE" ; then + echo "failure" + exit 1 + fi + echo "success" +} + +case "$1" in + start) + load_modules + load_keys + ;; + + stop) + clear_keys + unload_modules + ;; + + force-reload|reload) + clear_keys + load_keys + ;; + + restart) + $0 stop + sleep 1 + $0 start + ;; + + *) + echo "Usage: $0 {start|stop|restart|force-reload|reload}" + exit 1 + ;; +esac + +exit 0 diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..d5e5ef7 --- /dev/null +++ b/configure.ac @@ -0,0 +1,148 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +# $Id: configure.ac 58 2003-10-20 21:57:59Z lennart $ + +# This file is part of seppl. +# +# seppl 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 +# (at your option) any later version. +# +# seppl is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with seppl; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + +AC_PREREQ(2.57) +AC_INIT([seppl], [0.2], [mzfrccy (at) 0pointer (dot) de]) +AC_CONFIG_SRCDIR([kernel/seppl.c]) +AC_CONFIG_HEADERS([config.h]) +AM_INIT_AUTOMAKE([foreign -Wall]) +AC_DISABLE_STATIC +AC_PROG_LIBTOOL + +# Checks for programs. +AC_PROG_CXX +AC_PROG_CC + +AC_SUBST(PACKAGE_URL, [http://0pointer.de/lennart/projects/seppl/]) + +# If using GCC specifiy some additional parameters +if test "x$GCC" = "xyes" ; then + CFLAGS="$CFLAGS -pipe -Wall" +fi + +if type -p stow > /dev/null && test -d /usr/local/stow ; then + AC_MSG_NOTICE([*** Found /usr/local/stow: installing to /usr/local/stow/${PACKAGE_NAME}-${PACKAGE_VERSION} ***]) + AC_PREFIX_DEFAULT([/usr/local/stow/${PACKAGE_NAME}-${PACKAGE_VERSION}]) +fi + +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_MAKE_SET +AC_CHECK_FUNCS([memset]) +AC_C_CONST + +# Check for directory with kernel source... +AC_MSG_CHECKING(for directory with kernel source) +AC_ARG_WITH(kernel, + [ --with-kernel=dir give the directory with kernel sources] + [ [/usr/src/linux]], + KERNELDIR="$withval", + if test -d "/lib/modules/`uname -r`/build" -o -L "/lib/modules/`uname -r`/build"; then + KERNELDIR="/lib/modules/`uname -r`/build" + else + KERNELDIR="/usr/src/linux" + fi +) +AC_SUBST(KERNELDIR) +AC_MSG_RESULT([$KERNELDIR]) + +# Check for crypto.h +AC_MSG_CHECKING(for crypto.h) +if ! test -r $KERNELDIR/include/linux/crypto.h; then + cat << EOF +The file $KERNELDIR/include/linux/crypto.h does not exist. +Please, install the package with full kernel sources for 2.4.22 for your distribution +or use --with-kernel=dir option to specify another directory with kernel +sources (default is /usr/src/linux). +EOF + exit 1 +fi +AC_MSG_RESULT([found]) + +# Check for directory for kernel modules... +AC_MSG_CHECKING(for directory for kernel modules) +AC_ARG_WITH(moddir, + AC_HELP_STRING([--with-moddir=dir], [Give the directory to install kernel modules to]), + KERNELMODDIR="$withval", + if test -d "/lib/modules/`uname -r`/" -o -L "/lib/modules/`uname -r`/"; then + KERNELMODDIR="/lib/modules/`uname -r`/" + else + AC_MSG_ERROR([[*** Sorry, failed to find kernel module directory ***]]) + fi +) +AC_SUBST(KERNELMODDIR) +AC_MSG_RESULT([$KERNELMODDIR]) + +# iptables checks +AC_CHECK_HEADER(iptables.h,, [AC_MSG_ERROR([*** Sorry, failed to find iptables.h, you should install iptables-dev ***])]) + +# Set libiptdir +AC_MSG_CHECKING(for /lib/iptables) +if ! test -d /lib/iptables ; then + AC_MSG_ERROR([*** Sorry, failed to find iptables plugin directory ***]) +fi +LIB_IPTABLES_DIR=/lib/iptables +AC_SUBST(LIB_IPTABLES_DIR) +AC_MSG_RESULT([$LIB_IPTABLES_DIR]) + +AM_PATH_PYTHON([2.1]) + +# LYNX documentation generation +AC_ARG_ENABLE(lynx, + AC_HELP_STRING([--disable-lynx], [Turn off lynx usage for documentation generation]), +[case "${enableval}" in + yes) lynx=yes ;; + no) lynx=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-lynx) ;; +esac],[lynx=yes]) + +if test x$lynx = xyes ; then + AC_CHECK_PROG(have_lynx, lynx, yes, no) + + if test x$have_lynx = xno ; then + AC_MSG_ERROR([*** Sorry, you have to install lynx or use --disable-lynx ***]) + fi +fi + +AM_CONDITIONAL([USE_LYNX], [test "x$lynx" = xyes]) + +# XMLTOMAN manpage generation +AC_ARG_ENABLE(xmltoman, + AC_HELP_STRING([--disable-xmltoman], [Disable rebuilding of man pages with xmltoman]), +[case "${enableval}" in + yes) xmltoman=yes ;; + no) xmltoman=no ;; + *) AC_MSG_ERROR([bad value ${enableval} for --disable-xmltoman]) ;; +esac],[xmltoman=yes]) + +if test x$xmltoman = xyes ; then + AC_CHECK_PROG(have_xmltoman, xmltoman, yes, no) + + if test x$have_xmltoman = xno ; then + AC_MSG_WARN([*** Not rebuilding man pages as xmltoman is not found ***]) + xmltoman=no + fi +fi + +AM_CONDITIONAL([USE_XMLTOMAN], [test "x$xmltoman" = xyes]) + +AC_CONFIG_FILES([kernel/Makefile libs/Makefile Makefile utils/Makefile conf/Makefile ]) # doc/Makefile doc/README.html]) +AC_OUTPUT diff --git a/kernel/Makefile.in b/kernel/Makefile.in new file mode 100644 index 0000000..3be3826 --- /dev/null +++ b/kernel/Makefile.in @@ -0,0 +1,61 @@ +# $Id: Makefile.am 40 2003-10-27 18:32:45Z lennart $ +# +# This file is part of seppl. +# +# seppl 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 +# (at your option) any later version. +# +# seppl is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with seppl; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + +# This Makefile is NOT created by automake! + +KERNELDIR=@KERNELDIR@ +SEPPL_MODDIR=@KERNELMODDIR@/seppl +PACKAGE=@PACKAGE@ +VERSION=@VERSION@ +DISTFILES=seppl.c seppl.h ipt_CRYPT.c ipt_CRYPT.h ipt_DECRYPT.c ipt_DECRYPT.h test.sh Makefile.in seppl_protocol.h +distdir = ../$(PACKAGE)-$(VERSION) +CFLAGS=-Wall -g -O2 +KERNEL_CFLAGS= -I$(KERNELDIR)/include -DLINUX -DMODULE -D__KERNEL__ -DEXPORT_SYMTAB -DPACKAGE_BUGREPORT="\"@PACKAGE_BUGREPORT@\"" + +all: Makefile ipt_CRYPT.o ipt_DECRYPT.o seppl.o + +Makefile: Makefile.in + cd .. && ./config.status kernel/Makefile + +ipt_CRYPT.o: ipt_CRYPT.c + $(CC) $(CFLAGS) -c $^ -o $@ $(KERNEL_CFLAGS) + +ipt_DECRYPT.o: ipt_DECRYPT.c + $(CC) $(CFLAGS) -c $^ -o $@ $(KERNEL_CFLAGS) + +seppl.o: seppl.c + $(CC) $(CFLAGS) -c $^ -o $@ $(KERNEL_CFLAGS) + +install: + mkdir -p $(SEPPL_MODDIR) + install -m644 seppl.o ipt_CRYPT.o ipt_DECRYPT.o $(SEPPL_MODDIR) + +distdir: + mkdir -p $(distdir) + cp -p $(DISTFILES) $(distdir) + +mostlyclean: clean +distclean: clean + +maintainer-clean: clean + rm -f Makefile + +clean: + rm -f *.o + +.PHONY: all clean maintainer-clean mostlyclean distclean distdir install diff --git a/kernel/ipt_CRYPT.c b/kernel/ipt_CRYPT.c new file mode 100644 index 0000000..9f7d055 --- /dev/null +++ b/kernel/ipt_CRYPT.c @@ -0,0 +1,190 @@ +/* $Id: newmail.c 31 2003-10-22 22:59:07Z lennart $ */ + +/*** + This file is part of seppl + + seppl 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 + (at your option) any later version. + + seppl is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with seppl; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA +***/ + +#include +#include +#include +#include +#include +#include +struct in_device; +#include +#include +#include + +#include "seppl.h" +#include "ipt_CRYPT.h" + +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif +#ifdef MODULE_DESCRIPTION +MODULE_DESCRIPTION("SEPPL iptables Encryption Target"); +#endif +#ifdef MODULE_AUTHOR +MODULE_AUTHOR("Lennart Poettering <"PACKAGE_BUGREPORT">"); +#endif + +static unsigned int ipt_CRYPT_target(struct sk_buff **pskb, unsigned int hooknum, const struct net_device *in, const struct net_device *out, const void *_ti, void *userinfo) { + const struct ipt_crypt_info *ti = _ti; + struct iphdr *ih = (*pskb)->nh.iph; + unsigned d, new_l, crypt_l, ihl = ih->ihl<<2; + struct seppl_uncrypt_hdr *uh; + struct seppl_crypt_hdr *ch; + u8 *iv, *pl; + int ivs = ti->key->ivsize; + int bs = ti->key->blocksize; + struct sock *sk; + struct scatterlist sg[1]; + + // Calculate new packet size + new_l = ihl + sizeof(struct seppl_uncrypt_hdr) + ivs + ((sizeof(struct seppl_crypt_hdr) + ntohs(ih->tot_len) - ihl + bs - 1) / bs) * bs; + d = new_l - htons(ih->tot_len); + crypt_l = new_l - ihl - sizeof(struct seppl_uncrypt_hdr) - ivs; + + //DEBUGP("CRYPT: tot_len=%i, new_l=%i, d=%i, crypt_l=%i\n", htons(ih->tot_len), new_l, d, crypt_l); + + // Copy the skb if needed and increase it correctly + if (skb_tailroom(*pskb) < d || skb_cloned(*pskb)) { + struct sk_buff *n; + + if (!(n = skb_copy_expand(*pskb, skb_headroom(*pskb), d, GFP_ATOMIC))) { + if (net_ratelimit()) + printk(KERN_ERR "ipt_CRYPT: Unable to allocate larger skb, dropping packet.\n"); + + return NF_DROP; + } + + if ((*pskb)->sk) + skb_set_owner_w(n, (*pskb)->sk); + + kfree_skb(*pskb); + *pskb = n; + ih = (*pskb)->nh.iph; + } + + skb_put(*pskb, d); + + // Calculate some pointers + //ih = ... /* IP-Header */ + uh = (struct seppl_uncrypt_hdr*) ((u8*) ih + ihl); /* Unencrypted header */ + iv = ((u8*) uh) + sizeof(struct seppl_uncrypt_hdr); /* IV */ + ch = (struct seppl_crypt_hdr*) (iv + ivs); /* Crypted header */ + pl = ((u8*) ch) + sizeof(struct seppl_crypt_hdr); /* Payload */ + + // Copy the payload + memmove(pl, uh, ntohs(ih->tot_len) - ihl); + + // Fill the uncrypted header + uh->algorithm = ti->key->algorithm; + strncpy(uh->key_name, ti->key->name, 7); + + // Copy the IV + seppl_copy_iv(ti->key, iv); + + // Fill the crypted header + ch->ident = 0x00; + ch->saved_protocol = ih->protocol; + ch->saved_tot_len = ih->tot_len; + ch->saved_frag_off = ih->frag_off; + + // Fill the IP header + ih->protocol = SEPPL_PROTOCOL; + ih->tot_len = htons(new_l); + ih->frag_off = 0; + + // Checksum FIXME: Is this really needed? + ih->check = 0; + ih->check = ip_fast_csum((char *) ih, ih->ihl); + + // Crypt + sg[0].page = virt_to_page((void*) ch); + sg[0].offset = (((long) (void *) ch) & ~PAGE_MASK); + sg[0].length = crypt_l; + + crypto_cipher_set_iv(ti->key->tfm, iv, ti->key->ivsize); + + if (crypto_cipher_encrypt(ti->key->tfm, sg, sg, sg[0].length)) { + if (net_ratelimit()) + printk(KERN_ERR "ipt_CRYPT: encrypt() failure\n"); + return NF_DROP; + } + + // Finish + (*pskb)->ip_summed = CHECKSUM_NONE; + (*pskb)->nfcache |= NFC_UNKNOWN | NFC_ALTERED; + + return IPT_CONTINUE; +} + +static int ipt_CRYPT_check(const char *table, const struct ipt_entry *e, void *_ti, unsigned int ti_size, unsigned int hook_mask) { + struct ipt_crypt_info *ti = _ti; + + if (ti_size != IPT_ALIGN(sizeof(struct ipt_crypt_info))) { + printk(KERN_ERR "ipt_CRYPT: Structure too small\n"); + return 0; + } + + if (strcmp(table, "mangle") != 0) { + printk(KERN_ERR "ipt_CRYPT: Not in mangle table\n"); + return 0; + } + + if ((hook_mask & ~(1 << NF_IP_POST_ROUTING)) != 0) { + printk(KERN_ERR "ipt_CRYPT: Not in POSTROUTING chain\n"); + return 0; + } + + if (!(ti->key = seppl_claim_key(ti->algorithm, ti->name))) { + printk(KERN_ERR "ipt_CRYPT: Cannot find key\n"); + return 0; + } + + return 1; +} + +static void ipt_CRYPT_destroy(void *_ti, unsigned int ti_size) { + struct ipt_crypt_info *ti = _ti; + + seppl_release_key(ti->key); +} + +static struct ipt_target ipt_CRYPT_reg = { + { NULL, NULL }, + "CRYPT", + ipt_CRYPT_target, + ipt_CRYPT_check, + ipt_CRYPT_destroy, + THIS_MODULE +}; + +static int __init init(void) { + return ipt_register_target(&ipt_CRYPT_reg); +} + +static void __exit fini(void) { + ipt_unregister_target(&ipt_CRYPT_reg); +} + +module_init(init); +module_exit(fini); + +EXPORT_NO_SYMBOLS; diff --git a/kernel/ipt_CRYPT.h b/kernel/ipt_CRYPT.h new file mode 100644 index 0000000..f1602be --- /dev/null +++ b/kernel/ipt_CRYPT.h @@ -0,0 +1,32 @@ +#ifndef _IPT_CRYPT_H +#define _IPT_CRYPT_H + +/* $Id: newmail.c 31 2003-10-22 22:59:07Z lennart $ */ + +/*** + This file is part of seppl + + seppl 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 + (at your option) any later version. + + seppl is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with seppl; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA +***/ + +struct ipt_crypt_info { + unsigned char algorithm; + char name[7]; + + struct seppl_key *key; +}; + +#endif diff --git a/kernel/ipt_DECRYPT.c b/kernel/ipt_DECRYPT.c new file mode 100644 index 0000000..75db2bd --- /dev/null +++ b/kernel/ipt_DECRYPT.c @@ -0,0 +1,197 @@ +/* $Id: newmail.c 31 2003-10-22 22:59:07Z lennart $ */ + +/*** + This file is part of seppl + + seppl 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 + (at your option) any later version. + + seppl is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with seppl; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA +***/ + +#include +#include +#include +#include +#include +#include +struct in_device; +#include +#include +#include + +#include "seppl.h" +#include "ipt_DECRYPT.h" + +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif +#ifdef MODULE_DESCRIPTION +MODULE_DESCRIPTION ("SEPPL iptables Decryption Target"); +#endif +#ifdef MODULE_AUTHOR +MODULE_AUTHOR("Lennart Poettering <"PACKAGE_BUGREPORT">"); +#endif + +static unsigned int ipt_DECRYPT_target(struct sk_buff **pskb, unsigned int hooknum, const struct net_device *in, const struct net_device *out, const void *_ti, void *userinfo) { + struct iphdr *ih = (*pskb)->nh.iph; + unsigned ihl = ih->ihl<<2; + struct seppl_key *key; + struct seppl_uncrypt_hdr *uh; + struct seppl_crypt_hdr *ch; + u8* iv, *pl; + int ivs; + int crypt_l, bs; + struct scatterlist sg[1]; + + if (ih->protocol != SEPPL_PROTOCOL) { + if (net_ratelimit()) + printk(KERN_ERR "ipt_DECRYPT: Incorrect protocol\n"); + return NF_DROP; + } + + if (ntohs(ih->tot_len) <= ihl+sizeof(struct seppl_uncrypt_hdr)) { + if (net_ratelimit()) + printk(KERN_ERR "ipt_DECRYPT: Packet too short (1)\n"); + return NF_DROP; + } + + uh = (struct seppl_uncrypt_hdr*) ((u8*) ih + ihl); /* Unencrypted header */ + + if (!(key = seppl_claim_key(uh->algorithm, uh->key_name))) { + if (net_ratelimit()) + printk(KERN_ERR "ipt_DECRYPT: Recieved packet with unknown decryption key.\n"); + return NF_DROP; + } + + ivs = key->ivsize; + bs = key->blocksize; + + if (ntohs(ih->tot_len) <= ihl+sizeof(struct seppl_uncrypt_hdr)+ivs+sizeof(struct seppl_crypt_hdr)) { + if (net_ratelimit()) + printk(KERN_ERR "ipt_DECRYPT: Packet too short (2)\n"); + seppl_release_key(key); + return NF_DROP; + } + + crypt_l = ntohs(ih->tot_len)-ihl-sizeof(struct seppl_uncrypt_hdr)-ivs; + + if (crypt_l % bs) { + if (net_ratelimit()) + printk(KERN_ERR "ipt_DECRYPT: Packet too short (3)\n"); + seppl_release_key(key); + return NF_DROP; + } + + iv = ((u8*) uh) + sizeof(struct seppl_uncrypt_hdr); /* IV */ + ch = (struct seppl_crypt_hdr*) (iv + ivs); /* Crypted header */ + pl = ((u8*) ch) + sizeof(struct seppl_crypt_hdr); /* Payload */ + + sg[0].page = virt_to_page(ch); + sg[0].offset = ((long) ch & ~PAGE_MASK); + sg[0].length = crypt_l; + + crypto_cipher_set_iv(key->tfm, iv, key->ivsize); + + if (crypto_cipher_decrypt(key->tfm, sg, sg, sg[0].length)) { + if (net_ratelimit()) + printk(KERN_ERR "ipt_DECRYPT: decrypt() failure\n"); + seppl_release_key(key); + return NF_DROP; + } + + seppl_release_key(key); + + if (ch->ident != 0x00) { + if (net_ratelimit()) + printk(KERN_ERR "ipt_DECRYPT: Key not matching\n"); + return NF_DROP; + } + + if (ntohs(ch->saved_tot_len) > + ntohs(ih->tot_len) - + sizeof(struct seppl_uncrypt_hdr)- + ivs- + sizeof(struct seppl_crypt_hdr)) { + + if (net_ratelimit()) + printk(KERN_ERR "ipt_DECRYPT: Packet too short (4)"); + return NF_DROP; + } + + //DEBUGP("DECRYPT: tot_len=%i, real_l=%i, crypt_l=%i\n", htons(ih->tot_len), ntohs(ch->saved_tot_len), crypt_l); + + // Restore the IP header + ih->protocol = ch->saved_protocol; + ih->tot_len = ch->saved_tot_len; + ih->frag_off = ch->saved_frag_off; + + // The pay load + memmove(uh, pl, ntohs(ih->tot_len)-ihl); + + // Checksum + ih->check = 0; + ih->check = ip_fast_csum((char *) ih, ih->ihl); + + skb_trim(*pskb, ntohs(ih->tot_len)); + + // Finish + (*pskb)->ip_summed = CHECKSUM_NONE; + (*pskb)->nfcache |= NFC_UNKNOWN | NFC_ALTERED; + + return IPT_CONTINUE; +} + +static int ipt_DECRYPT_check(const char *table, const struct ipt_entry *e, void *_ti, unsigned int ti_size, unsigned int hook_mask) { + if (ti_size != IPT_ALIGN(sizeof(struct ipt_decrypt_info))) { + printk(KERN_ERR "ipt_DECRYPT: Structure too small"); + return 0; + } + + if (strcmp(table, "mangle") != 0) { + printk(KERN_ERR "ipt_DECRYPT: Not in mangle table\n"); + return 0; + } + + if ((hook_mask & ~(1 << NF_IP_PRE_ROUTING)) != 0) { + printk(KERN_ERR "ipt_DECRYPT: Not in PREROUTING chain"); + return 0; + } + + return 1; +} + +static struct ipt_target ipt_DECRYPT_reg = { + { NULL, NULL }, + "DECRYPT", + ipt_DECRYPT_target, + ipt_DECRYPT_check, + NULL, + THIS_MODULE +}; + +static int __init init(void) { + if (ipt_register_target(&ipt_DECRYPT_reg)) + return -EINVAL; + + return 0; +} + +static void __exit fini(void) { + ipt_unregister_target(&ipt_DECRYPT_reg); +} + +module_init(init); +module_exit(fini); + +EXPORT_NO_SYMBOLS; diff --git a/kernel/ipt_DECRYPT.h b/kernel/ipt_DECRYPT.h new file mode 100644 index 0000000..41f202a --- /dev/null +++ b/kernel/ipt_DECRYPT.h @@ -0,0 +1,28 @@ +#ifndef _IPT_DECRYPT_H +#define _IPT_DECRYPT_H + +/* $Id: newmail.c 31 2003-10-22 22:59:07Z lennart $ */ + +/*** + This file is part of seppl + + seppl 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 + (at your option) any later version. + + seppl is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with seppl; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA +***/ + +struct ipt_decrypt_info { +}; + +#endif diff --git a/kernel/seppl.c b/kernel/seppl.c new file mode 100644 index 0000000..de59eb1 --- /dev/null +++ b/kernel/seppl.c @@ -0,0 +1,429 @@ +/* $Id: newmail.c 31 2003-10-22 22:59:07Z lennart $ */ + +/*** + This file is part of seppl + + seppl 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 + (at your option) any later version. + + seppl is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with seppl; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA +***/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "seppl.h" + +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif +#ifdef MODULE_DESCRIPTION +MODULE_DESCRIPTION ("SEPPL Key Manager"); +#endif +#ifdef MODULE_AUTHOR +MODULE_AUTHOR("Lennart Poettering <"PACKAGE_BUGREPORT">"); +#endif + +static struct seppl_key *keyring = NULL; +static spinlock_t keyring_lock = SPIN_LOCK_UNLOCKED; + +#define PROC_FILE_NAME "seppl_keyring" +static struct proc_dir_entry* proc_file = NULL; + + +struct cipher_info { + char *name; + int bits; +}; + +#define CIPHER_DICT_MAX 2 + +static const struct cipher_info cipher_dict[CIPHER_DICT_MAX] = { + { "aes-cbc", 128 }, + { "aes-cbc", 192 } +}; + +const struct cipher_info *seppl_find_cipher(u8 id) { + if (id < CIPHER_DICT_MAX) + return &cipher_dict[id]; + + return NULL; +} + +struct seppl_key* seppl_find_key(u8 algorithm, const char *name, int r) { + struct seppl_key *key = NULL, *l; + + for (l = keyring; l; l = l->next) + if (l->algorithm == algorithm && strncmp(l->name, name, sizeof(l->name)) == 0) + if (!r || atomic_read(&l->ready)) { + key = l; + break; + } + + return key; +} + +struct seppl_key* seppl_claim_key(u8 algorithm, const char *name) { + struct seppl_key *key = NULL; + + spin_lock_bh(&keyring_lock); // FIXME: BH? + + if ((key = seppl_find_key(algorithm, name, 1))) { + atomic_inc(&key->usage); + MOD_INC_USE_COUNT; + } + + spin_unlock_bh(&keyring_lock); + + return key; +} + +void seppl_release_key(struct seppl_key* key) { + atomic_dec(&key->usage); + MOD_DEC_USE_COUNT; +} + +// not spinlocked! +static void seppl_next_iv(struct seppl_key *key) { + unsigned int i, m = key->ivsize; + + for (i = 0; i < m ; i++) { + key->iv[i]++; + if (key->iv[i] != 0) break; + } +} + +void seppl_copy_iv(struct seppl_key *key, u8* iv) { + spin_lock_bh(&key->iv_spinlock); // FIXME: BH? + + memcpy(iv, key->iv, key->ivsize); + seppl_next_iv(key); + + spin_unlock_bh(&key->iv_spinlock); +} + +int seppl_add_key(u8 algorithm, const char *name, const u8 *key_data) { + struct seppl_key* key = NULL; + int r = -EINVAL; + int locked = 1; + + spin_lock(&keyring_lock); + + if ((key = seppl_find_key(algorithm, name, 0))) { + + if (!atomic_read(&key->ready)) { + printk(KERN_ERR "SEPPL: Tried to replace incomplete key.\n"); + goto finish; + } + + memcpy(key->key, key_data, key->keysize); + if (crypto_cipher_setkey(key->tfm, key->key, key->keysize)) { + printk(KERN_ERR "SEPPL: Failed to set cipher key.\n"); + goto finish; + } + + printk(KERN_INFO "SEPPL: Replaced key sucessfully.\n"); + + r = 0; + goto finish; + } else { + const struct cipher_info* cinfo; + + if (!(cinfo = seppl_find_cipher(algorithm))) { + printk(KERN_ERR "SEPPL: Unknown cipher\n"); + goto finish; + } + + if(!(key = kmalloc(sizeof(struct seppl_key), GFP_KERNEL))) { + r = -ENOMEM; + printk(KERN_ERR "SEPPL: kmalloc() failed\n"); + goto finish; + } + + key->algorithm = algorithm; + memset(key->name, 0, 7); + strncpy(key->name, name, 7); + atomic_set(&key->ready, 0); + key->next = keyring; + keyring = key; + + spin_unlock(&keyring_lock); + locked = 0; + + key->key = key->iv = NULL; + key->tfm = NULL; + + atomic_set(&key->usage, 0); + spin_lock_init(&key->iv_spinlock); + + if (!(key->tfm = crypto_alloc_tfm("aes", CRYPTO_TFM_MODE_CBC))) { + printk(KERN_ERR "SEPPL: Failed to load cipher.\n"); + goto cleanup; + } + + /* Fill in key */ + if (!(key->key = kmalloc(key->keysize = cinfo->bits/8, GFP_KERNEL))) { + r = -ENOMEM; + printk(KERN_ERR "SEPPL: kmalloc() failed #2\n"); + goto cleanup; + } + memcpy(key->key, key_data, key->keysize); + + if (crypto_cipher_setkey(key->tfm, key->key, key->keysize)) { + printk(KERN_ERR "SEPPL: Failed to set cipher key.\n"); + goto cleanup; + } + + /* Fill in iv */ + if (!(key->iv = kmalloc(key->ivsize = crypto_tfm_alg_ivsize(key->tfm), GFP_KERNEL))) { + r = -ENOMEM; + printk(KERN_ERR "SEPPL: kmalloc() failed #3\n"); + goto cleanup; + } + get_random_bytes(key->iv, key->ivsize); + + key->blocksize = crypto_tfm_alg_blocksize(key->tfm); + + proc_file->size += 8 + key->keysize; + atomic_set(&key->ready, 1); + + printk(KERN_INFO "SEPPL: Added key sucessfully.\n"); + + r = 0; + goto finish; + } + +cleanup: + + if (key) { + struct seppl_key *i; + + spin_lock(&keyring_lock); + + if (keyring == key) + keyring = key->next; + else { + for (i = keyring; i; i = i->next) { + if (i->next == key) { + i->next = key->next; + break; + } + } + } + + spin_unlock(&keyring_lock); + + if (key->tfm) + crypto_free_tfm(key->tfm); + + if (key->key) + kfree(key->key); + + if (key->iv) + kfree(key->key); + + kfree(key); + } + +finish: + + if (locked) + spin_unlock(&keyring_lock); + + return r; +} + +void seppl_clear_keyring(void) { + struct seppl_key *key, *prev; + + printk(KERN_INFO "SEPPL: Clearing keyring\n"); + + spin_lock(&keyring_lock); + + prev = NULL; + key = keyring; + while (key) { + if (atomic_read(&key->ready) && !atomic_read(&key->usage)) { + struct seppl_key *k; + + atomic_set(&key->ready, 0); + + proc_file->size -= 8 + key->keysize; + + if (prev) + prev->next = key->next; + else + keyring = key->next; + + crypto_free_tfm(key->tfm); + kfree(key->key); + kfree(key->iv); + + k = key; + key = key->next; + kfree(k); + + continue; + } + + prev = key; + key = key->next; + } + + spin_unlock(&keyring_lock); +} + +#ifndef MIN +#define MIN(a,b) ((a)>(b)?(b):(a)) +#endif + +static int seppl_proc_read_func(char* page, char** start, off_t off, int count, int* eof, void* data) { + struct seppl_key *key; + char *e = page; + int d = 0; + + MOD_INC_USE_COUNT; + spin_lock(&keyring_lock); + + for (key = keyring; key; key = key->next) { + if (count <= 0) break; + + *e = key->algorithm; + e ++; count--; + + if (count <= 0) break; + + memcpy(e, key->name, d = MIN(7, count)); + e += d; count -= d; + + if (count <= 0) break; + + memcpy(e, key->key, d = MIN(key->keysize, count)); + e += d; count -= d; + + if (count <= 0) break; + + if (key->next == 0) + if (eof) + *eof = 1; + } + + spin_unlock(&keyring_lock); + MOD_DEC_USE_COUNT; + + return e-page; +} + + +static int seppl_proc_write_func(struct file* file, const char* buffer, unsigned long count, void* data) { + int r = -EINVAL; + u8* buf = NULL; + MOD_INC_USE_COUNT; + + count = count > 10*1024 ? 10*1024 : count; + + if (!(buf = kmalloc(count, GFP_ATOMIC))) { + r = -ENOMEM; + goto finish; + } + + if (copy_from_user(buf, buffer, count)) + goto finish; + + if (strcmp((char*) buf, "clear\n") == 0) { + seppl_clear_keyring(); + r = strlen(buf); + } else { + unsigned long n = count; + u8* p = buf; + + while (n >= 8) { + const struct cipher_info* ci = seppl_find_cipher(*p); + int l, t; + + if (!ci) { + printk(KERN_ERR "SEPPL: Unknown cipher\n"); + goto finish; + } + + l = 8+ci->bits/8; + + if (n < l) { + printk(KERN_ERR "SEPPL: Key data too short\n"); + goto finish; + } + + if ((t = seppl_add_key(*p, p+1, p+8)) < 0) { + r = t; + goto finish; + } + + p += l; + n -= l; + } + + if (n) { + printk(KERN_ERR "SEPPL: Data too short (%li)\n", n); + goto finish; + } + + r = (int) count; + } + +finish: + + if (buf) + kfree(buf); + + MOD_DEC_USE_COUNT; + return r; +} + +static int __init init(void) { + if (!(proc_file = create_proc_entry(PROC_FILE_NAME, 0600, proc_net))) + return -ENOMEM; + + proc_file->read_proc = seppl_proc_read_func; + proc_file->write_proc = seppl_proc_write_func; + proc_file->owner = THIS_MODULE; + proc_file->size = 0; + + printk("SEPPL: Loaded.\n"); + + return 0; +} + +static void __exit fini(void) { + seppl_clear_keyring(); + + if (keyring) + printk("SEPPL: Something wicked happened.\n"); + + remove_proc_entry(PROC_FILE_NAME, proc_net); + + printk("SEPPL: Unloaded.\n"); +} + +module_init(init); +module_exit(fini); + +EXPORT_SYMBOL(seppl_copy_iv); +EXPORT_SYMBOL(seppl_claim_key); +EXPORT_SYMBOL(seppl_release_key); + diff --git a/kernel/seppl.h b/kernel/seppl.h new file mode 100644 index 0000000..edc0d29 --- /dev/null +++ b/kernel/seppl.h @@ -0,0 +1,60 @@ +#ifndef _SEPPL_MODULE_H +#define _SEPPL_MODULE_H + +/* $Id: newmail.c 31 2003-10-22 22:59:07Z lennart $ */ + +/*** + This file is part of seppl + + seppl 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 + (at your option) any later version. + + seppl is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with seppl; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA +***/ + +#include +#include + +#if 0 +#define DEBUGP printk +#else +#define DEBUGP(format, args...) +#endif + +#include "seppl_protocol.h" + +struct seppl_key { + u8 algorithm; + char name[7]; + atomic_t ready; + atomic_t usage; + + struct crypto_tfm *tfm; + spinlock_t iv_spinlock; + u8 *iv; + u8 *key; + + unsigned int ivsize; + unsigned int keysize; + unsigned int blocksize; + + struct seppl_key *next; +}; + +struct seppl_key* seppl_claim_key(u8 algorithm, const char *name); +void seppl_release_key(struct seppl_key *key); +void seppl_copy_iv(struct seppl_key *key, u8* iv); +void seppl_clean_keys(void); +int seppl_add_key(u8 algorithm, const char *name, const u8* key_data); + +#endif diff --git a/kernel/seppl_protocol.h b/kernel/seppl_protocol.h new file mode 100644 index 0000000..08d4fa6 --- /dev/null +++ b/kernel/seppl_protocol.h @@ -0,0 +1,27 @@ +#ifndef _SEPPL_H +#define _SEPPL_H + +#define SEPPL_PROTOCOL 177 + +// Packet layout: +// 1. IP-Header PLAIN +// 2. Uncrypted header PLAIN +// 3. iv PLAIN +// 4. Crypted header CRYPTED +// 5. Payload (with TCP/UDP/...-Header) CRYPTED +// 6. Padding CRYPTED + +struct seppl_uncrypt_hdr { + uint8_t algorithm; + char key_name[7]; +} __attribute__((packed)) uncrypt_hdr; + +struct seppl_crypt_hdr{ + uint8_t ident; // 0x00 + uint8_t saved_protocol; + uint16_t saved_tot_len; + uint16_t saved_frag_off; +} __attribute__((packed)) crypt_hdr; + + +#endif diff --git a/kernel/test.sh b/kernel/test.sh new file mode 100755 index 0000000..fc41522 --- /dev/null +++ b/kernel/test.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +# $Id: Makefile.am 40 2003-10-27 18:32:45Z lennart $ +# +# This file is part of seppl. +# +# seppl 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 +# (at your option) any later version. +# +# seppl is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with seppl; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + +dmesg -n 7 + +iptables -t mangle -F POSTROUTING +iptables -t mangle -F PREROUTING + +sync + +make unload +sleep 2 +make load + +../utils/seppl-ls -f /etc/seppl/ring2.keys > /proc/net/seppl_keyring +../utils/seppl-ls + +iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -d 10.0.0.0/8 -j TCPMSS --set-mss $((1500-40-8-6-16)) +iptables -t mangle -A POSTROUTING -d 10.0.0.0/8 -j CRYPT --key `hostname` +iptables -t mangle -A PREROUTING -d 10.0.0.0/8 -j DECRYPT + +iptables -t mangle -L diff --git a/libs/Makefile.am b/libs/Makefile.am new file mode 100644 index 0000000..28de14f --- /dev/null +++ b/libs/Makefile.am @@ -0,0 +1,28 @@ +# $Id: Makefile.am 40 2003-10-27 18:32:45Z lennart $ +# +# This file is part of seppl. +# +# seppl 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 +# (at your option) any later version. +# +# seppl is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with seppl; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + +AM_CPPFLAGS=-I../kernel +iptlibdir = $(LIB_IPTABLES_DIR) + +iptlib_LTLIBRARIES = libipt_CRYPT.la libipt_DECRYPT.la + +libipt_CRYPT_la_SOURCES = libipt_CRYPT.c +libipt_CRYPT_la_LDFLAGS = -Wc,-nostartfiles -module + +libipt_DECRYPT_la_SOURCES = libipt_DECRYPT.c +libipt_DECRYPT_la_LDFLAGS = -Wc,-nostartfiles -module diff --git a/libs/libipt_CRYPT.c b/libs/libipt_CRYPT.c new file mode 100644 index 0000000..7e171f3 --- /dev/null +++ b/libs/libipt_CRYPT.c @@ -0,0 +1,114 @@ +/* $Id: newmail.c 31 2003-10-22 22:59:07Z lennart $ */ + +/*** + This file is part of seppl + + seppl 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 + (at your option) any later version. + + seppl is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with seppl; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA +***/ + +#include +#include +#include +#include + +#include +#include + +#include "ipt_CRYPT.h" + + +/* Function which prints out usage message. */ +static void help(void) { + printf("CRYPT options:\n" + " --algorithm algo Select algorithm\n" + " --key key Select key\n"); +} + +static struct option opts[] = { + { "algorithm", 1, 0, 'a' }, + { "key", 1, 0, 'k' }, + { 0 } +}; + +static void init(struct ipt_entry_target *t, unsigned int *nfcache) { + struct ipt_crypt_info *crypt = (struct ipt_crypt_info *) t->data; + + memset(crypt, 0, sizeof(struct ipt_crypt_info)); + strncpy(crypt->name, "def", 7); + + *nfcache |= NFC_UNKNOWN; +} + +static int parse(int c, char **argv, int invert, unsigned int *flags, const struct ipt_entry *entry, struct ipt_entry_target **target) { + struct ipt_crypt_info *crypt = (struct ipt_crypt_info *)(*target)->data; + + switch(c) { + case 'a': + crypt->algorithm = atoi(optarg); + return 1; + + case 'k': + strncpy(crypt->name, optarg, 7); + return 1; + + } + + return 0; +} + +static void final_check(unsigned int flags) { +} + +static void print(const struct ipt_ip *ip, const struct ipt_entry_target *target, int numeric) { + const struct ipt_crypt_info *crypt = (const struct ipt_crypt_info *)target->data; + char txt[8]; + + strncpy(txt, crypt->name, 7); + txt[7] = 0; + + printf("key: %s algo: %i\n", txt, crypt->algorithm); +} + +static void save(const struct ipt_ip *ip, const struct ipt_entry_target *target) { + const struct ipt_crypt_info *crypt = (const struct ipt_crypt_info *)target->data; + char txt[8]; + + strncpy(txt, crypt->name, 7); + txt[7] = 0; + + printf("--algorithm %i ", crypt->algorithm); + printf("--key '%s'", txt); + +} + +static struct iptables_target crypt = { + NULL, + "CRYPT", + "1.2.8", + IPT_ALIGN(sizeof(struct ipt_crypt_info)), + IPT_ALIGN(sizeof(struct ipt_crypt_info)), + &help, + &init, + &parse, + &final_check, + &print, + &save, + opts +}; + +void _init(void) { + register_target(&crypt); +} diff --git a/libs/libipt_DECRYPT.c b/libs/libipt_DECRYPT.c new file mode 100644 index 0000000..a9a5fc9 --- /dev/null +++ b/libs/libipt_DECRYPT.c @@ -0,0 +1,75 @@ +/* $Id: newmail.c 31 2003-10-22 22:59:07Z lennart $ */ + +/*** + This file is part of seppl + + seppl 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 + (at your option) any later version. + + seppl is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with seppl; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA +***/ + +#include +#include +#include +#include +#include +#include + +#include "ipt_DECRYPT.h" + + +/* Function which prints out usage message. */ +static void help(void) { + printf("DECRYPT options: none"); +} + +static struct option opts[] = { + { 0 } +}; + +static void init(struct ipt_entry_target *t, unsigned int *nfcache) { + *nfcache |= NFC_UNKNOWN; +} + +static int parse(int c, char **argv, int invert, unsigned int *flags, const struct ipt_entry *entry, struct ipt_entry_target **target) { + return 0; +} + +static void final_check(unsigned int flags) { +} + +static void print(const struct ipt_ip *ip, const struct ipt_entry_target *target, int numeric) { +} + +static void save(const struct ipt_ip *ip, const struct ipt_entry_target *target) { +} + +static struct iptables_target decrypt = { + NULL, + "DECRYPT", + "1.2.8", + IPT_ALIGN(sizeof(struct ipt_decrypt_info)), + IPT_ALIGN(sizeof(struct ipt_decrypt_info)), + &help, + &init, + &parse, + &final_check, + &print, + &save, + opts +}; + +void _init(void) { + register_target(&decrypt); +} diff --git a/utils/Makefile.am b/utils/Makefile.am new file mode 100644 index 0000000..49726f1 --- /dev/null +++ b/utils/Makefile.am @@ -0,0 +1,22 @@ +# $Id: Makefile.am 40 2003-10-27 18:32:45Z lennart $ +# +# This file is part of seppl. +# +# seppl 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 +# (at your option) any later version. +# +# seppl is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with seppl; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + +sbin_SCRIPTS=seppl-ls seppl-gen-key +python_PYTHON=seppl_common.py + +EXTRA_DIST=seppl-ls seppl-gen-key diff --git a/utils/seppl-gen-key b/utils/seppl-gen-key new file mode 100755 index 0000000..cc5817e --- /dev/null +++ b/utils/seppl-gen-key @@ -0,0 +1,110 @@ +#!/usr/bin/python + +# $Id: Makefile.am 40 2003-10-27 18:32:45Z lennart $ +# +# This file is part of seppl. +# +# seppl 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 +# (at your option) any later version. +# +# seppl is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with seppl; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + +from seppl_common import * +import getopt, sys + +def genkey(a, name, f): + + n, b = find_alg_by_number(a) + + if b == 0: + return -1 + + fd = open("/dev/random", "r+") + key = fd.read(b/8) + fd.close() + + if (len(key) != b/8): + sys.stderr("ERROR: Cannot generate randomness.\n") + return + + if f == dump_key_xml: + print "" + + f(a, name, key) + + if f == dump_key_xml: + print "" + + return 0 + +algorithm = "aes" +bits = 128 +name = "def" +func = dump_key_xml + +def usage(): + global algorithm, bits, name, func + x = { dump_key_xml : "disable", dump_key_bin : "enable" } + + print "%s:" % sys.argv[0] + print " -h --help Show this help" + print " -x --no-xml No xml output (%s)" % x[func] + print " -a --algorithm ALGORITHM Specify algorithm (%s)" % algorithm + print " -b --bits BITS Specify key length (%s)" % bits + print " -n --name NAME Specify key name (%s)" % name + + +def main(): + global algorithm, bits, name, func + + try: + opts, args = getopt.getopt(sys.argv[1:], "hxa:b:n:", ["help", "no-xml", "algorithm=", "bits=", "name="]) + except getopt.GetoptError: + usage() + sys.exit(1) + + u = 0; + + for o, a in opts: + if o in ("-h", "--help"): + u = 1 + + if o in ("-x", "--no-xml"): + func = dump_key_bin + + if o in ("-a", "--algorithm"): + algorithm = a + + if o in ("-b", "--bits"): + bits = int(a) + + if o in ("-n", "--name"): + name = a[:7] + + if u: + usage() + sys.exit(0) + + + a = find_alg_by_name(algorithm, bits) + + if a == -1: + sys.stderr.write("ERROR: Cipher not available\n") + sys.exit(2) + + genkey(a, name, func) + +if __name__ == "__main__": + main() + + + diff --git a/utils/seppl-ls b/utils/seppl-ls new file mode 100755 index 0000000..b05b949 --- /dev/null +++ b/utils/seppl-ls @@ -0,0 +1,198 @@ +#!/usr/bin/python + +# $Id: Makefile.am 40 2003-10-27 18:32:45Z lennart $ +# +# This file is part of seppl. +# +# seppl 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 +# (at your option) any later version. +# +# seppl is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with seppl; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + +import getopt, sys + +from seppl_common import * +import xml.sax, xml.sax.handler + +name = None +algorithm = None +bits = 0 +reverse = 0 +PROC_FILE_NAME = "/proc/net/seppl_keyring" +file = None + +class KeyContentHandler(xml.sax.handler.ContentHandler): + + last = None + + def startElement(self, name, attrs): + self.last = name + + if name != "key": + return + + self.name = "" + self.algorithm = "" + self.bits = "" + self.data = "" + + def endElement(self, n): + global name, algorithm, bits + self.last = None + + if n != "key": + return + + if self.name == "": + self.name = "def" + + if self.algorithm == "": + self.algorithm = "aes" + + if self.bits == "": + self.bits = 128 + else: + self.bits = int(self.bits) + + a = find_alg_by_name(self.algorithm, self.bits) + if a == -1: + raise xml.sax.SAXNotRecognizedException("Cipher not known") + + key = parse_key(self.data) + if key is None or len(key) != self.bits/8: + raise xml.sax.SAXNotRecognizedException("Could not parse key data.") + + if (name is None or name == self.name) and (algorithm is None or algorithm == self.algorithm) and (bits == 0 or bits == self.bits): + dump_key_bin(a, self.name, key) + + def characters(self, content): + content = content.strip() + + if len(content) == 0: + return + + if self.last == "name": + self.name += content + return + if self.last == "algorithm": + self.algorithm += content + return + if self.last == "bits": + self.bits += content + return + if self.last == "data": + self.data += content + return + + raise xml.sax.SAXNotRecognizedException("Malformed XML structure |%s|%s|" % (self.last, content)) + +def usage(): + global name, algorithm, bits, reverse, file + + print "%s:" % sys.argv[0] + print " -h --help Show this help" + print " -r --reverse Convert XML to binary, instead of the other way round (%s)" % { 0 : "disabled", 1 : "enabled" }[reverse] + print " -a --algorithm ALGORITHM Show only keys with algorithm (%s)" % algorithm + print " -b --bits BITS Show only keys with bit length (%s)" % bits + print " -n --name NAME Show only keys with name (%s)" % name + print " -f --file FILE Specify file (- for STDIN) (%s)" % file + pass + +def main(): + global name, algorithm, bits, reverse, file + + try: + opts, args = getopt.getopt(sys.argv[1:], "hn:a:b:rf:", ["help", "name=", "algorithm=", "bits=", "reverse", "file"]) + except getopt.GetoptError: + usage() + sys.exit(2) + + u = 0 + + for o, a in opts: + if o in ("-h", "--help"): + u = 1 + + if o in ("-n", "--name"): + name = a[:7] + + if o in ("-a", "--algorithm"): + algorithm = a + + if o in ("-b", "--bits"): + bits = int(a) + + if o in ("-r", "--reverse"): + reverse = 1 + + if o in ("-f", "--file"): + file = a + + if file is None: + if reverse: + file = "-" + else: + file = PROC_FILE_NAME + + if u: + usage() + sys.exit(0) + + + if file == "-": + buf = sys.stdin.read(); + else: + try: + fd = open(file, "r+") + buf = fd.read(); + fd.close() + except IOError, e: + sys.stderr.write("Could not open proc-file (%s).\n" % str(e)) + sys.exit(2) + + + if len(buf) == 0: + sys.exit(0) + + if buf[0] == '<': + reverse = 1 + + if not reverse: + + print "" + while len(buf) >= 8: + a, _name = unpack("B7s", buf[:8]) + n, b = find_alg_by_number(a) + + if (b == 0): + sys.stderr.write("ERROR: Unknown cipher. Please update.\n") + break + + _name = _name.replace("\000", "") + + if (name is None or name == _name) and (algorithm is None or algorithm == n) and (bits == 0 or b == bits): + dump_key_xml(a, _name, buf[8:b/8+8]) + + buf = buf[8+b/8:] + print "" + else: + try: + xml.sax.parseString(buf, KeyContentHandler()) + except xml.sax.SAXException, e: + sys.stderr.write("Parse error (%s)\n" %str(e)) + + +if __name__ == "__main__": + main() + + + diff --git a/utils/seppl_common.py b/utils/seppl_common.py new file mode 100644 index 0000000..c8fe5ca --- /dev/null +++ b/utils/seppl_common.py @@ -0,0 +1,105 @@ +#!/usr/bin/perl + +# $Id: Makefile.am 40 2003-10-27 18:32:45Z lennart $ +# +# This file is part of seppl. +# +# seppl 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 +# (at your option) any later version. +# +# seppl is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with seppl; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + +from struct import * +import re, string, sys + +algs = { 0 : ('aes', 128), 1 : ('aes', 192) } + +def find_alg_by_number(a): + global algs + + if algs.has_key(a): + return algs[a]; + else: + return ('unknown', 0) + +def find_alg_by_name(n, b): + global algs + + for i in algs.keys(): + if algs[i][0] == n and algs[i][1] == b: + return i + + return -1 + +def strhex(s): + r = "" + for i in range(len(s)): + (b,) = unpack("B", s[i]) + r = "%s:%02x" % (r, b) + + return r[1:] + +def dump_key_xml(a, name, key): + alg, bits = find_alg_by_number(a) + + if bits == 0: + sys.stderr.write("ERROR: Algorithm not found\n") + return -1 + + print "" + print " %s" % name + print " %s" % alg + print " %u" % bits + print " %s" % strhex(key) + print "" + + return 0 + +def dump_key_bin(a, name, key): + alg, bits = find_alg_by_number(a) + + if bits == 0: + sys.stderr.write("ERROR: Algorithm not found\n") + return -1 + + if len(key) != bits/8: + sys.stderr.write("ERROR: Key has wrong size\n") + return -1 + + name = name.encode("iso8859-1", 'ignore') + + sys.stdout.write(pack("B7s", a, name[:7])) + sys.stdout.write(key) + sys.stdout.flush() + +def parse_key(data): + + k = "" + + r = re.compile("^([0-9A-Fa-f][0-9A-Fa-f])") + + while len(data) > 0: + m = r.match(data+":") + + if m == None: + return None + + k += pack("B", string.atoi(m.group(0), 16)) + + data = data[3:] + + return k + + + + + -- cgit