diff options
Diffstat (limited to 'src')
692 files changed, 33578 insertions, 6661 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 38363d4f7..9608a3a13 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -69,7 +69,7 @@ if USE_STROKE endif if USE_UPDOWN - SUBDIRS += _updown _updown_espmark + SUBDIRS += _updown endif if USE_SCEPCLIENT diff --git a/src/Makefile.in b/src/Makefile.in index 2dd046042..7596e7e55 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -94,7 +94,7 @@ host_triplet = @host@ @USE_SYSTEMD_TRUE@am__append_15 = charon-systemd @USE_NM_TRUE@am__append_16 = charon-nm @USE_STROKE_TRUE@am__append_17 = stroke -@USE_UPDOWN_TRUE@am__append_18 = _updown _updown_espmark +@USE_UPDOWN_TRUE@am__append_18 = _updown @USE_SCEPCLIENT_TRUE@am__append_19 = scepclient @USE_PKI_TRUE@am__append_20 = pki @USE_SWANCTL_TRUE@am__append_21 = swanctl @@ -187,9 +187,9 @@ CTAGS = ctags DIST_SUBDIRS = . include libstrongswan libhydra libipsec libsimaka \ libtls libradius libtncif libtnccs libpttls libimcv libcharon \ starter ipsec _copyright charon charon-systemd charon-nm \ - stroke _updown _updown_espmark scepclient pki swanctl conftest \ - dumm libfast manager medsrv pool charon-tkm charon-cmd \ - charon-svc pt-tls-client checksum aikgen + stroke _updown scepclient pki swanctl conftest dumm libfast \ + manager medsrv pool charon-tkm charon-cmd charon-svc \ + pt-tls-client checksum aikgen DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -241,6 +241,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -301,10 +302,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -378,6 +381,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/_copyright/Makefile.in b/src/_copyright/Makefile.in index a17bbcc1a..2a4838c9a 100644 --- a/src/_copyright/Makefile.in +++ b/src/_copyright/Makefile.in @@ -195,6 +195,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -255,10 +256,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -332,6 +335,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/_updown/Makefile.am b/src/_updown/Makefile.am index b6a81f547..32fa0423a 100644 --- a/src/_updown/Makefile.am +++ b/src/_updown/Makefile.am @@ -1,6 +1,5 @@ ipsec_SCRIPTS = _updown CLEANFILES = _updown -dist_man8_MANS = _updown.8 EXTRA_DIST = _updown.in _updown : _updown.in diff --git a/src/_updown/Makefile.in b/src/_updown/Makefile.in index a215a2548..fe31dff64 100644 --- a/src/_updown/Makefile.in +++ b/src/_updown/Makefile.in @@ -79,8 +79,7 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = src/_updown -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(dist_man8_MANS) +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ $(top_srcdir)/m4/config/ltoptions.m4 \ @@ -125,7 +124,7 @@ am__uninstall_files_from_dir = { \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } -am__installdirs = "$(DESTDIR)$(ipsecdir)" "$(DESTDIR)$(man8dir)" +am__installdirs = "$(DESTDIR)$(ipsecdir)" SCRIPTS = $(ipsec_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) @@ -146,9 +145,6 @@ am__can_run_installinfo = \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac -man8dir = $(mandir)/man8 -NROFF = nroff -MANS = $(dist_man8_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ @@ -176,6 +172,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -236,10 +233,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -313,6 +312,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ @@ -373,7 +374,6 @@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ ipsec_SCRIPTS = _updown CLEANFILES = _updown -dist_man8_MANS = _updown.8 EXTRA_DIST = _updown.in all: all-am @@ -449,47 +449,6 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs -install-man8: $(dist_man8_MANS) - @$(NORMAL_INSTALL) - @list1='$(dist_man8_MANS)'; \ - list2=''; \ - test -n "$(man8dir)" \ - && test -n "`echo $$list1$$list2`" \ - || exit 0; \ - echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \ - { for i in $$list1; do echo "$$i"; done; \ - if test -n "$$list2"; then \ - for i in $$list2; do echo "$$i"; done \ - | sed -n '/\.8[a-z]*$$/p'; \ - fi; \ - } | while read p; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; echo "$$p"; \ - done | \ - sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ - sed 'N;N;s,\n, ,g' | { \ - list=; while read file base inst; do \ - if test "$$base" = "$$inst"; then list="$$list $$file"; else \ - echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ - $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ - fi; \ - done; \ - for i in $$list; do echo "$$i"; done | $(am__base_list) | \ - while read files; do \ - test -z "$$files" || { \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ - done; } - -uninstall-man8: - @$(NORMAL_UNINSTALL) - @list='$(dist_man8_MANS)'; test -n "$(man8dir)" || exit 0; \ - files=`{ for i in $$list; do echo "$$i"; done; \ - } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: @@ -529,9 +488,9 @@ distdir: $(DISTFILES) done check-am: all-am check: check-am -all-am: Makefile $(SCRIPTS) $(MANS) +all-am: Makefile $(SCRIPTS) installdirs: - for dir in "$(DESTDIR)$(ipsecdir)" "$(DESTDIR)$(man8dir)"; do \ + for dir in "$(DESTDIR)$(ipsecdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -585,7 +544,7 @@ info: info-am info-am: -install-data-am: install-ipsecSCRIPTS install-man +install-data-am: install-ipsecSCRIPTS install-dvi: install-dvi-am @@ -601,7 +560,7 @@ install-info: install-info-am install-info-am: -install-man: install-man8 +install-man: install-pdf: install-pdf-am @@ -629,9 +588,7 @@ ps: ps-am ps-am: -uninstall-am: uninstall-ipsecSCRIPTS uninstall-man - -uninstall-man: uninstall-man8 +uninstall-am: uninstall-ipsecSCRIPTS .MAKE: install-am install-strip @@ -641,13 +598,12 @@ uninstall-man: uninstall-man8 install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am \ - install-ipsecSCRIPTS install-man install-man8 install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ + install-ipsecSCRIPTS install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags-am uninstall \ - uninstall-am uninstall-ipsecSCRIPTS uninstall-man \ - uninstall-man8 + uninstall-am uninstall-ipsecSCRIPTS _updown : _updown.in diff --git a/src/_updown/_updown.8 b/src/_updown/_updown.8 deleted file mode 100644 index 8c88e5fb8..000000000 --- a/src/_updown/_updown.8 +++ /dev/null @@ -1,16 +0,0 @@ -.TH _UPDOWN 8 "27 Apr 2006" -.SH NAME -ipsec _updown \- route and firewall manipulation script -.SH SYNOPSIS -.I _updown -is invoked by pluto when it has brought up a new connection. This script -is used to insert the appropriate routing entries for IPsec operation. -It can also be used to insert and delete dynamic iptables firewall rules. -The interface to the script is documented in the pluto man page. -.SH "SEE ALSO" -ipsec(8), ipsec_pluto(8). -.SH HISTORY -Man page written for the Linux FreeS/WAN project <http://www.freeswan.org/> -by Michael Richardson. Original program written by Henry Spencer. Extended -for the Linux strongSwan project <http://www.strongswan.org/> by Andreas -Steffen. diff --git a/src/_updown/_updown.in b/src/_updown/_updown.in index 532bd2437..4090fe074 100644 --- a/src/_updown/_updown.in +++ b/src/_updown/_updown.in @@ -1,5 +1,5 @@ -#! /bin/sh -# iproute2 version, default updown script +#!/bin/sh +# default updown script # # Copyright (C) 2003-2004 Nigel Meteringham # Copyright (C) 2003-2004 Tuomo Soini @@ -22,8 +22,6 @@ # that, and use the (left/right)updown parameters in ipsec.conf to make # strongSwan use yours instead of this default one. -# things that this script gets (from ipsec_pluto(8) man page) -# # PLUTO_VERSION # indicates what version of this interface is being # used. This document describes version 1.1. This @@ -128,7 +126,7 @@ PATH="/sbin:/bin:/usr/sbin:/usr/bin:@sbindir@" export PATH -# uncomment to log VPN connections +# comment to disable logging VPN connections to syslog VPN_LOGGING=1 # # tag put in front of each log entry: @@ -142,21 +140,11 @@ FAC_PRIO=local0.notice # # local0.notice -/var/log/vpn -# in order to use source IP routing the Linux kernel options -# CONFIG_IP_ADVANCED_ROUTER and CONFIG_IP_MULTIPLE_TABLES -# must be enabled -# -# special routing table for sourceip routes -SOURCEIP_ROUTING_TABLE=@routing_table@ -# -# priority of the sourceip routing table -SOURCEIP_ROUTING_TABLE_PRIO=@routing_table_prio@ - # check interface version case "$PLUTO_VERSION" in -1.[0|1]) # Older Pluto?!? Play it safe, script may be using new features. +1.[0|1]) # Older release?!? Play it safe, script may be using new features. echo "$0: obsolete interface version \`$PLUTO_VERSION'," >&2 - echo "$0: called by obsolete Pluto?" >&2 + echo "$0: called by obsolete release?" >&2 exit 2 ;; 1.*) ;; @@ -178,120 +166,9 @@ custom:*) # custom parameters (see above CAUTION comment) ;; esac -# utility functions for route manipulation -# Meddling with this stuff should not be necessary and requires great care. -uproute() { - doroute add - ip route flush cache -} -downroute() { - doroute delete - ip route flush cache -} - -addsource() { - st=0 - if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local - then - it="ip addr add ${PLUTO_MY_SOURCEIP%/*}/32 dev $PLUTO_INTERFACE" - oops="`eval $it 2>&1`" - st=$? - if test " $oops" = " " -a " $st" != " 0" - then - oops="silent error, exit status $st" - fi - if test " $oops" != " " -o " $st" != " 0" - then - echo "$0: addsource \`$it' failed ($oops)" >&2 - fi - fi - return $st -} - -doroute() { - st=0 - - if [ -z "$PLUTO_MY_SOURCEIP" ] - then - for dir in /etc/sysconfig /etc/conf.d; do - if [ -f "$dir/defaultsource" ] - then - . "$dir/defaultsource" - fi - done - - if [ -n "$DEFAULTSOURCE" ] - then - PLUTO_MY_SOURCEIP=$DEFAULTSOURCE - fi - fi - - if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ] - then - # leave because no route entry is required - return $st - fi - - parms1="$PLUTO_PEER_CLIENT" - - if [ -n "$PLUTO_NEXT_HOP" ] - then - parms2="via $PLUTO_NEXT_HOP" - else - parms2="via $PLUTO_PEER" - fi - parms2="$parms2 dev $PLUTO_INTERFACE" - - parms3= - if [ -n "$PLUTO_MY_SOURCEIP" ] - then - if test "$1" = "add" - then - addsource - if ! ip rule list | grep -q "lookup $SOURCEIP_ROUTING_TABLE" - then - ip rule add pref $SOURCEIP_ROUTING_TABLE_PRIO table $SOURCEIP_ROUTING_TABLE - fi - fi - parms3="$parms3 src ${PLUTO_MY_SOURCEIP%/*} table $SOURCEIP_ROUTING_TABLE" - fi - - case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in - "0.0.0.0/0.0.0.0") - # opportunistic encryption work around - # need to provide route that eclipses default, without - # replacing it. - it="ip route $1 0.0.0.0/1 $parms2 $parms3 && - ip route $1 128.0.0.0/1 $parms2 $parms3" - ;; - *) it="ip route $1 $parms1 $parms2 $parms3" - ;; - esac - oops="`eval $it 2>&1`" - st=$? - if test " $oops" = " " -a " $st" != " 0" - then - oops="silent error, exit status $st" - fi - if test " $oops" != " " -o " $st" != " 0" - then - echo "$0: doroute \`$it' failed ($oops)" >&2 - fi - return $st -} - -# in the presence of KLIPS and ipsecN interfaces do not use IPSEC_POLICY -if [ `echo "$PLUTO_INTERFACE" | grep "ipsec"` ] -then - KLIPS=1 - IPSEC_POLICY_IN="" - IPSEC_POLICY_OUT="" -else - KLIPS= - IPSEC_POLICY="-m policy --pol ipsec --proto $PLUTO_PROTO --reqid $PLUTO_REQID" - IPSEC_POLICY_IN="$IPSEC_POLICY --dir in" - IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out" -fi +IPSEC_POLICY="-m policy --pol ipsec --proto $PLUTO_PROTO --reqid $PLUTO_REQID" +IPSEC_POLICY_IN="$IPSEC_POLICY --dir in" +IPSEC_POLICY_OUT="$IPSEC_POLICY --dir out" # use protocol specific options to set ports case "$PLUTO_MY_PROTOCOL" in @@ -334,59 +211,7 @@ fi PLUTO_MY_ID=`printf "$PLUTO_MY_ID"` PLUTO_PEER_ID=`printf "$PLUTO_PEER_ID"` -# the big choice case "$PLUTO_VERB:$1" in -prepare-host:*|prepare-client:*) - if [ -z "$KLIPS" -a -z "$PLUTO_MY_SOURCEIP" ] - then - # exit because no route will be added, - # so that existing routes can stay - exit 0 - fi - - # delete possibly-existing route (preliminary to adding a route) - case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in - "0.0.0.0/0.0.0.0") - # need to provide route that eclipses default, without - # replacing it. - parms1="0.0.0.0/1" - parms2="128.0.0.0/1" - it="ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1" - oops="`ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1`" - ;; - *) - parms="$PLUTO_PEER_CLIENT" - it="ip route delete $parms 2>&1" - oops="`ip route delete $parms 2>&1`" - ;; - esac - status="$?" - if test " $oops" = " " -a " $status" != " 0" - then - oops="silent error, exit status $status" - fi - case "$oops" in - *'RTNETLINK answers: No such process'*) - # This is what route (currently -- not documented!) gives - # for "could not find such a route". - oops= - status=0 - ;; - esac - if test " $oops" != " " -o " $status" != " 0" - then - echo "$0: \`$it' failed ($oops)" >&2 - fi - exit $status - ;; -route-host:*|route-client:*) - # connection to me or my client subnet being routed - uproute - ;; -unroute-host:*|unroute-client:*) - # connection to me or my client subnet being unrouted - downroute - ;; up-host:) # connection to me coming up # If you are doing a custom version, firewall commands go here. @@ -567,16 +392,6 @@ down-client:iptables) # # IPv6 # -prepare-host-v6:*|prepare-client-v6:*) - ;; -route-host-v6:*|route-client-v6:*) - # connection to me or my client subnet being routed - #uproute_v6 - ;; -unroute-host-v6:*|unroute-client-v6:*) - # connection to me or my client subnet being unrouted - #downroute_v6 - ;; up-host-v6:) # connection to me coming up # If you are doing a custom version, firewall commands go here. diff --git a/src/_updown_espmark/Makefile.am b/src/_updown_espmark/Makefile.am deleted file mode 100644 index 456702690..000000000 --- a/src/_updown_espmark/Makefile.am +++ /dev/null @@ -1,2 +0,0 @@ -dist_ipsec_SCRIPTS = _updown_espmark -dist_man8_MANS = _updown_espmark.8 diff --git a/src/_updown_espmark/_updown_espmark b/src/_updown_espmark/_updown_espmark deleted file mode 100644 index 864a91708..000000000 --- a/src/_updown_espmark/_updown_espmark +++ /dev/null @@ -1,438 +0,0 @@ -#! /bin/sh -# iproute2 version, default updown script -# -# Copyright (C) 2003-2004 Nigel Meteringham -# Copyright (C) 2003-2004 Tuomo Soini -# Copyright (C) 2002-2004 Michael Richardson -# Copyright (C) 2005 Andreas Steffen <andreas.steffen@strongsec.com> -# -# This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. -# -# This program 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. - - - -# CAUTION: Installing a new version of strongSwan will install a new -# copy of this script, wiping out any custom changes you make. If -# you need changes, make a copy of this under another name, and customize -# that, and use the (left/right)updown parameters in ipsec.conf to make -# FreeS/WAN use yours instead of this default one. - -# things that this script gets (from ipsec_pluto(8) man page) -# -# -# PLUTO_VERSION -# indicates what version of this interface is being -# used. This document describes version 1.1. This -# is upwardly compatible with version 1.0. -# -# PLUTO_VERB -# specifies the name of the operation to be performed -# (prepare-host, prepare-client, up-host, up-client, -# down-host, or down-client). If the address family -# for security gateway to security gateway communica- -# tions is IPv6, then a suffix of -v6 is added to the -# verb. -# -# PLUTO_CONNECTION -# is the name of the connection for which we are -# routing. -# -# PLUTO_INTERFACE -# is the name of the ipsec interface to be used. -# -# PLUTO_ME -# is the IP address of our host. -# -# PLUTO_MY_ID -# is the ID of our host. -# -# PLUTO_MY_CLIENT -# is the IP address / count of our client subnet. If -# the client is just the host, this will be the -# host's own IP address / max (where max is 32 for -# IPv4 and 128 for IPv6). -# -# PLUTO_MY_SOURCEIP -# if non-empty, then the source address for the route will be -# set to this IP address. -# -# PLUTO_MY_PROTOCOL -# is the IP protocol that will be transported. -# -# PLUTO_MY_PORT -# is the UDP/TCP port to which the IPsec SA is -# restricted on our side. -# -# PLUTO_PEER -# is the IP address of our peer. -# -# PLUTO_PEER_ID -# is the ID of our peer. -# -# PLUTO_PEER_CLIENT -# is the IP address / count of the peer's client sub- -# net. If the client is just the peer, this will be -# the peer's own IP address / max (where max is 32 -# for IPv4 and 128 for IPv6). -# -# PLUTO_PEER_PROTOCOL -# is the IP protocol that will be transported. -# -# PLUTO_PEER_PORT -# is the UDP/TCP port to which the IPsec SA is -# restricted on the peer side. -# -# PLUTO_XAUTH_ID -# is an optional user ID employed by the XAUTH protocol -# -# PLUTO_MARK_IN -# is an optional XFRM mark set on the inbound IPsec SA -# -# PLUTO_MARK_OUT -# is an optional XFRM mark set on the outbound IPsec SA -# -# PLUTO_UDP_ENC -# contains the remote UDP port in the case of ESP_IN_UDP -# encapsulation -# - -# logging of VPN connections -# -# tag put in front of each log entry: -TAG=vpn -# -# syslog facility and priority used: -FAC_PRIO=local0.notice -# -# to create a special vpn logging file, put the following line into -# the syslog configuration file /etc/syslog.conf: -# -# local0.notice -/var/log/vpn -# - -# check interface version -case "$PLUTO_VERSION" in -1.[0]) # Older Pluto?!? Play it safe, script may be using new features. - echo "$0: obsolete interface version \`$PLUTO_VERSION'," >&2 - echo "$0: called by obsolete Pluto?" >&2 - exit 2 - ;; -1.*) ;; -*) echo "$0: unknown interface version \`$PLUTO_VERSION'" >&2 - exit 2 - ;; -esac - -# check parameter(s) -case "$1:$*" in -':') # no parameters - ;; -ipfwadm:ipfwadm) # due to (left/right)firewall; for default script only - ;; -custom:*) # custom parameters (see above CAUTION comment) - ;; -*) echo "$0: unknown parameters \`$*'" >&2 - exit 2 - ;; -esac - -# utility functions for route manipulation -# Meddling with this stuff should not be necessary and requires great care. -uproute() { - doroute add - ip route flush cache -} -downroute() { - doroute delete - ip route flush cache -} - -addsource() { - st=0 - if ! ip -o route get ${PLUTO_MY_SOURCEIP%/*} | grep -q ^local - then - it="ip addr add ${PLUTO_MY_SOURCEIP%/*}/32 dev $PLUTO_INTERFACE" - oops="`eval $it 2>&1`" - st=$? - if test " $oops" = " " -a " $st" != " 0" - then - oops="silent error, exit status $st" - fi - if test " $oops" != " " -o " $st" != " 0" - then - echo "$0: addsource \`$it' failed ($oops)" >&2 - fi - fi - return $st -} - -doroute() { - st=0 - parms="$PLUTO_PEER_CLIENT" - - parms2= - if [ -n "$PLUTO_NEXT_HOP" ] - then - parms2="via $PLUTO_NEXT_HOP" - fi - parms2="$parms2 dev $PLUTO_INTERFACE" - - if [ -z "$PLUTO_MY_SOURCEIP" ] - then - for dir in /etc/sysconfig /etc/conf.d; do - if [ -f "$dir/defaultsource" ] - then - . "$dir/defaultsource" - fi - done - - if [ -n "$DEFAULTSOURCE" ] - then - PLUTO_MY_SOURCEIP=$DEFAULTSOURCE - fi - fi - - parms3= - if test "$1" = "add" -a -n "$PLUTO_MY_SOURCEIP" - then - addsource - parms3="$parms3 src ${PLUTO_MY_SOURCEIP%/*}" - fi - - case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in - "0.0.0.0/0.0.0.0") - # opportunistic encryption work around - # need to provide route that eclipses default, without - # replacing it. - it="ip route $1 0.0.0.0/1 $parms2 $parms3 && - ip route $1 128.0.0.0/1 $parms2 $parms3" - ;; - *) it="ip route $1 $parms $parms2 $parms3" - ;; - esac - oops="`eval $it 2>&1`" - st=$? - if test " $oops" = " " -a " $st" != " 0" - then - oops="silent error, exit status $st" - fi - if test " $oops" != " " -o " $st" != " 0" - then - echo "$0: doroute \`$it' failed ($oops)" >&2 - fi - return $st -} - -# define ESP mark -ESP_MARK=50 - -# add the following static rule to the INPUT chain in the mangle table -# iptables -t mangle -A INPUT -p 50 -j MARK --set-mark 50 - -# NAT traversal via UDP encapsulation is supported with the rule -# iptables -t mangle -A INPUT -p udp --dport 4500 -j MARK --set-mark 50 - -# in the presence of KLIPS and ipsecN interfaces do not use ESP mark rules -if [ `echo "$PLUTO_INTERFACE" | grep "ipsec"` ] -then - CHECK_MARK="" -else - CHECK_MARK="-m mark --mark $ESP_MARK" -fi - -# are there port numbers? -if [ "$PLUTO_MY_PORT" != 0 ] -then - S_MY_PORT="--sport $PLUTO_MY_PORT" - D_MY_PORT="--dport $PLUTO_MY_PORT" -fi -if [ "$PLUTO_PEER_PORT" != 0 ] -then - S_PEER_PORT="--sport $PLUTO_PEER_PORT" - D_PEER_PORT="--dport $PLUTO_PEER_PORT" -fi - -# resolve octal escape sequences -PLUTO_MY_ID=`printf "$PLUTO_MY_ID"` -PLUTO_PEER_ID=`printf "$PLUTO_PEER_ID"` - -# the big choice -case "$PLUTO_VERB:$1" in -prepare-host:*|prepare-client:*) - # delete possibly-existing route (preliminary to adding a route) - case "$PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK" in - "0.0.0.0/0.0.0.0") - # need to provide route that eclipses default, without - # replacing it. - parms1="0.0.0.0/1" - parms2="128.0.0.0/1" - it="ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1" - oops="`ip route delete $parms1 2>&1 ; ip route delete $parms2 2>&1`" - ;; - *) - parms="$PLUTO_PEER_CLIENT" - it="ip route delete $parms 2>&1" - oops="`ip route delete $parms 2>&1`" - ;; - esac - status="$?" - if test " $oops" = " " -a " $status" != " 0" - then - oops="silent error, exit status $status" - fi - case "$oops" in - *'RTNETLINK answers: No such process'*) - # This is what route (currently -- not documented!) gives - # for "could not find such a route". - oops= - status=0 - ;; - esac - if test " $oops" != " " -o " $status" != " 0" - then - echo "$0: \`$it' failed ($oops)" >&2 - fi - exit $status - ;; -route-host:*|route-client:*) - # connection to me or my client subnet being routed - uproute - ;; -unroute-host:*|unroute-client:*) - # connection to me or my client subnet being unrouted - downroute - ;; -up-host:*) - # connection to me coming up - # If you are doing a custom version, firewall commands go here. - iptables -I INPUT 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \ - -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \ - -d $PLUTO_ME $D_MY_PORT $CHECK_MARK -j ACCEPT - iptables -I OUTPUT 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \ - -s $PLUTO_ME $S_MY_PORT \ - -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT - # - if [ "$PLUTO_PEER_CLIENT" = "$PLUTO_PEER/32" ] - then - logger -t $TAG -p $FAC_PRIO \ - "+ $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME" - else - logger -t $TAG -p $FAC_PRIO \ - "+ $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME" - fi - ;; -down-host:*) - # connection to me going down - # If you are doing a custom version, firewall commands go here. - # connection to me going down - # If you are doing a custom version, firewall commands go here. - iptables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \ - -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \ - -d $PLUTO_ME $D_MY_PORT $CHECK_MARK -j ACCEPT - iptables -D OUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \ - -s $PLUTO_ME $S_MY_PORT \ - -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT - # - if [ "$PLUTO_PEER_CLIENT" = "$PLUTO_PEER/32" ] - then - logger -t $TAG -p $FAC_PRIO -- \ - "- $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME" - else - logger -t $TAG -p $FAC_PRIO -- \ - "- $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME" - fi - ;; -up-client:) - # connection to my client subnet coming up - # If you are doing a custom version, firewall commands go here. - iptables -I FORWARD 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \ - -s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $S_MY_PORT \ - -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT - iptables -I FORWARD 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \ - -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \ - -d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $D_MY_PORT \ - $CHECK_MARK -j ACCEPT - # - if [ "$PLUTO_PEER_CLIENT" = "$PLUTO_PEER/32" ] - then - logger -t $TAG -p $FAC_PRIO \ - "+ $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT" - else - logger -t $TAG -p $FAC_PRIO \ - "+ $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT" - fi - ;; -down-client:) - # connection to my client subnet going down - # If you are doing a custom version, firewall commands go here. - iptables -D FORWARD -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \ - -s $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $S_MY_PORT \ - -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT - iptables -D FORWARD -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \ - -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \ - -d $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $D_MY_PORT \ - $CHECK_MARK -j ACCEPT - # - if [ "$PLUTO_PEER_CLIENT" = "$PLUTO_PEER/32" ] - then - logger -t $TAG -p $FAC_PRIO -- \ - "- $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT" - else - logger -t $TAG -p $FAC_PRIO -- \ - "- $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT" - fi - ;; -up-client:ipfwadm) - # connection to client subnet, with (left/right)firewall=yes, coming up - # This is used only by the default updown script, not by your custom - # ones, so do not mess with it; see CAUTION comment up at top. - ipfwadm -F -i accept -b -S $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK \ - -D $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK - ;; -down-client:ipfwadm) - # connection to client subnet, with (left/right)firewall=yes, going down - # This is used only by the default updown script, not by your custom - # ones, so do not mess with it; see CAUTION comment up at top. - ipfwadm -F -d accept -b -S $PLUTO_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK \ - -D $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK - ;; -# -# IPv6 -# -prepare-host-v6:*|prepare-client-v6:*) - ;; -route-host-v6:*|route-client-v6:*) - # connection to me or my client subnet being routed - #uproute_v6 - ;; -unroute-host-v6:*|unroute-client-v6:*) - # connection to me or my client subnet being unrouted - #downroute_v6 - ;; -up-host-v6:*) - # connection to me coming up - # If you are doing a custom version, firewall commands go here. - ;; -down-host-v6:*) - # connection to me going down - # If you are doing a custom version, firewall commands go here. - ;; -up-client-v6:) - # connection to my client subnet coming up - # If you are doing a custom version, firewall commands go here. - ;; -down-client-v6:) - # connection to my client subnet going down - # If you are doing a custom version, firewall commands go here. - ;; -*) echo "$0: unknown verb \`$PLUTO_VERB' or parameter \`$1'" >&2 - exit 1 - ;; -esac diff --git a/src/_updown_espmark/_updown_espmark.8 b/src/_updown_espmark/_updown_espmark.8 deleted file mode 100644 index 34383cb8e..000000000 --- a/src/_updown_espmark/_updown_espmark.8 +++ /dev/null @@ -1,15 +0,0 @@ -.TH _UPDOWN_ESPMARK 8 "7 Apr 2005" -.SH NAME -ipsec _updown_espmark \- manages routes and firewall rules -.SH SYNOPSIS -.I _updown_espmark -is invoked by pluto when it has brought up a new connection. This script -is used to insert the appropriate routing and iptables firewall entries for -IPsec operation. The incoming ESP traffic must be marked by a static rule -in the mangle table. The default value for the mark is 50. -The interface to the script is documented in the pluto man page. -.SH "SEE ALSO" -ipsec(8), ipsec_pluto(8). -.SH HISTORY -Man page written for the Linux strongSwan project <http://www.strongswan.org/> -by Andreas Steffen. Original program written by Henry Spencer. diff --git a/src/aikgen/Makefile.in b/src/aikgen/Makefile.in index 2bd5be64b..33ed13397 100644 --- a/src/aikgen/Makefile.in +++ b/src/aikgen/Makefile.in @@ -198,6 +198,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -258,10 +259,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -335,6 +338,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/charon-cmd/Makefile.in b/src/charon-cmd/Makefile.in index 9f67eec1f..64dea34c7 100644 --- a/src/charon-cmd/Makefile.in +++ b/src/charon-cmd/Makefile.in @@ -232,6 +232,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -292,10 +293,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -369,6 +372,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/charon-nm/Makefile.in b/src/charon-nm/Makefile.in index 69cbfe07e..82f6fbcb2 100644 --- a/src/charon-nm/Makefile.in +++ b/src/charon-nm/Makefile.in @@ -203,6 +203,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -263,10 +264,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -340,6 +343,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/charon-nm/nm/nm_backend.c b/src/charon-nm/nm/nm_backend.c index 613c2f6b5..601daca0a 100644 --- a/src/charon-nm/nm/nm_backend.c +++ b/src/charon-nm/nm/nm_backend.c @@ -18,7 +18,6 @@ #include "nm_creds.h" #include "nm_handler.h" -#include <hydra.h> #include <daemon.h> #include <processing/jobs/callback_job.h> @@ -97,7 +96,8 @@ static void nm_backend_deinit() g_object_unref(this->plugin); } lib->credmgr->remove_set(lib->credmgr, &this->creds->set); - hydra->attributes->remove_handler(hydra->attributes, &this->handler->handler); + charon->attributes->remove_handler(charon->attributes, + &this->handler->handler); this->creds->destroy(this->creds); this->handler->destroy(this->handler); free(this); @@ -130,7 +130,7 @@ static bool nm_backend_init() this->plugin = nm_strongswan_plugin_new(this->creds, this->handler); nm_backend = this; - hydra->attributes->add_handler(hydra->attributes, &this->handler->handler); + charon->attributes->add_handler(charon->attributes, &this->handler->handler); lib->credmgr->add_set(lib->credmgr, &this->creds->set); if (!this->plugin) { diff --git a/src/charon-nm/nm/nm_handler.c b/src/charon-nm/nm/nm_handler.c index 28aa04b31..bdc0667cf 100644 --- a/src/charon-nm/nm/nm_handler.c +++ b/src/charon-nm/nm/nm_handler.c @@ -41,7 +41,7 @@ struct private_nm_handler_t { }; METHOD(attribute_handler_t, handle, bool, - private_nm_handler_t *this, identification_t *server, + private_nm_handler_t *this, ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data) { linked_list_t *list; @@ -92,7 +92,7 @@ static bool enumerate_dns(enumerator_t *this, } METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, - private_nm_handler_t *this, identification_t *server, linked_list_t *vips) + private_nm_handler_t *this, ike_sa_t *ike_sa, linked_list_t *vips) { if (vips->get_count(vips)) { @@ -185,4 +185,3 @@ nm_handler_t *nm_handler_create() return &this->public; } - diff --git a/src/charon-svc/Makefile.in b/src/charon-svc/Makefile.in index 3783ac9f0..1c0a4058d 100644 --- a/src/charon-svc/Makefile.in +++ b/src/charon-svc/Makefile.in @@ -197,6 +197,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -257,10 +258,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -334,6 +337,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/charon-systemd/Makefile.in b/src/charon-systemd/Makefile.in index 790c8ef8f..d6e1c471c 100644 --- a/src/charon-systemd/Makefile.in +++ b/src/charon-systemd/Makefile.in @@ -200,6 +200,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -260,10 +261,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -337,6 +340,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/charon-systemd/charon-systemd.c b/src/charon-systemd/charon-systemd.c index 4a2136fc9..e391a5397 100644 --- a/src/charon-systemd/charon-systemd.c +++ b/src/charon-systemd/charon-systemd.c @@ -40,6 +40,17 @@ #include <threading/rwlock.h> /** + * Default user and group + */ +#ifndef IPSEC_USER +#define IPSEC_USER NULL +#endif + +#ifndef IPSEC_GROUP +#define IPSEC_GROUP NULL +#endif + +/** * hook in library for debugging messages */ extern void (*dbg) (debug_t group, level_t level, char *fmt, ...); @@ -268,18 +279,20 @@ static int run() */ static bool lookup_uid_gid() { -#ifdef IPSEC_USER - if (!lib->caps->resolve_uid(lib->caps, IPSEC_USER)) + char *name; + + name = lib->settings->get_str(lib->settings, "%s.user", IPSEC_USER, + lib->ns); + if (name && !lib->caps->resolve_uid(lib->caps, name)) { return FALSE; } -#endif /* IPSEC_USER */ -#ifdef IPSEC_GROUP - if (!lib->caps->resolve_gid(lib->caps, IPSEC_GROUP)) + name = lib->settings->get_str(lib->settings, "%s.group", IPSEC_GROUP, + lib->ns); + if (name && !lib->caps->resolve_gid(lib->caps, name)) { return FALSE; } -#endif /* IPSEC_GROUP */ return TRUE; } @@ -365,7 +378,8 @@ int main(int argc, char *argv[]) lib->plugins->add_static_features(lib->plugins, lib->ns, features, countof(features), TRUE, journal_reload, &journal); - if (!charon->initialize(charon, PLUGINS)) + if (!charon->initialize(charon, + lib->settings->get_str(lib->settings, "%s.load", PLUGINS, lib->ns))) { sd_notifyf(0, "STATUS=charon initialization failed"); return SS_RC_INITIALIZATION_FAILED; diff --git a/src/charon-tkm/Makefile.in b/src/charon-tkm/Makefile.in index fe6606bc5..bff198ab8 100644 --- a/src/charon-tkm/Makefile.in +++ b/src/charon-tkm/Makefile.in @@ -142,6 +142,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -202,10 +203,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -279,6 +282,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/charon-tkm/src/charon-tkm.c b/src/charon-tkm/src/charon-tkm.c index a6770fc50..7c60f0ca8 100644 --- a/src/charon-tkm/src/charon-tkm.c +++ b/src/charon-tkm/src/charon-tkm.c @@ -276,6 +276,10 @@ int main(int argc, char *argv[]) goto deinit; } + /* the authorize hook currently does not support RFC 7427 signature auth */ + lib->settings->set_bool(lib->settings, "%s.signature_authentication", FALSE, + dmn_name); + /* make sure we log to the DAEMON facility by default */ lib->settings->set_int(lib->settings, "%s.syslog.daemon.default", lib->settings->get_int(lib->settings, "%s.syslog.daemon.default", 1, diff --git a/src/charon-tkm/src/ees/ees_callbacks.c b/src/charon-tkm/src/ees/ees_callbacks.c index 2d9653837..74c0d3618 100644 --- a/src/charon-tkm/src/ees/ees_callbacks.c +++ b/src/charon-tkm/src/ees/ees_callbacks.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Reto Buerki + * Copyright (C) 2012-2014 Reto Buerki * Copyright (C) 2012 Adrian-Ken Rueegsegger * Hochschule fuer Technik Rapperswil * @@ -19,11 +19,12 @@ #include <tkm/constants.h> #include <tkm/types.h> +#include "tkm.h" #include "ees_callbacks.h" void charon_esa_acquire(result_type *res, const sp_id_type sp_id) { - DBG1(DBG_KNL, "ees: acquire received for reqid {%d}", sp_id); + DBG1(DBG_KNL, "ees: acquire received for reqid %u", sp_id); hydra->kernel_interface->acquire(hydra->kernel_interface, sp_id, NULL, NULL); *res = TKM_OK; @@ -33,8 +34,19 @@ void charon_esa_expire(result_type *res, const sp_id_type sp_id, const esp_spi_type spi_rem, const protocol_type protocol, const expiry_flag_type hard) { - DBG1(DBG_KNL, "ees: expire received for reqid {%d}", sp_id); - hydra->kernel_interface->expire(hydra->kernel_interface, sp_id, protocol, - spi_rem, hard != 0); + host_t *dst; + + dst = tkm->sad->get_dst_host(tkm->sad, sp_id, spi_rem, protocol); *res = TKM_OK; + if (dst == NULL) + { + DBG3(DBG_KNL, "ees: destination host not found for reqid %u, spi %x, " + "proto %u", sp_id, ntohl(spi_rem), protocol); + return; + } + + DBG1(DBG_KNL, "ees: expire received for reqid %u, spi %x, dst %H", sp_id, + ntohl(spi_rem), dst); + hydra->kernel_interface->expire(hydra->kernel_interface, protocol, + spi_rem, dst, hard != 0); } diff --git a/src/charon-tkm/src/tkm/tkm.c b/src/charon-tkm/src/tkm/tkm.c index 61eb6056c..333b699a0 100644 --- a/src/charon-tkm/src/tkm/tkm.c +++ b/src/charon-tkm/src/tkm/tkm.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Reto Buerki + * Copyright (C) 2012-2014 Reto Buerki * Copyright (C) 2012 Adrian-Ken Rueegsegger * Hochschule fuer Technik Rapperswil * @@ -95,6 +95,7 @@ bool tkm_init() .public = { .idmgr = tkm_id_manager_create(limits), .chunk_map = tkm_chunk_map_create(), + .sad = tkm_kernel_sad_create(), }, ); tkm = &this->public; @@ -114,6 +115,7 @@ void tkm_deinit() private_tkm_t *this = (private_tkm_t*)tkm; this->public.idmgr->destroy(this->public.idmgr); this->public.chunk_map->destroy(this->public.chunk_map); + this->public.sad->destroy(this->public.sad); ees_server_finalize(); diff --git a/src/charon-tkm/src/tkm/tkm.h b/src/charon-tkm/src/tkm/tkm.h index fb5acd117..4aed08602 100644 --- a/src/charon-tkm/src/tkm/tkm.h +++ b/src/charon-tkm/src/tkm/tkm.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Reto Buerki + * Copyright (C) 2012-2014 Reto Buerki * Copyright (C) 2012 Adrian-Ken Rueegsegger * Hochschule fuer Technik Rapperswil * @@ -72,6 +72,7 @@ #include "tkm_id_manager.h" #include "tkm_chunk_map.h" +#include "tkm_kernel_sad.h" typedef struct tkm_t tkm_t; @@ -90,6 +91,11 @@ struct tkm_t { */ tkm_chunk_map_t *chunk_map; + /** + * CHILD/ESP SA database. + */ + tkm_kernel_sad_t *sad; + }; /** diff --git a/src/charon-tkm/src/tkm/tkm_diffie_hellman.c b/src/charon-tkm/src/tkm/tkm_diffie_hellman.c index 67db5e6d8..c4953b6aa 100644 --- a/src/charon-tkm/src/tkm/tkm_diffie_hellman.c +++ b/src/charon-tkm/src/tkm/tkm_diffie_hellman.c @@ -41,7 +41,7 @@ struct private_tkm_diffie_hellman_t { /** * Diffie Hellman group number. */ - u_int16_t group; + diffie_hellman_group_t group; /** * Diffie Hellman public value. @@ -55,30 +55,29 @@ struct private_tkm_diffie_hellman_t { }; -METHOD(diffie_hellman_t, get_my_public_value, void, +METHOD(diffie_hellman_t, get_my_public_value, bool, private_tkm_diffie_hellman_t *this, chunk_t *value) { sequence_to_chunk(this->pubvalue.data, this->pubvalue.size, value); + return TRUE; } -METHOD(diffie_hellman_t, get_shared_secret, status_t, +METHOD(diffie_hellman_t, get_shared_secret, bool, private_tkm_diffie_hellman_t *this, chunk_t *secret) { *secret = chunk_empty; - return SUCCESS; + return TRUE; } -METHOD(diffie_hellman_t, set_other_public_value, void, +METHOD(diffie_hellman_t, set_other_public_value, bool, private_tkm_diffie_hellman_t *this, chunk_t value) { - // TODO: unvoid this function - dh_pubvalue_type othervalue; othervalue.size = value.len; memcpy(&othervalue.data, value.ptr, value.len); - ike_dh_generate_key(this->context_id, othervalue); + return ike_dh_generate_key(this->context_id, othervalue) == TKM_OK; } METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, diff --git a/src/charon-tkm/src/tkm/tkm_encoder.c~ b/src/charon-tkm/src/tkm/tkm_encoder.c~ new file mode 100644 index 000000000..145615f14 --- /dev/null +++ b/src/charon-tkm/src/tkm/tkm_encoder.c~ @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2013 Reto Buerki + * Copyright (C) 2013 Adrian-Ken Rueegsegger + * Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include <utils/debug.h> +#include <asn1/asn1.h> +#include <asn1/oid.h> + +#include "tkm_encoder.h" + +/** + * Build the SHA1 hash of pubkey(info) ASN.1 data. + */ +static bool hash_pubkey(chunk_t pubkey, chunk_t *hash) +{ + hasher_t *hasher; + + hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); + if (!hasher || !hasher->allocate_hash(hasher, pubkey, hash)) + { + DBG1(DBG_LIB, "SHA1 hash algorithm not supported, " + "fingerprinting failed"); + DESTROY_IF(hasher); + chunk_free(&pubkey); + return FALSE; + } + hasher->destroy(hasher); + chunk_free(&pubkey); + return TRUE; +} + +/** + * Encode the public key blob into subjectPublicKeyInfo. + */ +static bool build_pub_info(chunk_t *encoding, va_list args) +{ + chunk_t blob; + + if (cred_encoding_args(args, CRED_PART_RSA_PUB_ASN1_DER, &blob, + CRED_PART_END)) + { + *encoding = asn1_wrap(ASN1_SEQUENCE, "mm", + asn1_algorithmIdentifier(OID_RSA_ENCRYPTION), + asn1_bitstring("c", blob, 0)); + return TRUE; + } + return FALSE; +} + +/** + * Build the fingerprint of the subjectPublicKeyInfo object. + */ +static bool build_info_sha1(chunk_t *encoding, va_list args) +{ + chunk_t pubkey; + + if (build_pub_info(&pubkey, args)) + { + return hash_pubkey(pubkey, encoding); + } + return FALSE; +} + +/** + * Build the fingerprint of the subjectPublicKey object. + */ +static bool build_sha1(chunk_t *encoding, va_list args) +{ + chunk_t blob; + + if (cred_encoding_args(args, CRED_PART_RSA_PUB_ASN1_DER, &blob, + CRED_PART_END)) + { + return hash_pubkey(chunk_clone(blob), encoding); + } + return FALSE; +} + +/** + * See header. + */ +bool tkm_encoder_encode(cred_encoding_type_t type, chunk_t *encoding, + va_list args) +{ + switch (type) + { + case KEYID_PUBKEY_INFO_SHA1: + return build_info_sha1(encoding, args); + case KEYID_PUBKEY_SHA1: + return build_sha1(encoding, args); + default: + return FALSE; + } +} diff --git a/src/charon-tkm/src/tkm/tkm_id_manager.c b/src/charon-tkm/src/tkm/tkm_id_manager.c index 0fadf1acf..e6d571b83 100644 --- a/src/charon-tkm/src/tkm/tkm_id_manager.c +++ b/src/charon-tkm/src/tkm/tkm_id_manager.c @@ -24,7 +24,7 @@ ENUM_BEGIN(tkm_context_kind_names, TKM_CTX_NONCE, TKM_CTX_ESA, "NONCE_CONTEXT", "DH_CONTEXT", - "CC_CONTEXT" + "CC_CONTEXT", "ISA_CONTEXT", "AE_CONTEXT", "ESA_CONTEXT"); diff --git a/src/charon-tkm/src/tkm/tkm_kernel_ipsec.c b/src/charon-tkm/src/tkm/tkm_kernel_ipsec.c index dbeea93f2..734b1ec55 100644 --- a/src/charon-tkm/src/tkm/tkm_kernel_ipsec.c +++ b/src/charon-tkm/src/tkm/tkm_kernel_ipsec.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Reto Buerki + * Copyright (C) 2012-2014 Reto Buerki * Copyright (C) 2012 Adrian-Ken Rueegsegger * Hochschule fuer Technik Rapperswil * @@ -26,7 +26,6 @@ #include "tkm_utils.h" #include "tkm_types.h" #include "tkm_keymat.h" -#include "tkm_kernel_sad.h" #include "tkm_kernel_ipsec.h" /** From linux/in.h */ @@ -51,16 +50,11 @@ struct private_tkm_kernel_ipsec_t { */ rng_t *rng; - /** - * CHILD/ESP SA database. - */ - tkm_kernel_sad_t *sad; - }; METHOD(kernel_ipsec_t, get_spi, status_t, private_tkm_kernel_ipsec_t *this, host_t *src, host_t *dst, - u_int8_t protocol, u_int32_t reqid, u_int32_t *spi) + u_int8_t protocol, u_int32_t *spi) { bool result; @@ -74,7 +68,6 @@ METHOD(kernel_ipsec_t, get_spi, status_t, } } - DBG1(DBG_KNL, "getting SPI for reqid {%u}", reqid); result = this->rng->get_bytes(this->rng, sizeof(u_int32_t), (u_int8_t *)spi); return result ? SUCCESS : FAILED; @@ -82,7 +75,7 @@ METHOD(kernel_ipsec_t, get_spi, status_t, METHOD(kernel_ipsec_t, get_cpi, status_t, private_tkm_kernel_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t reqid, u_int16_t *cpi) + u_int16_t *cpi) { return NOT_SUPPORTED; } @@ -93,11 +86,10 @@ METHOD(kernel_ipsec_t, add_sa, status_t, u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key, u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window, - bool _initiator, bool encap, bool esn, bool inbound, - traffic_selector_t* src_ts, traffic_selector_t* dst_ts) + bool initiator, bool encap, bool esn, bool inbound, bool update, + linked_list_t* src_ts, linked_list_t* dst_ts) { esa_info_t esa; - bool initiator; esp_spi_type spi_loc, spi_rem; host_t *local, *peer; chunk_t *nonce_loc, *nonce_rem; @@ -120,9 +112,6 @@ METHOD(kernel_ipsec_t, add_sa, status_t, return SUCCESS; } - /* Initiator if encr_r is passed as enc_key to the inbound add_sa call */ - /* TODO: does the new _initiator parameter have the same meaning? */ - initiator = esa.is_encr_r && inbound; if (initiator) { spi_loc = spi; @@ -143,7 +132,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t, } esa_id = tkm->idmgr->acquire_id(tkm->idmgr, TKM_CTX_ESA); - if (!this->sad->insert(this->sad, esa_id, peer, local, spi_loc, protocol)) + if (!tkm->sad->insert(tkm->sad, reqid, esa_id, local, peer, spi_rem, + protocol)) { DBG1(DBG_KNL, "unable to add entry (%llu) to SAD", esa_id); goto sad_failure; @@ -207,7 +197,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t, return SUCCESS; failure: - this->sad->remove(this->sad, esa_id); + tkm->sad->remove(tkm->sad, esa_id); sad_failure: tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_ESA, esa_id); chunk_free(&esa.nonce_i); @@ -229,7 +219,7 @@ METHOD(kernel_ipsec_t, del_sa, status_t, { esa_id_type esa_id; - esa_id = this->sad->get_esa_id(this->sad, src, dst, spi, protocol); + esa_id = tkm->sad->get_esa_id(tkm->sad, src, dst, spi, protocol); if (esa_id) { DBG1(DBG_KNL, "deleting child SA (esa: %llu, spi: %x)", esa_id, @@ -239,7 +229,7 @@ METHOD(kernel_ipsec_t, del_sa, status_t, DBG1(DBG_KNL, "child SA (%llu) deletion failed", esa_id); return FAILED; } - this->sad->remove(this->sad, esa_id); + tkm->sad->remove(tkm->sad, esa_id); tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_ESA, esa_id); } return SUCCESS; @@ -350,7 +340,6 @@ METHOD(kernel_ipsec_t, destroy, void, private_tkm_kernel_ipsec_t *this) { DESTROY_IF(this->rng); - DESTROY_IF(this->sad); free(this); } @@ -380,15 +369,7 @@ tkm_kernel_ipsec_t *tkm_kernel_ipsec_create() .destroy = _destroy, }, }, - .sad = tkm_kernel_sad_create(), ); - if (!this->sad) - { - DBG1(DBG_KNL, "unable to create SAD"); - destroy(this); - return NULL; - } - return &this->public; } diff --git a/src/charon-tkm/src/tkm/tkm_kernel_sad.c b/src/charon-tkm/src/tkm/tkm_kernel_sad.c index 360a47bdc..3394b58af 100644 --- a/src/charon-tkm/src/tkm/tkm_kernel_sad.c +++ b/src/charon-tkm/src/tkm/tkm_kernel_sad.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Reto Buerki + * Copyright (C) 2012-2014 Reto Buerki * Copyright (C) 2012 Adrian-Ken Rueegsegger * Hochschule fuer Technik Rapperswil * @@ -57,6 +57,11 @@ struct sad_entry_t { esa_id_type esa_id; /** + * Reqid. + */ + u_int32_t reqid; + + /** * Source address of CHILD SA. */ host_t *src; @@ -109,6 +114,19 @@ static bool sad_entry_match(sad_entry_t * const entry, const host_t * const src, } /** + * Find a list entry with given reqid, spi and proto values. + */ +static bool sad_entry_match_dst(sad_entry_t * const entry, + const u_int32_t * const reqid, + const u_int32_t * const spi, + const u_int8_t * const proto) +{ + return entry->reqid == *reqid && + entry->spi == *spi && + entry->proto == *proto; +} + +/** * Compare two SAD entries for equality. */ static bool sad_entry_equal(sad_entry_t * const left, sad_entry_t * const right) @@ -119,6 +137,7 @@ static bool sad_entry_equal(sad_entry_t * const left, sad_entry_t * const right) return FALSE; } return left->esa_id == right->esa_id && + left->reqid == right->reqid && left->src->ip_equals(left->src, right->src) && left->dst->ip_equals(left->dst, right->dst) && left->spi == right->spi && left->proto == right->proto; @@ -126,14 +145,15 @@ static bool sad_entry_equal(sad_entry_t * const left, sad_entry_t * const right) METHOD(tkm_kernel_sad_t, insert, bool, private_tkm_kernel_sad_t * const this, const esa_id_type esa_id, - const host_t * const src, const host_t * const dst, const u_int32_t spi, - const u_int8_t proto) + const u_int32_t reqid, const host_t * const src, const host_t * const dst, + const u_int32_t spi, const u_int8_t proto) { status_t result; sad_entry_t *new_entry; INIT(new_entry, .esa_id = esa_id, + .reqid = reqid, .src = (host_t *)src, .dst = (host_t *)dst, .spi = spi, @@ -146,8 +166,9 @@ METHOD(tkm_kernel_sad_t, insert, bool, new_entry); if (result == NOT_FOUND) { - DBG3(DBG_KNL, "inserting SAD entry (esa: %llu, src: %H, dst: %H, " - "spi: %x, proto: %u)", esa_id, src, dst, ntohl(spi), proto); + DBG3(DBG_KNL, "inserting SAD entry (esa: %llu, reqid: %u, src: %H, " + "dst: %H, spi: %x, proto: %u)", esa_id, reqid, src, dst, + ntohl(spi), proto); new_entry->src = src->clone((host_t *)src); new_entry->dst = dst->clone((host_t *)dst); this->data->insert_last(this->data, new_entry); @@ -176,18 +197,44 @@ METHOD(tkm_kernel_sad_t, get_esa_id, esa_id_type, if (res == SUCCESS && entry) { id = entry->esa_id; - DBG3(DBG_KNL, "getting ESA id of SAD entry (esa: %llu, src: %H, " - "dst: %H, spi: %x, proto: %u)", id, src, dst, ntohl(spi), - proto); + DBG3(DBG_KNL, "returning ESA id %llu of SAD entry (src: %H, dst: %H, " + "spi: %x, proto: %u)", id, src, dst, ntohl(spi), proto); } else { - DBG3(DBG_KNL, "no SAD entry found"); + DBG3(DBG_KNL, "no SAD entry found for src %H, dst %H, spi %x, proto %u", + src, dst, ntohl(spi), proto); } this->mutex->unlock(this->mutex); return id; } +METHOD(tkm_kernel_sad_t, get_dst_host, host_t *, + private_tkm_kernel_sad_t * const this, const u_int32_t reqid, + const u_int32_t spi, const u_int8_t proto) +{ + host_t *dst = NULL; + sad_entry_t *entry = NULL; + + this->mutex->lock(this->mutex); + const status_t res = this->data->find_first(this->data, + (linked_list_match_t)sad_entry_match_dst, + (void**)&entry, &reqid, &spi, &proto); + if (res == SUCCESS && entry) + { + dst = entry->dst; + DBG3(DBG_KNL, "returning destination host %H of SAD entry (reqid: %u," + " spi: %x, proto: %u)", dst, reqid, ntohl(spi), proto); + } + else + { + DBG3(DBG_KNL, "no SAD entry found for reqid %u, spi %x, proto: %u", + reqid, ntohl(spi), proto); + } + this->mutex->unlock(this->mutex); + return dst; +} + METHOD(tkm_kernel_sad_t, _remove, bool, private_tkm_kernel_sad_t * const this, const esa_id_type esa_id) { @@ -242,6 +289,7 @@ tkm_kernel_sad_t *tkm_kernel_sad_create() .public = { .insert = _insert, .get_esa_id = _get_esa_id, + .get_dst_host = _get_dst_host, .remove = __remove, .destroy = _destroy, }, diff --git a/src/charon-tkm/src/tkm/tkm_kernel_sad.h b/src/charon-tkm/src/tkm/tkm_kernel_sad.h index 0194cd3bc..38b19dd01 100644 --- a/src/charon-tkm/src/tkm/tkm_kernel_sad.h +++ b/src/charon-tkm/src/tkm/tkm_kernel_sad.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Reto Buerki + * Copyright (C) 2012-2014 Reto Buerki * Copyright (C) 2012 Adrian-Ken Rueegsegger * Hochschule fuer Technik Rapperswil * @@ -37,6 +37,7 @@ struct tkm_kernel_sad_t { * Insert new SAD entry with specified parameters. * * @param esa_id ESP SA context identifier + * @param reqid reqid of the SA * @param src source address of CHILD SA * @param dst destination address of CHILD SA * @param spi SPI of CHILD SA @@ -44,8 +45,9 @@ struct tkm_kernel_sad_t { * @return TRUE if entry was inserted, FALSE otherwise */ bool (*insert)(tkm_kernel_sad_t * const this, const esa_id_type esa_id, - const host_t * const src, const host_t * const dst, - const u_int32_t spi, const u_int8_t proto); + const u_int32_t reqid, const host_t * const src, + const host_t * const dst, const u_int32_t spi, + const u_int8_t proto); /** * Get ESA id for entry with given parameters. @@ -61,6 +63,17 @@ struct tkm_kernel_sad_t { const u_int32_t spi, const u_int8_t proto); /** + * Get destination host for entry with given parameters. + * + * @param reqid reqid of CHILD SA + * @param spi SPI of CHILD SA + * @param proto protocol of CHILD SA (ESP/AH) + * @return destination host of entry if found, NULL otherwise + */ + host_t * (*get_dst_host)(tkm_kernel_sad_t * const this, + const u_int32_t reqid, const u_int32_t spi, const u_int8_t proto); + + /** * Remove entry with given ESA id from SAD. * * @param esa_id ESA identifier of entry to remove diff --git a/src/charon-tkm/src/tkm/tkm_keymat.c b/src/charon-tkm/src/tkm/tkm_keymat.c index 772fac8b0..80721fafe 100644 --- a/src/charon-tkm/src/tkm/tkm_keymat.c +++ b/src/charon-tkm/src/tkm/tkm_keymat.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2015 Tobias Brunner * Copyrigth (C) 2012 Reto Buerki * Copyright (C) 2012 Adrian-Ken Rueegsegger * Hochschule fuer Technik Rapperswil @@ -17,6 +18,7 @@ #include <daemon.h> #include <tkm/constants.h> #include <tkm/client.h> +#include <crypto/hashers/hash_algorithm_set.h> #include "tkm.h" #include "tkm_types.h" @@ -71,6 +73,10 @@ struct private_tkm_keymat_t { */ chunk_t other_init_msg; + /** + * Set of hash algorithms supported by peer for signature authentication + */ + hash_algorithm_set_t *hash_algorithms; }; /** @@ -417,6 +423,26 @@ METHOD(keymat_v2_t, get_psk_sig, bool, return FALSE; } +METHOD(keymat_v2_t, hash_algorithm_supported, bool, + private_tkm_keymat_t *this, hash_algorithm_t hash) +{ + if (!this->hash_algorithms) + { + return FALSE; + } + return this->hash_algorithms->contains(this->hash_algorithms, hash); +} + +METHOD(keymat_v2_t, add_hash_algorithm, void, + private_tkm_keymat_t *this, hash_algorithm_t hash) +{ + if (!this->hash_algorithms) + { + this->hash_algorithms = hash_algorithm_set_create(); + } + this->hash_algorithms->add(this->hash_algorithms, hash); +} + METHOD(keymat_t, destroy, void, private_tkm_keymat_t *this) { @@ -435,6 +461,7 @@ METHOD(keymat_t, destroy, void, tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_AE, this->ae_ctx_id); } + DESTROY_IF(this->hash_algorithms); DESTROY_IF(this->aead_in); DESTROY_IF(this->aead_out); chunk_free(&this->auth_payload); @@ -488,6 +515,8 @@ tkm_keymat_t *tkm_keymat_create(bool initiator) .get_skd = _get_skd, .get_auth_octets = _get_auth_octets, .get_psk_sig = _get_psk_sig, + .add_hash_algorithm = _add_hash_algorithm, + .hash_algorithm_supported = _hash_algorithm_supported, }, .get_isa_id = _get_isa_id, .set_auth_payload = _set_auth_payload, diff --git a/src/charon-tkm/src/tkm/tkm_listener.c b/src/charon-tkm/src/tkm/tkm_listener.c index b2692a586..bb1218266 100644 --- a/src/charon-tkm/src/tkm/tkm_listener.c +++ b/src/charon-tkm/src/tkm/tkm_listener.c @@ -240,6 +240,8 @@ METHOD(listener_t, authorize, bool, return TRUE; } + *success = FALSE; + keymat = (tkm_keymat_t*)ike_sa->get_keymat(ike_sa); isa_id = keymat->get_isa_id(keymat); DBG1(DBG_IKE, "TKM authorize listener called for ISA context %llu", isa_id); @@ -248,28 +250,26 @@ METHOD(listener_t, authorize, bool, if (!cc_id) { DBG1(DBG_IKE, "unable to acquire CC context id"); - *success = FALSE; return TRUE; } if (!build_cert_chain(ike_sa, cc_id)) { DBG1(DBG_IKE, "unable to build certificate chain"); - *success = FALSE; - return TRUE; + goto cc_reset; } auth = keymat->get_auth_payload(keymat); if (!auth->ptr) { DBG1(DBG_IKE, "no AUTHENTICATION data available"); - *success = FALSE; + goto cc_reset; } other_init_msg = keymat->get_peer_init_msg(keymat); if (!other_init_msg->ptr) { DBG1(DBG_IKE, "no peer init message available"); - *success = FALSE; + goto cc_reset; } chunk_to_sequence(auth, &signature, sizeof(signature_type)); @@ -279,7 +279,7 @@ METHOD(listener_t, authorize, bool, { DBG1(DBG_IKE, "TKM based authentication failed" " for ISA context %llu", isa_id); - *success = FALSE; + goto cc_reset; } else { @@ -288,7 +288,13 @@ METHOD(listener_t, authorize, bool, *success = TRUE; } - return TRUE; +cc_reset: + if (ike_cc_reset(cc_id) != TKM_OK) + { + DBG1(DBG_IKE, "unable to reset CC context %llu", cc_id); + } + tkm->idmgr->release_id(tkm->idmgr, TKM_CTX_CC, cc_id); + return TRUE; /* stay registered */ } METHOD(listener_t, message, bool, diff --git a/src/charon-tkm/tests/diffie_hellman_tests.c b/src/charon-tkm/tests/diffie_hellman_tests.c index 89658a770..5ef6f41ab 100644 --- a/src/charon-tkm/tests/diffie_hellman_tests.c +++ b/src/charon-tkm/tests/diffie_hellman_tests.c @@ -40,7 +40,7 @@ START_TEST(test_dh_get_my_pubvalue) fail_if(!dh, "Unable to create DH"); chunk_t value; - dh->dh.get_my_public_value(&dh->dh, &value); + ck_assert(dh->dh.get_my_public_value(&dh->dh, &value)); dh->dh.destroy(&dh->dh); fail_if(value.ptr == NULL, "Pubvalue is NULL"); diff --git a/src/charon-tkm/tests/kernel_sad_tests.c b/src/charon-tkm/tests/kernel_sad_tests.c index 6f0b396d3..b9ab3cb5e 100644 --- a/src/charon-tkm/tests/kernel_sad_tests.c +++ b/src/charon-tkm/tests/kernel_sad_tests.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Reto Buerki + * Copyright (C) 2012-2014 Reto Buerki * Copyright (C) 2012 Adrian-Ken Rueegsegger * Hochschule fuer Technik Rapperswil * @@ -34,7 +34,7 @@ START_TEST(test_insert) host_t *addr = host_create_from_string("127.0.0.1", 1024); tkm_kernel_sad_t *sad = tkm_kernel_sad_create(); - fail_unless(sad->insert(sad, 1, addr, addr, 42, 50), + fail_unless(sad->insert(sad, 1, 2, addr, addr, 42, 50), "Error inserting SAD entry"); sad->destroy(sad); @@ -47,9 +47,9 @@ START_TEST(test_insert_duplicate) host_t *addr = host_create_from_string("127.0.0.1", 1024); tkm_kernel_sad_t *sad = tkm_kernel_sad_create(); - fail_unless(sad->insert(sad, 1, addr, addr, 42, 50), + fail_unless(sad->insert(sad, 1, 2, addr, addr, 42, 50), "Error inserting SAD entry"); - fail_if(sad->insert(sad, 1, addr, addr, 42, 50), + fail_if(sad->insert(sad, 1, 2, addr, addr, 42, 50), "Expected error inserting duplicate entry"); sad->destroy(sad); @@ -61,7 +61,7 @@ START_TEST(test_get_esa_id) { host_t *addr = host_create_from_string("127.0.0.1", 1024); tkm_kernel_sad_t *sad = tkm_kernel_sad_create(); - fail_unless(sad->insert(sad, 23, addr, addr, 42, 50), + fail_unless(sad->insert(sad, 23, 54, addr, addr, 42, 50), "Error inserting SAD entry"); fail_unless(sad->get_esa_id(sad, addr, addr, 42, 50) == 23, "Error getting esa id"); @@ -81,11 +81,34 @@ START_TEST(test_get_esa_id_nonexistent) } END_TEST +START_TEST(test_get_dst_host) +{ + host_t *addr = host_create_from_string("127.0.0.1", 1024); + tkm_kernel_sad_t *sad = tkm_kernel_sad_create(); + fail_unless(sad->insert(sad, 23, 54, addr, addr, 42, 50), + "Error inserting SAD entry"); + + host_t *dst = sad->get_dst_host(sad, 54, 42, 50); + fail_unless(addr->equals(addr, dst), "Error getting dst host"); + sad->destroy(sad); + addr->destroy(addr); +} +END_TEST + +START_TEST(test_get_dst_host_nonexistent) +{ + tkm_kernel_sad_t *sad = tkm_kernel_sad_create(); + fail_unless(sad->get_dst_host(sad, 1, 12, 50) == NULL, + "Got dst for nonexistent SAD entry"); + sad->destroy(sad); +} +END_TEST + START_TEST(test_remove) { host_t *addr = host_create_from_string("127.0.0.1", 1024); tkm_kernel_sad_t *sad = tkm_kernel_sad_create(); - fail_unless(sad->insert(sad, 23, addr, addr, 42, 50), + fail_unless(sad->insert(sad, 23, 54, addr, addr, 42, 50), "Error inserting SAD entry"); fail_unless(sad->get_esa_id(sad, addr, addr, 42, 50) == 23, "Error getting esa id"); @@ -128,6 +151,11 @@ Suite *make_kernel_sad_tests() tcase_add_test(tc, test_get_esa_id_nonexistent); suite_add_tcase(s, tc); + tc = tcase_create("get_dst_host"); + tcase_add_test(tc, test_get_dst_host); + tcase_add_test(tc, test_get_dst_host_nonexistent); + suite_add_tcase(s, tc); + tc = tcase_create("remove"); tcase_add_test(tc, test_remove); tcase_add_test(tc, test_remove_nonexistent); diff --git a/src/charon-tkm/tests/keymat_tests.c b/src/charon-tkm/tests/keymat_tests.c index 1982671d3..889965a78 100644 --- a/src/charon-tkm/tests/keymat_tests.c +++ b/src/charon-tkm/tests/keymat_tests.c @@ -53,8 +53,8 @@ START_TEST(test_derive_ike_keys) /* Use the same pubvalue for both sides */ chunk_t pubvalue; - dh->dh.get_my_public_value(&dh->dh, &pubvalue); - dh->dh.set_other_public_value(&dh->dh, pubvalue); + ck_assert(dh->dh.get_my_public_value(&dh->dh, &pubvalue)); + ck_assert(dh->dh.set_other_public_value(&dh->dh, pubvalue)); fail_unless(keymat->keymat_v2.derive_ike_keys(&keymat->keymat_v2, proposal, &dh->dh, nonce, nonce, ike_sa_id, PRF_UNDEFINED, chunk_empty), diff --git a/src/charon-tkm/tests/tests.c b/src/charon-tkm/tests/tests.c index 80894a133..669f4d500 100644 --- a/src/charon-tkm/tests/tests.c +++ b/src/charon-tkm/tests/tests.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2013 Tobias Brunner - * Copyright (C) 2012 Reto Buerki + * Copyright (C) 2012-2014 Reto Buerki * Copyright (C) 2012 Adrian-Ken Rueegsegger * Hochschule fuer Technik Rapperswil * @@ -53,7 +53,7 @@ static bool test_runner_init(bool init) libhydra_init(); libcharon_init(); lib->settings->set_int(lib->settings, - "test_runner.filelog.stdout.default", 0); + "test-runner.filelog.stdout.default", 0); charon->load_loggers(charon, NULL, FALSE); /* Register TKM specific plugins */ diff --git a/src/charon/Makefile.in b/src/charon/Makefile.in index f4dcf4fb0..e1cc5c202 100644 --- a/src/charon/Makefile.in +++ b/src/charon/Makefile.in @@ -199,6 +199,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -259,10 +260,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -336,6 +339,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/checksum/Makefile.in b/src/checksum/Makefile.in index 86e7ca6dd..4e4134625 100644 --- a/src/checksum/Makefile.in +++ b/src/checksum/Makefile.in @@ -266,6 +266,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -326,10 +327,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -403,6 +406,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/conftest/Makefile.in b/src/conftest/Makefile.in index e3c2e4335..78438d8f5 100644 --- a/src/conftest/Makefile.in +++ b/src/conftest/Makefile.in @@ -213,6 +213,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -273,10 +274,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -350,6 +353,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/conftest/actions.c b/src/conftest/actions.c index 7532e95cf..474672ca1 100644 --- a/src/conftest/actions.c +++ b/src/conftest/actions.c @@ -117,19 +117,20 @@ static job_requeue_t rekey_child(char *config) enumerator_t *enumerator, *children; ike_sa_t *ike_sa; child_sa_t *child_sa; - u_int32_t reqid = 0, spi = 0; - protocol_id_t proto = PROTO_ESP; + u_int32_t spi, proto; + host_t *dst = NULL; enumerator = charon->controller->create_ike_sa_enumerator( charon->controller, TRUE); while (enumerator->enumerate(enumerator, &ike_sa)) { children = ike_sa->create_child_sa_enumerator(ike_sa); - while (children->enumerate(children, (void**)&child_sa)) + while (children->enumerate(children, &child_sa)) { if (streq(config, child_sa->get_name(child_sa))) { - reqid = child_sa->get_reqid(child_sa); + dst = ike_sa->get_my_host(ike_sa); + dst = dst->clone(dst); proto = child_sa->get_protocol(child_sa); spi = child_sa->get_spi(child_sa, TRUE); break; @@ -138,11 +139,12 @@ static job_requeue_t rekey_child(char *config) children->destroy(children); } enumerator->destroy(enumerator); - if (reqid) + if (dst) { DBG1(DBG_CFG, "starting rekey of CHILD_SA '%s'", config); lib->processor->queue_job(lib->processor, - (job_t*)rekey_child_sa_job_create(reqid, proto, spi)); + (job_t*)rekey_child_sa_job_create(proto, spi, dst)); + dst->destroy(dst); } else { @@ -236,7 +238,7 @@ static job_requeue_t close_child(char *config) { if (streq(config, child_sa->get_name(child_sa))) { - id = child_sa->get_reqid(child_sa); + id = child_sa->get_unique_id(child_sa); break; } } diff --git a/src/dumm/Makefile.in b/src/dumm/Makefile.in index 56ac3447f..2ecf61194 100644 --- a/src/dumm/Makefile.in +++ b/src/dumm/Makefile.in @@ -234,6 +234,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -294,10 +295,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -371,6 +374,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/dumm/ext/dumm.c b/src/dumm/ext/dumm.c index d791c089d..df7ec4703 100644 --- a/src/dumm/ext/dumm.c +++ b/src/dumm/ext/dumm.c @@ -629,7 +629,7 @@ static VALUE iface_each_addr(int argc, VALUE *argv, VALUE self) linked_list_t *list; iface_t *iface; host_t *addr; - char buf[64]; + char buf[64], *fmt = "%H"; if (!rb_block_given_p()) { @@ -645,7 +645,7 @@ static VALUE iface_each_addr(int argc, VALUE *argv, VALUE self) enumerator->destroy(enumerator); while (list->remove_first(list, (void**)&addr) == SUCCESS) { - snprintf(buf, sizeof(buf), "%H", addr); + snprintf(buf, sizeof(buf), fmt, addr); addr->destroy(addr); rb_yield(rb_str_new2(buf)); } diff --git a/src/include/Makefile.in b/src/include/Makefile.in index 042c46cab..64be6ac4f 100644 --- a/src/include/Makefile.in +++ b/src/include/Makefile.in @@ -142,6 +142,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -202,10 +203,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -279,6 +282,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/ipsec/Makefile.in b/src/ipsec/Makefile.in index 526c7c46e..d4dafcb0c 100644 --- a/src/ipsec/Makefile.in +++ b/src/ipsec/Makefile.in @@ -176,6 +176,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -236,10 +237,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -313,6 +316,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/ipsec/_ipsec.8 b/src/ipsec/_ipsec.8 index 9ba9bd842..d2d0c2edd 100644 --- a/src/ipsec/_ipsec.8 +++ b/src/ipsec/_ipsec.8 @@ -1,4 +1,4 @@ -.TH IPSEC 8 "2013-10-29" "5.2.1" "strongSwan" +.TH IPSEC 8 "2013-10-29" "5.3.0" "strongSwan" . .SH NAME . @@ -210,15 +210,18 @@ flushes and rereads all secrets defined in \fIipsec.secrets\fP. . .TP .B "rereadcacerts" -reads all certificate files contained in the \fI/etc/ipsec.d/cacerts\fP -directory and adds them to the list of Certification Authority (CA) -certificates. +removes previously loaded CA certificates, reads all certificate files +contained in the \fI/etc/ipsec.d/cacerts\fP directory and adds them to the list +of Certification Authority (CA) certificates. This does not affect certificates +explicitly defined in a +.BR ipsec.conf (5) +ca section, which may be separately updated using the \fBupdate\fP command. . .TP .B "rereadaacerts" -reads all certificate files contained in the \fI/etc/ipsec.d/aacerts\fP -directory and adds them to the list of Authorization Authority (AA) -certificates. +removes previously loaded AA certificates, reads all certificate files +contained in the \fI/etc/ipsec.d/aacerts\fP directory and adds them to the list +of Authorization Authority (AA) certificates. . .TP .B "rereadocspcerts" diff --git a/src/ipsec/_ipsec.8.in b/src/ipsec/_ipsec.8.in index 210d74ef8..0aef8c031 100644 --- a/src/ipsec/_ipsec.8.in +++ b/src/ipsec/_ipsec.8.in @@ -210,15 +210,18 @@ flushes and rereads all secrets defined in \fIipsec.secrets\fP. . .TP .B "rereadcacerts" -reads all certificate files contained in the \fI/etc/ipsec.d/cacerts\fP -directory and adds them to the list of Certification Authority (CA) -certificates. +removes previously loaded CA certificates, reads all certificate files +contained in the \fI/etc/ipsec.d/cacerts\fP directory and adds them to the list +of Certification Authority (CA) certificates. This does not affect certificates +explicitly defined in a +.BR ipsec.conf (5) +ca section, which may be separately updated using the \fBupdate\fP command. . .TP .B "rereadaacerts" -reads all certificate files contained in the \fI/etc/ipsec.d/aacerts\fP -directory and adds them to the list of Authorization Authority (AA) -certificates. +removes previously loaded AA certificates, reads all certificate files +contained in the \fI/etc/ipsec.d/aacerts\fP directory and adds them to the list +of Authorization Authority (AA) certificates. . .TP .B "rereadocspcerts" diff --git a/src/libcharon/Android.mk b/src/libcharon/Android.mk index 4212ee87a..5eef6fdc6 100644 --- a/src/libcharon/Android.mk +++ b/src/libcharon/Android.mk @@ -3,6 +3,10 @@ include $(CLEAR_VARS) # copy-n-paste from Makefile.am libcharon_la_SOURCES := \ +attributes/attributes.c attributes/attributes.h \ +attributes/attribute_provider.h attributes/attribute_handler.h \ +attributes/attribute_manager.c attributes/attribute_manager.h \ +attributes/mem_pool.c attributes/mem_pool.h \ bus/bus.c bus/bus.h \ bus/listeners/listener.h \ bus/listeners/logger.h \ @@ -62,6 +66,7 @@ processing/jobs/start_action_job.c processing/jobs/start_action_job.h \ processing/jobs/roam_job.c processing/jobs/roam_job.h \ processing/jobs/update_sa_job.c processing/jobs/update_sa_job.h \ processing/jobs/inactivity_job.c processing/jobs/inactivity_job.h \ +processing/jobs/initiate_tasks_job.c processing/jobs/initiate_tasks_job.h \ sa/eap/eap_method.c sa/eap/eap_method.h sa/eap/eap_inner_method.h \ sa/eap/eap_manager.c sa/eap/eap_manager.h \ sa/xauth/xauth_method.c sa/xauth/xauth_method.h \ @@ -72,6 +77,7 @@ sa/ike_sa.c sa/ike_sa.h \ sa/ike_sa_id.c sa/ike_sa_id.h \ sa/keymat.h sa/keymat.c \ sa/ike_sa_manager.c sa/ike_sa_manager.h \ +sa/child_sa_manager.c sa/child_sa_manager.h \ sa/task_manager.h sa/task_manager.c \ sa/shunt_manager.c sa/shunt_manager.h \ sa/trap_manager.c sa/trap_manager.h \ @@ -97,6 +103,7 @@ sa/ikev2/tasks/ike_natd.c sa/ikev2/tasks/ike_natd.h \ sa/ikev2/tasks/ike_mobike.c sa/ikev2/tasks/ike_mobike.h \ sa/ikev2/tasks/ike_rekey.c sa/ikev2/tasks/ike_rekey.h \ sa/ikev2/tasks/ike_reauth.c sa/ikev2/tasks/ike_reauth.h \ +sa/ikev2/tasks/ike_reauth_complete.c sa/ikev2/tasks/ike_reauth_complete.h \ sa/ikev2/tasks/ike_auth_lifetime.c sa/ikev2/tasks/ike_auth_lifetime.h \ sa/ikev2/tasks/ike_vendor.c sa/ikev2/tasks/ike_vendor.h @@ -238,4 +245,3 @@ LOCAL_PRELINK_MODULE := false LOCAL_SHARED_LIBRARIES += libstrongswan libhydra include $(BUILD_SHARED_LIBRARY) - diff --git a/src/libcharon/Makefile.am b/src/libcharon/Makefile.am index e98f5e137..cd81a5eee 100644 --- a/src/libcharon/Makefile.am +++ b/src/libcharon/Makefile.am @@ -1,6 +1,10 @@ ipseclib_LTLIBRARIES = libcharon.la libcharon_la_SOURCES = \ +attributes/attributes.c attributes/attributes.h \ +attributes/attribute_provider.h attributes/attribute_handler.h \ +attributes/attribute_manager.c attributes/attribute_manager.h \ +attributes/mem_pool.c attributes/mem_pool.h \ bus/bus.c bus/bus.h \ bus/listeners/listener.h \ bus/listeners/logger.h \ @@ -60,6 +64,7 @@ processing/jobs/start_action_job.c processing/jobs/start_action_job.h \ processing/jobs/roam_job.c processing/jobs/roam_job.h \ processing/jobs/update_sa_job.c processing/jobs/update_sa_job.h \ processing/jobs/inactivity_job.c processing/jobs/inactivity_job.h \ +processing/jobs/initiate_tasks_job.c processing/jobs/initiate_tasks_job.h \ sa/eap/eap_method.c sa/eap/eap_method.h sa/eap/eap_inner_method.h \ sa/eap/eap_manager.c sa/eap/eap_manager.h \ sa/xauth/xauth_method.c sa/xauth/xauth_method.h \ @@ -70,6 +75,7 @@ sa/ike_sa.c sa/ike_sa.h \ sa/ike_sa_id.c sa/ike_sa_id.h \ sa/keymat.h sa/keymat.c \ sa/ike_sa_manager.c sa/ike_sa_manager.h \ +sa/child_sa_manager.c sa/child_sa_manager.h \ sa/task_manager.h sa/task_manager.c \ sa/shunt_manager.c sa/shunt_manager.h \ sa/trap_manager.c sa/trap_manager.h \ @@ -96,6 +102,7 @@ sa/ikev2/tasks/ike_natd.c sa/ikev2/tasks/ike_natd.h \ sa/ikev2/tasks/ike_mobike.c sa/ikev2/tasks/ike_mobike.h \ sa/ikev2/tasks/ike_rekey.c sa/ikev2/tasks/ike_rekey.h \ sa/ikev2/tasks/ike_reauth.c sa/ikev2/tasks/ike_reauth.h \ +sa/ikev2/tasks/ike_reauth_complete.c sa/ikev2/tasks/ike_reauth_complete.h \ sa/ikev2/tasks/ike_auth_lifetime.c sa/ikev2/tasks/ike_auth_lifetime.h \ sa/ikev2/tasks/ike_vendor.c sa/ikev2/tasks/ike_vendor.h endif @@ -203,6 +210,20 @@ if MONOLITHIC endif endif +if USE_CONNMARK + SUBDIRS += plugins/connmark +if MONOLITHIC + libcharon_la_LIBADD += plugins/connmark/libstrongswan-connmark.la +endif +endif + +if USE_FORECAST + SUBDIRS += plugins/forecast +if MONOLITHIC + libcharon_la_LIBADD += plugins/forecast/libstrongswan-forecast.la +endif +endif + if USE_FARP SUBDIRS += plugins/farp if MONOLITHIC @@ -595,13 +616,6 @@ if MONOLITHIC endif endif -if USE_UNIT_TESTS - SUBDIRS += plugins/unit_tester -if MONOLITHIC - libcharon_la_LIBADD += plugins/unit_tester/libstrongswan-unit-tester.la -endif -endif - if USE_XAUTH_GENERIC SUBDIRS += plugins/xauth_generic if MONOLITHIC @@ -629,3 +643,29 @@ if MONOLITHIC libcharon_la_LIBADD += plugins/xauth_noauth/libstrongswan-xauth-noauth.la endif endif + +if USE_RESOLVE + SUBDIRS += plugins/resolve +if MONOLITHIC + libcharon_la_LIBADD += plugins/resolve/libstrongswan-resolve.la +endif +endif + +if USE_ATTR + SUBDIRS += plugins/attr +if MONOLITHIC + libcharon_la_LIBADD += plugins/attr/libstrongswan-attr.la +endif +endif + +if USE_ATTR_SQL + SUBDIRS += plugins/attr_sql +if MONOLITHIC + libcharon_la_LIBADD += plugins/attr_sql/libstrongswan-attr-sql.la +endif +endif + +if MONOLITHIC + SUBDIRS += . +endif +SUBDIRS += tests diff --git a/src/libcharon/Makefile.in b/src/libcharon/Makefile.in index 4d89794b5..3d425e0b4 100644 --- a/src/libcharon/Makefile.in +++ b/src/libcharon/Makefile.in @@ -98,6 +98,7 @@ host_triplet = @host@ @USE_IKEV2_TRUE@sa/ikev2/tasks/ike_mobike.c sa/ikev2/tasks/ike_mobike.h \ @USE_IKEV2_TRUE@sa/ikev2/tasks/ike_rekey.c sa/ikev2/tasks/ike_rekey.h \ @USE_IKEV2_TRUE@sa/ikev2/tasks/ike_reauth.c sa/ikev2/tasks/ike_reauth.h \ +@USE_IKEV2_TRUE@sa/ikev2/tasks/ike_reauth_complete.c sa/ikev2/tasks/ike_reauth_complete.h \ @USE_IKEV2_TRUE@sa/ikev2/tasks/ike_auth_lifetime.c sa/ikev2/tasks/ike_auth_lifetime.h \ @USE_IKEV2_TRUE@sa/ikev2/tasks/ike_vendor.c sa/ikev2/tasks/ike_vendor.h @@ -146,124 +147,132 @@ host_triplet = @host@ @MONOLITHIC_TRUE@@USE_SOCKET_DYNAMIC_TRUE@am__append_11 = plugins/socket_dynamic/libstrongswan-socket-dynamic.la @USE_SOCKET_WIN_TRUE@am__append_12 = plugins/socket_win @MONOLITHIC_TRUE@@USE_SOCKET_WIN_TRUE@am__append_13 = plugins/socket_win/libstrongswan-socket-win.la -@USE_FARP_TRUE@am__append_14 = plugins/farp -@MONOLITHIC_TRUE@@USE_FARP_TRUE@am__append_15 = plugins/farp/libstrongswan-farp.la -@USE_STROKE_TRUE@am__append_16 = plugins/stroke -@MONOLITHIC_TRUE@@USE_STROKE_TRUE@am__append_17 = plugins/stroke/libstrongswan-stroke.la -@USE_VICI_TRUE@am__append_18 = plugins/vici -@MONOLITHIC_TRUE@@USE_VICI_TRUE@am__append_19 = plugins/vici/libstrongswan-vici.la -@USE_SMP_TRUE@am__append_20 = plugins/smp -@MONOLITHIC_TRUE@@USE_SMP_TRUE@am__append_21 = plugins/smp/libstrongswan-smp.la -@USE_SQL_TRUE@am__append_22 = plugins/sql -@MONOLITHIC_TRUE@@USE_SQL_TRUE@am__append_23 = plugins/sql/libstrongswan-sql.la -@USE_DNSCERT_TRUE@am__append_24 = plugins/dnscert -@MONOLITHIC_TRUE@@USE_DNSCERT_TRUE@am__append_25 = plugins/dnscert/libstrongswan-dnscert.la -@USE_IPSECKEY_TRUE@am__append_26 = plugins/ipseckey -@MONOLITHIC_TRUE@@USE_IPSECKEY_TRUE@am__append_27 = plugins/ipseckey/libstrongswan-ipseckey.la -@USE_UPDOWN_TRUE@am__append_28 = plugins/updown -@MONOLITHIC_TRUE@@USE_UPDOWN_TRUE@am__append_29 = plugins/updown/libstrongswan-updown.la -@USE_EXT_AUTH_TRUE@am__append_30 = plugins/ext_auth -@MONOLITHIC_TRUE@@USE_EXT_AUTH_TRUE@am__append_31 = plugins/ext_auth/libstrongswan-ext-auth.la -@USE_EAP_IDENTITY_TRUE@am__append_32 = plugins/eap_identity -@MONOLITHIC_TRUE@@USE_EAP_IDENTITY_TRUE@am__append_33 = plugins/eap_identity/libstrongswan-eap-identity.la -@USE_EAP_SIM_TRUE@am__append_34 = plugins/eap_sim -@MONOLITHIC_TRUE@@USE_EAP_SIM_TRUE@am__append_35 = plugins/eap_sim/libstrongswan-eap-sim.la -@USE_EAP_SIM_FILE_TRUE@am__append_36 = plugins/eap_sim_file -@MONOLITHIC_TRUE@@USE_EAP_SIM_FILE_TRUE@am__append_37 = plugins/eap_sim_file/libstrongswan-eap-sim-file.la -@USE_EAP_SIM_PCSC_TRUE@am__append_38 = plugins/eap_sim_pcsc -@MONOLITHIC_TRUE@@USE_EAP_SIM_PCSC_TRUE@am__append_39 = plugins/eap_sim_pcsc/libstrongswan-eap-sim-pcsc.la -@USE_EAP_SIMAKA_SQL_TRUE@am__append_40 = plugins/eap_simaka_sql -@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_SQL_TRUE@am__append_41 = plugins/eap_simaka_sql/libstrongswan-eap-simaka-sql.la -@USE_EAP_SIMAKA_PSEUDONYM_TRUE@am__append_42 = plugins/eap_simaka_pseudonym -@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_PSEUDONYM_TRUE@am__append_43 = plugins/eap_simaka_pseudonym/libstrongswan-eap-simaka-pseudonym.la -@USE_EAP_SIMAKA_REAUTH_TRUE@am__append_44 = plugins/eap_simaka_reauth -@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_REAUTH_TRUE@am__append_45 = plugins/eap_simaka_reauth/libstrongswan-eap-simaka-reauth.la -@USE_EAP_AKA_TRUE@am__append_46 = plugins/eap_aka -@MONOLITHIC_TRUE@@USE_EAP_AKA_TRUE@am__append_47 = plugins/eap_aka/libstrongswan-eap-aka.la -@USE_EAP_AKA_3GPP2_TRUE@am__append_48 = plugins/eap_aka_3gpp2 -@MONOLITHIC_TRUE@@USE_EAP_AKA_3GPP2_TRUE@am__append_49 = plugins/eap_aka_3gpp2/libstrongswan-eap-aka-3gpp2.la -@MONOLITHIC_TRUE@@USE_SIMAKA_TRUE@am__append_50 = $(top_builddir)/src/libsimaka/libsimaka.la -@USE_EAP_MD5_TRUE@am__append_51 = plugins/eap_md5 -@MONOLITHIC_TRUE@@USE_EAP_MD5_TRUE@am__append_52 = plugins/eap_md5/libstrongswan-eap-md5.la -@USE_EAP_GTC_TRUE@am__append_53 = plugins/eap_gtc -@MONOLITHIC_TRUE@@USE_EAP_GTC_TRUE@am__append_54 = plugins/eap_gtc/libstrongswan-eap-gtc.la -@USE_EAP_MSCHAPV2_TRUE@am__append_55 = plugins/eap_mschapv2 -@MONOLITHIC_TRUE@@USE_EAP_MSCHAPV2_TRUE@am__append_56 = plugins/eap_mschapv2/libstrongswan-eap-mschapv2.la -@USE_EAP_DYNAMIC_TRUE@am__append_57 = plugins/eap_dynamic -@MONOLITHIC_TRUE@@USE_EAP_DYNAMIC_TRUE@am__append_58 = plugins/eap_dynamic/libstrongswan-eap-dynamic.la -@USE_EAP_RADIUS_TRUE@am__append_59 = plugins/eap_radius -@MONOLITHIC_TRUE@@USE_EAP_RADIUS_TRUE@am__append_60 = plugins/eap_radius/libstrongswan-eap-radius.la -@USE_EAP_TLS_TRUE@am__append_61 = plugins/eap_tls -@MONOLITHIC_TRUE@@USE_EAP_TLS_TRUE@am__append_62 = plugins/eap_tls/libstrongswan-eap-tls.la -@USE_EAP_TTLS_TRUE@am__append_63 = plugins/eap_ttls -@MONOLITHIC_TRUE@@USE_EAP_TTLS_TRUE@am__append_64 = plugins/eap_ttls/libstrongswan-eap-ttls.la -@USE_EAP_PEAP_TRUE@am__append_65 = plugins/eap_peap -@MONOLITHIC_TRUE@@USE_EAP_PEAP_TRUE@am__append_66 = plugins/eap_peap/libstrongswan-eap-peap.la -@USE_EAP_TNC_TRUE@am__append_67 = plugins/eap_tnc -@MONOLITHIC_TRUE@@USE_EAP_TNC_TRUE@am__append_68 = plugins/eap_tnc/libstrongswan-eap-tnc.la -@MONOLITHIC_TRUE@@USE_TLS_TRUE@am__append_69 = $(top_builddir)/src/libtls/libtls.la -@MONOLITHIC_TRUE@@USE_RADIUS_TRUE@am__append_70 = $(top_builddir)/src/libradius/libradius.la -@USE_TNC_IFMAP_TRUE@am__append_71 = plugins/tnc_ifmap -@MONOLITHIC_TRUE@@USE_TNC_IFMAP_TRUE@am__append_72 = plugins/tnc_ifmap/libstrongswan-tnc-ifmap.la -@USE_TNC_PDP_TRUE@am__append_73 = plugins/tnc_pdp -@MONOLITHIC_TRUE@@USE_TNC_PDP_TRUE@am__append_74 = plugins/tnc_pdp/libstrongswan-tnc-pdp.la -@MONOLITHIC_TRUE@@USE_LIBTNCCS_TRUE@am__append_75 = $(top_builddir)/src/libtnccs/libtnccs.la -@USE_MEDSRV_TRUE@am__append_76 = plugins/medsrv -@MONOLITHIC_TRUE@@USE_MEDSRV_TRUE@am__append_77 = plugins/medsrv/libstrongswan-medsrv.la -@USE_MEDCLI_TRUE@am__append_78 = plugins/medcli -@MONOLITHIC_TRUE@@USE_MEDCLI_TRUE@am__append_79 = plugins/medcli/libstrongswan-medcli.la -@USE_DHCP_TRUE@am__append_80 = plugins/dhcp -@MONOLITHIC_TRUE@@USE_DHCP_TRUE@am__append_81 = plugins/dhcp/libstrongswan-dhcp.la -@USE_OSX_ATTR_TRUE@am__append_82 = plugins/osx_attr -@MONOLITHIC_TRUE@@USE_OSX_ATTR_TRUE@am__append_83 = plugins/osx_attr/libstrongswan-osx-attr.la -@USE_ANDROID_DNS_TRUE@am__append_84 = plugins/android_dns -@MONOLITHIC_TRUE@@USE_ANDROID_DNS_TRUE@am__append_85 = plugins/android_dns/libstrongswan-android-dns.la -@USE_ANDROID_LOG_TRUE@am__append_86 = plugins/android_log -@MONOLITHIC_TRUE@@USE_ANDROID_LOG_TRUE@am__append_87 = plugins/android_log/libstrongswan-android-log.la -@USE_MAEMO_TRUE@am__append_88 = plugins/maemo -@MONOLITHIC_TRUE@@USE_MAEMO_TRUE@am__append_89 = plugins/maemo/libstrongswan-maemo.la -@USE_HA_TRUE@am__append_90 = plugins/ha -@MONOLITHIC_TRUE@@USE_HA_TRUE@am__append_91 = plugins/ha/libstrongswan-ha.la -@USE_KERNEL_LIBIPSEC_TRUE@am__append_92 = plugins/kernel_libipsec -@MONOLITHIC_TRUE@@USE_KERNEL_LIBIPSEC_TRUE@am__append_93 = plugins/kernel_libipsec/libstrongswan-kernel-libipsec.la -@USE_KERNEL_WFP_TRUE@am__append_94 = plugins/kernel_wfp -@MONOLITHIC_TRUE@@USE_KERNEL_WFP_TRUE@am__append_95 = plugins/kernel_wfp/libstrongswan-kernel-wfp.la -@USE_KERNEL_IPH_TRUE@am__append_96 = plugins/kernel_iph -@MONOLITHIC_TRUE@@USE_KERNEL_IPH_TRUE@am__append_97 = plugins/kernel_iph/libstrongswan-kernel-iph.la -@USE_WHITELIST_TRUE@am__append_98 = plugins/whitelist -@MONOLITHIC_TRUE@@USE_WHITELIST_TRUE@am__append_99 = plugins/whitelist/libstrongswan-whitelist.la -@USE_LOOKIP_TRUE@am__append_100 = plugins/lookip -@MONOLITHIC_TRUE@@USE_LOOKIP_TRUE@am__append_101 = plugins/lookip/libstrongswan-lookip.la -@USE_ERROR_NOTIFY_TRUE@am__append_102 = plugins/error_notify -@MONOLITHIC_TRUE@@USE_ERROR_NOTIFY_TRUE@am__append_103 = plugins/error_notify/libstrongswan-error-notify.la -@USE_CERTEXPIRE_TRUE@am__append_104 = plugins/certexpire -@MONOLITHIC_TRUE@@USE_CERTEXPIRE_TRUE@am__append_105 = plugins/certexpire/libstrongswan-certexpire.la -@USE_SYSTIME_FIX_TRUE@am__append_106 = plugins/systime_fix -@MONOLITHIC_TRUE@@USE_SYSTIME_FIX_TRUE@am__append_107 = plugins/systime_fix/libstrongswan-systime-fix.la -@USE_LED_TRUE@am__append_108 = plugins/led -@MONOLITHIC_TRUE@@USE_LED_TRUE@am__append_109 = plugins/led/libstrongswan-led.la -@USE_DUPLICHECK_TRUE@am__append_110 = plugins/duplicheck -@MONOLITHIC_TRUE@@USE_DUPLICHECK_TRUE@am__append_111 = plugins/duplicheck/libstrongswan-duplicheck.la -@USE_COUPLING_TRUE@am__append_112 = plugins/coupling -@MONOLITHIC_TRUE@@USE_COUPLING_TRUE@am__append_113 = plugins/coupling/libstrongswan-coupling.la -@USE_RADATTR_TRUE@am__append_114 = plugins/radattr -@MONOLITHIC_TRUE@@USE_RADATTR_TRUE@am__append_115 = plugins/radattr/libstrongswan-radattr.la -@USE_UCI_TRUE@am__append_116 = plugins/uci -@MONOLITHIC_TRUE@@USE_UCI_TRUE@am__append_117 = plugins/uci/libstrongswan-uci.la -@USE_ADDRBLOCK_TRUE@am__append_118 = plugins/addrblock -@MONOLITHIC_TRUE@@USE_ADDRBLOCK_TRUE@am__append_119 = plugins/addrblock/libstrongswan-addrblock.la -@USE_UNITY_TRUE@am__append_120 = plugins/unity -@MONOLITHIC_TRUE@@USE_UNITY_TRUE@am__append_121 = plugins/unity/libstrongswan-unity.la -@USE_UNIT_TESTS_TRUE@am__append_122 = plugins/unit_tester -@MONOLITHIC_TRUE@@USE_UNIT_TESTS_TRUE@am__append_123 = plugins/unit_tester/libstrongswan-unit-tester.la -@USE_XAUTH_GENERIC_TRUE@am__append_124 = plugins/xauth_generic -@MONOLITHIC_TRUE@@USE_XAUTH_GENERIC_TRUE@am__append_125 = plugins/xauth_generic/libstrongswan-xauth-generic.la -@USE_XAUTH_EAP_TRUE@am__append_126 = plugins/xauth_eap -@MONOLITHIC_TRUE@@USE_XAUTH_EAP_TRUE@am__append_127 = plugins/xauth_eap/libstrongswan-xauth-eap.la -@USE_XAUTH_PAM_TRUE@am__append_128 = plugins/xauth_pam -@MONOLITHIC_TRUE@@USE_XAUTH_PAM_TRUE@am__append_129 = plugins/xauth_pam/libstrongswan-xauth-pam.la -@USE_XAUTH_NOAUTH_TRUE@am__append_130 = plugins/xauth_noauth -@MONOLITHIC_TRUE@@USE_XAUTH_NOAUTH_TRUE@am__append_131 = plugins/xauth_noauth/libstrongswan-xauth-noauth.la +@USE_CONNMARK_TRUE@am__append_14 = plugins/connmark +@MONOLITHIC_TRUE@@USE_CONNMARK_TRUE@am__append_15 = plugins/connmark/libstrongswan-connmark.la +@USE_FORECAST_TRUE@am__append_16 = plugins/forecast +@MONOLITHIC_TRUE@@USE_FORECAST_TRUE@am__append_17 = plugins/forecast/libstrongswan-forecast.la +@USE_FARP_TRUE@am__append_18 = plugins/farp +@MONOLITHIC_TRUE@@USE_FARP_TRUE@am__append_19 = plugins/farp/libstrongswan-farp.la +@USE_STROKE_TRUE@am__append_20 = plugins/stroke +@MONOLITHIC_TRUE@@USE_STROKE_TRUE@am__append_21 = plugins/stroke/libstrongswan-stroke.la +@USE_VICI_TRUE@am__append_22 = plugins/vici +@MONOLITHIC_TRUE@@USE_VICI_TRUE@am__append_23 = plugins/vici/libstrongswan-vici.la +@USE_SMP_TRUE@am__append_24 = plugins/smp +@MONOLITHIC_TRUE@@USE_SMP_TRUE@am__append_25 = plugins/smp/libstrongswan-smp.la +@USE_SQL_TRUE@am__append_26 = plugins/sql +@MONOLITHIC_TRUE@@USE_SQL_TRUE@am__append_27 = plugins/sql/libstrongswan-sql.la +@USE_DNSCERT_TRUE@am__append_28 = plugins/dnscert +@MONOLITHIC_TRUE@@USE_DNSCERT_TRUE@am__append_29 = plugins/dnscert/libstrongswan-dnscert.la +@USE_IPSECKEY_TRUE@am__append_30 = plugins/ipseckey +@MONOLITHIC_TRUE@@USE_IPSECKEY_TRUE@am__append_31 = plugins/ipseckey/libstrongswan-ipseckey.la +@USE_UPDOWN_TRUE@am__append_32 = plugins/updown +@MONOLITHIC_TRUE@@USE_UPDOWN_TRUE@am__append_33 = plugins/updown/libstrongswan-updown.la +@USE_EXT_AUTH_TRUE@am__append_34 = plugins/ext_auth +@MONOLITHIC_TRUE@@USE_EXT_AUTH_TRUE@am__append_35 = plugins/ext_auth/libstrongswan-ext-auth.la +@USE_EAP_IDENTITY_TRUE@am__append_36 = plugins/eap_identity +@MONOLITHIC_TRUE@@USE_EAP_IDENTITY_TRUE@am__append_37 = plugins/eap_identity/libstrongswan-eap-identity.la +@USE_EAP_SIM_TRUE@am__append_38 = plugins/eap_sim +@MONOLITHIC_TRUE@@USE_EAP_SIM_TRUE@am__append_39 = plugins/eap_sim/libstrongswan-eap-sim.la +@USE_EAP_SIM_FILE_TRUE@am__append_40 = plugins/eap_sim_file +@MONOLITHIC_TRUE@@USE_EAP_SIM_FILE_TRUE@am__append_41 = plugins/eap_sim_file/libstrongswan-eap-sim-file.la +@USE_EAP_SIM_PCSC_TRUE@am__append_42 = plugins/eap_sim_pcsc +@MONOLITHIC_TRUE@@USE_EAP_SIM_PCSC_TRUE@am__append_43 = plugins/eap_sim_pcsc/libstrongswan-eap-sim-pcsc.la +@USE_EAP_SIMAKA_SQL_TRUE@am__append_44 = plugins/eap_simaka_sql +@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_SQL_TRUE@am__append_45 = plugins/eap_simaka_sql/libstrongswan-eap-simaka-sql.la +@USE_EAP_SIMAKA_PSEUDONYM_TRUE@am__append_46 = plugins/eap_simaka_pseudonym +@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_PSEUDONYM_TRUE@am__append_47 = plugins/eap_simaka_pseudonym/libstrongswan-eap-simaka-pseudonym.la +@USE_EAP_SIMAKA_REAUTH_TRUE@am__append_48 = plugins/eap_simaka_reauth +@MONOLITHIC_TRUE@@USE_EAP_SIMAKA_REAUTH_TRUE@am__append_49 = plugins/eap_simaka_reauth/libstrongswan-eap-simaka-reauth.la +@USE_EAP_AKA_TRUE@am__append_50 = plugins/eap_aka +@MONOLITHIC_TRUE@@USE_EAP_AKA_TRUE@am__append_51 = plugins/eap_aka/libstrongswan-eap-aka.la +@USE_EAP_AKA_3GPP2_TRUE@am__append_52 = plugins/eap_aka_3gpp2 +@MONOLITHIC_TRUE@@USE_EAP_AKA_3GPP2_TRUE@am__append_53 = plugins/eap_aka_3gpp2/libstrongswan-eap-aka-3gpp2.la +@MONOLITHIC_TRUE@@USE_SIMAKA_TRUE@am__append_54 = $(top_builddir)/src/libsimaka/libsimaka.la +@USE_EAP_MD5_TRUE@am__append_55 = plugins/eap_md5 +@MONOLITHIC_TRUE@@USE_EAP_MD5_TRUE@am__append_56 = plugins/eap_md5/libstrongswan-eap-md5.la +@USE_EAP_GTC_TRUE@am__append_57 = plugins/eap_gtc +@MONOLITHIC_TRUE@@USE_EAP_GTC_TRUE@am__append_58 = plugins/eap_gtc/libstrongswan-eap-gtc.la +@USE_EAP_MSCHAPV2_TRUE@am__append_59 = plugins/eap_mschapv2 +@MONOLITHIC_TRUE@@USE_EAP_MSCHAPV2_TRUE@am__append_60 = plugins/eap_mschapv2/libstrongswan-eap-mschapv2.la +@USE_EAP_DYNAMIC_TRUE@am__append_61 = plugins/eap_dynamic +@MONOLITHIC_TRUE@@USE_EAP_DYNAMIC_TRUE@am__append_62 = plugins/eap_dynamic/libstrongswan-eap-dynamic.la +@USE_EAP_RADIUS_TRUE@am__append_63 = plugins/eap_radius +@MONOLITHIC_TRUE@@USE_EAP_RADIUS_TRUE@am__append_64 = plugins/eap_radius/libstrongswan-eap-radius.la +@USE_EAP_TLS_TRUE@am__append_65 = plugins/eap_tls +@MONOLITHIC_TRUE@@USE_EAP_TLS_TRUE@am__append_66 = plugins/eap_tls/libstrongswan-eap-tls.la +@USE_EAP_TTLS_TRUE@am__append_67 = plugins/eap_ttls +@MONOLITHIC_TRUE@@USE_EAP_TTLS_TRUE@am__append_68 = plugins/eap_ttls/libstrongswan-eap-ttls.la +@USE_EAP_PEAP_TRUE@am__append_69 = plugins/eap_peap +@MONOLITHIC_TRUE@@USE_EAP_PEAP_TRUE@am__append_70 = plugins/eap_peap/libstrongswan-eap-peap.la +@USE_EAP_TNC_TRUE@am__append_71 = plugins/eap_tnc +@MONOLITHIC_TRUE@@USE_EAP_TNC_TRUE@am__append_72 = plugins/eap_tnc/libstrongswan-eap-tnc.la +@MONOLITHIC_TRUE@@USE_TLS_TRUE@am__append_73 = $(top_builddir)/src/libtls/libtls.la +@MONOLITHIC_TRUE@@USE_RADIUS_TRUE@am__append_74 = $(top_builddir)/src/libradius/libradius.la +@USE_TNC_IFMAP_TRUE@am__append_75 = plugins/tnc_ifmap +@MONOLITHIC_TRUE@@USE_TNC_IFMAP_TRUE@am__append_76 = plugins/tnc_ifmap/libstrongswan-tnc-ifmap.la +@USE_TNC_PDP_TRUE@am__append_77 = plugins/tnc_pdp +@MONOLITHIC_TRUE@@USE_TNC_PDP_TRUE@am__append_78 = plugins/tnc_pdp/libstrongswan-tnc-pdp.la +@MONOLITHIC_TRUE@@USE_LIBTNCCS_TRUE@am__append_79 = $(top_builddir)/src/libtnccs/libtnccs.la +@USE_MEDSRV_TRUE@am__append_80 = plugins/medsrv +@MONOLITHIC_TRUE@@USE_MEDSRV_TRUE@am__append_81 = plugins/medsrv/libstrongswan-medsrv.la +@USE_MEDCLI_TRUE@am__append_82 = plugins/medcli +@MONOLITHIC_TRUE@@USE_MEDCLI_TRUE@am__append_83 = plugins/medcli/libstrongswan-medcli.la +@USE_DHCP_TRUE@am__append_84 = plugins/dhcp +@MONOLITHIC_TRUE@@USE_DHCP_TRUE@am__append_85 = plugins/dhcp/libstrongswan-dhcp.la +@USE_OSX_ATTR_TRUE@am__append_86 = plugins/osx_attr +@MONOLITHIC_TRUE@@USE_OSX_ATTR_TRUE@am__append_87 = plugins/osx_attr/libstrongswan-osx-attr.la +@USE_ANDROID_DNS_TRUE@am__append_88 = plugins/android_dns +@MONOLITHIC_TRUE@@USE_ANDROID_DNS_TRUE@am__append_89 = plugins/android_dns/libstrongswan-android-dns.la +@USE_ANDROID_LOG_TRUE@am__append_90 = plugins/android_log +@MONOLITHIC_TRUE@@USE_ANDROID_LOG_TRUE@am__append_91 = plugins/android_log/libstrongswan-android-log.la +@USE_MAEMO_TRUE@am__append_92 = plugins/maemo +@MONOLITHIC_TRUE@@USE_MAEMO_TRUE@am__append_93 = plugins/maemo/libstrongswan-maemo.la +@USE_HA_TRUE@am__append_94 = plugins/ha +@MONOLITHIC_TRUE@@USE_HA_TRUE@am__append_95 = plugins/ha/libstrongswan-ha.la +@USE_KERNEL_LIBIPSEC_TRUE@am__append_96 = plugins/kernel_libipsec +@MONOLITHIC_TRUE@@USE_KERNEL_LIBIPSEC_TRUE@am__append_97 = plugins/kernel_libipsec/libstrongswan-kernel-libipsec.la +@USE_KERNEL_WFP_TRUE@am__append_98 = plugins/kernel_wfp +@MONOLITHIC_TRUE@@USE_KERNEL_WFP_TRUE@am__append_99 = plugins/kernel_wfp/libstrongswan-kernel-wfp.la +@USE_KERNEL_IPH_TRUE@am__append_100 = plugins/kernel_iph +@MONOLITHIC_TRUE@@USE_KERNEL_IPH_TRUE@am__append_101 = plugins/kernel_iph/libstrongswan-kernel-iph.la +@USE_WHITELIST_TRUE@am__append_102 = plugins/whitelist +@MONOLITHIC_TRUE@@USE_WHITELIST_TRUE@am__append_103 = plugins/whitelist/libstrongswan-whitelist.la +@USE_LOOKIP_TRUE@am__append_104 = plugins/lookip +@MONOLITHIC_TRUE@@USE_LOOKIP_TRUE@am__append_105 = plugins/lookip/libstrongswan-lookip.la +@USE_ERROR_NOTIFY_TRUE@am__append_106 = plugins/error_notify +@MONOLITHIC_TRUE@@USE_ERROR_NOTIFY_TRUE@am__append_107 = plugins/error_notify/libstrongswan-error-notify.la +@USE_CERTEXPIRE_TRUE@am__append_108 = plugins/certexpire +@MONOLITHIC_TRUE@@USE_CERTEXPIRE_TRUE@am__append_109 = plugins/certexpire/libstrongswan-certexpire.la +@USE_SYSTIME_FIX_TRUE@am__append_110 = plugins/systime_fix +@MONOLITHIC_TRUE@@USE_SYSTIME_FIX_TRUE@am__append_111 = plugins/systime_fix/libstrongswan-systime-fix.la +@USE_LED_TRUE@am__append_112 = plugins/led +@MONOLITHIC_TRUE@@USE_LED_TRUE@am__append_113 = plugins/led/libstrongswan-led.la +@USE_DUPLICHECK_TRUE@am__append_114 = plugins/duplicheck +@MONOLITHIC_TRUE@@USE_DUPLICHECK_TRUE@am__append_115 = plugins/duplicheck/libstrongswan-duplicheck.la +@USE_COUPLING_TRUE@am__append_116 = plugins/coupling +@MONOLITHIC_TRUE@@USE_COUPLING_TRUE@am__append_117 = plugins/coupling/libstrongswan-coupling.la +@USE_RADATTR_TRUE@am__append_118 = plugins/radattr +@MONOLITHIC_TRUE@@USE_RADATTR_TRUE@am__append_119 = plugins/radattr/libstrongswan-radattr.la +@USE_UCI_TRUE@am__append_120 = plugins/uci +@MONOLITHIC_TRUE@@USE_UCI_TRUE@am__append_121 = plugins/uci/libstrongswan-uci.la +@USE_ADDRBLOCK_TRUE@am__append_122 = plugins/addrblock +@MONOLITHIC_TRUE@@USE_ADDRBLOCK_TRUE@am__append_123 = plugins/addrblock/libstrongswan-addrblock.la +@USE_UNITY_TRUE@am__append_124 = plugins/unity +@MONOLITHIC_TRUE@@USE_UNITY_TRUE@am__append_125 = plugins/unity/libstrongswan-unity.la +@USE_XAUTH_GENERIC_TRUE@am__append_126 = plugins/xauth_generic +@MONOLITHIC_TRUE@@USE_XAUTH_GENERIC_TRUE@am__append_127 = plugins/xauth_generic/libstrongswan-xauth-generic.la +@USE_XAUTH_EAP_TRUE@am__append_128 = plugins/xauth_eap +@MONOLITHIC_TRUE@@USE_XAUTH_EAP_TRUE@am__append_129 = plugins/xauth_eap/libstrongswan-xauth-eap.la +@USE_XAUTH_PAM_TRUE@am__append_130 = plugins/xauth_pam +@MONOLITHIC_TRUE@@USE_XAUTH_PAM_TRUE@am__append_131 = plugins/xauth_pam/libstrongswan-xauth-pam.la +@USE_XAUTH_NOAUTH_TRUE@am__append_132 = plugins/xauth_noauth +@MONOLITHIC_TRUE@@USE_XAUTH_NOAUTH_TRUE@am__append_133 = plugins/xauth_noauth/libstrongswan-xauth-noauth.la +@USE_RESOLVE_TRUE@am__append_134 = plugins/resolve +@MONOLITHIC_TRUE@@USE_RESOLVE_TRUE@am__append_135 = plugins/resolve/libstrongswan-resolve.la +@USE_ATTR_TRUE@am__append_136 = plugins/attr +@MONOLITHIC_TRUE@@USE_ATTR_TRUE@am__append_137 = plugins/attr/libstrongswan-attr.la +@USE_ATTR_SQL_TRUE@am__append_138 = plugins/attr_sql +@MONOLITHIC_TRUE@@USE_ATTR_SQL_TRUE@am__append_139 = plugins/attr_sql/libstrongswan-attr-sql.la subdir = src/libcharon DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp @@ -325,12 +334,12 @@ libcharon_la_DEPENDENCIES = \ $(am__append_29) $(am__append_31) $(am__append_33) \ $(am__append_35) $(am__append_37) $(am__append_39) \ $(am__append_41) $(am__append_43) $(am__append_45) \ - $(am__append_47) $(am__append_49) $(am__append_50) \ - $(am__append_52) $(am__append_54) $(am__append_56) \ + $(am__append_47) $(am__append_49) $(am__append_51) \ + $(am__append_53) $(am__append_54) $(am__append_56) \ $(am__append_58) $(am__append_60) $(am__append_62) \ $(am__append_64) $(am__append_66) $(am__append_68) \ - $(am__append_69) $(am__append_70) $(am__append_72) \ - $(am__append_74) $(am__append_75) $(am__append_77) \ + $(am__append_70) $(am__append_72) $(am__append_73) \ + $(am__append_74) $(am__append_76) $(am__append_78) \ $(am__append_79) $(am__append_81) $(am__append_83) \ $(am__append_85) $(am__append_87) $(am__append_89) \ $(am__append_91) $(am__append_93) $(am__append_95) \ @@ -339,8 +348,14 @@ libcharon_la_DEPENDENCIES = \ $(am__append_109) $(am__append_111) $(am__append_113) \ $(am__append_115) $(am__append_117) $(am__append_119) \ $(am__append_121) $(am__append_123) $(am__append_125) \ - $(am__append_127) $(am__append_129) $(am__append_131) -am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \ + $(am__append_127) $(am__append_129) $(am__append_131) \ + $(am__append_133) $(am__append_135) $(am__append_137) \ + $(am__append_139) +am__libcharon_la_SOURCES_DIST = attributes/attributes.c \ + attributes/attributes.h attributes/attribute_provider.h \ + attributes/attribute_handler.h attributes/attribute_manager.c \ + attributes/attribute_manager.h attributes/mem_pool.c \ + attributes/mem_pool.h bus/bus.c bus/bus.h \ bus/listeners/listener.h bus/listeners/logger.h \ bus/listeners/file_logger.c bus/listeners/file_logger.h \ config/backend_manager.c config/backend_manager.h \ @@ -421,7 +436,9 @@ am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \ processing/jobs/roam_job.h processing/jobs/update_sa_job.c \ processing/jobs/update_sa_job.h \ processing/jobs/inactivity_job.c \ - processing/jobs/inactivity_job.h sa/eap/eap_method.c \ + processing/jobs/inactivity_job.h \ + processing/jobs/initiate_tasks_job.c \ + processing/jobs/initiate_tasks_job.h sa/eap/eap_method.c \ sa/eap/eap_method.h sa/eap/eap_inner_method.h \ sa/eap/eap_manager.c sa/eap/eap_manager.h \ sa/xauth/xauth_method.c sa/xauth/xauth_method.h \ @@ -429,7 +446,8 @@ am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \ sa/authenticator.c sa/authenticator.h sa/child_sa.c \ sa/child_sa.h sa/ike_sa.c sa/ike_sa.h sa/ike_sa_id.c \ sa/ike_sa_id.h sa/keymat.h sa/keymat.c sa/ike_sa_manager.c \ - sa/ike_sa_manager.h sa/task_manager.h sa/task_manager.c \ + sa/ike_sa_manager.h sa/child_sa_manager.c \ + sa/child_sa_manager.h sa/task_manager.h sa/task_manager.c \ sa/shunt_manager.c sa/shunt_manager.h sa/trap_manager.c \ sa/trap_manager.h sa/task.c sa/task.h sa/ikev2/keymat_v2.c \ sa/ikev2/keymat_v2.h sa/ikev2/task_manager_v2.c \ @@ -454,6 +472,8 @@ am__libcharon_la_SOURCES_DIST = bus/bus.c bus/bus.h \ sa/ikev2/tasks/ike_mobike.c sa/ikev2/tasks/ike_mobike.h \ sa/ikev2/tasks/ike_rekey.c sa/ikev2/tasks/ike_rekey.h \ sa/ikev2/tasks/ike_reauth.c sa/ikev2/tasks/ike_reauth.h \ + sa/ikev2/tasks/ike_reauth_complete.c \ + sa/ikev2/tasks/ike_reauth_complete.h \ sa/ikev2/tasks/ike_auth_lifetime.c \ sa/ikev2/tasks/ike_auth_lifetime.h sa/ikev2/tasks/ike_vendor.c \ sa/ikev2/tasks/ike_vendor.h sa/ikev1/keymat_v1.c \ @@ -514,6 +534,7 @@ am__dirstamp = $(am__leading_dot)dirstamp @USE_IKEV2_TRUE@ sa/ikev2/tasks/ike_mobike.lo \ @USE_IKEV2_TRUE@ sa/ikev2/tasks/ike_rekey.lo \ @USE_IKEV2_TRUE@ sa/ikev2/tasks/ike_reauth.lo \ +@USE_IKEV2_TRUE@ sa/ikev2/tasks/ike_reauth_complete.lo \ @USE_IKEV2_TRUE@ sa/ikev2/tasks/ike_auth_lifetime.lo \ @USE_IKEV2_TRUE@ sa/ikev2/tasks/ike_vendor.lo @USE_IKEV1_TRUE@am__objects_2 = sa/ikev1/keymat_v1.lo \ @@ -543,7 +564,9 @@ am__dirstamp = $(am__leading_dot)dirstamp @USE_ME_TRUE@ sa/ikev2/connect_manager.lo \ @USE_ME_TRUE@ sa/ikev2/mediation_manager.lo \ @USE_ME_TRUE@ sa/ikev2/tasks/ike_me.lo -am_libcharon_la_OBJECTS = bus/bus.lo bus/listeners/file_logger.lo \ +am_libcharon_la_OBJECTS = attributes/attributes.lo \ + attributes/attribute_manager.lo attributes/mem_pool.lo \ + bus/bus.lo bus/listeners/file_logger.lo \ config/backend_manager.lo config/child_cfg.lo \ config/ike_cfg.lo config/peer_cfg.lo config/proposal.lo \ control/controller.lo daemon.lo encoding/generator.lo \ @@ -587,13 +610,14 @@ am_libcharon_la_OBJECTS = bus/bus.lo bus/listeners/file_logger.lo \ processing/jobs/send_keepalive_job.lo \ processing/jobs/start_action_job.lo \ processing/jobs/roam_job.lo processing/jobs/update_sa_job.lo \ - processing/jobs/inactivity_job.lo sa/eap/eap_method.lo \ + processing/jobs/inactivity_job.lo \ + processing/jobs/initiate_tasks_job.lo sa/eap/eap_method.lo \ sa/eap/eap_manager.lo sa/xauth/xauth_method.lo \ sa/xauth/xauth_manager.lo sa/authenticator.lo sa/child_sa.lo \ sa/ike_sa.lo sa/ike_sa_id.lo sa/keymat.lo sa/ike_sa_manager.lo \ - sa/task_manager.lo sa/shunt_manager.lo sa/trap_manager.lo \ - sa/task.lo $(am__objects_1) $(am__objects_2) $(am__objects_3) \ - $(am__objects_4) + sa/child_sa_manager.lo sa/task_manager.lo sa/shunt_manager.lo \ + sa/trap_manager.lo sa/task.lo $(am__objects_1) \ + $(am__objects_2) $(am__objects_3) $(am__objects_4) libcharon_la_OBJECTS = $(am_libcharon_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -676,11 +700,11 @@ am__define_uniq_tagged_files = \ ETAGS = etags CTAGS = ctags DIST_SUBDIRS = . plugins/load_tester plugins/socket_default \ - plugins/socket_dynamic plugins/socket_win plugins/farp \ - plugins/stroke plugins/vici plugins/smp plugins/sql \ - plugins/dnscert plugins/ipseckey plugins/updown \ - plugins/ext_auth plugins/eap_identity plugins/eap_sim \ - plugins/eap_sim_file plugins/eap_sim_pcsc \ + plugins/socket_dynamic plugins/socket_win plugins/connmark \ + plugins/forecast plugins/farp plugins/stroke plugins/vici \ + plugins/smp plugins/sql plugins/dnscert plugins/ipseckey \ + plugins/updown plugins/ext_auth plugins/eap_identity \ + plugins/eap_sim plugins/eap_sim_file plugins/eap_sim_pcsc \ plugins/eap_simaka_sql plugins/eap_simaka_pseudonym \ plugins/eap_simaka_reauth plugins/eap_aka \ plugins/eap_aka_3gpp2 plugins/eap_md5 plugins/eap_gtc \ @@ -694,8 +718,9 @@ DIST_SUBDIRS = . plugins/load_tester plugins/socket_default \ plugins/error_notify plugins/certexpire plugins/systime_fix \ plugins/led plugins/duplicheck plugins/coupling \ plugins/radattr plugins/uci plugins/addrblock plugins/unity \ - plugins/unit_tester plugins/xauth_generic plugins/xauth_eap \ - plugins/xauth_pam plugins/xauth_noauth + plugins/xauth_generic plugins/xauth_eap plugins/xauth_pam \ + plugins/xauth_noauth plugins/resolve plugins/attr \ + plugins/attr_sql tests DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -747,6 +772,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -807,10 +833,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -884,6 +912,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ @@ -943,16 +973,20 @@ urandom_device = @urandom_device@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ ipseclib_LTLIBRARIES = libcharon.la -libcharon_la_SOURCES = bus/bus.c bus/bus.h bus/listeners/listener.h \ - bus/listeners/logger.h bus/listeners/file_logger.c \ - bus/listeners/file_logger.h config/backend_manager.c \ - config/backend_manager.h config/backend.h config/child_cfg.c \ - config/child_cfg.h config/ike_cfg.c config/ike_cfg.h \ - config/peer_cfg.c config/peer_cfg.h config/proposal.c \ - config/proposal.h control/controller.c control/controller.h \ - daemon.c daemon.h encoding/generator.c encoding/generator.h \ - encoding/message.c encoding/message.h encoding/parser.c \ - encoding/parser.h encoding/payloads/auth_payload.c \ +libcharon_la_SOURCES = attributes/attributes.c attributes/attributes.h \ + attributes/attribute_provider.h attributes/attribute_handler.h \ + attributes/attribute_manager.c attributes/attribute_manager.h \ + attributes/mem_pool.c attributes/mem_pool.h bus/bus.c \ + bus/bus.h bus/listeners/listener.h bus/listeners/logger.h \ + bus/listeners/file_logger.c bus/listeners/file_logger.h \ + config/backend_manager.c config/backend_manager.h \ + config/backend.h config/child_cfg.c config/child_cfg.h \ + config/ike_cfg.c config/ike_cfg.h config/peer_cfg.c \ + config/peer_cfg.h config/proposal.c config/proposal.h \ + control/controller.c control/controller.h daemon.c daemon.h \ + encoding/generator.c encoding/generator.h encoding/message.c \ + encoding/message.h encoding/parser.c encoding/parser.h \ + encoding/payloads/auth_payload.c \ encoding/payloads/auth_payload.h \ encoding/payloads/cert_payload.c \ encoding/payloads/cert_payload.h \ @@ -1023,7 +1057,9 @@ libcharon_la_SOURCES = bus/bus.c bus/bus.h bus/listeners/listener.h \ processing/jobs/roam_job.h processing/jobs/update_sa_job.c \ processing/jobs/update_sa_job.h \ processing/jobs/inactivity_job.c \ - processing/jobs/inactivity_job.h sa/eap/eap_method.c \ + processing/jobs/inactivity_job.h \ + processing/jobs/initiate_tasks_job.c \ + processing/jobs/initiate_tasks_job.h sa/eap/eap_method.c \ sa/eap/eap_method.h sa/eap/eap_inner_method.h \ sa/eap/eap_manager.c sa/eap/eap_manager.h \ sa/xauth/xauth_method.c sa/xauth/xauth_method.h \ @@ -1031,7 +1067,8 @@ libcharon_la_SOURCES = bus/bus.c bus/bus.h bus/listeners/listener.h \ sa/authenticator.c sa/authenticator.h sa/child_sa.c \ sa/child_sa.h sa/ike_sa.c sa/ike_sa.h sa/ike_sa_id.c \ sa/ike_sa_id.h sa/keymat.h sa/keymat.c sa/ike_sa_manager.c \ - sa/ike_sa_manager.h sa/task_manager.h sa/task_manager.c \ + sa/ike_sa_manager.h sa/child_sa_manager.c \ + sa/child_sa_manager.h sa/task_manager.h sa/task_manager.c \ sa/shunt_manager.c sa/shunt_manager.h sa/trap_manager.c \ sa/trap_manager.h sa/task.c sa/task.h $(am__append_1) \ $(am__append_2) $(am__append_3) $(am__append_5) @@ -1057,12 +1094,12 @@ libcharon_la_LIBADD = \ $(am__append_33) $(am__append_35) $(am__append_37) \ $(am__append_39) $(am__append_41) $(am__append_43) \ $(am__append_45) $(am__append_47) $(am__append_49) \ - $(am__append_50) $(am__append_52) $(am__append_54) \ + $(am__append_51) $(am__append_53) $(am__append_54) \ $(am__append_56) $(am__append_58) $(am__append_60) \ $(am__append_62) $(am__append_64) $(am__append_66) \ - $(am__append_68) $(am__append_69) $(am__append_70) \ - $(am__append_72) $(am__append_74) $(am__append_75) \ - $(am__append_77) $(am__append_79) $(am__append_81) \ + $(am__append_68) $(am__append_70) $(am__append_72) \ + $(am__append_73) $(am__append_74) $(am__append_76) \ + $(am__append_78) $(am__append_79) $(am__append_81) \ $(am__append_83) $(am__append_85) $(am__append_87) \ $(am__append_89) $(am__append_91) $(am__append_93) \ $(am__append_95) $(am__append_97) $(am__append_99) \ @@ -1071,7 +1108,8 @@ libcharon_la_LIBADD = \ $(am__append_113) $(am__append_115) $(am__append_117) \ $(am__append_119) $(am__append_121) $(am__append_123) \ $(am__append_125) $(am__append_127) $(am__append_129) \ - $(am__append_131) + $(am__append_131) $(am__append_133) $(am__append_135) \ + $(am__append_137) $(am__append_139) EXTRA_DIST = Android.mk @MONOLITHIC_FALSE@SUBDIRS = . $(am__append_6) $(am__append_8) \ @MONOLITHIC_FALSE@ $(am__append_10) $(am__append_12) \ @@ -1084,13 +1122,13 @@ EXTRA_DIST = Android.mk @MONOLITHIC_FALSE@ $(am__append_38) $(am__append_40) \ @MONOLITHIC_FALSE@ $(am__append_42) $(am__append_44) \ @MONOLITHIC_FALSE@ $(am__append_46) $(am__append_48) \ -@MONOLITHIC_FALSE@ $(am__append_51) $(am__append_53) \ +@MONOLITHIC_FALSE@ $(am__append_50) $(am__append_52) \ @MONOLITHIC_FALSE@ $(am__append_55) $(am__append_57) \ @MONOLITHIC_FALSE@ $(am__append_59) $(am__append_61) \ @MONOLITHIC_FALSE@ $(am__append_63) $(am__append_65) \ -@MONOLITHIC_FALSE@ $(am__append_67) $(am__append_71) \ -@MONOLITHIC_FALSE@ $(am__append_73) $(am__append_76) \ -@MONOLITHIC_FALSE@ $(am__append_78) $(am__append_80) \ +@MONOLITHIC_FALSE@ $(am__append_67) $(am__append_69) \ +@MONOLITHIC_FALSE@ $(am__append_71) $(am__append_75) \ +@MONOLITHIC_FALSE@ $(am__append_77) $(am__append_80) \ @MONOLITHIC_FALSE@ $(am__append_82) $(am__append_84) \ @MONOLITHIC_FALSE@ $(am__append_86) $(am__append_88) \ @MONOLITHIC_FALSE@ $(am__append_90) $(am__append_92) \ @@ -1103,7 +1141,9 @@ EXTRA_DIST = Android.mk @MONOLITHIC_FALSE@ $(am__append_118) $(am__append_120) \ @MONOLITHIC_FALSE@ $(am__append_122) $(am__append_124) \ @MONOLITHIC_FALSE@ $(am__append_126) $(am__append_128) \ -@MONOLITHIC_FALSE@ $(am__append_130) +@MONOLITHIC_FALSE@ $(am__append_130) $(am__append_132) \ +@MONOLITHIC_FALSE@ $(am__append_134) $(am__append_136) \ +@MONOLITHIC_FALSE@ $(am__append_138) tests # build optional plugins ######################## @@ -1118,13 +1158,13 @@ EXTRA_DIST = Android.mk @MONOLITHIC_TRUE@ $(am__append_38) $(am__append_40) \ @MONOLITHIC_TRUE@ $(am__append_42) $(am__append_44) \ @MONOLITHIC_TRUE@ $(am__append_46) $(am__append_48) \ -@MONOLITHIC_TRUE@ $(am__append_51) $(am__append_53) \ +@MONOLITHIC_TRUE@ $(am__append_50) $(am__append_52) \ @MONOLITHIC_TRUE@ $(am__append_55) $(am__append_57) \ @MONOLITHIC_TRUE@ $(am__append_59) $(am__append_61) \ @MONOLITHIC_TRUE@ $(am__append_63) $(am__append_65) \ -@MONOLITHIC_TRUE@ $(am__append_67) $(am__append_71) \ -@MONOLITHIC_TRUE@ $(am__append_73) $(am__append_76) \ -@MONOLITHIC_TRUE@ $(am__append_78) $(am__append_80) \ +@MONOLITHIC_TRUE@ $(am__append_67) $(am__append_69) \ +@MONOLITHIC_TRUE@ $(am__append_71) $(am__append_75) \ +@MONOLITHIC_TRUE@ $(am__append_77) $(am__append_80) \ @MONOLITHIC_TRUE@ $(am__append_82) $(am__append_84) \ @MONOLITHIC_TRUE@ $(am__append_86) $(am__append_88) \ @MONOLITHIC_TRUE@ $(am__append_90) $(am__append_92) \ @@ -1137,7 +1177,9 @@ EXTRA_DIST = Android.mk @MONOLITHIC_TRUE@ $(am__append_118) $(am__append_120) \ @MONOLITHIC_TRUE@ $(am__append_122) $(am__append_124) \ @MONOLITHIC_TRUE@ $(am__append_126) $(am__append_128) \ -@MONOLITHIC_TRUE@ $(am__append_130) +@MONOLITHIC_TRUE@ $(am__append_130) $(am__append_132) \ +@MONOLITHIC_TRUE@ $(am__append_134) $(am__append_136) \ +@MONOLITHIC_TRUE@ $(am__append_138) . tests all: all-recursive .SUFFIXES: @@ -1207,6 +1249,18 @@ clean-ipseclibLTLIBRARIES: echo rm -f $${locs}; \ rm -f $${locs}; \ } +attributes/$(am__dirstamp): + @$(MKDIR_P) attributes + @: > attributes/$(am__dirstamp) +attributes/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) attributes/$(DEPDIR) + @: > attributes/$(DEPDIR)/$(am__dirstamp) +attributes/attributes.lo: attributes/$(am__dirstamp) \ + attributes/$(DEPDIR)/$(am__dirstamp) +attributes/attribute_manager.lo: attributes/$(am__dirstamp) \ + attributes/$(DEPDIR)/$(am__dirstamp) +attributes/mem_pool.lo: attributes/$(am__dirstamp) \ + attributes/$(DEPDIR)/$(am__dirstamp) bus/$(am__dirstamp): @$(MKDIR_P) bus @: > bus/$(am__dirstamp) @@ -1389,6 +1443,9 @@ processing/jobs/update_sa_job.lo: processing/jobs/$(am__dirstamp) \ processing/jobs/$(DEPDIR)/$(am__dirstamp) processing/jobs/inactivity_job.lo: processing/jobs/$(am__dirstamp) \ processing/jobs/$(DEPDIR)/$(am__dirstamp) +processing/jobs/initiate_tasks_job.lo: \ + processing/jobs/$(am__dirstamp) \ + processing/jobs/$(DEPDIR)/$(am__dirstamp) sa/eap/$(am__dirstamp): @$(MKDIR_P) sa/eap @: > sa/eap/$(am__dirstamp) @@ -1421,6 +1478,8 @@ sa/ike_sa.lo: sa/$(am__dirstamp) sa/$(DEPDIR)/$(am__dirstamp) sa/ike_sa_id.lo: sa/$(am__dirstamp) sa/$(DEPDIR)/$(am__dirstamp) sa/keymat.lo: sa/$(am__dirstamp) sa/$(DEPDIR)/$(am__dirstamp) sa/ike_sa_manager.lo: sa/$(am__dirstamp) sa/$(DEPDIR)/$(am__dirstamp) +sa/child_sa_manager.lo: sa/$(am__dirstamp) \ + sa/$(DEPDIR)/$(am__dirstamp) sa/task_manager.lo: sa/$(am__dirstamp) sa/$(DEPDIR)/$(am__dirstamp) sa/shunt_manager.lo: sa/$(am__dirstamp) sa/$(DEPDIR)/$(am__dirstamp) sa/trap_manager.lo: sa/$(am__dirstamp) sa/$(DEPDIR)/$(am__dirstamp) @@ -1484,6 +1543,8 @@ sa/ikev2/tasks/ike_rekey.lo: sa/ikev2/tasks/$(am__dirstamp) \ sa/ikev2/tasks/$(DEPDIR)/$(am__dirstamp) sa/ikev2/tasks/ike_reauth.lo: sa/ikev2/tasks/$(am__dirstamp) \ sa/ikev2/tasks/$(DEPDIR)/$(am__dirstamp) +sa/ikev2/tasks/ike_reauth_complete.lo: sa/ikev2/tasks/$(am__dirstamp) \ + sa/ikev2/tasks/$(DEPDIR)/$(am__dirstamp) sa/ikev2/tasks/ike_auth_lifetime.lo: sa/ikev2/tasks/$(am__dirstamp) \ sa/ikev2/tasks/$(DEPDIR)/$(am__dirstamp) sa/ikev2/tasks/ike_vendor.lo: sa/ikev2/tasks/$(am__dirstamp) \ @@ -1574,6 +1635,8 @@ libcharon.la: $(libcharon_la_OBJECTS) $(libcharon_la_DEPENDENCIES) $(EXTRA_libch mostlyclean-compile: -rm -f *.$(OBJEXT) + -rm -f attributes/*.$(OBJEXT) + -rm -f attributes/*.lo -rm -f bus/*.$(OBJEXT) -rm -f bus/*.lo -rm -f bus/listeners/*.$(OBJEXT) @@ -1615,6 +1678,9 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/daemon.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@attributes/$(DEPDIR)/attribute_manager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@attributes/$(DEPDIR)/attributes.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@attributes/$(DEPDIR)/mem_pool.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@bus/$(DEPDIR)/bus.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@bus/listeners/$(DEPDIR)/file_logger.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@bus/listeners/$(DEPDIR)/sys_logger.Plo@am__quote@ @@ -1665,6 +1731,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@processing/jobs/$(DEPDIR)/dpd_timeout_job.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@processing/jobs/$(DEPDIR)/inactivity_job.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@processing/jobs/$(DEPDIR)/initiate_mediation_job.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@processing/jobs/$(DEPDIR)/initiate_tasks_job.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@processing/jobs/$(DEPDIR)/mediation_job.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@processing/jobs/$(DEPDIR)/migrate_job.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@processing/jobs/$(DEPDIR)/process_message_job.Plo@am__quote@ @@ -1679,6 +1746,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@processing/jobs/$(DEPDIR)/update_sa_job.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sa/$(DEPDIR)/authenticator.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sa/$(DEPDIR)/child_sa.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@sa/$(DEPDIR)/child_sa_manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sa/$(DEPDIR)/ike_sa.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sa/$(DEPDIR)/ike_sa_id.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sa/$(DEPDIR)/ike_sa_manager.Plo@am__quote@ @@ -1730,6 +1798,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@sa/ikev2/tasks/$(DEPDIR)/ike_mobike.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sa/ikev2/tasks/$(DEPDIR)/ike_natd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sa/ikev2/tasks/$(DEPDIR)/ike_reauth.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@sa/ikev2/tasks/$(DEPDIR)/ike_reauth_complete.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sa/ikev2/tasks/$(DEPDIR)/ike_rekey.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sa/ikev2/tasks/$(DEPDIR)/ike_vendor.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@sa/xauth/$(DEPDIR)/xauth_manager.Plo@am__quote@ @@ -1764,6 +1833,7 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs + -rm -rf attributes/.libs attributes/_libs -rm -rf bus/.libs bus/_libs -rm -rf bus/listeners/.libs bus/listeners/_libs -rm -rf config/.libs config/_libs @@ -1971,6 +2041,8 @@ clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f attributes/$(DEPDIR)/$(am__dirstamp) + -rm -f attributes/$(am__dirstamp) -rm -f bus/$(DEPDIR)/$(am__dirstamp) -rm -f bus/$(am__dirstamp) -rm -f bus/listeners/$(DEPDIR)/$(am__dirstamp) @@ -2017,7 +2089,7 @@ clean-am: clean-generic clean-ipseclibLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-recursive - -rm -rf ./$(DEPDIR) bus/$(DEPDIR) bus/listeners/$(DEPDIR) config/$(DEPDIR) control/$(DEPDIR) encoding/$(DEPDIR) encoding/payloads/$(DEPDIR) kernel/$(DEPDIR) network/$(DEPDIR) processing/jobs/$(DEPDIR) sa/$(DEPDIR) sa/eap/$(DEPDIR) sa/ikev1/$(DEPDIR) sa/ikev1/authenticators/$(DEPDIR) sa/ikev1/tasks/$(DEPDIR) sa/ikev2/$(DEPDIR) sa/ikev2/authenticators/$(DEPDIR) sa/ikev2/tasks/$(DEPDIR) sa/xauth/$(DEPDIR) + -rm -rf ./$(DEPDIR) attributes/$(DEPDIR) bus/$(DEPDIR) bus/listeners/$(DEPDIR) config/$(DEPDIR) control/$(DEPDIR) encoding/$(DEPDIR) encoding/payloads/$(DEPDIR) kernel/$(DEPDIR) network/$(DEPDIR) processing/jobs/$(DEPDIR) sa/$(DEPDIR) sa/eap/$(DEPDIR) sa/ikev1/$(DEPDIR) sa/ikev1/authenticators/$(DEPDIR) sa/ikev1/tasks/$(DEPDIR) sa/ikev2/$(DEPDIR) sa/ikev2/authenticators/$(DEPDIR) sa/ikev2/tasks/$(DEPDIR) sa/xauth/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -2063,7 +2135,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive - -rm -rf ./$(DEPDIR) bus/$(DEPDIR) bus/listeners/$(DEPDIR) config/$(DEPDIR) control/$(DEPDIR) encoding/$(DEPDIR) encoding/payloads/$(DEPDIR) kernel/$(DEPDIR) network/$(DEPDIR) processing/jobs/$(DEPDIR) sa/$(DEPDIR) sa/eap/$(DEPDIR) sa/ikev1/$(DEPDIR) sa/ikev1/authenticators/$(DEPDIR) sa/ikev1/tasks/$(DEPDIR) sa/ikev2/$(DEPDIR) sa/ikev2/authenticators/$(DEPDIR) sa/ikev2/tasks/$(DEPDIR) sa/xauth/$(DEPDIR) + -rm -rf ./$(DEPDIR) attributes/$(DEPDIR) bus/$(DEPDIR) bus/listeners/$(DEPDIR) config/$(DEPDIR) control/$(DEPDIR) encoding/$(DEPDIR) encoding/payloads/$(DEPDIR) kernel/$(DEPDIR) network/$(DEPDIR) processing/jobs/$(DEPDIR) sa/$(DEPDIR) sa/eap/$(DEPDIR) sa/ikev1/$(DEPDIR) sa/ikev1/authenticators/$(DEPDIR) sa/ikev1/tasks/$(DEPDIR) sa/ikev2/$(DEPDIR) sa/ikev2/authenticators/$(DEPDIR) sa/ikev2/tasks/$(DEPDIR) sa/xauth/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic diff --git a/src/libhydra/attributes/attribute_handler.h b/src/libcharon/attributes/attribute_handler.h index bc488f6cb..3c14323a3 100644 --- a/src/libhydra/attributes/attribute_handler.h +++ b/src/libcharon/attributes/attribute_handler.h @@ -21,14 +21,14 @@ #ifndef ATTRIBUTE_HANDLER_H_ #define ATTRIBUTE_HANDLER_H_ +typedef struct attribute_handler_t attribute_handler_t; + +#include <sa/ike_sa.h> #include <utils/chunk.h> -#include <utils/identification.h> #include <collections/linked_list.h> #include "attributes.h" -typedef struct attribute_handler_t attribute_handler_t; - /** * Interface to handle configuration payload attributes. */ @@ -40,12 +40,12 @@ struct attribute_handler_t { * After receiving a configuration attriubte, it is passed to each * attribute handler until it is handled. * - * @param server server from which the attribute was received + * @param ike_sa IKE_SA under which attribute is received * @param type type of configuration attribute to handle * @param data associated attribute data * @return TRUE if attribute handled */ - bool (*handle)(attribute_handler_t *this, identification_t *server, + bool (*handle)(attribute_handler_t *this, ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data); /** @@ -54,19 +54,23 @@ struct attribute_handler_t { * A handler that handle()d an attribute gets a call to release() when the * connection gets closed. Depending on the implementation, this is required * to remove the attribute. + * + * @param ike_sa IKE_SA which releases attribute + * @param type type of configuration attribute to release + * @param data associated attribute data */ - void (*release)(attribute_handler_t *this, identification_t *server, + void (*release)(attribute_handler_t *this, ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data); /** * Enumerate attributes to request from a server. * - * @param server server identity to request attributes from + * @param ike_sa IKE_SA to request attributes for * @param vips list of virtual IPs (host_t*) we are requesting * @return enumerator (configuration_attribute_type_t, chunk_t) */ enumerator_t* (*create_attribute_enumerator)(attribute_handler_t *this, - identification_t *server, linked_list_t *vips); + ike_sa_t *ike_sa, linked_list_t *vips); }; #endif /** ATTRIBUTE_HANDLER_H_ @}*/ diff --git a/src/libhydra/attributes/attribute_manager.c b/src/libcharon/attributes/attribute_manager.c index 5fda8b426..2ab7ed118 100644 --- a/src/libhydra/attributes/attribute_manager.c +++ b/src/libcharon/attributes/attribute_manager.c @@ -53,15 +53,15 @@ struct private_attribute_manager_t { typedef struct { /** attribute group pools */ linked_list_t *pools; - /** server/peer identity */ - identification_t *id; + /** associated IKE_SA */ + ike_sa_t *ike_sa; /** requesting/assigned virtual IPs */ linked_list_t *vips; } enum_data_t; METHOD(attribute_manager_t, acquire_address, host_t*, private_attribute_manager_t *this, linked_list_t *pools, - identification_t *id, host_t *requested) + ike_sa_t *ike_sa, host_t *requested) { enumerator_t *enumerator; attribute_provider_t *current; @@ -71,7 +71,7 @@ METHOD(attribute_manager_t, acquire_address, host_t*, enumerator = this->providers->create_enumerator(this->providers); while (enumerator->enumerate(enumerator, ¤t)) { - host = current->acquire_address(current, pools, id, requested); + host = current->acquire_address(current, pools, ike_sa, requested); if (host) { break; @@ -85,7 +85,7 @@ METHOD(attribute_manager_t, acquire_address, host_t*, METHOD(attribute_manager_t, release_address, bool, private_attribute_manager_t *this, linked_list_t *pools, host_t *address, - identification_t *id) + ike_sa_t *ike_sa) { enumerator_t *enumerator; attribute_provider_t *current; @@ -95,7 +95,7 @@ METHOD(attribute_manager_t, release_address, bool, enumerator = this->providers->create_enumerator(this->providers); while (enumerator->enumerate(enumerator, ¤t)) { - if (current->release_address(current, pools, address, id)) + if (current->release_address(current, pools, address, ike_sa)) { found = TRUE; break; @@ -114,18 +114,18 @@ static enumerator_t *responder_enum_create(attribute_provider_t *provider, enum_data_t *data) { return provider->create_attribute_enumerator(provider, data->pools, - data->id, data->vips); + data->ike_sa, data->vips); } METHOD(attribute_manager_t, create_responder_enumerator, enumerator_t*, private_attribute_manager_t *this, linked_list_t *pools, - identification_t *id, linked_list_t *vips) + ike_sa_t *ike_sa, linked_list_t *vips) { enum_data_t *data; INIT(data, .pools = pools, - .id = id, + .ike_sa = ike_sa, .vips = vips, ); this->lock->read_lock(this->lock); @@ -153,7 +153,7 @@ METHOD(attribute_manager_t, remove_provider, void, } METHOD(attribute_manager_t, handle, attribute_handler_t*, - private_attribute_manager_t *this, identification_t *server, + private_attribute_manager_t *this, ike_sa_t *ike_sa, attribute_handler_t *handler, configuration_attribute_type_t type, chunk_t data) { @@ -166,7 +166,7 @@ METHOD(attribute_manager_t, handle, attribute_handler_t*, enumerator = this->handlers->create_enumerator(this->handlers); while (enumerator->enumerate(enumerator, ¤t)) { - if (current == handler && current->handle(current, server, type, data)) + if (current == handler && current->handle(current, ike_sa, type, data)) { handled = current; break; @@ -178,7 +178,7 @@ METHOD(attribute_manager_t, handle, attribute_handler_t*, enumerator = this->handlers->create_enumerator(this->handlers); while (enumerator->enumerate(enumerator, ¤t)) { - if (current->handle(current, server, type, data)) + if (current->handle(current, ike_sa, type, data)) { handled = current; break; @@ -198,7 +198,7 @@ METHOD(attribute_manager_t, handle, attribute_handler_t*, METHOD(attribute_manager_t, release, void, private_attribute_manager_t *this, attribute_handler_t *handler, - identification_t *server, configuration_attribute_type_t type, chunk_t data) + ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data) { enumerator_t *enumerator; attribute_handler_t *current; @@ -209,7 +209,7 @@ METHOD(attribute_manager_t, release, void, { if (current == handler) { - current->release(current, server, type, data); + current->release(current, ike_sa, type, data); break; } } @@ -231,8 +231,8 @@ typedef struct { enumerator_t *outer; /** inner enumerator over current handlers attributes */ enumerator_t *inner; - /** server ID we want attributes for */ - identification_t *id; + /** IKE_SA to request attributes for */ + ike_sa_t *ike_sa; /** virtual IPs we are requesting along with attriubutes */ linked_list_t *vips; } initiator_enumerator_t; @@ -254,7 +254,7 @@ static bool initiator_enumerate(initiator_enumerator_t *this, } DESTROY_IF(this->inner); this->inner = this->handler->create_attribute_enumerator(this->handler, - this->id, this->vips); + this->ike_sa, this->vips); } /* inject the handler as additional attribute */ *handler = this->handler; @@ -273,7 +273,7 @@ static void initiator_destroy(initiator_enumerator_t *this) } METHOD(attribute_manager_t, create_initiator_enumerator, enumerator_t*, - private_attribute_manager_t *this, identification_t *id, linked_list_t *vips) + private_attribute_manager_t *this, ike_sa_t *ike_sa, linked_list_t *vips) { initiator_enumerator_t *enumerator; @@ -285,7 +285,7 @@ METHOD(attribute_manager_t, create_initiator_enumerator, enumerator_t*, .destroy = (void*)initiator_destroy, }, .this = this, - .id = id, + .ike_sa = ike_sa, .vips = vips, .outer = this->handlers->create_enumerator(this->handlers), ); @@ -345,4 +345,3 @@ attribute_manager_t *attribute_manager_create() return &this->public; } - diff --git a/src/libhydra/attributes/attribute_manager.h b/src/libcharon/attributes/attribute_manager.h index 99f41772c..6db664968 100644 --- a/src/libhydra/attributes/attribute_manager.h +++ b/src/libcharon/attributes/attribute_manager.h @@ -24,6 +24,8 @@ #include "attribute_provider.h" #include "attribute_handler.h" +#include <sa/ike_sa.h> + typedef struct attribute_manager_t attribute_manager_t; /** @@ -40,12 +42,12 @@ struct attribute_manager_t { * Acquire a virtual IP address to assign to a peer. * * @param pools list of pool names (char*) to acquire from - * @param id peer identity to get address forua + * @param ike_sa associated IKE_SA for which an address is requested * @param requested IP in configuration request * @return allocated address, NULL to serve none */ host_t* (*acquire_address)(attribute_manager_t *this, - linked_list_t *pool, identification_t *id, + linked_list_t *pool, ike_sa_t *ike_sa, host_t *requested); /** @@ -53,23 +55,23 @@ struct attribute_manager_t { * * @param pools list of pool names (char*) to release to * @param address address to release - * @param id peer identity to get address for + * @param ike_sa associated IKE_SA for which an address is released * @return TRUE if address released to pool */ bool (*release_address)(attribute_manager_t *this, linked_list_t *pools, host_t *address, - identification_t *id); + ike_sa_t *ike_sa); /** * Create an enumerator over attributes to hand out to a peer. * * @param pool list of pools names (char*) to query attributes from - * @param id peer identity to hand out attributes to + * @param ike_sa associated IKE_SA for which attributes are requested * @param vip list of virtual IPs (host_t*) to assign to peer * @return enumerator (configuration_attribute_type_t, chunk_t) */ enumerator_t* (*create_responder_enumerator)(attribute_manager_t *this, - linked_list_t *pool, identification_t *id, + linked_list_t *pool, ike_sa_t *ike_sa, linked_list_t *vips); /** @@ -90,38 +92,37 @@ struct attribute_manager_t { /** * Handle a configuration attribute by passing them to the handlers. * - * @param server server from which the attribute was received + * @param ike_sa associated IKE_SA to handle an attribute for * @param handler handler we requested the attribute for, if any * @param type type of configuration attribute * @param data associated attribute data * @return handler which handled this attribute, NULL if none */ attribute_handler_t* (*handle)(attribute_manager_t *this, - identification_t *server, attribute_handler_t *handler, + ike_sa_t *ike_sa, attribute_handler_t *handler, configuration_attribute_type_t type, chunk_t data); /** * Release an attribute previously handle()d by a handler. * - * @param handler handler returned by handle() for this attribute + * @param ike_sa associated IKE_SA to release an attribute for * @param server server from which the attribute was received * @param type type of attribute to release * @param data associated attribute data */ void (*release)(attribute_manager_t *this, attribute_handler_t *handler, - identification_t *server, - configuration_attribute_type_t type, + ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data); /** * Create an enumerator over attributes to request from server. * - * @param id server identity to hand out attributes to + * @param ike_sa associated IKE_SA to request attributes for * @param vip list of virtual IPs (host_t*) going to request * @return enumerator (attribute_handler_t, ca_type_t, chunk_t) */ enumerator_t* (*create_initiator_enumerator)(attribute_manager_t *this, - identification_t *id, linked_list_t *vips); + ike_sa_t *ike_sa, linked_list_t *vips); /** * Register an attribute handler to the manager. diff --git a/src/libhydra/attributes/attribute_provider.h b/src/libcharon/attributes/attribute_provider.h index adfd4a516..57453c2a0 100644 --- a/src/libhydra/attributes/attribute_provider.h +++ b/src/libcharon/attributes/attribute_provider.h @@ -21,8 +21,8 @@ #ifndef ATTRIBUTE_PROVIDER_H_ #define ATTRIBUTE_PROVIDER_H_ +#include <sa/ike_sa.h> #include <networking/host.h> -#include <utils/identification.h> #include <collections/linked_list.h> typedef struct attribute_provider_t attribute_provider_t; @@ -36,35 +36,35 @@ struct attribute_provider_t { * Acquire a virtual IP address to assign to a peer. * * @param pools list of pool names (char*) to acquire from - * @param id peer ID + * @param ike_sa associated IKE_SA to assign address over * @param requested IP in configuration request * @return allocated address, NULL to serve none */ host_t* (*acquire_address)(attribute_provider_t *this, - linked_list_t *pools, identification_t *id, + linked_list_t *pools, ike_sa_t *ike_sa, host_t *requested); /** * Release a previously acquired address. * * @param pools list of pool names (char*) to release to * @param address address to release - * @param id peer ID + * @param ike_sa IKE_SA to release address for * @return TRUE if the address has been released by the provider */ bool (*release_address)(attribute_provider_t *this, linked_list_t *pools, host_t *address, - identification_t *id); + ike_sa_t *ike_sa); /** * Create an enumerator over attributes to hand out to a peer. * * @param pool list of pools names (char*) to query attributes from - * @param id peer ID + * @param ike_sa IKE_SA to request attributes for * @param vip list of virtual IPs (host_t*) to assign to peer * @return enumerator (configuration_attribute_type_t, chunk_t) */ enumerator_t* (*create_attribute_enumerator)(attribute_provider_t *this, - linked_list_t *pools, identification_t *id, + linked_list_t *pools, ike_sa_t *ike_sa, linked_list_t *vips); }; diff --git a/src/libhydra/attributes/attributes.c b/src/libcharon/attributes/attributes.c index 9fabcf4e4..9fabcf4e4 100644 --- a/src/libhydra/attributes/attributes.c +++ b/src/libcharon/attributes/attributes.c diff --git a/src/libhydra/attributes/attributes.h b/src/libcharon/attributes/attributes.h index 5d1e9f9ba..5d1e9f9ba 100644 --- a/src/libhydra/attributes/attributes.h +++ b/src/libcharon/attributes/attributes.h diff --git a/src/libhydra/attributes/mem_pool.c b/src/libcharon/attributes/mem_pool.c index cc45e5629..279668249 100644 --- a/src/libhydra/attributes/mem_pool.c +++ b/src/libcharon/attributes/mem_pool.c @@ -47,6 +47,11 @@ struct private_mem_pool_t { host_t *base; /** + * whether base is the network id of the subnet on which the pool is based + */ + bool base_is_network_id; + + /** * size of the pool */ u_int size; @@ -65,20 +70,25 @@ struct private_mem_pool_t { * lock to safely access the pool */ mutex_t *mutex; - - /** - * Do we reassign online leases to the same identity, if requested? - */ - bool reassign_online; }; /** + * A unique lease address offset, with a hash of the peer host address + */ +typedef struct { + /** lease, as offset */ + u_int offset; + /** hash of remote address, to allow duplicates */ + u_int hash; +} unique_lease_t; + +/** * Lease entry. */ typedef struct { /* identitiy reference */ identification_t *id; - /* array of online leases, as u_int offset */ + /* array of online leases, as unique_lease_t */ array_t *online; /* array of offline leases, as u_int offset */ array_t *offline; @@ -93,13 +103,24 @@ static entry_t* entry_create(identification_t *id) INIT(entry, .id = id->clone(id), - .online = array_create(sizeof(u_int), 0), + .online = array_create(sizeof(unique_lease_t), 0), .offline = array_create(sizeof(u_int), 0), ); return entry; } /** + * Destroy an entry + */ +static void entry_destroy(entry_t *this) +{ + this->id->destroy(this->id); + array_destroy(this->online); + array_destroy(this->offline); + free(this); +} + +/** * hashtable hash function for identities */ static u_int id_hash(identification_t *id) @@ -235,12 +256,25 @@ METHOD(mem_pool_t, get_offline, u_int, } /** + * Create a unique hash for a remote address + */ +static u_int hash_addr(host_t *addr) +{ + if (addr) + { + return chunk_hash_inc(addr->get_address(addr), addr->get_port(addr)); + } + return 0; +} + +/** * Get an existing lease for id */ static int get_existing(private_mem_pool_t *this, identification_t *id, - host_t *requested) + host_t *requested, host_t *peer) { enumerator_t *enumerator; + unique_lease_t *lease, reassign; u_int *current; entry_t *entry; int offset = 0; @@ -255,8 +289,9 @@ static int get_existing(private_mem_pool_t *this, identification_t *id, enumerator = array_create_enumerator(entry->offline); if (enumerator->enumerate(enumerator, ¤t)) { - offset = *current; - array_insert(entry->online, ARRAY_TAIL, current); + reassign.offset = offset = *current; + reassign.hash = hash_addr(peer); + array_insert(entry->online, ARRAY_TAIL, &reassign); array_remove_at(entry->offline, enumerator); } enumerator->destroy(enumerator); @@ -265,19 +300,20 @@ static int get_existing(private_mem_pool_t *this, identification_t *id, DBG1(DBG_CFG, "reassigning offline lease to '%Y'", id); return offset; } - if (!this->reassign_online) + if (!peer) { return 0; } /* check for a valid online lease to reassign */ enumerator = array_create_enumerator(entry->online); - while (enumerator->enumerate(enumerator, ¤t)) + while (enumerator->enumerate(enumerator, &lease)) { - if (*current == host2offset(this, requested)) + if (lease->offset == host2offset(this, requested) && + lease->hash == hash_addr(peer)) { - offset = *current; + offset = lease->offset; /* add an additional "online" entry */ - array_insert(entry->online, ARRAY_TAIL, current); + array_insert(entry->online, ARRAY_TAIL, lease); break; } } @@ -292,10 +328,10 @@ static int get_existing(private_mem_pool_t *this, identification_t *id, /** * Get a new lease for id */ -static int get_new(private_mem_pool_t *this, identification_t *id) +static int get_new(private_mem_pool_t *this, identification_t *id, host_t *peer) { entry_t *entry; - u_int offset = 0; + unique_lease_t lease = {}; if (this->unused < this->size) { @@ -306,47 +342,63 @@ static int get_new(private_mem_pool_t *this, identification_t *id) this->leases->put(this->leases, entry->id, entry); } /* assigning offset, starting by 1 */ - offset = ++this->unused; - array_insert(entry->online, ARRAY_TAIL, &offset); + lease.offset = ++this->unused + (this->base_is_network_id ? 1 : 0); + lease.hash = hash_addr(peer); + array_insert(entry->online, ARRAY_TAIL, &lease); DBG1(DBG_CFG, "assigning new lease to '%Y'", id); } - return offset; + return lease.offset; } /** * Get a reassigned lease for id in case the pool is full */ -static int get_reassigned(private_mem_pool_t *this, identification_t *id) +static int get_reassigned(private_mem_pool_t *this, identification_t *id, + host_t *peer) { enumerator_t *enumerator; entry_t *entry; - u_int current, offset = 0; + u_int current; + unique_lease_t lease = {}; enumerator = this->leases->create_enumerator(this->leases); while (enumerator->enumerate(enumerator, NULL, &entry)) { if (array_remove(entry->offline, ARRAY_HEAD, ¤t)) { - offset = current; - DBG1(DBG_CFG, "reassigning existing offline lease by '%Y'" - " to '%Y'", entry->id, id); + lease.offset = current; + DBG1(DBG_CFG, "reassigning existing offline lease by '%Y' " + "to '%Y'", entry->id, id); + } + if (!array_count(entry->online) && !array_count(entry->offline)) + { + this->leases->remove_at(this->leases, enumerator); + entry_destroy(entry); + } + if (lease.offset) + { break; } } enumerator->destroy(enumerator); - if (offset) + if (lease.offset) { - entry = entry_create(id); - array_insert(entry->online, ARRAY_TAIL, &offset); - this->leases->put(this->leases, entry->id, entry); + entry = this->leases->get(this->leases, id); + if (!entry) + { + entry = entry_create(id); + this->leases->put(this->leases, entry->id, entry); + } + lease.hash = hash_addr(peer); + array_insert(entry->online, ARRAY_TAIL, &lease); } - return offset; + return lease.offset; } METHOD(mem_pool_t, acquire_address, host_t*, private_mem_pool_t *this, identification_t *id, host_t *requested, - mem_pool_op_t operation) + mem_pool_op_t operation, host_t *peer) { int offset = 0; @@ -367,13 +419,13 @@ METHOD(mem_pool_t, acquire_address, host_t*, switch (operation) { case MEM_POOL_EXISTING: - offset = get_existing(this, id, requested); + offset = get_existing(this, id, requested, peer); break; case MEM_POOL_NEW: - offset = get_new(this, id); + offset = get_new(this, id, peer); break; case MEM_POOL_REASSIGN: - offset = get_reassigned(this, id); + offset = get_reassigned(this, id, peer); if (!offset) { DBG1(DBG_CFG, "pool '%s' is full, unable to assign address", @@ -398,7 +450,8 @@ METHOD(mem_pool_t, release_address, bool, enumerator_t *enumerator; bool found = FALSE, more = FALSE; entry_t *entry; - u_int offset, *current; + u_int offset; + unique_lease_t *current; if (this->size != 0) { @@ -411,7 +464,7 @@ METHOD(mem_pool_t, release_address, bool, enumerator = array_create_enumerator(entry->online); while (enumerator->enumerate(enumerator, ¤t)) { - if (*current == offset) + if (current->offset == offset) { if (!found) { /* remove the first entry only */ @@ -463,6 +516,7 @@ METHOD(enumerator_t, lease_enumerate, bool, lease_enumerator_t *this, identification_t **id, host_t **addr, bool *online) { u_int *offset; + unique_lease_t *lease; DESTROY_IF(this->addr); this->addr = NULL; @@ -471,10 +525,10 @@ METHOD(enumerator_t, lease_enumerate, bool, { if (this->entry) { - if (this->online->enumerate(this->online, &offset)) + if (this->online->enumerate(this->online, &lease)) { *id = this->entry->id; - *addr = this->addr = offset2host(this->pool, *offset); + *addr = this->addr = offset2host(this->pool, lease->offset); *online = TRUE; return TRUE; } @@ -535,10 +589,7 @@ METHOD(mem_pool_t, destroy, void, enumerator = this->leases->create_enumerator(this->leases); while (enumerator->enumerate(enumerator, NULL, &entry)) { - entry->id->destroy(entry->id); - array_destroy(entry->online); - array_destroy(entry->offline); - free(entry); + entry_destroy(entry); } enumerator->destroy(enumerator); @@ -572,26 +623,45 @@ static private_mem_pool_t *create_generic(char *name) .leases = hashtable_create((hashtable_hash_t)id_hash, (hashtable_equals_t)id_equals, 16), .mutex = mutex_create(MUTEX_TYPE_DEFAULT), - .reassign_online = lib->settings->get_bool(lib->settings, - "%s.mem-pool.reassign_online", FALSE, lib->ns), ); return this; } /** + * Check if the given host is the network ID of a subnet, that is, if hostbits + * are zero. Since we limit pools to 2^31 addresses we only have to check the + * last 4 bytes. + */ +static u_int network_id_diff(host_t *host, int hostbits) +{ + u_int32_t last; + chunk_t addr; + + if (!hostbits) + { + return 0; + } + addr = host->get_address(host); + last = untoh32(addr.ptr + addr.len - sizeof(last)); + hostbits = sizeof(last) * 8 - hostbits; + return (last << hostbits) >> hostbits; +} + +/** * Described in header */ mem_pool_t *mem_pool_create(char *name, host_t *base, int bits) { private_mem_pool_t *this; + u_int diff; int addr_bits; this = create_generic(name); if (base) { addr_bits = base->get_family(base) == AF_INET ? 32 : 128; - bits = max(0, min(bits, base->get_family(base) == AF_INET ? 32 : 128)); + bits = max(0, min(bits, addr_bits)); /* net bits -> host bits */ bits = addr_bits - bits; if (bits > POOL_LIMIT) @@ -601,15 +671,31 @@ mem_pool_t *mem_pool_create(char *name, host_t *base, int bits) base, addr_bits - bits); } this->size = 1 << bits; + this->base = base->clone(base); if (this->size > 2) - { /* do not use first and last addresses of a block */ - this->unused++; - this->size -= 2; + { + /* if base is the network id we later skip the first address, + * otherwise adjust the size to represent the actual number + * of assignable addresses */ + diff = network_id_diff(base, bits); + if (!diff) + { + this->base_is_network_id = TRUE; + this->size--; + } + else + { + this->size -= diff; + } + /* skip the last address (broadcast) of the subnet */ + this->size--; + } + else if (network_id_diff(base, bits)) + { /* only serve the second address of the subnet */ + this->size--; } - this->base = base->clone(base); } - return &this->public; } diff --git a/src/libhydra/attributes/mem_pool.h b/src/libcharon/attributes/mem_pool.h index 7347bb547..3ee1dd37d 100644 --- a/src/libhydra/attributes/mem_pool.h +++ b/src/libcharon/attributes/mem_pool.h @@ -87,13 +87,21 @@ struct mem_pool_t { * acquire a new lease (MEM_POOL_NEW), and if the pool is full once again * to assign an existing offline lease (MEM_POOL_REASSIGN). * + * If the same identity requests a virtual IP that is already assigned to + * it, the peer address and port is used to check if it is the same client + * instance that is connecting. If this is true, the request is considered + * a request for a reauthentication attempt, and the same virtual IP gets + * assigned to the peer. + * * @param id the id to acquire an address for * @param requested acquire this address, if possible * @param operation acquire operation to perform, see above + * @param peer optional remote IKE address and port * @return the acquired address */ host_t* (*acquire_address)(mem_pool_t *this, identification_t *id, - host_t *requested, mem_pool_op_t operation); + host_t *requested, mem_pool_op_t operation, + host_t *peer); /** * Release a previously acquired address. diff --git a/src/libcharon/bus/bus.c b/src/libcharon/bus/bus.c index cb59f976b..7938f46cc 100644 --- a/src/libcharon/bus/bus.c +++ b/src/libcharon/bus/bus.c @@ -755,6 +755,33 @@ METHOD(bus_t, ike_rekey, void, this->mutex->unlock(this->mutex); } +METHOD(bus_t, ike_update, void, + private_bus_t *this, ike_sa_t *ike_sa, bool local, host_t *new) +{ + enumerator_t *enumerator; + entry_t *entry; + bool keep; + + this->mutex->lock(this->mutex); + enumerator = this->listeners->create_enumerator(this->listeners); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->calling || !entry->listener->ike_update) + { + continue; + } + entry->calling++; + keep = entry->listener->ike_update(entry->listener, ike_sa, local, new); + entry->calling--; + if (!keep) + { + unregister_listener(this, entry, enumerator); + } + } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); +} + METHOD(bus_t, ike_reestablish_pre, void, private_bus_t *this, ike_sa_t *old, ike_sa_t *new) { @@ -1006,6 +1033,7 @@ bus_t *bus_create() .child_keys = _child_keys, .ike_updown = _ike_updown, .ike_rekey = _ike_rekey, + .ike_update = _ike_update, .ike_reestablish_pre = _ike_reestablish_pre, .ike_reestablish_post = _ike_reestablish_post, .child_updown = _child_updown, diff --git a/src/libcharon/bus/bus.h b/src/libcharon/bus/bus.h index e1d221ca5..051c429f9 100644 --- a/src/libcharon/bus/bus.h +++ b/src/libcharon/bus/bus.h @@ -382,6 +382,15 @@ struct bus_t { void (*ike_rekey)(bus_t *this, ike_sa_t *old, ike_sa_t *new); /** + * IKE_SA peer endpoint update hook. + * + * @param ike_sa updated IKE_SA, having old endpoints set + * @param local TRUE if local endpoint gets updated, FALSE for remote + * @param new new endpoint address and port + */ + void (*ike_update)(bus_t *this, ike_sa_t *ike_sa, bool local, host_t *new); + + /** * IKE_SA reestablishing hook (before resolving hosts). * * @param old reestablished and obsolete IKE_SA diff --git a/src/libcharon/bus/listeners/listener.h b/src/libcharon/bus/listeners/listener.h index 0910cb361..3447d8f99 100644 --- a/src/libcharon/bus/listeners/listener.h +++ b/src/libcharon/bus/listeners/listener.h @@ -128,6 +128,17 @@ struct listener_t { bool (*ike_rekey)(listener_t *this, ike_sa_t *old, ike_sa_t *new); /** + * Hook called for IKE_SA peer endpoint updates. + * + * @param ike_sa updated IKE_SA, having old endpoints set + * @param local TRUE if local endpoint gets updated, FALSE for remote + * @param new new endpoint address and port + * @return TRUE to stay registered, FALSE to unregister + */ + bool (*ike_update)(listener_t *this, ike_sa_t *ike_sa, + bool local, host_t *new); + + /** * Hook called when an initiator reestablishes an IKE_SA. * * This is invoked right after creating the new IKE_SA and setting the diff --git a/src/libcharon/config/ike_cfg.c b/src/libcharon/config/ike_cfg.c index 42a3e9057..9464ceb5d 100644 --- a/src/libcharon/config/ike_cfg.c +++ b/src/libcharon/config/ike_cfg.c @@ -459,25 +459,10 @@ static traffic_selector_t* make_range(char *str) { traffic_selector_t *ts; ts_type_t type; - char *pos; host_t *from, *to; - pos = strchr(str, '-'); - if (!pos) - { - return NULL; - } - to = host_create_from_string(pos + 1, 0); - if (!to) - { - return NULL; - } - str = strndup(str, pos - str); - from = host_create_from_string_and_family(str, to->get_family(to), 0); - free(str); - if (!from) + if (!host_create_from_range(str, &from, &to)) { - to->destroy(to); return NULL; } if (to->get_family(to) == AF_INET) diff --git a/src/libcharon/config/proposal.c b/src/libcharon/config/proposal.c index 50d3c6f66..e59dcd9ec 100644 --- a/src/libcharon/config/proposal.c +++ b/src/libcharon/config/proposal.c @@ -399,10 +399,12 @@ static const struct { pseudo_random_function_t prf; } integ_prf_map[] = { {AUTH_HMAC_SHA1_96, PRF_HMAC_SHA1 }, + {AUTH_HMAC_SHA1_160, PRF_HMAC_SHA1 }, {AUTH_HMAC_SHA2_256_128, PRF_HMAC_SHA2_256 }, {AUTH_HMAC_SHA2_384_192, PRF_HMAC_SHA2_384 }, {AUTH_HMAC_SHA2_512_256, PRF_HMAC_SHA2_512 }, {AUTH_HMAC_MD5_96, PRF_HMAC_MD5 }, + {AUTH_HMAC_MD5_128, PRF_HMAC_MD5 }, {AUTH_AES_XCBC_96, PRF_AES128_XCBC }, {AUTH_CAMELLIA_XCBC_96, PRF_CAMELLIA128_XCBC }, {AUTH_AES_CMAC_96, PRF_AES128_CMAC }, diff --git a/src/libcharon/control/controller.c b/src/libcharon/control/controller.c index 25667e532..fd8349e2f 100644 --- a/src/libcharon/control/controller.c +++ b/src/libcharon/control/controller.c @@ -303,6 +303,18 @@ METHOD(listener_t, child_state_change, bool, /* proper delete */ this->status = SUCCESS; break; + case CHILD_RETRYING: + /* retrying with a different DH group; survive another + * initiation round */ + this->status = NEED_MORE; + return TRUE; + case CHILD_CREATED: + if (this->status == NEED_MORE) + { + this->status = FAILED; + return TRUE; + } + break; default: break; } @@ -437,7 +449,7 @@ METHOD(job_t, terminate_ike_execute, job_requeue_t, ike_sa_t *ike_sa; ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager, - unique_id, FALSE); + unique_id); if (!ike_sa) { DBG1(DBG_IKE, "unable to terminate IKE_SA: ID %d not found", unique_id); @@ -522,17 +534,15 @@ METHOD(job_t, terminate_child_execute, job_requeue_t, interface_job_t *job) { interface_listener_t *listener = &job->listener; - u_int32_t reqid = listener->id; - enumerator_t *enumerator; + u_int32_t id = listener->id; child_sa_t *child_sa; ike_sa_t *ike_sa; - ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager, - reqid, TRUE); + ike_sa = charon->child_sa_manager->checkout_by_id(charon->child_sa_manager, + id, &child_sa); if (!ike_sa) { - DBG1(DBG_IKE, "unable to terminate, CHILD_SA with ID %d not found", - reqid); + DBG1(DBG_IKE, "unable to terminate, CHILD_SA with ID %d not found", id); listener->status = NOT_FOUND; /* release listener */ listener_done(listener); @@ -542,22 +552,10 @@ METHOD(job_t, terminate_child_execute, job_requeue_t, listener->ike_sa = ike_sa; listener->lock->unlock(listener->lock); - enumerator = ike_sa->create_child_sa_enumerator(ike_sa); - while (enumerator->enumerate(enumerator, (void**)&child_sa)) - { - if (child_sa->get_state(child_sa) != CHILD_ROUTED && - child_sa->get_reqid(child_sa) == reqid) - { - break; - } - child_sa = NULL; - } - enumerator->destroy(enumerator); - - if (!child_sa) + if (child_sa->get_state(child_sa) == CHILD_ROUTED) { DBG1(DBG_IKE, "unable to terminate, established " - "CHILD_SA with ID %d not found", reqid); + "CHILD_SA with ID %d not found", id); charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); listener->status = NOT_FOUND; /* release listener */ @@ -584,7 +582,7 @@ METHOD(job_t, terminate_child_execute, job_requeue_t, } METHOD(controller_t, terminate_child, status_t, - controller_t *this, u_int32_t reqid, + controller_t *this, u_int32_t unique_id, controller_cb_t callback, void *param, u_int timeout) { interface_job_t *job; @@ -605,7 +603,7 @@ METHOD(controller_t, terminate_child, status_t, .param = param, }, .status = FAILED, - .id = reqid, + .id = unique_id, .lock = spinlock_create(), }, .public = { diff --git a/src/libcharon/control/controller.h b/src/libcharon/control/controller.h index 222285cde..02f4ebb2b 100644 --- a/src/libcharon/control/controller.h +++ b/src/libcharon/control/controller.h @@ -118,7 +118,7 @@ struct controller_t { * If a callback is provided the function is synchronous and thus blocks * until the CHILD_SA is properly deleted, or the call timed out. * - * @param reqid reqid of the CHILD_SA to terminate + * @param unique_id CHILD_SA unique ID to terminate * @param cb logging callback * @param param parameter to include in each call of cb * @param timeout timeout in ms to wait for callbacks, 0 to disable @@ -128,7 +128,7 @@ struct controller_t { * - NEED_MORE, if callback returned FALSE * - OUT_OF_RES if timed out */ - status_t (*terminate_child)(controller_t *this, u_int32_t reqid, + status_t (*terminate_child)(controller_t *this, u_int32_t unique_id, controller_cb_t callback, void *param, u_int timeout); diff --git a/src/libcharon/daemon.c b/src/libcharon/daemon.c index 3ae7c4e6f..b1b8f57f0 100644 --- a/src/libcharon/daemon.c +++ b/src/libcharon/daemon.c @@ -474,12 +474,15 @@ static void destroy(private_daemon_t *this) DESTROY_IF(this->public.connect_manager); DESTROY_IF(this->public.mediation_manager); #endif /* ME */ - /* make sure the cache is clear before unloading plugins */ + /* make sure the cache and scheduler are clear before unloading plugins */ lib->credmgr->flush_cache(lib->credmgr, CERT_ANY); + lib->scheduler->flush(lib->scheduler); lib->plugins->unload(lib->plugins); + DESTROY_IF(this->public.attributes); DESTROY_IF(this->kernel_handler); DESTROY_IF(this->public.traps); DESTROY_IF(this->public.shunts); + DESTROY_IF(this->public.child_sa_manager); DESTROY_IF(this->public.ike_sa_manager); DESTROY_IF(this->public.controller); DESTROY_IF(this->public.eap); @@ -606,6 +609,7 @@ METHOD(daemon_t, initialize, bool, { return FALSE; } + this->public.child_sa_manager = child_sa_manager_create(); /* Queue start_action job */ lib->processor->queue_job(lib->processor, (job_t*)start_action_job_create()); @@ -642,6 +646,7 @@ private_daemon_t *daemon_create() .ref = 1, ); charon = &this->public; + this->public.attributes = attribute_manager_create(); this->public.controller = controller_create(); this->public.eap = eap_manager_create(); this->public.xauth = xauth_manager_create(); diff --git a/src/libcharon/daemon.h b/src/libcharon/daemon.h index 36242bb04..d16bf1ddb 100644 --- a/src/libcharon/daemon.h +++ b/src/libcharon/daemon.h @@ -19,6 +19,9 @@ /** * @defgroup libcharon libcharon * + * @defgroup attributes attributes + * @ingroup libcharon + * * @defgroup bus bus * @ingroup libcharon * @@ -152,12 +155,14 @@ typedef struct daemon_t daemon_t; +#include <attributes/attribute_manager.h> #include <network/sender.h> #include <network/receiver.h> #include <network/socket_manager.h> #include <control/controller.h> #include <bus/bus.h> #include <sa/ike_sa_manager.h> +#include <sa/child_sa_manager.h> #include <sa/trap_manager.h> #include <sa/shunt_manager.h> #include <config/backend_manager.h> @@ -215,6 +220,11 @@ struct daemon_t { ike_sa_manager_t *ike_sa_manager; /** + * A child_sa_manager_t instance. + */ + child_sa_manager_t *child_sa_manager; + + /** * Manager for triggering policies, called traps */ trap_manager_t *traps; @@ -240,6 +250,11 @@ struct daemon_t { receiver_t *receiver; /** + * Manager for IKE configuration attributes + */ + attribute_manager_t *attributes; + + /** * The signaling bus. */ bus_t *bus; diff --git a/src/libcharon/encoding/message.c b/src/libcharon/encoding/message.c index cb6c97f25..0a596ffb0 100644 --- a/src/libcharon/encoding/message.c +++ b/src/libcharon/encoding/message.c @@ -180,6 +180,7 @@ static payload_order_t ike_sa_init_r_order[] = { */ static payload_rule_t ike_auth_i_rules[] = { /* payload type min max encr suff */ + {PLV2_FRAGMENT, 0, 1, TRUE, TRUE}, {PLV2_NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE}, {PLV2_EAP, 0, 1, TRUE, TRUE}, {PLV2_AUTH, 0, 1, TRUE, TRUE}, @@ -227,6 +228,7 @@ static payload_order_t ike_auth_i_order[] = { {PLV2_NOTIFY, NO_ADDITIONAL_ADDRESSES}, {PLV2_NOTIFY, 0}, {PLV2_VENDOR_ID, 0}, + {PLV2_FRAGMENT, 0}, }; /** @@ -234,6 +236,7 @@ static payload_order_t ike_auth_i_order[] = { */ static payload_rule_t ike_auth_r_rules[] = { /* payload type min max encr suff */ + {PLV2_FRAGMENT, 0, 1, TRUE, TRUE}, {PLV2_NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, TRUE}, {PLV2_EAP, 0, 1, TRUE, TRUE}, {PLV2_AUTH, 0, 1, TRUE, TRUE}, @@ -270,6 +273,7 @@ static payload_order_t ike_auth_r_order[] = { {PLV2_NOTIFY, NO_ADDITIONAL_ADDRESSES}, {PLV2_NOTIFY, 0}, {PLV2_VENDOR_ID, 0}, + {PLV2_FRAGMENT, 0}, }; /** @@ -277,6 +281,7 @@ static payload_order_t ike_auth_r_order[] = { */ static payload_rule_t informational_i_rules[] = { /* payload type min max encr suff */ + {PLV2_FRAGMENT, 0, 1, TRUE, TRUE}, {PLV2_NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE}, {PLV2_CONFIGURATION, 0, 1, TRUE, FALSE}, {PLV2_DELETE, 0, MAX_DELETE_PAYLOADS, TRUE, FALSE}, @@ -295,6 +300,7 @@ static payload_order_t informational_i_order[] = { {PLV2_NOTIFY, 0}, {PLV2_DELETE, 0}, {PLV2_CONFIGURATION, 0}, + {PLV2_FRAGMENT, 0}, }; /** @@ -302,6 +308,7 @@ static payload_order_t informational_i_order[] = { */ static payload_rule_t informational_r_rules[] = { /* payload type min max encr suff */ + {PLV2_FRAGMENT, 0, 1, TRUE, TRUE}, {PLV2_NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE}, {PLV2_CONFIGURATION, 0, 1, TRUE, FALSE}, {PLV2_DELETE, 0, MAX_DELETE_PAYLOADS, TRUE, FALSE}, @@ -320,6 +327,7 @@ static payload_order_t informational_r_order[] = { {PLV2_NOTIFY, 0}, {PLV2_DELETE, 0}, {PLV2_CONFIGURATION, 0}, + {PLV2_FRAGMENT, 0}, }; /** @@ -327,6 +335,7 @@ static payload_order_t informational_r_order[] = { */ static payload_rule_t create_child_sa_i_rules[] = { /* payload type min max encr suff */ + {PLV2_FRAGMENT, 0, 1, TRUE, TRUE}, {PLV2_NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, FALSE}, {PLV2_SECURITY_ASSOCIATION, 1, 1, TRUE, FALSE}, {PLV2_NONCE, 1, 1, TRUE, FALSE}, @@ -353,6 +362,7 @@ static payload_order_t create_child_sa_i_order[] = { {PLV2_TS_INITIATOR, 0}, {PLV2_TS_RESPONDER, 0}, {PLV2_NOTIFY, 0}, + {PLV2_FRAGMENT, 0}, }; /** @@ -360,6 +370,7 @@ static payload_order_t create_child_sa_i_order[] = { */ static payload_rule_t create_child_sa_r_rules[] = { /* payload type min max encr suff */ + {PLV2_FRAGMENT, 0, 1, TRUE, TRUE}, {PLV2_NOTIFY, 0, MAX_NOTIFY_PAYLOADS, TRUE, TRUE}, {PLV2_SECURITY_ASSOCIATION, 1, 1, TRUE, FALSE}, {PLV2_NONCE, 1, 1, TRUE, FALSE}, @@ -386,6 +397,7 @@ static payload_order_t create_child_sa_r_order[] = { {PLV2_TS_RESPONDER, 0}, {PLV2_NOTIFY, ADDITIONAL_TS_POSSIBLE}, {PLV2_NOTIFY, 0}, + {PLV2_FRAGMENT, 0}, }; #ifdef ME @@ -2143,6 +2155,8 @@ METHOD(message_t, parse_header, status_t, } ike_header->destroy(ike_header); + this->parser->set_major_version(this->parser, this->major_version); + DBG2(DBG_ENC, "parsed a %N %s header", exchange_type_names, this->exchange_type, this->major_version == IKEV1_MAJOR_VERSION ? "message" : (this->is_request ? "request" : "response")); @@ -2463,7 +2477,7 @@ static status_t decrypt_payloads(private_message_t *this, keymat_t *keymat) was_encrypted = "encrypted fragment payload"; } - if (payload_is_known(type) && !was_encrypted && + if (payload_is_known(type, this->major_version) && !was_encrypted && !is_connectivity_check(this, payload) && this->exchange_type != AGGRESSIVE) { diff --git a/src/libcharon/encoding/parser.c b/src/libcharon/encoding/parser.c index d6240fde2..f8340367e 100644 --- a/src/libcharon/encoding/parser.c +++ b/src/libcharon/encoding/parser.c @@ -59,6 +59,11 @@ struct private_parser_t { parser_t public; /** + * major IKE version + */ + u_int8_t major_version; + + /** * Current bit for reading in input data. */ u_int8_t bit_pos; @@ -369,7 +374,14 @@ METHOD(parser_t, parse_payload, status_t, encoding_rule_t *rule; /* create instance of the payload to parse */ - pld = payload_create(payload_type); + if (payload_is_known(payload_type, this->major_version)) + { + pld = payload_create(payload_type); + } + else + { + pld = (payload_t*)unknown_payload_create(payload_type); + } DBG2(DBG_ENC, "parsing %N payload, %d bytes left", payload_type_names, payload_type, this->input_roof - this->byte_pos); @@ -629,6 +641,12 @@ METHOD(parser_t, reset_context, void, this->bit_pos = 0; } +METHOD(parser_t, set_major_version, void, + private_parser_t *this, u_int8_t major_version) +{ + this->major_version = major_version; +} + METHOD(parser_t, destroy, void, private_parser_t *this) { @@ -646,6 +664,7 @@ parser_t *parser_create(chunk_t data) .public = { .parse_payload = _parse_payload, .reset_context = _reset_context, + .set_major_version = _set_major_version, .get_remaining_byte_count = _get_remaining_byte_count, .destroy = _destroy, }, diff --git a/src/libcharon/encoding/parser.h b/src/libcharon/encoding/parser.h index 27c5f03fe..5fd3e86ee 100644 --- a/src/libcharon/encoding/parser.h +++ b/src/libcharon/encoding/parser.h @@ -29,7 +29,7 @@ typedef struct parser_t parser_t; #include <encoding/payloads/payload.h> /** - * A parser_t class to parse IKEv2 payloads. + * A parser_t class to parse IKE payloads. * * A parser is used for parsing one chunk of data. Multiple * payloads can be parsed out of the chunk using parse_payload. @@ -50,7 +50,8 @@ struct parser_t { * - SUCCESSFUL if succeeded, * - PARSE_ERROR if corrupted/invalid data found */ - status_t (*parse_payload) (parser_t *this, payload_type_t payload_type, payload_t **payload); + status_t (*parse_payload) (parser_t *this, payload_type_t payload_type, + payload_t **payload); /** * Gets the remaining byte count which is not currently parsed. @@ -63,6 +64,13 @@ struct parser_t { void (*reset_context) (parser_t *this); /** + * Set the major IKE version. + * + * @param major_version the major IKE version + */ + void (*set_major_version) (parser_t *this, u_int8_t major_version); + + /** * Destroys a parser_t object. */ void (*destroy) (parser_t *this); diff --git a/src/libcharon/encoding/payloads/delete_payload.c b/src/libcharon/encoding/payloads/delete_payload.c index c2ab3b951..f11ea485c 100644 --- a/src/libcharon/encoding/payloads/delete_payload.c +++ b/src/libcharon/encoding/payloads/delete_payload.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2015 Tobias Brunner * Copyright (C) 2005-2010 Martin Willi * Copyright (C) 2010 revosec AG * Copyright (C) 2005 Jan Hutter @@ -281,6 +282,19 @@ METHOD(delete_payload_t, set_ike_spi, void, this->payload_length = get_header_length(this) + this->spi_size; } +METHOD(delete_payload_t, get_ike_spi, bool, + private_delete_payload_t *this, u_int64_t *spi_i, u_int64_t *spi_r) +{ + if (this->protocol_id != PROTO_IKE || + this->spis.len < 2 * sizeof(u_int64_t)) + { + return FALSE; + } + memcpy(spi_i, this->spis.ptr, sizeof(u_int64_t)); + memcpy(spi_r, this->spis.ptr + sizeof(u_int64_t), sizeof(u_int64_t)); + return TRUE; +} + /** * SPI enumerator implementation */ @@ -352,6 +366,7 @@ delete_payload_t *delete_payload_create(payload_type_t type, .get_protocol_id = _get_protocol_id, .add_spi = _add_spi, .set_ike_spi = _set_ike_spi, + .get_ike_spi = _get_ike_spi, .create_spi_enumerator = _create_spi_enumerator, .destroy = _destroy, }, diff --git a/src/libcharon/encoding/payloads/delete_payload.h b/src/libcharon/encoding/payloads/delete_payload.h index 46a89eab6..6728718cd 100644 --- a/src/libcharon/encoding/payloads/delete_payload.h +++ b/src/libcharon/encoding/payloads/delete_payload.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2015 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -61,6 +62,15 @@ struct delete_payload_t { void (*set_ike_spi)(delete_payload_t *this, u_int64_t spi_i, u_int64_t spi_r); /** + * Get the IKE SPIs from an IKEv1 delete. + * + * @param spi_i initiator SPI + * @param spi_r responder SPI + * @return TRUE if SPIs extracted successfully + */ + bool (*get_ike_spi)(delete_payload_t *this, u_int64_t *spi_i, u_int64_t *spi_r); + + /** * Get an enumerator over the SPIs in network order. * * @return enumerator over SPIs, u_int32_t diff --git a/src/libcharon/encoding/payloads/encrypted_payload.c b/src/libcharon/encoding/payloads/encrypted_payload.c index 5c574c34d..04372fdf0 100644 --- a/src/libcharon/encoding/payloads/encrypted_payload.c +++ b/src/libcharon/encoding/payloads/encrypted_payload.c @@ -561,6 +561,7 @@ static status_t parse(private_encrypted_payload_t *this, chunk_t plain) payload_type_t type; parser = parser_create(plain); + parser->set_major_version(parser, this->type == PLV1_ENCRYPTED ? 1 : 2); type = this->next_payload; while (type != PL_NONE) { diff --git a/src/libcharon/encoding/payloads/id_payload.c b/src/libcharon/encoding/payloads/id_payload.c index a002a8f21..bb8aab748 100644 --- a/src/libcharon/encoding/payloads/id_payload.c +++ b/src/libcharon/encoding/payloads/id_payload.c @@ -258,17 +258,20 @@ static traffic_selector_t *get_ts_from_range(private_id_payload_t *this, static traffic_selector_t *get_ts_from_subnet(private_id_payload_t *this, ts_type_t type) { + traffic_selector_t *ts; chunk_t net, netmask; int i; net = chunk_create(this->id_data.ptr, this->id_data.len / 2); - netmask = chunk_skip(this->id_data, this->id_data.len / 2); + netmask = chunk_clone(chunk_skip(this->id_data, this->id_data.len / 2)); for (i = 0; i < net.len; i++) { netmask.ptr[i] = (netmask.ptr[i] ^ 0xFF) | net.ptr[i]; } - return traffic_selector_create_from_bytes(this->protocol_id, type, + ts = traffic_selector_create_from_bytes(this->protocol_id, type, net, this->port, netmask, this->port ?: 65535); + chunk_free(&netmask); + return ts; } /** diff --git a/src/libcharon/encoding/payloads/ke_payload.c b/src/libcharon/encoding/payloads/ke_payload.c index 4f552d6ac..50fd73f90 100644 --- a/src/libcharon/encoding/payloads/ke_payload.c +++ b/src/libcharon/encoding/payloads/ke_payload.c @@ -247,9 +247,15 @@ ke_payload_t *ke_payload_create(payload_type_t type) ke_payload_t *ke_payload_create_from_diffie_hellman(payload_type_t type, diffie_hellman_t *dh) { - private_ke_payload_t *this = (private_ke_payload_t*)ke_payload_create(type); + private_ke_payload_t *this; + chunk_t value; - dh->get_my_public_value(dh, &this->key_exchange_data); + if (!dh->get_my_public_value(dh, &value)) + { + return NULL; + } + this = (private_ke_payload_t*)ke_payload_create(type); + this->key_exchange_data = value; this->dh_group_number = dh->get_dh_group(dh); this->payload_length += this->key_exchange_data.len; diff --git a/src/libcharon/encoding/payloads/ke_payload.h b/src/libcharon/encoding/payloads/ke_payload.h index dfc6308b4..96c5096a5 100644 --- a/src/libcharon/encoding/payloads/ke_payload.h +++ b/src/libcharon/encoding/payloads/ke_payload.h @@ -73,7 +73,7 @@ ke_payload_t *ke_payload_create(payload_type_t type); * * @param type PLV2_KEY_EXCHANGE or PLV1_KEY_EXCHANGE * @param dh diffie hellman object containing group and key - * @return ke_payload_t object + * @return ke_payload_t object, NULL on error */ ke_payload_t *ke_payload_create_from_diffie_hellman(payload_type_t type, diffie_hellman_t *dh); diff --git a/src/libcharon/encoding/payloads/notify_payload.c b/src/libcharon/encoding/payloads/notify_payload.c index 94723ddd7..f32a1273f 100644 --- a/src/libcharon/encoding/payloads/notify_payload.c +++ b/src/libcharon/encoding/payloads/notify_payload.c @@ -65,7 +65,7 @@ ENUM_NEXT(notify_type_names, ME_CONNECT_FAILED, ME_CONNECT_FAILED, CHILD_SA_NOT_ "ME_CONNECT_FAILED"); ENUM_NEXT(notify_type_names, MS_NOTIFY_STATUS, MS_NOTIFY_STATUS, ME_CONNECT_FAILED, "MS_NOTIFY_STATUS"); -ENUM_NEXT(notify_type_names, INITIAL_CONTACT, FRAGMENTATION_SUPPORTED, MS_NOTIFY_STATUS, +ENUM_NEXT(notify_type_names, INITIAL_CONTACT, SIGNATURE_HASH_ALGORITHMS, MS_NOTIFY_STATUS, "INITIAL_CONTACT", "SET_WINDOW_SIZE", "ADDITIONAL_TS_POSSIBLE", @@ -112,8 +112,9 @@ ENUM_NEXT(notify_type_names, INITIAL_CONTACT, FRAGMENTATION_SUPPORTED, MS_NOTIFY "ERX_SUPPORTED", "IFOM_CAPABILITY", "SENDER_REQUEST_ID", - "FRAGMENTATION_SUPPORTED"); -ENUM_NEXT(notify_type_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, FRAGMENTATION_SUPPORTED, + "FRAGMENTATION_SUPPORTED", + "SIGNATURE_HASH_ALGORITHMS"); +ENUM_NEXT(notify_type_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, SIGNATURE_HASH_ALGORITHMS, "INITIAL_CONTACT"); ENUM_NEXT(notify_type_names, DPD_R_U_THERE, DPD_R_U_THERE_ACK, INITIAL_CONTACT_IKEV1, "DPD_R_U_THERE", @@ -174,7 +175,7 @@ ENUM_NEXT(notify_type_short_names, ME_CONNECT_FAILED, ME_CONNECT_FAILED, CHILD_S "ME_CONN_FAIL"); ENUM_NEXT(notify_type_short_names, MS_NOTIFY_STATUS, MS_NOTIFY_STATUS, ME_CONNECT_FAILED, "MS_STATUS"); -ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, FRAGMENTATION_SUPPORTED, MS_NOTIFY_STATUS, +ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, SIGNATURE_HASH_ALGORITHMS, MS_NOTIFY_STATUS, "INIT_CONTACT", "SET_WINSIZE", "ADD_TS_POSS", @@ -221,8 +222,9 @@ ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, FRAGMENTATION_SUPPORTED, MS_ "ERX_SUP", "IFOM_CAP", "SENDER_REQ_ID", - "FRAG_SUP"); -ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, FRAGMENTATION_SUPPORTED, + "FRAG_SUP", + "HASH_ALG"); +ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, SIGNATURE_HASH_ALGORITHMS, "INITIAL_CONTACT"); ENUM_NEXT(notify_type_short_names, DPD_R_U_THERE, DPD_R_U_THERE_ACK, INITIAL_CONTACT_IKEV1, "DPD", @@ -473,6 +475,14 @@ METHOD(payload_t, verify, status_t, } break; } + case SIGNATURE_HASH_ALGORITHMS: + { + if (this->notify_data.len % 2) + { + bad_length = TRUE; + } + break; + } case AUTH_LIFETIME: { if (this->notify_data.len != 4) diff --git a/src/libcharon/encoding/payloads/notify_payload.h b/src/libcharon/encoding/payloads/notify_payload.h index 25521c2bb..690757383 100644 --- a/src/libcharon/encoding/payloads/notify_payload.h +++ b/src/libcharon/encoding/payloads/notify_payload.h @@ -151,6 +151,8 @@ enum notify_type_t { SENDER_REQUEST_ID = 16429, /* IKEv2 fragmentation supported, RFC 7383 */ FRAGMENTATION_SUPPORTED = 16430, + /* Signature Hash Algorithms, RFC 7427 */ + SIGNATURE_HASH_ALGORITHMS = 16431, /* IKEv1 initial contact */ INITIAL_CONTACT_IKEV1 = 24578, /* IKEv1 DPD */ diff --git a/src/libcharon/encoding/payloads/payload.c b/src/libcharon/encoding/payloads/payload.c index 600b6dd68..a1cd2f945 100644 --- a/src/libcharon/encoding/payloads/payload.c +++ b/src/libcharon/encoding/payloads/payload.c @@ -266,37 +266,51 @@ payload_t *payload_create(payload_type_t type) /** * See header. */ -bool payload_is_known(payload_type_t type) +bool payload_is_known(payload_type_t type, u_int8_t maj_ver) { - if (type == PL_HEADER) + if (type >= PL_HEADER) { return TRUE; } - if (type >= PLV1_SECURITY_ASSOCIATION && type <= PLV1_CONFIGURATION) + switch (maj_ver) { - return TRUE; - } - if (type >= PLV1_NAT_D && type <= PLV1_NAT_OA) - { - return TRUE; - } - if (type >= PLV2_SECURITY_ASSOCIATION && type <= PLV2_EAP) - { - return TRUE; - } - if (type == PLV2_FRAGMENT) - { - return TRUE; - } + case 0: + case IKEV1_MAJOR_VERSION: + if (type >= PLV1_SECURITY_ASSOCIATION && type <= PLV1_CONFIGURATION) + { + return TRUE; + } + if (type >= PLV1_NAT_D && type <= PLV1_NAT_OA) + { + return TRUE; + } + if (type >= PLV1_NAT_D_DRAFT_00_03 && type <= PLV1_FRAGMENT) + { + return TRUE; + } + if (maj_ver) + { + break; + } + /* fall-through */ + case IKEV2_MAJOR_VERSION: + if (type >= PLV2_SECURITY_ASSOCIATION && type <= PLV2_EAP) + { + return TRUE; + } + if (type == PLV2_FRAGMENT) + { + return TRUE; + } #ifdef ME - if (type == PLV2_ID_PEER) - { - return TRUE; - } + if (type == PLV2_ID_PEER) + { + return TRUE; + } #endif - if (type >= PLV1_NAT_D_DRAFT_00_03 && type <= PLV1_FRAGMENT) - { - return TRUE; + break; + default: + break; } return FALSE; } diff --git a/src/libcharon/encoding/payloads/payload.h b/src/libcharon/encoding/payloads/payload.h index 036cd422d..920779bd1 100644 --- a/src/libcharon/encoding/payloads/payload.h +++ b/src/libcharon/encoding/payloads/payload.h @@ -405,9 +405,10 @@ payload_t *payload_create(payload_type_t type); * Check if a specific payload is implemented, or handled as unknown payload. * * @param type type of the payload to check + * @param maj_ver major IKE version (use 0 to skip version check) * @return FALSE if payload type handled as unknown payload */ -bool payload_is_known(payload_type_t type); +bool payload_is_known(payload_type_t type, u_int8_t maj_ver); /** * Get the value field in a payload using encoding rules. diff --git a/src/libcharon/encoding/payloads/proposal_substructure.c b/src/libcharon/encoding/payloads/proposal_substructure.c index 53e8cf3ad..48dcfeb24 100644 --- a/src/libcharon/encoding/payloads/proposal_substructure.c +++ b/src/libcharon/encoding/payloads/proposal_substructure.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2012-2014 Tobias Brunner * Copyright (C) 2005-2010 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -224,26 +224,7 @@ typedef enum { /* FreeS/WAN proprietary */ IKEV1_ESP_ENCR_SERPENT = 252, IKEV1_ESP_ENCR_TWOFISH = 253, -} ikev1_esp_encr_transid_t; - -/** - * IKEv1 Transform ID ESP authentication algorithm. - */ -typedef enum { - IKEV1_ESP_AUTH_HMAC_MD5 = 1, - IKEV1_ESP_AUTH_HMAC_SHA = 2, - IKEV1_ESP_AUTH_DES_MAC = 3, - IKEV1_ESP_AUTH_KPDK = 4, - IKEV1_ESP_AUTH_HMAC_SHA2_256 = 5, - IKEV1_ESP_AUTH_HMAC_SHA2_384 = 6, - IKEV1_ESP_AUTH_HMAC_SHA2_512 = 7, - IKEV1_ESP_AUTH_HMAC_RIPEMD = 8, - IKEV1_ESP_AUTH_AES_XCBC_MAC = 9, - IKEV1_ESP_AUTH_SIG_RSA = 10, - IKEV1_ESP_AUTH_AES_128_GMAC = 11, - IKEV1_ESP_AUTH_AES_192_GMAC = 12, - IKEV1_ESP_AUTH_AES_256_GMAC = 13, -} ikev1_esp_auth_transid_it; +} ikev1_esp_transid_t; /** * IKEv1 Transform ID AH authentication algorithm. @@ -264,6 +245,25 @@ typedef enum { } ikev1_ah_transid_t; /** + * IKEv1 authentication algorithm. + */ +typedef enum { + IKEV1_AUTH_HMAC_MD5 = 1, + IKEV1_AUTH_HMAC_SHA = 2, + IKEV1_AUTH_DES_MAC = 3, + IKEV1_AUTH_KPDK = 4, + IKEV1_AUTH_HMAC_SHA2_256 = 5, + IKEV1_AUTH_HMAC_SHA2_384 = 6, + IKEV1_AUTH_HMAC_SHA2_512 = 7, + IKEV1_AUTH_HMAC_RIPEMD = 8, + IKEV1_AUTH_AES_XCBC_MAC = 9, + IKEV1_AUTH_SIG_RSA = 10, + IKEV1_AUTH_AES_128_GMAC = 11, + IKEV1_AUTH_AES_192_GMAC = 12, + IKEV1_AUTH_AES_256_GMAC = 13, +} ikev1_auth_algo_t; + +/** * IKEv1 ESP Encapsulation mode. */ typedef enum { @@ -345,7 +345,7 @@ METHOD(payload_t, verify, status_t, switch (this->protocol_id) { case PROTO_IPCOMP: - if (this->spi.len != 2) + if (this->spi.len != 2 && this->spi.len != 4) { DBG1(DBG_ENC, "invalid CPI length in IPCOMP proposal"); return FAILED; @@ -536,7 +536,7 @@ METHOD(proposal_substructure_t, get_cpi, bool, { if (cpi) { - *cpi = *((u_int16_t*)this->spi.ptr); + *cpi = htons(untoh16(this->spi.ptr + this->spi.len - 2)); } enumerator->destroy(enumerator); return TRUE; @@ -620,7 +620,7 @@ static algo_map_t map_prf[] = { /** * ESP encryption algorithm mapping */ -static algo_map_t map_esp_encr[] = { +static algo_map_t map_esp[] = { { IKEV1_ESP_ENCR_DES_IV64, ENCR_DES_IV64 }, { IKEV1_ESP_ENCR_DES, ENCR_DES }, { IKEV1_ESP_ENCR_3DES, ENCR_3DES }, @@ -646,23 +646,6 @@ static algo_map_t map_esp_encr[] = { }; /** - * ESP authentication algorithm mapping - */ -static algo_map_t map_esp_auth[] = { - { IKEV1_ESP_AUTH_HMAC_MD5, AUTH_HMAC_MD5_96 }, - { IKEV1_ESP_AUTH_HMAC_SHA, AUTH_HMAC_SHA1_96 }, - { IKEV1_ESP_AUTH_DES_MAC, AUTH_DES_MAC }, - { IKEV1_ESP_AUTH_KPDK, AUTH_KPDK_MD5 }, - { IKEV1_ESP_AUTH_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_128 }, - { IKEV1_ESP_AUTH_HMAC_SHA2_384, AUTH_HMAC_SHA2_384_192 }, - { IKEV1_ESP_AUTH_HMAC_SHA2_512, AUTH_HMAC_SHA2_512_256 }, - { IKEV1_ESP_AUTH_AES_XCBC_MAC, AUTH_AES_XCBC_96 }, - { IKEV1_ESP_AUTH_AES_128_GMAC, AUTH_AES_128_GMAC }, - { IKEV1_ESP_AUTH_AES_192_GMAC, AUTH_AES_192_GMAC }, - { IKEV1_ESP_AUTH_AES_256_GMAC, AUTH_AES_256_GMAC }, -}; - -/** * AH authentication algorithm mapping */ static algo_map_t map_ah[] = { @@ -679,34 +662,30 @@ static algo_map_t map_ah[] = { }; /** - * Get IKEv2 algorithm from IKEv1 identifier + * ESP/AH authentication algorithm mapping */ -static u_int16_t get_alg_from_ikev1(transform_type_t type, u_int16_t value) +static algo_map_t map_auth[] = { + { IKEV1_AUTH_HMAC_MD5, AUTH_HMAC_MD5_96 }, + { IKEV1_AUTH_HMAC_SHA, AUTH_HMAC_SHA1_96 }, + { IKEV1_AUTH_DES_MAC, AUTH_DES_MAC }, + { IKEV1_AUTH_KPDK, AUTH_KPDK_MD5 }, + { IKEV1_AUTH_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_128 }, + { IKEV1_AUTH_HMAC_SHA2_384, AUTH_HMAC_SHA2_384_192 }, + { IKEV1_AUTH_HMAC_SHA2_512, AUTH_HMAC_SHA2_512_256 }, + { IKEV1_AUTH_AES_XCBC_MAC, AUTH_AES_XCBC_96 }, + { IKEV1_AUTH_AES_128_GMAC, AUTH_AES_128_GMAC }, + { IKEV1_AUTH_AES_192_GMAC, AUTH_AES_192_GMAC }, + { IKEV1_AUTH_AES_256_GMAC, AUTH_AES_256_GMAC }, +}; + +/** + * Map an IKEv1 to an IKEv2 identifier + */ +static u_int16_t ikev2_from_ikev1(algo_map_t *map, int count, u_int16_t def, + u_int16_t value) { - algo_map_t *map; - u_int16_t def; - int i, count; + int i; - switch (type) - { - case ENCRYPTION_ALGORITHM: - map = map_encr; - count = countof(map_encr); - def = ENCR_UNDEFINED; - break; - case INTEGRITY_ALGORITHM: - map = map_integ; - count = countof(map_integ); - def = AUTH_UNDEFINED; - break; - case PSEUDO_RANDOM_FUNCTION: - map = map_prf; - count = countof(map_prf); - def = PRF_UNDEFINED; - break; - default: - return 0; - } for (i = 0; i < count; i++) { if (map[i].ikev1 == value) @@ -718,30 +697,12 @@ static u_int16_t get_alg_from_ikev1(transform_type_t type, u_int16_t value) } /** - * Get IKEv1 algorithm from IKEv2 identifier + * Map an IKEv2 to an IKEv1 identifier */ -static u_int16_t get_ikev1_from_alg(transform_type_t type, u_int16_t value) +static u_int16_t ikev1_from_ikev2(algo_map_t *map, int count, u_int16_t value) { - algo_map_t *map; - int i, count; + int i; - switch (type) - { - case ENCRYPTION_ALGORITHM: - map = map_encr; - count = countof(map_encr); - break; - case INTEGRITY_ALGORITHM: - map = map_integ; - count = countof(map_integ); - break; - case PSEUDO_RANDOM_FUNCTION: - map = map_prf; - count = countof(map_prf); - break; - default: - return 0; - } for (i = 0; i < count; i++) { if (map[i].ikev2 == value) @@ -753,87 +714,96 @@ static u_int16_t get_ikev1_from_alg(transform_type_t type, u_int16_t value) } /** - * Get IKEv2 algorithm from IKEv1 ESP transaction ID + * Get IKEv2 algorithm from IKEv1 identifier */ -static u_int16_t get_alg_from_ikev1_transid(protocol_id_t proto, - transform_type_t type, u_int16_t value) +static u_int16_t get_alg_from_ikev1(transform_type_t type, u_int16_t value) { - algo_map_t *map; - u_int16_t def; - int i, count; - switch (type) { case ENCRYPTION_ALGORITHM: - map = map_esp_encr; - count = countof(map_esp_encr); - def = ENCR_UNDEFINED; - break; + return ikev2_from_ikev1(map_encr, countof(map_encr), + ENCR_UNDEFINED, value); case INTEGRITY_ALGORITHM: - if (proto == PROTO_ESP) - { - map = map_esp_auth; - count = countof(map_esp_auth); - } - else - { - map = map_ah; - count = countof(map_ah); - } - def = AUTH_UNDEFINED; - break; + return ikev2_from_ikev1(map_integ, countof(map_integ), + AUTH_UNDEFINED, value); + case PSEUDO_RANDOM_FUNCTION: + return ikev2_from_ikev1(map_prf, countof(map_prf), + PRF_UNDEFINED, value); default: return 0; } - for (i = 0; i < count; i++) +} + +/** + * Get IKEv1 algorithm from IKEv2 identifier + */ +static u_int16_t get_ikev1_from_alg(transform_type_t type, u_int16_t value) +{ + switch (type) { - if (map[i].ikev1 == value) - { - return map[i].ikev2; - } + case ENCRYPTION_ALGORITHM: + return ikev1_from_ikev2(map_encr, countof(map_encr), value); + case INTEGRITY_ALGORITHM: + return ikev1_from_ikev2(map_integ, countof(map_integ), value); + case PSEUDO_RANDOM_FUNCTION: + return ikev1_from_ikev2(map_prf, countof(map_prf), value); + default: + return 0; } - return def; } /** - * Get IKEv1 ESP/AH transaction ID from IKEv2 identifier + * Get IKEv2 algorithm from IKEv1 ESP/AH transform ID */ -static u_int16_t get_ikev1_transid_from_alg(protocol_id_t proto, - transform_type_t type, u_int16_t value) +static u_int16_t get_alg_from_ikev1_transid(transform_type_t type, + u_int16_t value) { - algo_map_t *map; - int i, count; - switch (type) { case ENCRYPTION_ALGORITHM: - map = map_esp_encr; - count = countof(map_esp_encr); - break; + return ikev2_from_ikev1(map_esp, countof(map_esp), + ENCR_UNDEFINED, value); case INTEGRITY_ALGORITHM: - if (proto == PROTO_ESP) - { - map = map_esp_auth; - count = countof(map_esp_auth); - } - else - { - map = map_ah; - count = countof(map_ah); - } - break; + return ikev2_from_ikev1(map_ah, countof(map_ah), + AUTH_UNDEFINED, value); default: return 0; } - for (i = 0; i < count; i++) +} + +/** + * Get IKEv1 ESP/AH transform ID from IKEv2 identifier + */ +static u_int16_t get_ikev1_transid_from_alg(transform_type_t type, + u_int16_t value) +{ + switch (type) { - if (map[i].ikev2 == value) - { - return map[i].ikev1; - } + case ENCRYPTION_ALGORITHM: + return ikev1_from_ikev2(map_esp, countof(map_esp), value); + case INTEGRITY_ALGORITHM: + return ikev1_from_ikev2(map_ah, countof(map_ah), value); + default: + return 0; } - return 0; } + +/** + * Get IKEv1 authentication algorithm from IKEv2 identifier + */ +static u_int16_t get_alg_from_ikev1_auth(u_int16_t value) +{ + return ikev2_from_ikev1(map_auth, countof(map_auth), AUTH_UNDEFINED, value); +} + +/** + * Get IKEv1 authentication algorithm from IKEv2 identifier + */ +static u_int16_t get_ikev1_auth_from_alg(u_int16_t value) +{ + return ikev1_from_ikev2(map_auth, countof(map_auth), value); +} + /** * Get IKEv1 authentication attribute from auth_method_t */ @@ -971,8 +941,7 @@ static void add_to_proposal_v1(proposal_t *proposal, break; case TATTR_PH2_AUTH_ALGORITHM: proposal->add_algorithm(proposal, INTEGRITY_ALGORITHM, - get_alg_from_ikev1_transid(proto, INTEGRITY_ALGORITHM, - value), 0); + get_alg_from_ikev1_auth(value), 0); break; case TATTR_PH2_GROUP: proposal->add_algorithm(proposal, DIFFIE_HELLMAN_GROUP, @@ -989,7 +958,7 @@ static void add_to_proposal_v1(proposal_t *proposal, NO_EXT_SEQ_NUMBERS, 0); if (proto == PROTO_ESP) { - encr = get_alg_from_ikev1_transid(proto, ENCRYPTION_ALGORITHM, + encr = get_alg_from_ikev1_transid(ENCRYPTION_ALGORITHM, transform->get_transform_id(transform)); if (encr) { @@ -1354,19 +1323,17 @@ static void set_from_proposal_v1(private_proposal_substructure_t *this, ipsec_mode_t mode, encap_t udp, int number) { transform_substructure_t *transform = NULL; - u_int16_t alg, key_size; + u_int16_t alg, transid, key_size; enumerator_t *enumerator; - protocol_id_t proto; - proto = proposal->get_protocol(proposal); enumerator = proposal->create_enumerator(proposal, ENCRYPTION_ALGORITHM); if (enumerator->enumerate(enumerator, &alg, &key_size)) { - alg = get_ikev1_transid_from_alg(proto, ENCRYPTION_ALGORITHM, alg); - if (alg) + transid = get_ikev1_transid_from_alg(ENCRYPTION_ALGORITHM, alg); + if (transid) { transform = transform_substructure_create_type( - PLV1_TRANSFORM_SUBSTRUCTURE, number, alg); + PLV1_TRANSFORM_SUBSTRUCTURE, number, transid); if (key_size) { transform->add_transform_attribute(transform, @@ -1380,13 +1347,14 @@ static void set_from_proposal_v1(private_proposal_substructure_t *this, enumerator = proposal->create_enumerator(proposal, INTEGRITY_ALGORITHM); if (enumerator->enumerate(enumerator, &alg, &key_size)) { - alg = get_ikev1_transid_from_alg(proto, INTEGRITY_ALGORITHM, alg); - if (alg) + transid = get_ikev1_transid_from_alg(INTEGRITY_ALGORITHM, alg); + alg = get_ikev1_auth_from_alg(alg); + if (transid && alg) { if (!transform) { transform = transform_substructure_create_type( - PLV1_TRANSFORM_SUBSTRUCTURE, number, alg); + PLV1_TRANSFORM_SUBSTRUCTURE, number, transid); } transform->add_transform_attribute(transform, transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE, diff --git a/src/libcharon/kernel/kernel_handler.c b/src/libcharon/kernel/kernel_handler.c index 059124e35..9c0e2602b 100644 --- a/src/libcharon/kernel/kernel_handler.c +++ b/src/libcharon/kernel/kernel_handler.c @@ -72,36 +72,39 @@ METHOD(kernel_listener_t, acquire, bool, } METHOD(kernel_listener_t, expire, bool, - private_kernel_handler_t *this, u_int32_t reqid, u_int8_t protocol, - u_int32_t spi, bool hard) + private_kernel_handler_t *this, u_int8_t protocol, u_int32_t spi, + host_t *dst, bool hard) { protocol_id_t proto = proto_ip2ike(protocol); - DBG1(DBG_KNL, "creating %s job for %N CHILD_SA with SPI %.8x and reqid {%u}", - hard ? "delete" : "rekey", protocol_id_names, proto, ntohl(spi), reqid); + DBG1(DBG_KNL, "creating %s job for CHILD_SA %N/0x%08x/%H", + hard ? "delete" : "rekey", protocol_id_names, proto, ntohl(spi), dst); if (hard) { lib->processor->queue_job(lib->processor, - (job_t*)delete_child_sa_job_create(reqid, proto, spi, hard)); + (job_t*)delete_child_sa_job_create(proto, spi, dst, hard)); } else { lib->processor->queue_job(lib->processor, - (job_t*)rekey_child_sa_job_create(reqid, proto, spi)); + (job_t*)rekey_child_sa_job_create(proto, spi, dst)); } return TRUE; } METHOD(kernel_listener_t, mapping, bool, - private_kernel_handler_t *this, u_int32_t reqid, u_int32_t spi, - host_t *remote) + private_kernel_handler_t *this, u_int8_t protocol, u_int32_t spi, + host_t *dst, host_t *remote) { - DBG1(DBG_KNL, "NAT mappings of ESP CHILD_SA with SPI %.8x and reqid {%u} " - "changed, queuing update job", ntohl(spi), reqid); + protocol_id_t proto = proto_ip2ike(protocol); + + DBG1(DBG_KNL, "NAT mappings of CHILD_SA %N/0x%08x/%H changed to %#H, " + "queuing update job", protocol_id_names, proto, ntohl(spi), dst, + remote); lib->processor->queue_job(lib->processor, - (job_t*)update_sa_job_create(reqid, remote)); + (job_t*)update_sa_job_create(proto, spi, dst, remote)); return TRUE; } diff --git a/src/libcharon/plugins/addrblock/Makefile.in b/src/libcharon/plugins/addrblock/Makefile.in index c3b014c3c..0554465b9 100644 --- a/src/libcharon/plugins/addrblock/Makefile.in +++ b/src/libcharon/plugins/addrblock/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/android_dns/Makefile.in b/src/libcharon/plugins/android_dns/Makefile.in index 50594a452..58cf97b6e 100644 --- a/src/libcharon/plugins/android_dns/Makefile.in +++ b/src/libcharon/plugins/android_dns/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/android_dns/android_dns_handler.c b/src/libcharon/plugins/android_dns/android_dns_handler.c index 526810355..160a145d3 100644 --- a/src/libcharon/plugins/android_dns/android_dns_handler.c +++ b/src/libcharon/plugins/android_dns/android_dns_handler.c @@ -128,7 +128,7 @@ static bool set_dns_server(private_android_dns_handler_t *this, int index, } METHOD(attribute_handler_t, handle, bool, - private_android_dns_handler_t *this, identification_t *id, + private_android_dns_handler_t *this, ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data) { switch (type) @@ -158,7 +158,7 @@ METHOD(attribute_handler_t, handle, bool, } METHOD(attribute_handler_t, release, void, - private_android_dns_handler_t *this, identification_t *server, + private_android_dns_handler_t *this, ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data) { if (type == INTERNAL_IP4_DNS) @@ -192,7 +192,7 @@ METHOD(enumerator_t, enumerate_dns, bool, } METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *, - private_android_dns_handler_t *this, identification_t *id, + private_android_dns_handler_t *this, ike_sa_t *ike_sa, linked_list_t *vips) { enumerator_t *enumerator; @@ -232,4 +232,3 @@ android_dns_handler_t *android_dns_handler_create() return &this->public; } - diff --git a/src/libcharon/plugins/android_dns/android_dns_plugin.c b/src/libcharon/plugins/android_dns/android_dns_plugin.c index b8eb11b57..9b6ec0dba 100644 --- a/src/libcharon/plugins/android_dns/android_dns_plugin.c +++ b/src/libcharon/plugins/android_dns/android_dns_plugin.c @@ -16,7 +16,6 @@ #include "android_dns_plugin.h" #include "android_dns_handler.h" -#include <hydra.h> #include <daemon.h> typedef struct private_android_dns_plugin_t private_android_dns_plugin_t; @@ -51,13 +50,13 @@ static bool plugin_cb(private_android_dns_plugin_t *this, { if (reg) { - hydra->attributes->add_handler(hydra->attributes, - &this->handler->handler); + charon->attributes->add_handler(charon->attributes, + &this->handler->handler); } else { - hydra->attributes->remove_handler(hydra->attributes, - &this->handler->handler); + charon->attributes->remove_handler(charon->attributes, + &this->handler->handler); } return TRUE; } diff --git a/src/libcharon/plugins/android_log/Makefile.in b/src/libcharon/plugins/android_log/Makefile.in index 700a4219c..8ce92e577 100644 --- a/src/libcharon/plugins/android_log/Makefile.in +++ b/src/libcharon/plugins/android_log/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libhydra/plugins/attr/Makefile.am b/src/libcharon/plugins/attr/Makefile.am index 5b899b80c..6bc7e77d8 100644 --- a/src/libhydra/plugins/attr/Makefile.am +++ b/src/libcharon/plugins/attr/Makefile.am @@ -1,6 +1,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra + -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ $(PLUGIN_CFLAGS) diff --git a/src/libhydra/plugins/attr/Makefile.in b/src/libcharon/plugins/attr/Makefile.in index 50ea066c5..486b3c0b0 100644 --- a/src/libhydra/plugins/attr/Makefile.in +++ b/src/libcharon/plugins/attr/Makefile.in @@ -78,7 +78,7 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -subdir = src/libhydra/plugins/attr +subdir = src/libcharon/plugins/attr DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -226,6 +226,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ @@ -423,7 +428,8 @@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra + -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ $(PLUGIN_CFLAGS) @@ -448,9 +454,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libhydra/plugins/attr/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/attr/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/libhydra/plugins/attr/Makefile + $(AUTOMAKE) --gnu src/libcharon/plugins/attr/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ diff --git a/src/libhydra/plugins/attr/attr_plugin.c b/src/libcharon/plugins/attr/attr_plugin.c index 72fcd6dff..9b15c3cc9 100644 --- a/src/libhydra/plugins/attr/attr_plugin.c +++ b/src/libcharon/plugins/attr/attr_plugin.c @@ -16,7 +16,7 @@ #include "attr_plugin.h" #include "attr_provider.h" -#include <hydra.h> +#include <daemon.h> typedef struct private_attr_plugin_t private_attr_plugin_t; @@ -50,13 +50,13 @@ static bool plugin_cb(private_attr_plugin_t *this, { if (reg) { - hydra->attributes->add_provider(hydra->attributes, - &this->provider->provider); + charon->attributes->add_provider(charon->attributes, + &this->provider->provider); } else { - hydra->attributes->remove_provider(hydra->attributes, - &this->provider->provider); + charon->attributes->remove_provider(charon->attributes, + &this->provider->provider); } return TRUE; } diff --git a/src/libhydra/plugins/attr/attr_plugin.h b/src/libcharon/plugins/attr/attr_plugin.h index 29fb33839..0c6eebfa7 100644 --- a/src/libhydra/plugins/attr/attr_plugin.h +++ b/src/libcharon/plugins/attr/attr_plugin.h @@ -15,7 +15,7 @@ /** * @defgroup attr attr - * @ingroup hplugins + * @ingroup cplugins * * @defgroup attr_plugin attr_plugin * @{ @ingroup attr diff --git a/src/libhydra/plugins/attr/attr_provider.c b/src/libcharon/plugins/attr/attr_provider.c index c1788df94..cac0ae4bf 100644 --- a/src/libhydra/plugins/attr/attr_provider.c +++ b/src/libcharon/plugins/attr/attr_provider.c @@ -18,7 +18,7 @@ #include <time.h> -#include <hydra.h> +#include <daemon.h> #include <utils/debug.h> #include <collections/linked_list.h> #include <threading/rwlock.h> @@ -78,7 +78,7 @@ static bool attr_enum_filter(void *null, attribute_entry_t **in, METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, private_attr_provider_t *this, linked_list_t *pools, - identification_t *id, linked_list_t *vips) + ike_sa_t *ike_sa, linked_list_t *vips) { if (vips->get_count(vips)) { diff --git a/src/libhydra/plugins/attr/attr_provider.h b/src/libcharon/plugins/attr/attr_provider.h index 17db30408..17db30408 100644 --- a/src/libhydra/plugins/attr/attr_provider.h +++ b/src/libcharon/plugins/attr/attr_provider.h diff --git a/src/libhydra/plugins/attr_sql/Makefile.am b/src/libcharon/plugins/attr_sql/Makefile.am index 6e7eae5eb..366c902f7 100644 --- a/src/libhydra/plugins/attr_sql/Makefile.am +++ b/src/libcharon/plugins/attr_sql/Makefile.am @@ -1,6 +1,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra + -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ $(PLUGIN_CFLAGS) @@ -13,6 +14,6 @@ endif libstrongswan_attr_sql_la_SOURCES = \ attr_sql_plugin.h attr_sql_plugin.c \ - sql_attribute.h sql_attribute.c + attr_sql_provider.h attr_sql_provider.c libstrongswan_attr_sql_la_LDFLAGS = -module -avoid-version diff --git a/src/libhydra/plugins/attr_sql/Makefile.in b/src/libcharon/plugins/attr_sql/Makefile.in index 076e1f8f2..8f1b3c0ff 100644 --- a/src/libhydra/plugins/attr_sql/Makefile.in +++ b/src/libcharon/plugins/attr_sql/Makefile.in @@ -78,7 +78,7 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -subdir = src/libhydra/plugins/attr_sql +subdir = src/libcharon/plugins/attr_sql DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -129,7 +129,7 @@ am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) libstrongswan_attr_sql_la_LIBADD = am_libstrongswan_attr_sql_la_OBJECTS = attr_sql_plugin.lo \ - sql_attribute.lo + attr_sql_provider.lo libstrongswan_attr_sql_la_OBJECTS = \ $(am_libstrongswan_attr_sql_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ @@ -426,7 +431,8 @@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra + -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ $(PLUGIN_CFLAGS) @@ -435,7 +441,7 @@ AM_CFLAGS = \ @MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-attr-sql.la libstrongswan_attr_sql_la_SOURCES = \ attr_sql_plugin.h attr_sql_plugin.c \ - sql_attribute.h sql_attribute.c + attr_sql_provider.h attr_sql_provider.c libstrongswan_attr_sql_la_LDFLAGS = -module -avoid-version all: all-am @@ -451,9 +457,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libhydra/plugins/attr_sql/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/attr_sql/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/libhydra/plugins/attr_sql/Makefile + $(AUTOMAKE) --gnu src/libcharon/plugins/attr_sql/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ @@ -529,7 +535,7 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attr_sql_plugin.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sql_attribute.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attr_sql_provider.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ diff --git a/src/libhydra/plugins/attr_sql/attr_sql_plugin.c b/src/libcharon/plugins/attr_sql/attr_sql_plugin.c index dde90051a..908877514 100644 --- a/src/libhydra/plugins/attr_sql/attr_sql_plugin.c +++ b/src/libcharon/plugins/attr_sql/attr_sql_plugin.c @@ -14,12 +14,12 @@ * for more details. */ -#include <hydra.h> +#include <daemon.h> #include <utils/debug.h> #include <plugins/plugin_feature.h> #include "attr_sql_plugin.h" -#include "sql_attribute.h" +#include "attr_sql_provider.h" typedef struct private_attr_sql_plugin_t private_attr_sql_plugin_t; @@ -41,7 +41,7 @@ struct private_attr_sql_plugin_t { /** * configuration attributes */ - sql_attribute_t *attribute; + attr_sql_provider_t *attribute; }; METHOD(plugin_t, get_name, char*, @@ -74,14 +74,14 @@ static bool open_database(private_attr_sql_plugin_t *this, DBG1(DBG_CFG, "attr-sql plugin failed to connect to database"); return FALSE; } - this->attribute = sql_attribute_create(this->db); - hydra->attributes->add_provider(hydra->attributes, - &this->attribute->provider); + this->attribute = attr_sql_provider_create(this->db); + charon->attributes->add_provider(charon->attributes, + &this->attribute->provider); } else { - hydra->attributes->remove_provider(hydra->attributes, - &this->attribute->provider); + charon->attributes->remove_provider(charon->attributes, + &this->attribute->provider); this->attribute->destroy(this->attribute); this->db->destroy(this->db); } diff --git a/src/libhydra/plugins/attr_sql/attr_sql_plugin.h b/src/libcharon/plugins/attr_sql/attr_sql_plugin.h index ba85a6b28..b6b04ccc0 100644 --- a/src/libhydra/plugins/attr_sql/attr_sql_plugin.h +++ b/src/libcharon/plugins/attr_sql/attr_sql_plugin.h @@ -15,9 +15,9 @@ /** * @defgroup attr_sql attr_sql - * @ingroup hplugins + * @ingroup cplugins * - * @defgroup sql_plugin sql_plugin + * @defgroup attr_sql_plugin attr_sql_plugin * @{ @ingroup attr_sql */ diff --git a/src/libhydra/plugins/attr_sql/sql_attribute.c b/src/libcharon/plugins/attr_sql/attr_sql_provider.c index d527c3fba..c2410705d 100644 --- a/src/libhydra/plugins/attr_sql/sql_attribute.c +++ b/src/libcharon/plugins/attr_sql/attr_sql_provider.c @@ -18,19 +18,19 @@ #include <utils/debug.h> #include <library.h> -#include "sql_attribute.h" +#include "attr_sql_provider.h" -typedef struct private_sql_attribute_t private_sql_attribute_t; +typedef struct private_attr_sql_provider_t private_attr_sql_provider_t; /** - * private data of sql_attribute + * private data of attr_sql_provider */ -struct private_sql_attribute_t { +struct private_attr_sql_provider_t { /** * public functions */ - sql_attribute_t public; + attr_sql_provider_t public; /** * database connection @@ -46,11 +46,14 @@ struct private_sql_attribute_t { /** * lookup/insert an identity */ -static u_int get_identity(private_sql_attribute_t *this, identification_t *id) +static u_int get_identity(private_attr_sql_provider_t *this, ike_sa_t *ike_sa) { + identification_t *id; enumerator_t *e; u_int row; + id = ike_sa->get_other_eap_id(ike_sa); + this->db->transaction(this->db, TRUE); /* look for peer identity in the identities table */ e = this->db->query(this->db, @@ -79,7 +82,7 @@ static u_int get_identity(private_sql_attribute_t *this, identification_t *id) /** * Lookup an attribute pool by name */ -static u_int get_attr_pool(private_sql_attribute_t *this, char *name) +static u_int get_attr_pool(private_attr_sql_provider_t *this, char *name) { enumerator_t *e; u_int row = 0; @@ -99,7 +102,7 @@ static u_int get_attr_pool(private_sql_attribute_t *this, char *name) /** * Lookup pool by name and address family */ -static u_int get_pool(private_sql_attribute_t *this, char *name, int family, +static u_int get_pool(private_attr_sql_provider_t *this, char *name, int family, u_int *timeout) { enumerator_t *e; @@ -125,7 +128,7 @@ static u_int get_pool(private_sql_attribute_t *this, char *name, int family, /** * Look up an existing lease */ -static host_t* check_lease(private_sql_attribute_t *this, char *name, +static host_t* check_lease(private_attr_sql_provider_t *this, char *name, u_int pool, u_int identity) { while (TRUE) @@ -171,7 +174,7 @@ static host_t* check_lease(private_sql_attribute_t *this, char *name, * address as a candidate, but double check later on if it is still available * during the update operation. This allows us to work without locking. */ -static host_t* get_lease(private_sql_attribute_t *this, char *name, +static host_t* get_lease(private_attr_sql_provider_t *this, char *name, u_int pool, u_int timeout, u_int identity) { while (TRUE) @@ -243,7 +246,7 @@ static host_t* get_lease(private_sql_attribute_t *this, char *name, } METHOD(attribute_provider_t, acquire_address, host_t*, - private_sql_attribute_t *this, linked_list_t *pools, identification_t *id, + private_attr_sql_provider_t *this, linked_list_t *pools, ike_sa_t *ike_sa, host_t *requested) { enumerator_t *enumerator; @@ -252,7 +255,7 @@ METHOD(attribute_provider_t, acquire_address, host_t*, char *name; int family; - identity = get_identity(this, id); + identity = get_identity(this, ike_sa); if (identity) { family = requested->get_family(requested); @@ -295,8 +298,8 @@ METHOD(attribute_provider_t, acquire_address, host_t*, } METHOD(attribute_provider_t, release_address, bool, - private_sql_attribute_t *this, linked_list_t *pools, host_t *address, - identification_t *id) + private_attr_sql_provider_t *this, linked_list_t *pools, host_t *address, + ike_sa_t *ike_sa) { enumerator_t *enumerator; u_int pool, timeout; @@ -338,7 +341,7 @@ METHOD(attribute_provider_t, release_address, bool, } METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, - private_sql_attribute_t *this, linked_list_t *pools, identification_t *id, + private_attr_sql_provider_t *this, linked_list_t *pools, ike_sa_t *ike_sa, linked_list_t *vips) { enumerator_t *attr_enumerator = NULL; @@ -350,9 +353,9 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, char *name; /* in a first step check for attributes that match name and id */ - if (id) + if (ike_sa) { - u_int identity = get_identity(this, id); + u_int identity = get_identity(this, ike_sa); pool_enumerator = pools->create_enumerator(pools); while (pool_enumerator->enumerate(pool_enumerator, &name)) @@ -432,8 +435,8 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, return (attr_enumerator ? attr_enumerator : enumerator_create_empty()); } -METHOD(sql_attribute_t, destroy, void, - private_sql_attribute_t *this) +METHOD(attr_sql_provider_t, destroy, void, + private_attr_sql_provider_t *this) { free(this); } @@ -441,9 +444,9 @@ METHOD(sql_attribute_t, destroy, void, /* * see header file */ -sql_attribute_t *sql_attribute_create(database_t *db) +attr_sql_provider_t *attr_sql_provider_create(database_t *db) { - private_sql_attribute_t *this; + private_attr_sql_provider_t *this; time_t now = time(NULL); INIT(this, diff --git a/src/libhydra/plugins/attr_sql/sql_attribute.h b/src/libcharon/plugins/attr_sql/attr_sql_provider.h index ca87eb27e..a9b037bf5 100644 --- a/src/libhydra/plugins/attr_sql/sql_attribute.h +++ b/src/libcharon/plugins/attr_sql/attr_sql_provider.h @@ -14,22 +14,22 @@ */ /** - * @defgroup sql_attribute sql_attribute + * @defgroup attr_sql_provider attr_sql_provider * @{ @ingroup attr_sql */ -#ifndef SQL_ATTRIBUTE_H_ -#define SQL_ATTRIBUTE_H_ +#ifndef ATTR_SQL_PROVIDER_H_ +#define ATTR_SQL_PROVIDER_H_ #include <attributes/attribute_provider.h> #include <database/database.h> -typedef struct sql_attribute_t sql_attribute_t; +typedef struct attr_sql_provider_t attr_sql_provider_t; /** * SQL database based IKEv2 cfg attribute provider. */ -struct sql_attribute_t { +struct attr_sql_provider_t { /** * Implements attribute provider interface @@ -37,14 +37,14 @@ struct sql_attribute_t { attribute_provider_t provider; /** - * Destroy a sql_attribute instance. + * Destroy a attr_sql_provider instance. */ - void (*destroy)(sql_attribute_t *this); + void (*destroy)(attr_sql_provider_t *this); }; /** - * Create a sql_attribute instance. + * Create a attr_sql_provider instance. */ -sql_attribute_t *sql_attribute_create(database_t *db); +attr_sql_provider_t *attr_sql_provider_create(database_t *db); -#endif /** SQL_ATTRIBUTE_H_ @}*/ +#endif /** ATTR_SQL_PROVIDER_H_ @}*/ diff --git a/src/libcharon/plugins/certexpire/Makefile.in b/src/libcharon/plugins/certexpire/Makefile.in index 08101d51d..f946d73c1 100644 --- a/src/libcharon/plugins/certexpire/Makefile.in +++ b/src/libcharon/plugins/certexpire/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/connmark/Makefile.am b/src/libcharon/plugins/connmark/Makefile.am new file mode 100644 index 000000000..cc4d0ec8d --- /dev/null +++ b/src/libcharon/plugins/connmark/Makefile.am @@ -0,0 +1,20 @@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon + +AM_CFLAGS = \ + $(PLUGIN_CFLAGS) $(libiptc_CFLAGS) + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-connmark.la +else +plugin_LTLIBRARIES = libstrongswan-connmark.la +endif + +libstrongswan_connmark_la_SOURCES = \ + connmark_listener.h connmark_listener.c \ + connmark_plugin.h connmark_plugin.c + +libstrongswan_connmark_la_LDFLAGS = -module -avoid-version +libstrongswan_connmark_la_LIBADD = $(libiptc_LIBS) diff --git a/src/libcharon/plugins/unit_tester/Makefile.in b/src/libcharon/plugins/connmark/Makefile.in index 1aca319c7..65f53fde9 100644 --- a/src/libcharon/plugins/unit_tester/Makefile.in +++ b/src/libcharon/plugins/connmark/Makefile.in @@ -78,7 +78,7 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -subdir = src/libcharon/plugins/unit_tester +subdir = src/libcharon/plugins/connmark DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -127,25 +127,23 @@ am__uninstall_files_from_dir = { \ } am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) -libstrongswan_unit_tester_la_LIBADD = -am__dirstamp = $(am__leading_dot)dirstamp -am_libstrongswan_unit_tester_la_OBJECTS = unit_tester.lo \ - tests/test_auth_info.lo tests/test_curl.lo tests/test_mysql.lo \ - tests/test_sqlite.lo tests/test_cert.lo tests/test_med_db.lo \ - tests/test_pool.lo tests/test_agent.lo -libstrongswan_unit_tester_la_OBJECTS = \ - $(am_libstrongswan_unit_tester_la_OBJECTS) +am__DEPENDENCIES_1 = +libstrongswan_connmark_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_libstrongswan_connmark_la_OBJECTS = connmark_listener.lo \ + connmark_plugin.lo +libstrongswan_connmark_la_OBJECTS = \ + $(am_libstrongswan_connmark_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = -libstrongswan_unit_tester_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ +libstrongswan_connmark_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_unit_tester_la_LDFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_connmark_la_LDFLAGS) \ $(LDFLAGS) -o $@ -@MONOLITHIC_FALSE@am_libstrongswan_unit_tester_la_rpath = -rpath \ +@MONOLITHIC_FALSE@am_libstrongswan_connmark_la_rpath = -rpath \ @MONOLITHIC_FALSE@ $(plugindir) -@MONOLITHIC_TRUE@am_libstrongswan_unit_tester_la_rpath = +@MONOLITHIC_TRUE@am_libstrongswan_connmark_la_rpath = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -180,8 +178,8 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = $(libstrongswan_unit_tester_la_SOURCES) -DIST_SOURCES = $(libstrongswan_unit_tester_la_SOURCES) +SOURCES = $(libstrongswan_connmark_la_SOURCES) +DIST_SOURCES = $(libstrongswan_connmark_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -232,6 +230,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -292,10 +291,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -369,6 +370,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ @@ -433,22 +436,16 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libcharon AM_CFLAGS = \ - $(PLUGIN_CFLAGS) - -@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-unit-tester.la -@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-unit-tester.la -libstrongswan_unit_tester_la_SOURCES = \ - unit_tester.c unit_tester.h tests.h \ - tests/test_auth_info.c \ - tests/test_curl.c \ - tests/test_mysql.c \ - tests/test_sqlite.c \ - tests/test_cert.c \ - tests/test_med_db.c \ - tests/test_pool.c \ - tests/test_agent.c - -libstrongswan_unit_tester_la_LDFLAGS = -module -avoid-version + $(PLUGIN_CFLAGS) $(libiptc_CFLAGS) + +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-connmark.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-connmark.la +libstrongswan_connmark_la_SOURCES = \ + connmark_listener.h connmark_listener.c \ + connmark_plugin.h connmark_plugin.c + +libstrongswan_connmark_la_LDFLAGS = -module -avoid-version +libstrongswan_connmark_la_LIBADD = $(libiptc_LIBS) all: all-am .SUFFIXES: @@ -462,9 +459,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/unit_tester/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/connmark/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/libcharon/plugins/unit_tester/Makefile + $(AUTOMAKE) --gnu src/libcharon/plugins/connmark/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ @@ -529,49 +526,18 @@ clean-pluginLTLIBRARIES: echo rm -f $${locs}; \ rm -f $${locs}; \ } -tests/$(am__dirstamp): - @$(MKDIR_P) tests - @: > tests/$(am__dirstamp) -tests/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) tests/$(DEPDIR) - @: > tests/$(DEPDIR)/$(am__dirstamp) -tests/test_auth_info.lo: tests/$(am__dirstamp) \ - tests/$(DEPDIR)/$(am__dirstamp) -tests/test_curl.lo: tests/$(am__dirstamp) \ - tests/$(DEPDIR)/$(am__dirstamp) -tests/test_mysql.lo: tests/$(am__dirstamp) \ - tests/$(DEPDIR)/$(am__dirstamp) -tests/test_sqlite.lo: tests/$(am__dirstamp) \ - tests/$(DEPDIR)/$(am__dirstamp) -tests/test_cert.lo: tests/$(am__dirstamp) \ - tests/$(DEPDIR)/$(am__dirstamp) -tests/test_med_db.lo: tests/$(am__dirstamp) \ - tests/$(DEPDIR)/$(am__dirstamp) -tests/test_pool.lo: tests/$(am__dirstamp) \ - tests/$(DEPDIR)/$(am__dirstamp) -tests/test_agent.lo: tests/$(am__dirstamp) \ - tests/$(DEPDIR)/$(am__dirstamp) - -libstrongswan-unit-tester.la: $(libstrongswan_unit_tester_la_OBJECTS) $(libstrongswan_unit_tester_la_DEPENDENCIES) $(EXTRA_libstrongswan_unit_tester_la_DEPENDENCIES) - $(AM_V_CCLD)$(libstrongswan_unit_tester_la_LINK) $(am_libstrongswan_unit_tester_la_rpath) $(libstrongswan_unit_tester_la_OBJECTS) $(libstrongswan_unit_tester_la_LIBADD) $(LIBS) + +libstrongswan-connmark.la: $(libstrongswan_connmark_la_OBJECTS) $(libstrongswan_connmark_la_DEPENDENCIES) $(EXTRA_libstrongswan_connmark_la_DEPENDENCIES) + $(AM_V_CCLD)$(libstrongswan_connmark_la_LINK) $(am_libstrongswan_connmark_la_rpath) $(libstrongswan_connmark_la_OBJECTS) $(libstrongswan_connmark_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) - -rm -f tests/*.$(OBJEXT) - -rm -f tests/*.lo distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unit_tester.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_agent.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_auth_info.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_cert.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_curl.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_med_db.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_mysql.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_pool.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@tests/$(DEPDIR)/test_sqlite.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connmark_listener.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/connmark_plugin.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @@ -602,7 +568,6 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs - -rm -rf tests/.libs tests/_libs ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique @@ -719,8 +684,6 @@ clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f tests/$(DEPDIR)/$(am__dirstamp) - -rm -f tests/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -731,7 +694,7 @@ clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ clean-pluginLTLIBRARIES mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) tests/$(DEPDIR) + -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -777,7 +740,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) tests/$(DEPDIR) + -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic diff --git a/src/libcharon/plugins/connmark/connmark_listener.c b/src/libcharon/plugins/connmark/connmark_listener.c new file mode 100644 index 000000000..23df690e8 --- /dev/null +++ b/src/libcharon/plugins/connmark/connmark_listener.c @@ -0,0 +1,538 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "connmark_listener.h" + +#include <daemon.h> + +#include <errno.h> +#include <libiptc/libiptc.h> +#include <linux/netfilter/xt_esp.h> +#include <linux/netfilter/xt_tcpudp.h> +#include <linux/netfilter/xt_MARK.h> +#include <linux/netfilter/xt_policy.h> +#include <linux/netfilter/xt_CONNMARK.h> + + +typedef struct private_connmark_listener_t private_connmark_listener_t; + +/** + * Private data of an connmark_listener_t object. + */ +struct private_connmark_listener_t { + + /** + * Public connmark_listener_t interface. + */ + connmark_listener_t public; +}; + +/** + * Convert an (IPv4) traffic selector to an address and mask + */ +static bool ts2in(traffic_selector_t *ts, + struct in_addr *addr, struct in_addr *mask) +{ + u_int8_t bits; + host_t *net; + + if (ts->get_type(ts) == TS_IPV4_ADDR_RANGE && + ts->to_subnet(ts, &net, &bits)) + { + memcpy(&addr->s_addr, net->get_address(net).ptr, 4); + net->destroy(net); + mask->s_addr = htonl(0xffffffffU << (32 - bits)); + return TRUE; + } + return FALSE; +} + +/** + * Convert an (IPv4) host to an address with mask + */ +static bool host2in(host_t *host, struct in_addr *addr, struct in_addr *mask) +{ + if (host->get_family(host) == AF_INET) + { + memcpy(&addr->s_addr, host->get_address(host).ptr, 4); + mask->s_addr = ~0; + return TRUE; + } + return FALSE; +} + +/** + * Add or remove a rule to/from the specified chain + */ +static bool manage_rule(struct iptc_handle *ipth, const char *chain, + bool add, struct ipt_entry *e) +{ + if (add) + { + if (!iptc_insert_entry(chain, e, 0, ipth)) + { + DBG1(DBG_CFG, "appending %s rule failed: %s", + chain, iptc_strerror(errno)); + return FALSE; + } + } + else + { + if (!iptc_delete_entry(chain, e, "", ipth)) + { + DBG1(DBG_CFG, "deleting %s rule failed: %s", + chain, iptc_strerror(errno)); + return FALSE; + } + } + return TRUE; +} + +/** + * Add rule marking UDP-encapsulated ESP packets to match the correct policy + */ +static bool manage_pre_esp_in_udp(private_connmark_listener_t *this, + struct iptc_handle *ipth, bool add, + u_int mark, u_int32_t spi, + host_t *dst, host_t *src) +{ + struct { + struct ipt_entry e; + struct ipt_entry_match m; + struct xt_udp udp; + struct ipt_entry_target t; + struct xt_mark_tginfo2 tm; + } ipt = { + .e = { + .target_offset = XT_ALIGN(sizeof(ipt.e) + sizeof(ipt.m) + + sizeof(ipt.udp)), + .next_offset = sizeof(ipt), + .ip = { + .proto = IPPROTO_UDP, + }, + }, + .m = { + .u = { + .user = { + .match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.udp)), + .name = "udp", + }, + }, + }, + .udp = { + .spts = { src->get_port(src), src->get_port(src) }, + .dpts = { dst->get_port(dst), dst->get_port(dst) }, + }, + .t = { + .u = { + .user = { + .target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.tm)), + .name = "MARK", + .revision = 2, + }, + }, + }, + .tm = { + .mark = mark, + .mask = ~0, + }, + }; + + if (!host2in(dst, &ipt.e.ip.dst, &ipt.e.ip.dmsk) || + !host2in(src, &ipt.e.ip.src, &ipt.e.ip.smsk)) + { + return FALSE; + } + return manage_rule(ipth, "PREROUTING", add, &ipt.e); +} + +/** + * Add rule marking non-encapsulated ESP packets to match the correct policy + */ +static bool manage_pre_esp(private_connmark_listener_t *this, + struct iptc_handle *ipth, bool add, + u_int mark, u_int32_t spi, + host_t *dst, host_t *src) +{ + struct { + struct ipt_entry e; + struct ipt_entry_match m; + struct xt_esp esp; + struct ipt_entry_target t; + struct xt_mark_tginfo2 tm; + } ipt = { + .e = { + .target_offset = XT_ALIGN(sizeof(ipt.e) + sizeof(ipt.m) + + sizeof(ipt.esp)), + .next_offset = sizeof(ipt), + .ip = { + .proto = IPPROTO_ESP, + }, + }, + .m = { + .u = { + .user = { + .match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.esp)), + .name = "esp", + }, + }, + }, + .esp = { + .spis = { htonl(spi), htonl(spi) }, + }, + .t = { + .u = { + .user = { + .target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.tm)), + .name = "MARK", + .revision = 2, + }, + }, + }, + .tm = { + .mark = mark, + .mask = ~0, + }, + }; + + if (!host2in(dst, &ipt.e.ip.dst, &ipt.e.ip.dmsk) || + !host2in(src, &ipt.e.ip.src, &ipt.e.ip.smsk)) + { + return FALSE; + } + return manage_rule(ipth, "PREROUTING", add, &ipt.e); +} + +/** + * Add rule marking ESP packets to match the correct policy + */ +static bool manage_pre(private_connmark_listener_t *this, + struct iptc_handle *ipth, bool add, + u_int mark, u_int32_t spi, bool encap, + host_t *dst, host_t *src) +{ + if (encap) + { + return manage_pre_esp_in_udp(this, ipth, add, mark, spi, dst, src); + } + return manage_pre_esp(this, ipth, add, mark, spi, dst, src); +} + +/** + * Add inbound rule applying CONNMARK to matching traffic + */ +static bool manage_in(private_connmark_listener_t *this, + struct iptc_handle *ipth, bool add, + u_int mark, u_int32_t spi, + traffic_selector_t *dst, traffic_selector_t *src) +{ + struct { + struct ipt_entry e; + struct ipt_entry_match m; + struct xt_policy_info p; + struct ipt_entry_target t; + struct xt_connmark_tginfo1 cm; + } ipt = { + .e = { + .target_offset = XT_ALIGN(sizeof(ipt.e) + sizeof(ipt.m) + + sizeof(ipt.p)), + .next_offset = sizeof(ipt), + }, + .m = { + .u = { + .user = { + .match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.p)), + .name = "policy", + }, + }, + }, + .p = { + .pol = { + { + .spi = spi, + .match.spi = 1, + }, + }, + .len = 1, + .flags = XT_POLICY_MATCH_IN, + }, + .t = { + .u = { + .user = { + .target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.cm)), + .name = "CONNMARK", + .revision = 1, + }, + }, + }, + .cm = { + .ctmark = mark, + .ctmask = ~0, + .nfmask = ~0, + .mode = XT_CONNMARK_SET, + }, + }; + + if (!ts2in(dst, &ipt.e.ip.dst, &ipt.e.ip.dmsk) || + !ts2in(src, &ipt.e.ip.src, &ipt.e.ip.smsk)) + { + return FALSE; + } + return manage_rule(ipth, "INPUT", add, &ipt.e); +} + +/** + * Add outbund rule restoring CONNMARK on matching traffic + */ +static bool manage_out(private_connmark_listener_t *this, + struct iptc_handle *ipth, bool add, + traffic_selector_t *dst, traffic_selector_t *src) +{ + struct { + struct ipt_entry e; + struct ipt_entry_target t; + struct xt_connmark_tginfo1 cm; + } ipt = { + .e = { + .target_offset = XT_ALIGN(sizeof(ipt.e)), + .next_offset = sizeof(ipt), + }, + .t = { + .u = { + .user = { + .target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.cm)), + .name = "CONNMARK", + .revision = 1, + }, + }, + }, + .cm = { + .ctmask = ~0, + .nfmask = ~0, + .mode = XT_CONNMARK_RESTORE, + }, + }; + + if (!ts2in(dst, &ipt.e.ip.dst, &ipt.e.ip.dmsk) || + !ts2in(src, &ipt.e.ip.src, &ipt.e.ip.smsk)) + { + return FALSE; + } + return manage_rule(ipth, "OUTPUT", add, &ipt.e); +} + +/** + * Initialize iptables handle, log error + */ +static struct iptc_handle* init_handle() +{ + struct iptc_handle *ipth; + + ipth = iptc_init("mangle"); + if (ipth) + { + return ipth; + } + DBG1(DBG_CFG, "initializing iptables failed: %s", iptc_strerror(errno)); + return NULL; +} + +/** + * Commit iptables rules, log error + */ +static bool commit_handle(struct iptc_handle *ipth) +{ + if (iptc_commit(ipth)) + { + return TRUE; + } + DBG1(DBG_CFG, "forecast iptables commit failed: %s", iptc_strerror(errno)); + return FALSE; +} + +/** + * Add/Remove policies for a CHILD_SA using a iptables handle + */ +static bool manage_policies(private_connmark_listener_t *this, + struct iptc_handle *ipth, host_t *dst, host_t *src, + bool encap, child_sa_t *child_sa, bool add) +{ + traffic_selector_t *local, *remote; + enumerator_t *enumerator; + u_int32_t spi; + u_int mark; + bool done = TRUE; + + spi = child_sa->get_spi(child_sa, TRUE); + mark = child_sa->get_mark(child_sa, TRUE).value; + + enumerator = child_sa->create_policy_enumerator(child_sa); + while (enumerator->enumerate(enumerator, &local, &remote)) + { + if (!manage_pre(this, ipth, add, mark, spi, encap, dst, src) || + !manage_in(this, ipth, add, mark, spi, local, remote) || + !manage_out(this, ipth, add, remote, local)) + { + done = FALSE; + break; + } + } + enumerator->destroy(enumerator); + + return done; +} + +/** + * Check if rules should be installed for given CHILD_SA + */ +static bool handle_sa(child_sa_t *child_sa) +{ + return child_sa->get_mark(child_sa, TRUE).value && + child_sa->get_mark(child_sa, FALSE).value && + child_sa->get_mode(child_sa) == MODE_TRANSPORT && + child_sa->get_protocol(child_sa) == PROTO_ESP; +} + +METHOD(listener_t, child_updown, bool, + private_connmark_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, + bool up) +{ + struct iptc_handle *ipth; + host_t *dst, *src; + bool encap; + + dst = ike_sa->get_my_host(ike_sa); + src = ike_sa->get_other_host(ike_sa); + encap = child_sa->has_encap(child_sa); + + if (handle_sa(child_sa)) + { + ipth = init_handle(); + if (ipth) + { + if (manage_policies(this, ipth, dst, src, encap, child_sa, up)) + { + commit_handle(ipth); + } + iptc_free(ipth); + } + } + return TRUE; +} + +METHOD(listener_t, child_rekey, bool, + private_connmark_listener_t *this, ike_sa_t *ike_sa, + child_sa_t *old, child_sa_t *new) +{ + struct iptc_handle *ipth; + host_t *dst, *src; + bool oldencap, newencap; + + dst = ike_sa->get_my_host(ike_sa); + src = ike_sa->get_other_host(ike_sa); + oldencap = old->has_encap(old); + newencap = new->has_encap(new); + + if (handle_sa(old)) + { + ipth = init_handle(); + if (ipth) + { + if (manage_policies(this, ipth, dst, src, oldencap, old, FALSE) && + manage_policies(this, ipth, dst, src, newencap, new, TRUE)) + { + commit_handle(ipth); + } + iptc_free(ipth); + } + } + return TRUE; +} + +METHOD(listener_t, ike_update, bool, + private_connmark_listener_t *this, ike_sa_t *ike_sa, + bool local, host_t *new) +{ + struct iptc_handle *ipth; + enumerator_t *enumerator; + child_sa_t *child_sa; + host_t *dst, *src; + bool oldencap, newencap; + + if (local) + { + dst = new; + src = ike_sa->get_other_host(ike_sa); + } + else + { + dst = ike_sa->get_my_host(ike_sa); + src = new; + } + /* during ike_update(), has_encap() on the CHILD_SA has not yet been + * updated, but shows the old state. */ + newencap = ike_sa->has_condition(ike_sa, COND_NAT_ANY); + + enumerator = ike_sa->create_child_sa_enumerator(ike_sa); + while (enumerator->enumerate(enumerator, &child_sa)) + { + if (handle_sa(child_sa)) + { + oldencap = child_sa->has_encap(child_sa); + ipth = init_handle(); + if (ipth) + { + if (manage_policies(this, ipth, dst, src, oldencap, + child_sa, FALSE) && + manage_policies(this, ipth, dst, src, newencap, + child_sa, TRUE)) + { + commit_handle(ipth); + } + iptc_free(ipth); + } + } + } + enumerator->destroy(enumerator); + + return TRUE; +} + +METHOD(connmark_listener_t, destroy, void, + private_connmark_listener_t *this) +{ + free(this); +} + +/** + * See header + */ +connmark_listener_t *connmark_listener_create() +{ + private_connmark_listener_t *this; + + INIT(this, + .public = { + .listener = { + .ike_update = _ike_update, + .child_updown = _child_updown, + .child_rekey = _child_rekey, + }, + .destroy = _destroy, + }, + ); + + return &this->public; +} diff --git a/src/libcharon/plugins/connmark/connmark_listener.h b/src/libcharon/plugins/connmark/connmark_listener.h new file mode 100644 index 000000000..2d4098fb6 --- /dev/null +++ b/src/libcharon/plugins/connmark/connmark_listener.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup connmark_listener connmark_listener + * @{ @ingroup connmark + */ + +#ifndef CONNMARK_LISTENER_H_ +#define CONNMARK_LISTENER_H_ + +#include <bus/listeners/listener.h> + +typedef struct connmark_listener_t connmark_listener_t; + +/** + * Listener to install Netfilter rules + */ +struct connmark_listener_t { + + /** + * Implements listener_t interface. + */ + listener_t listener; + + /** + * Destroy a connmark_listener_t. + */ + void (*destroy)(connmark_listener_t *this); +}; + +/** + * Create a connmark_listener instance. + */ +connmark_listener_t *connmark_listener_create(); + +#endif /** CONNMARK_LISTENER_H_ @}*/ diff --git a/src/libcharon/plugins/connmark/connmark_plugin.c b/src/libcharon/plugins/connmark/connmark_plugin.c new file mode 100644 index 000000000..3f276f93e --- /dev/null +++ b/src/libcharon/plugins/connmark/connmark_plugin.c @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "connmark_plugin.h" +#include "connmark_listener.h" + +#include <daemon.h> + +typedef struct private_connmark_plugin_t private_connmark_plugin_t; + +/** + * private data of connmark plugin + */ +struct private_connmark_plugin_t { + + /** + * implements plugin interface + */ + connmark_plugin_t public; + + /** + * Listener installing netfilter rules + */ + connmark_listener_t *listener; +}; + +METHOD(plugin_t, get_name, char*, + private_connmark_plugin_t *this) +{ + return "connmark"; +} + +/** + * Register listener + */ +static bool plugin_cb(private_connmark_plugin_t *this, + plugin_feature_t *feature, bool reg, void *cb_data) +{ + if (reg) + { + charon->bus->add_listener(charon->bus, &this->listener->listener); + } + else + { + charon->bus->remove_listener(charon->bus, &this->listener->listener); + } + return TRUE; +} + +METHOD(plugin_t, get_features, int, + private_connmark_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL), + PLUGIN_PROVIDE(CUSTOM, "connmark"), + }; + *features = f; + return countof(f); +} + +METHOD(plugin_t, destroy, void, + private_connmark_plugin_t *this) +{ + this->listener->destroy(this->listener); + free(this); +} + +/** + * Plugin constructor + */ +plugin_t *connmark_plugin_create() +{ + private_connmark_plugin_t *this; + + if (!lib->caps->keep(lib->caps, CAP_NET_ADMIN)) + { + DBG1(DBG_NET, "connmark plugin requires CAP_NET_ADMIN capability"); + return NULL; + } + + INIT(this, + .public = { + .plugin = { + .get_name = _get_name, + .get_features = _get_features, + .destroy = _destroy, + }, + }, + .listener = connmark_listener_create(), + ); + + return &this->public.plugin; +} diff --git a/src/libcharon/plugins/connmark/connmark_plugin.h b/src/libcharon/plugins/connmark/connmark_plugin.h new file mode 100644 index 000000000..5b4ccebbe --- /dev/null +++ b/src/libcharon/plugins/connmark/connmark_plugin.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup connmark connmark + * @ingroup cplugins + * + * @defgroup connmark_plugin connmark_plugin + * @{ @ingroup connmark + */ + +#ifndef CONNMARK_PLUGIN_H_ +#define CONNMARK_PLUGIN_H_ + +#include <plugins/plugin.h> + +typedef struct connmark_plugin_t connmark_plugin_t; + +/** + * Plugin using marks to select return path SA based on conntrack. + */ +struct connmark_plugin_t { + + /** + * implements plugin interface + */ + plugin_t plugin; +}; + +#endif /** CONNMARK_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/coupling/Makefile.in b/src/libcharon/plugins/coupling/Makefile.in index 679d2dae6..dff80c37f 100644 --- a/src/libcharon/plugins/coupling/Makefile.in +++ b/src/libcharon/plugins/coupling/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/dhcp/Makefile.in b/src/libcharon/plugins/dhcp/Makefile.in index 768c2b32b..1e84f04e2 100644 --- a/src/libcharon/plugins/dhcp/Makefile.in +++ b/src/libcharon/plugins/dhcp/Makefile.in @@ -227,6 +227,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/dhcp/dhcp_plugin.c b/src/libcharon/plugins/dhcp/dhcp_plugin.c index c36c60d28..642e28afc 100644 --- a/src/libcharon/plugins/dhcp/dhcp_plugin.c +++ b/src/libcharon/plugins/dhcp/dhcp_plugin.c @@ -18,7 +18,6 @@ #include "dhcp_plugin.h" -#include <hydra.h> #include <daemon.h> #include <plugins/plugin_feature.h> @@ -69,13 +68,13 @@ static bool plugin_cb(private_dhcp_plugin_t *this, return FALSE; } this->provider = dhcp_provider_create(this->socket); - hydra->attributes->add_provider(hydra->attributes, - &this->provider->provider); + charon->attributes->add_provider(charon->attributes, + &this->provider->provider); } else { - hydra->attributes->remove_provider(hydra->attributes, - &this->provider->provider); + charon->attributes->remove_provider(charon->attributes, + &this->provider->provider); this->provider->destroy(this->provider); this->socket->destroy(this->socket); } diff --git a/src/libcharon/plugins/dhcp/dhcp_provider.c b/src/libcharon/plugins/dhcp/dhcp_provider.c index f5325b566..f0681b1da 100644 --- a/src/libcharon/plugins/dhcp/dhcp_provider.c +++ b/src/libcharon/plugins/dhcp/dhcp_provider.c @@ -66,10 +66,11 @@ static uintptr_t hash_transaction(dhcp_transaction_t *transaction) METHOD(attribute_provider_t, acquire_address, host_t*, private_dhcp_provider_t *this, linked_list_t *pools, - identification_t *id, host_t *requested) + ike_sa_t *ike_sa, host_t *requested) { dhcp_transaction_t *transaction, *old; enumerator_t *enumerator; + identification_t *id; char *pool; host_t *vip = NULL; @@ -77,6 +78,7 @@ METHOD(attribute_provider_t, acquire_address, host_t*, { return NULL; } + id = ike_sa->get_other_eap_id(ike_sa); enumerator = pools->create_enumerator(pools); while (enumerator->enumerate(enumerator, &pool)) { @@ -104,10 +106,11 @@ METHOD(attribute_provider_t, acquire_address, host_t*, METHOD(attribute_provider_t, release_address, bool, private_dhcp_provider_t *this, linked_list_t *pools, - host_t *address, identification_t *id) + host_t *address, ike_sa_t *ike_sa) { dhcp_transaction_t *transaction; enumerator_t *enumerator; + identification_t *id; bool found = FALSE; char *pool; @@ -115,6 +118,7 @@ METHOD(attribute_provider_t, release_address, bool, { return FALSE; } + id = ike_sa->get_other_eap_id(ike_sa); enumerator = pools->create_enumerator(pools); while (enumerator->enumerate(enumerator, &pool)) { @@ -139,11 +143,12 @@ METHOD(attribute_provider_t, release_address, bool, } METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, - private_dhcp_provider_t *this, linked_list_t *pools, identification_t *id, + private_dhcp_provider_t *this, linked_list_t *pools, ike_sa_t *ike_sa, linked_list_t *vips) { dhcp_transaction_t *transaction = NULL; enumerator_t *enumerator; + identification_t *id; host_t *vip; if (pools->find_first(pools, (linked_list_match_t)streq, @@ -152,6 +157,7 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, return NULL; } + id = ike_sa->get_other_eap_id(ike_sa); this->mutex->lock(this->mutex); enumerator = vips->create_enumerator(vips); while (enumerator->enumerate(enumerator, &vip)) diff --git a/src/libcharon/plugins/dnscert/Makefile.in b/src/libcharon/plugins/dnscert/Makefile.in index 3484e08a3..ed873b316 100644 --- a/src/libcharon/plugins/dnscert/Makefile.in +++ b/src/libcharon/plugins/dnscert/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/duplicheck/Makefile.in b/src/libcharon/plugins/duplicheck/Makefile.in index 381d7a119..41862cb2a 100644 --- a/src/libcharon/plugins/duplicheck/Makefile.in +++ b/src/libcharon/plugins/duplicheck/Makefile.in @@ -236,6 +236,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -296,10 +297,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -373,6 +376,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/eap_aka/Makefile.in b/src/libcharon/plugins/eap_aka/Makefile.in index 3b0f8763c..dacddfb87 100644 --- a/src/libcharon/plugins/eap_aka/Makefile.in +++ b/src/libcharon/plugins/eap_aka/Makefile.in @@ -230,6 +230,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -290,10 +291,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -367,6 +370,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in index 839a379ea..3c26b8511 100644 --- a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in +++ b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in @@ -231,6 +231,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/eap_dynamic/Makefile.in b/src/libcharon/plugins/eap_dynamic/Makefile.in index fdbad6234..402c7cadc 100644 --- a/src/libcharon/plugins/eap_dynamic/Makefile.in +++ b/src/libcharon/plugins/eap_dynamic/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/eap_gtc/Makefile.in b/src/libcharon/plugins/eap_gtc/Makefile.in index 9675104da..2279b2514 100644 --- a/src/libcharon/plugins/eap_gtc/Makefile.in +++ b/src/libcharon/plugins/eap_gtc/Makefile.in @@ -228,6 +228,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -288,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -365,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/eap_identity/Makefile.in b/src/libcharon/plugins/eap_identity/Makefile.in index 0610b5859..30d2c88d1 100644 --- a/src/libcharon/plugins/eap_identity/Makefile.in +++ b/src/libcharon/plugins/eap_identity/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/eap_md5/Makefile.in b/src/libcharon/plugins/eap_md5/Makefile.in index 38c9d0b7c..14616c214 100644 --- a/src/libcharon/plugins/eap_md5/Makefile.in +++ b/src/libcharon/plugins/eap_md5/Makefile.in @@ -228,6 +228,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -288,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -365,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/eap_mschapv2/Makefile.in b/src/libcharon/plugins/eap_mschapv2/Makefile.in index f5dfd6814..78dfd29e3 100644 --- a/src/libcharon/plugins/eap_mschapv2/Makefile.in +++ b/src/libcharon/plugins/eap_mschapv2/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/eap_peap/Makefile.in b/src/libcharon/plugins/eap_peap/Makefile.in index 5ccd58158..2f0d65d6d 100644 --- a/src/libcharon/plugins/eap_peap/Makefile.in +++ b/src/libcharon/plugins/eap_peap/Makefile.in @@ -230,6 +230,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -290,10 +291,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -367,6 +370,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/eap_radius/Makefile.in b/src/libcharon/plugins/eap_radius/Makefile.in index 04cc422f5..47534372b 100644 --- a/src/libcharon/plugins/eap_radius/Makefile.in +++ b/src/libcharon/plugins/eap_radius/Makefile.in @@ -231,6 +231,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/eap_radius/eap_radius_accounting.c b/src/libcharon/plugins/eap_radius/eap_radius_accounting.c index 31c96d229..ac4ecfc86 100644 --- a/src/libcharon/plugins/eap_radius/eap_radius_accounting.c +++ b/src/libcharon/plugins/eap_radius/eap_radius_accounting.c @@ -99,7 +99,7 @@ typedef struct { /** IKE_SA identifier this entry is stored under */ ike_sa_id_t *id; /** RADIUS accounting session ID */ - char sid[16]; + char sid[24]; /** number of sent/received octets/packets */ struct { u_int64_t sent; diff --git a/src/libcharon/plugins/eap_radius/eap_radius_plugin.c b/src/libcharon/plugins/eap_radius/eap_radius_plugin.c index 1a48c07e5..6a4a0384e 100644 --- a/src/libcharon/plugins/eap_radius/eap_radius_plugin.c +++ b/src/libcharon/plugins/eap_radius/eap_radius_plugin.c @@ -26,7 +26,7 @@ #include <radius_client.h> #include <radius_config.h> -#include <hydra.h> +#include <daemon.h> #include <threading/rwlock.h> #include <processing/jobs/callback_job.h> #include <processing/jobs/delete_ike_sa_job.h> @@ -149,19 +149,26 @@ static void load_configs(private_eap_radius_plugin_t *this) continue; } nas_identifier = lib->settings->get_str(lib->settings, - "%s.plugins.eap-radius.servers.%s.nas_identifier", "strongSwan", + "%s.plugins.eap-radius.servers.%s.nas_identifier", + lib->settings->get_str(lib->settings, + "%s.plugins.eap-radius.nas_identifier", "strongSwan", + lib->ns), lib->ns, section); auth_port = lib->settings->get_int(lib->settings, "%s.plugins.eap-radius.servers.%s.auth_port", lib->settings->get_int(lib->settings, "%s.plugins.eap-radius.servers.%s.port", - AUTH_PORT, lib->ns, section), + lib->settings->get_int(lib->settings, + "%s.plugins.eap-radius.port", AUTH_PORT, lib->ns), + lib->ns, section), lib->ns, section); acct_port = lib->settings->get_int(lib->settings, "%s.plugins.eap-radius.servers.%s.acct_port", ACCT_PORT, lib->ns, section); sockets = lib->settings->get_int(lib->settings, - "%s.plugins.eap-radius.servers.%s.sockets", 1, + "%s.plugins.eap-radius.servers.%s.sockets", + lib->settings->get_int(lib->settings, + "%s.plugins.eap-radius.sockets", 1, lib->ns), lib->ns, section); preference = lib->settings->get_int(lib->settings, "%s.plugins.eap-radius.servers.%s.preference", 0, @@ -211,13 +218,13 @@ static bool plugin_cb(private_eap_radius_plugin_t *this, { charon->bus->add_listener(charon->bus, &this->forward->listener); } - hydra->attributes->add_provider(hydra->attributes, - &this->provider->provider); + charon->attributes->add_provider(charon->attributes, + &this->provider->provider); } else { - hydra->attributes->remove_provider(hydra->attributes, - &this->provider->provider); + charon->attributes->remove_provider(charon->attributes, + &this->provider->provider); if (this->forward) { charon->bus->remove_listener(charon->bus, &this->forward->listener); diff --git a/src/libcharon/plugins/eap_radius/eap_radius_provider.c b/src/libcharon/plugins/eap_radius/eap_radius_provider.c index 7c794616b..0cf723711 100644 --- a/src/libcharon/plugins/eap_radius/eap_radius_provider.c +++ b/src/libcharon/plugins/eap_radius/eap_radius_provider.c @@ -311,19 +311,13 @@ METHOD(listener_t, ike_rekey, bool, METHOD(attribute_provider_t, acquire_address, host_t*, private_eap_radius_provider_t *this, linked_list_t *pools, - identification_t *id, host_t *requested) + ike_sa_t *ike_sa, host_t *requested) { enumerator_t *enumerator; host_t *addr = NULL; - ike_sa_t *ike_sa; uintptr_t sa; char *name; - ike_sa = charon->bus->get_sa(charon->bus); - if (!ike_sa) - { - return NULL; - } sa = ike_sa->get_unique_id(ike_sa); enumerator = pools->create_enumerator(pools); @@ -348,19 +342,13 @@ METHOD(attribute_provider_t, acquire_address, host_t*, METHOD(attribute_provider_t, release_address, bool, private_eap_radius_provider_t *this, linked_list_t *pools, host_t *address, - identification_t *id) + ike_sa_t *ike_sa) { enumerator_t *enumerator; host_t *found = NULL; - ike_sa_t *ike_sa; uintptr_t sa; char *name; - ike_sa = charon->bus->get_sa(charon->bus); - if (!ike_sa) - { - return FALSE; - } sa = ike_sa->get_unique_id(ike_sa); enumerator = pools->create_enumerator(pools); @@ -428,18 +416,12 @@ METHOD(enumerator_t, attribute_destroy, void, METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, private_eap_radius_provider_t *this, linked_list_t *pools, - identification_t *id, linked_list_t *vips) + ike_sa_t *ike_sa, linked_list_t *vips) { attribute_enumerator_t *enumerator; attr_t *attr; - ike_sa_t *ike_sa; uintptr_t sa; - ike_sa = charon->bus->get_sa(charon->bus); - if (!ike_sa) - { - return NULL; - } sa = ike_sa->get_unique_id(ike_sa); INIT(enumerator, diff --git a/src/libcharon/plugins/eap_sim/Makefile.in b/src/libcharon/plugins/eap_sim/Makefile.in index 6a00ea74d..251eeeeba 100644 --- a/src/libcharon/plugins/eap_sim/Makefile.in +++ b/src/libcharon/plugins/eap_sim/Makefile.in @@ -230,6 +230,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -290,10 +291,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -367,6 +370,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/eap_sim_file/Makefile.in b/src/libcharon/plugins/eap_sim_file/Makefile.in index 7a08f4e0e..bffcbc0df 100644 --- a/src/libcharon/plugins/eap_sim_file/Makefile.in +++ b/src/libcharon/plugins/eap_sim_file/Makefile.in @@ -231,6 +231,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/eap_sim_pcsc/Makefile.in b/src/libcharon/plugins/eap_sim_pcsc/Makefile.in index a1ec7adc1..78682ce37 100644 --- a/src/libcharon/plugins/eap_sim_pcsc/Makefile.in +++ b/src/libcharon/plugins/eap_sim_pcsc/Makefile.in @@ -232,6 +232,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -292,10 +293,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -369,6 +372,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in index bf99ab095..2a6be5fd9 100644 --- a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in +++ b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in @@ -232,6 +232,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -292,10 +293,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -369,6 +372,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in index ce4602365..de504d4cd 100644 --- a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in +++ b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in @@ -231,6 +231,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/eap_simaka_sql/Makefile.in b/src/libcharon/plugins/eap_simaka_sql/Makefile.in index 0c0b7fd52..de3508a07 100644 --- a/src/libcharon/plugins/eap_simaka_sql/Makefile.in +++ b/src/libcharon/plugins/eap_simaka_sql/Makefile.in @@ -230,6 +230,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -290,10 +291,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -367,6 +370,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/eap_tls/Makefile.in b/src/libcharon/plugins/eap_tls/Makefile.in index 25696f524..d4219b876 100644 --- a/src/libcharon/plugins/eap_tls/Makefile.in +++ b/src/libcharon/plugins/eap_tls/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/eap_tls/eap_tls.c b/src/libcharon/plugins/eap_tls/eap_tls.c index dffbaf266..bc01ba5df 100644 --- a/src/libcharon/plugins/eap_tls/eap_tls.c +++ b/src/libcharon/plugins/eap_tls/eap_tls.c @@ -109,6 +109,12 @@ METHOD(eap_method_t, is_mutual, bool, return TRUE; } +METHOD(eap_method_t, get_auth, auth_cfg_t*, + private_eap_tls_t *this) +{ + return this->tls_eap->get_auth(this->tls_eap); +} + METHOD(eap_method_t, destroy, void, private_eap_tls_t *this) { @@ -138,6 +144,7 @@ static eap_tls_t *eap_tls_create(identification_t *server, .get_msk = _get_msk, .get_identifier = _get_identifier, .set_identifier = _set_identifier, + .get_auth = _get_auth, .destroy = _destroy, }, }, diff --git a/src/libcharon/plugins/eap_tnc/Makefile.in b/src/libcharon/plugins/eap_tnc/Makefile.in index 2d5d65875..6c34ed098 100644 --- a/src/libcharon/plugins/eap_tnc/Makefile.in +++ b/src/libcharon/plugins/eap_tnc/Makefile.in @@ -230,6 +230,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -290,10 +291,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -367,6 +370,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/eap_tnc/eap_tnc.c b/src/libcharon/plugins/eap_tnc/eap_tnc.c index 62d23d064..f70f47ef6 100644 --- a/src/libcharon/plugins/eap_tnc/eap_tnc.c +++ b/src/libcharon/plugins/eap_tnc/eap_tnc.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2013 Andreas Steffen + * Copyright (C) 2010-2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -256,6 +256,8 @@ static eap_tnc_t *eap_tnc_create(identification_t *server, private_eap_tnc_t *this; int max_msg_count; char* protocol; + ike_sa_t *ike_sa; + host_t *server_ip, *peer_ip; tnccs_t *tnccs; tnccs_type_t tnccs_type; @@ -302,8 +304,29 @@ static eap_tnc_t *eap_tnc_create(identification_t *server, free(this); return NULL; } + + /* Determine IP addresses of server and peer */ + ike_sa = charon->bus->get_sa(charon->bus); + if (!ike_sa) + { + DBG1(DBG_TNC, "%N constructor did not find IKE_SA", + eap_type_names, type); + free(this); + return NULL; + } + if (is_server) + { + server_ip = ike_sa->get_my_host(ike_sa); + peer_ip = ike_sa->get_other_host(ike_sa); + } + else + { + peer_ip = ike_sa->get_my_host(ike_sa); + server_ip = ike_sa->get_other_host(ike_sa); + } + tnccs = tnc->tnccs->create_instance(tnc->tnccs, tnccs_type, - is_server, server, peer, + is_server, server, peer, server_ip, peer_ip, (type == EAP_TNC) ? TNC_IFT_EAP_1_1 : TNC_IFT_EAP_2_0, is_server ? enforce_recommendation : NULL); if (!tnccs) diff --git a/src/libcharon/plugins/eap_ttls/Makefile.in b/src/libcharon/plugins/eap_ttls/Makefile.in index 38c7632ac..0babf1766 100644 --- a/src/libcharon/plugins/eap_ttls/Makefile.in +++ b/src/libcharon/plugins/eap_ttls/Makefile.in @@ -231,6 +231,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/eap_ttls/eap_ttls.c b/src/libcharon/plugins/eap_ttls/eap_ttls.c index 703cd3f29..c99d47f8d 100644 --- a/src/libcharon/plugins/eap_ttls/eap_ttls.c +++ b/src/libcharon/plugins/eap_ttls/eap_ttls.c @@ -111,6 +111,12 @@ METHOD(eap_method_t, is_mutual, bool, return TRUE; } +METHOD(eap_method_t, get_auth, auth_cfg_t*, + private_eap_ttls_t *this) +{ + return this->tls_eap->get_auth(this->tls_eap); +} + METHOD(eap_method_t, destroy, void, private_eap_ttls_t *this) { @@ -141,6 +147,7 @@ static eap_ttls_t *eap_ttls_create(identification_t *server, .get_identifier = _get_identifier, .set_identifier = _set_identifier, .get_msk = _get_msk, + .get_auth = _get_auth, .destroy = _destroy, }, }, diff --git a/src/libcharon/plugins/error_notify/Makefile.in b/src/libcharon/plugins/error_notify/Makefile.in index d9fa454ca..0a07aa7a3 100644 --- a/src/libcharon/plugins/error_notify/Makefile.in +++ b/src/libcharon/plugins/error_notify/Makefile.in @@ -237,6 +237,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -297,10 +298,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -374,6 +377,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/ext_auth/Makefile.in b/src/libcharon/plugins/ext_auth/Makefile.in index a1b47dd33..d23e680aa 100644 --- a/src/libcharon/plugins/ext_auth/Makefile.in +++ b/src/libcharon/plugins/ext_auth/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/farp/Makefile.in b/src/libcharon/plugins/farp/Makefile.in index 2bfd38ba1..318400fc9 100644 --- a/src/libcharon/plugins/farp/Makefile.in +++ b/src/libcharon/plugins/farp/Makefile.in @@ -227,6 +227,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/forecast/Makefile.am b/src/libcharon/plugins/forecast/Makefile.am new file mode 100644 index 000000000..ce573135d --- /dev/null +++ b/src/libcharon/plugins/forecast/Makefile.am @@ -0,0 +1,21 @@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon + +AM_CFLAGS = \ + $(PLUGIN_CFLAGS) $(libiptc_CFLAGS) + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-forecast.la +else +plugin_LTLIBRARIES = libstrongswan-forecast.la +endif + +libstrongswan_forecast_la_SOURCES = \ + forecast_listener.h forecast_listener.c \ + forecast_forwarder.h forecast_forwarder.c \ + forecast_plugin.h forecast_plugin.c + +libstrongswan_forecast_la_LDFLAGS = -module -avoid-version +libstrongswan_forecast_la_LIBADD = $(libiptc_LIBS) diff --git a/src/libcharon/plugins/forecast/Makefile.in b/src/libcharon/plugins/forecast/Makefile.in new file mode 100644 index 000000000..7b190ca25 --- /dev/null +++ b/src/libcharon/plugins/forecast/Makefile.in @@ -0,0 +1,784 @@ +# Makefile.in generated by automake 1.14.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/libcharon/plugins/forecast +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ + $(top_srcdir)/m4/config/ltoptions.m4 \ + $(top_srcdir)/m4/config/ltsugar.m4 \ + $(top_srcdir)/m4/config/ltversion.m4 \ + $(top_srcdir)/m4/config/lt~obsolete.m4 \ + $(top_srcdir)/m4/macros/split-package-version.m4 \ + $(top_srcdir)/m4/macros/with.m4 \ + $(top_srcdir)/m4/macros/enable-disable.m4 \ + $(top_srcdir)/m4/macros/add-plugin.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(plugindir)" +LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) +am__DEPENDENCIES_1 = +libstrongswan_forecast_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_libstrongswan_forecast_la_OBJECTS = forecast_listener.lo \ + forecast_forwarder.lo forecast_plugin.lo +libstrongswan_forecast_la_OBJECTS = \ + $(am_libstrongswan_forecast_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libstrongswan_forecast_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_forecast_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_forecast_la_rpath = -rpath \ +@MONOLITHIC_FALSE@ $(plugindir) +@MONOLITHIC_TRUE@am_libstrongswan_forecast_la_rpath = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libstrongswan_forecast_la_SOURCES) +DIST_SOURCES = $(libstrongswan_forecast_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BFDLIB = @BFDLIB@ +BTLIB = @BTLIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +COVERAGE_CFLAGS = @COVERAGE_CFLAGS@ +COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLIB = @DLLIB@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GEM = @GEM@ +GENHTML = @GENHTML@ +GPERF = @GPERF@ +GPRBUILD = @GPRBUILD@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQLCFLAG = @MYSQLCFLAG@ +MYSQLCONFIG = @MYSQLCONFIG@ +MYSQLLIB = @MYSQLLIB@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_LIB = @OPENSSL_LIB@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@ +PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@ +PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@ +PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ +PTHREADLIB = @PTHREADLIB@ +PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ +RANLIB = @RANLIB@ +RTLIB = @RTLIB@ +RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ +RUBYINCLUDE = @RUBYINCLUDE@ +RUBYLIB = @RUBYLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ +STRIP = @STRIP@ +UNWINDLIB = @UNWINDLIB@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +aikgen_plugins = @aikgen_plugins@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ +clearsilver_LIBS = @clearsilver_LIBS@ +cmd_plugins = @cmd_plugins@ +datadir = @datadir@ +datarootdir = @datarootdir@ +dbusservicedir = @dbusservicedir@ +dev_headers = @dev_headers@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +fips_mode = @fips_mode@ +gtk_CFLAGS = @gtk_CFLAGS@ +gtk_LIBS = @gtk_LIBS@ +h_plugins = @h_plugins@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +imcvdir = @imcvdir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ +ipsecdir = @ipsecdir@ +ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ +ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ +linux_headers = @linux_headers@ +localedir = @localedir@ +localstatedir = @localstatedir@ +maemo_CFLAGS = @maemo_CFLAGS@ +maemo_LIBS = @maemo_LIBS@ +manager_plugins = @manager_plugins@ +mandir = @mandir@ +medsrv_plugins = @medsrv_plugins@ +mkdir_p = @mkdir_p@ +nm_CFLAGS = @nm_CFLAGS@ +nm_LIBS = @nm_LIBS@ +nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ +oldincludedir = @oldincludedir@ +pcsclite_CFLAGS = @pcsclite_CFLAGS@ +pcsclite_LIBS = @pcsclite_LIBS@ +pdfdir = @pdfdir@ +piddir = @piddir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +pki_plugins = @pki_plugins@ +plugindir = @plugindir@ +pool_plugins = @pool_plugins@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +random_device = @random_device@ +resolv_conf = @resolv_conf@ +routing_table = @routing_table@ +routing_table_prio = @routing_table_prio@ +s_plugins = @s_plugins@ +sbindir = @sbindir@ +scepclient_plugins = @scepclient_plugins@ +scripts_plugins = @scripts_plugins@ +sharedstatedir = @sharedstatedir@ +soup_CFLAGS = @soup_CFLAGS@ +soup_LIBS = @soup_LIBS@ +srcdir = @srcdir@ +starter_plugins = @starter_plugins@ +strongswan_conf = @strongswan_conf@ +strongswan_options = @strongswan_options@ +swanctldir = @swanctldir@ +sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ +systemdsystemunitdir = @systemdsystemunitdir@ +t_plugins = @t_plugins@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +urandom_device = @urandom_device@ +xml_CFLAGS = @xml_CFLAGS@ +xml_LIBS = @xml_LIBS@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon + +AM_CFLAGS = \ + $(PLUGIN_CFLAGS) $(libiptc_CFLAGS) + +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-forecast.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-forecast.la +libstrongswan_forecast_la_SOURCES = \ + forecast_listener.h forecast_listener.c \ + forecast_forwarder.h forecast_forwarder.c \ + forecast_plugin.h forecast_plugin.c + +libstrongswan_forecast_la_LDFLAGS = -module -avoid-version +libstrongswan_forecast_la_LIBADD = $(libiptc_LIBS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/forecast/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libcharon/plugins/forecast/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ + } + +uninstall-pluginLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ + done + +clean-pluginLTLIBRARIES: + -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) + @list='$(plugin_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libstrongswan-forecast.la: $(libstrongswan_forecast_la_OBJECTS) $(libstrongswan_forecast_la_DEPENDENCIES) $(EXTRA_libstrongswan_forecast_la_DEPENDENCIES) + $(AM_V_CCLD)$(libstrongswan_forecast_la_LINK) $(am_libstrongswan_forecast_la_rpath) $(libstrongswan_forecast_la_OBJECTS) $(libstrongswan_forecast_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/forecast_forwarder.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/forecast_listener.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/forecast_plugin.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + clean-pluginLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-pluginLTLIBRARIES + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pluginLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pluginLTLIBRARIES + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libcharon/plugins/forecast/forecast_forwarder.c b/src/libcharon/plugins/forecast/forecast_forwarder.c new file mode 100644 index 000000000..07a3d4953 --- /dev/null +++ b/src/libcharon/plugins/forecast/forecast_forwarder.c @@ -0,0 +1,496 @@ +/* + * Copyright (C) 2010-2014 Martin Willi + * Copyright (C) 2010-2014 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "forecast_forwarder.h" + +#include <errno.h> +#include <unistd.h> +#include <netinet/ip.h> +#include <netinet/udp.h> +#include <linux/socket.h> +#include <netinet/if_ether.h> +#include <linux/if_packet.h> +#include <linux/filter.h> +#include <sys/ioctl.h> +#include <ifaddrs.h> +#include <net/if.h> + +#include <hydra.h> +#include <daemon.h> +#include <threading/thread.h> +#include <processing/jobs/callback_job.h> + +#define BOOTP_SERVER_PORT 67 +#define BOOTP_CLIENT_PORT 68 + +typedef struct private_forecast_forwarder_t private_forecast_forwarder_t; +typedef struct private_kernel_listener_t private_kernel_listener_t; + +/** + * Private data of registered kernel listener + */ +struct private_kernel_listener_t { + + /** + * Implements kernel_listener_t + */ + kernel_listener_t listener; + + /** + * Listener that knows active addresses + */ + forecast_listener_t *fc; + + /** + * current broadcast address of internal network + */ + u_int32_t broadcast; + + /** + * LAN interface index + */ + int ifindex; + + /** + * Packet socket + */ + int pkt; + + /** + * RAW socket + */ + int raw; +}; + +/** + * Private data of an forecast_forwarder_t object. + */ +struct private_forecast_forwarder_t { + + /** + * Public forecast_forwarder_t interface. + */ + forecast_forwarder_t public; + + /** + * Public kernel_listener_t interface. + */ + private_kernel_listener_t kernel; +}; + +/** + * Send a broadcast/multicast packet to a network + */ +static void send_net(private_forecast_forwarder_t *this, + struct sockaddr_ll *addr, void *buf, size_t len) +{ + if (sendto(this->kernel.pkt, buf, len, 0, + (struct sockaddr*)addr, sizeof(*addr)) != len) + { + DBG1(DBG_NET, "forecast send_net() failed: %s", strerror(errno)); + } +} + +/** + * Send a broadcast/multicast packet to a peer + */ +static void send_peer(private_forecast_forwarder_t *this, u_int32_t dst, + void *buf, size_t len, int mark) +{ + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_addr.s_addr = dst, + }; + + if (setsockopt(this->kernel.raw, SOL_SOCKET, SO_MARK, + &mark, sizeof(mark)) != 0) + { + DBG1(DBG_NET, "forecast setting SO_MARK failed: %s", strerror(errno)); + } + if (sendto(this->kernel.raw, buf, len, 0, + (struct sockaddr*)&addr, sizeof(addr)) != len) + { + DBG1(DBG_NET, "forecast send_peer() failed: %s", strerror(errno)); + } +} + +/** + * Check if an IP packet is BOOTP/DHCP + */ +static bool is_bootp(void *buf, size_t len) +{ + struct __attribute__((__packed__)) { + struct iphdr ip; + struct udphdr udp; + } *pkt = buf; + + if (len > sizeof(*pkt)) + { + if (ntohs(pkt->udp.source) == BOOTP_CLIENT_PORT && + ntohs(pkt->udp.dest) == BOOTP_SERVER_PORT) + { + return TRUE; + } + if (ntohs(pkt->udp.source) == BOOTP_SERVER_PORT && + ntohs(pkt->udp.dest) == BOOTP_CLIENT_PORT) + { + return TRUE; + } + } + return FALSE; +} + +/** + * Broadcast/Multicast receiver + */ +static bool receive_casts(private_forecast_forwarder_t *this) +{ + struct __attribute__((packed)) { + struct iphdr hdr; + char data[2048]; + } buf; + char *type; + ssize_t len; + u_int mark, origin = 0; + host_t *src, *dst; + traffic_selector_t *ts; + enumerator_t *enumerator; + struct sockaddr_ll addr; + socklen_t alen = sizeof(addr); + bool reinject; + + len = recvfrom(this->kernel.pkt, &buf, sizeof(buf), MSG_DONTWAIT, + (struct sockaddr*)&addr, &alen); + if (len < 0) + { + if (errno != EAGAIN && errno != EWOULDBLOCK) + { + DBG1(DBG_NET, "receiving from forecast socket failed: %s", + strerror(errno)); + } + return TRUE; + } + else if (len < sizeof(struct iphdr)) + { + DBG1(DBG_NET, "received short forecast packet: %zd bytes", len); + return TRUE; + } + if (is_bootp(&buf, len)) + { /* don't forward DHCP broadcasts */ + return TRUE; + } + + src = host_create_from_chunk(AF_INET, chunk_from_thing(buf.hdr.saddr), 0); + dst = host_create_from_chunk(AF_INET, chunk_from_thing(buf.hdr.daddr), 0); + + /* create valid broadcast/multicast MAC to send out */ + if (IN_MULTICAST(ntohl(buf.hdr.daddr))) + { + type = "multi"; + ETHER_MAP_IP_MULTICAST(&buf.hdr.daddr, addr.sll_addr); + } + else + { + type = "broad"; + memset(&addr.sll_addr, 0xFF, sizeof(addr.sll_addr)); + } + DBG2(DBG_NET, "forecast intercepted packet: %H to %H", src, dst); + + /* find mark of originating tunnel */ + enumerator = this->kernel.fc->create_enumerator(this->kernel.fc, FALSE); + while (enumerator->enumerate(enumerator, &ts, &mark, &reinject)) + { + if (ts->includes(ts, src)) + { + origin = mark; + break; + } + } + enumerator->destroy(enumerator); + + /* send packet over all tunnels, but not the packets origin */ + enumerator = this->kernel.fc->create_enumerator(this->kernel.fc, FALSE); + while (enumerator->enumerate(enumerator, &ts, &mark, &reinject)) + { + if (ts->includes(ts, dst)) + { + if ((reinject && origin != mark) || origin == 0) + { + DBG2(DBG_NET, "forwarding a %H %scast from %H to peer %R (%u)", + dst, type, src, ts, mark); + send_peer(this, buf.hdr.daddr, &buf, len, mark); + } + } + } + enumerator->destroy(enumerator); + + if (origin) + { + /* forward broadcast/multicast from client to network */ + DBG2(DBG_NET, "forwarding a %H %scast from peer %H to internal network", + dst, type, src); + addr.sll_ifindex = this->kernel.ifindex; + send_net(this, &addr, &buf, len); + } + + dst->destroy(dst); + src->destroy(src); + + return TRUE; +} + +/** + * Join a multicast group + */ +static void join_group(private_kernel_listener_t *this, char *group, + struct sockaddr *addr) +{ + struct sockaddr_in *in; + struct ip_mreqn mreq; + host_t *host; + + host = host_create_from_string(group, 0); + if (host) + { + memset(&mreq, 0, sizeof(mreq)); + memcpy(&mreq.imr_multiaddr.s_addr, host->get_address(host).ptr, 4); + if (addr->sa_family == AF_INET) + { + in = (struct sockaddr_in*)addr; + memcpy(&mreq.imr_address, &in->sin_addr.s_addr, + sizeof(in->sin_addr.s_addr)); + } + mreq.imr_ifindex = this->ifindex; + if (setsockopt(this->raw, IPPROTO_IP, IP_ADD_MEMBERSHIP, + &mreq, sizeof(mreq)) == -1) + { + if (errno != EADDRINUSE) + { + DBG1(DBG_NET, "forecast multicast join to %s failed: %s", + group, strerror(errno)); + } + } + else + { + DBG2(DBG_NET, "forwarding multicast group %s", group); + } + host->destroy(host); + } +} + +/** + * (Re-)Join all multicast groups we want to forward + */ +static void join_groups(private_kernel_listener_t *this, struct sockaddr *addr) +{ + enumerator_t *enumerator; + char *groups, *group; + static char *def = + "224.0.0.1," /* host multicast */ + "224.0.0.22," /* IGMP */ + "224.0.0.251," /* mDNS */ + "224.0.0.252," /* LLMNR */ + "239.255.255.250"; /* SSDP/WS-discovery */ + + groups = lib->settings->get_str(lib->settings, + "%s.plugins.forecast.groups", def, lib->ns); + DBG1(DBG_CFG, "joining forecast multicast groups: %s", groups); + enumerator = enumerator_create_token(groups, ",", " "); + while (enumerator->enumerate(enumerator, &group)) + { + join_group(this, group, addr); + } + enumerator->destroy(enumerator); +} + +/** + * Attach the socket filter to the socket + */ +static bool attach_filter(int fd, u_int32_t broadcast) +{ + struct sock_filter filter_code[] = { + /* destination address: is ... */ + BPF_STMT(BPF_LD+BPF_W+BPF_ABS, offsetof(struct iphdr, daddr)), + /* broadcast, as received from the local network */ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ntohl(broadcast), 4, 0), + /* broadcast, as Win7 sends them */ + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0xFFFFFFFF, 3, 0), + /* any multicast, 224.0.0.0/4 */ + BPF_STMT(BPF_ALU+BPF_AND+BPF_K, 0xF0000000), + BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0xE0000000, 1, 0), + BPF_STMT(BPF_RET+BPF_K, 0), + BPF_STMT(BPF_LD+BPF_W+BPF_LEN, 0), + BPF_STMT(BPF_RET+BPF_A, 0), + }; + struct sock_fprog filter = { + sizeof(filter_code) / sizeof(struct sock_filter), + filter_code, + }; + + if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, + &filter, sizeof(filter)) < 0) + { + DBG1(DBG_NET, "installing forecast PACKET socket filter failed: %s", + strerror(errno)); + return FALSE; + } + return TRUE; +} + +/** + * Get the interface index of an interface name + */ +static int get_ifindex(private_kernel_listener_t *this, char *ifname) +{ + struct ifreq ifr = {}; + + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + if (ioctl(this->raw, SIOCGIFINDEX, &ifr) == 0) + { + return ifr.ifr_ifindex; + } + return 0; +} + +/** + * Set up the interface for broad/multicast forwarding + */ +static void setup_interface(private_kernel_listener_t *this) +{ + struct ifaddrs *addrs, *current; + struct sockaddr_in *in; + host_t *host; + char *name; + + name = lib->settings->get_str(lib->settings, + "%s.plugins.forecast.interface", NULL, lib->ns); + if (getifaddrs(&addrs) == 0) + { + for (current = addrs; current; current = current->ifa_next) + { + if (name && !streq(name, current->ifa_name)) + { + continue; + } + if (current->ifa_flags & IFF_BROADCAST && + current->ifa_broadaddr && + current->ifa_broadaddr->sa_family == AF_INET) + { + DBG1(DBG_NET, "using forecast interface %s", current->ifa_name); + this->ifindex = get_ifindex(this, current->ifa_name); + in = (struct sockaddr_in*)current->ifa_broadaddr; + attach_filter(this->pkt, in->sin_addr.s_addr); + join_groups(this, current->ifa_addr); + host = host_create_from_sockaddr(current->ifa_broadaddr); + if (host) + { + this->fc->set_broadcast(this->fc, host); + host->destroy(host); + } + break; + } + } + } + freeifaddrs(addrs); +} + +METHOD(kernel_listener_t, roam, bool, + private_kernel_listener_t *this, bool address) +{ + if (address) + { + setup_interface(this); + } + return TRUE; +} + +METHOD(forecast_forwarder_t, destroy, void, + private_forecast_forwarder_t *this) +{ + if (this->kernel.raw != -1) + { + close(this->kernel.raw); + } + if (this->kernel.pkt != -1) + { + lib->watcher->remove(lib->watcher, this->kernel.pkt); + close(this->kernel.pkt); + } + hydra->kernel_interface->remove_listener(hydra->kernel_interface, + &this->kernel.listener); + free(this); +} + +/** + * See header + */ +forecast_forwarder_t *forecast_forwarder_create(forecast_listener_t *listener) +{ + private_forecast_forwarder_t *this; + int on = 1; + + INIT(this, + .public = { + .destroy = _destroy, + }, + .kernel = { + .listener = { + .roam = _roam, + }, + .raw = -1, + .pkt = -1, + .fc = listener, + }, + ); + + this->kernel.pkt = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); + if (this->kernel.pkt == -1) + { + DBG1(DBG_NET, "opening PACKET socket failed: %s", strerror(errno)); + destroy(this); + return NULL; + } + this->kernel.raw = socket(AF_INET, SOCK_RAW, IPPROTO_UDP); + if (this->kernel.raw == -1) + { + DBG1(DBG_NET, "opening RAW socket failed: %s", strerror(errno)); + destroy(this); + return NULL; + } + if (setsockopt(this->kernel.raw, IPPROTO_IP, IP_HDRINCL, + &on, sizeof(on)) == -1) + { + DBG1(DBG_NET, "forecast socket HDRINCL failed: %s", strerror(errno)); + destroy(this); + return NULL; + } + if (setsockopt(this->kernel.raw, SOL_SOCKET, SO_BROADCAST, + &on, sizeof(on)) == -1) + { + DBG1(DBG_NET, "forecast socket BROADCAST failed: %s", strerror(errno)); + destroy(this); + return NULL; + } + + setup_interface(&this->kernel); + + hydra->kernel_interface->add_listener(hydra->kernel_interface, + &this->kernel.listener); + + lib->watcher->add(lib->watcher, this->kernel.pkt, WATCHER_READ, + (watcher_cb_t)receive_casts, this); + + return &this->public; +} diff --git a/src/libcharon/plugins/forecast/forecast_forwarder.h b/src/libcharon/plugins/forecast/forecast_forwarder.h new file mode 100644 index 000000000..14d107361 --- /dev/null +++ b/src/libcharon/plugins/forecast/forecast_forwarder.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2010-2014 Martin Willi + * Copyright (C) 2010-2014 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup forecast_forwarder forecast_forwarder + * @{ @ingroup forecast + */ + +#ifndef FORECAST_FORWARDER_H_ +#define FORECAST_FORWARDER_H_ + +#include "forecast_listener.h" + +typedef struct forecast_forwarder_t forecast_forwarder_t; + +/** + * Broadcast/Multicast sniffer and forwarder. + */ +struct forecast_forwarder_t { + + /** + * Destroy a forecast_forwarder_t. + */ + void (*destroy)(forecast_forwarder_t *this); +}; + +/** + * Create a forecast_forwarder instance. + * + * @param listener listener to check for addresses to forward to + * @return forwarder instance + */ +forecast_forwarder_t *forecast_forwarder_create(forecast_listener_t *listener); + +#endif /** FORECAST_FORWARDER_H_ @}*/ diff --git a/src/libcharon/plugins/forecast/forecast_listener.c b/src/libcharon/plugins/forecast/forecast_listener.c new file mode 100644 index 000000000..63a8cb15b --- /dev/null +++ b/src/libcharon/plugins/forecast/forecast_listener.c @@ -0,0 +1,680 @@ +/* + * Copyright (C) 2010-2014 Martin Willi + * Copyright (C) 2010-2014 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "forecast_listener.h" + +#include <errno.h> +#include <libiptc/libiptc.h> +#include <linux/netfilter/xt_MARK.h> +#include <linux/netfilter/xt_esp.h> + +#include <daemon.h> +#include <collections/array.h> +#include <collections/hashtable.h> +#include <threading/rwlock.h> + +typedef struct private_forecast_listener_t private_forecast_listener_t; + +/** + * Private data of an forecast_listener_t object. + */ +struct private_forecast_listener_t { + + /** + * Public forecast_listener_t interface. + */ + forecast_listener_t public; + + /** + * List of entries + */ + linked_list_t *entries; + + /** + * RWlock for IP list + */ + rwlock_t *lock; + + /** + * Configs we do reinjection + */ + char *reinject_configs; + + /** + * Broadcast address on LAN interface, network order + */ + u_int32_t broadcast; +}; + +/** + * Hashtable entry + */ +typedef struct { + /** local traffic selectors */ + array_t *lts; + /** remote traffic selectors */ + array_t *rts; + /** firewall mark used by CHILD_SA */ + u_int mark; + /** local IKE_SA endpoint */ + host_t *lhost; + /** remote IKE_SA endpoint */ + host_t *rhost; + /** inbound SPI */ + u_int32_t spi; + /** use UDP encapsulation */ + bool encap; + /** whether we should allow reencapsulation of IPsec received forecasts */ + bool reinject; + /** broadcast address used for that entry */ + u_int32_t broadcast; +} entry_t; + +/** + * Destroy an entry + */ +static void entry_destroy(entry_t *entry) +{ + if (entry) + { + entry->lhost->destroy(entry->lhost); + entry->rhost->destroy(entry->rhost); + array_destroy_offset(entry->lts, offsetof(traffic_selector_t, destroy)); + array_destroy_offset(entry->rts, offsetof(traffic_selector_t, destroy)); + free(entry); + } +} + +/** + * Convert an (IPv4) traffic selector to an address and mask + */ +static bool ts2in(traffic_selector_t *ts, + struct in_addr *addr, struct in_addr *mask) +{ + u_int8_t bits; + host_t *net; + + if (ts->get_type(ts) == TS_IPV4_ADDR_RANGE && + ts->to_subnet(ts, &net, &bits)) + { + memcpy(&addr->s_addr, net->get_address(net).ptr, 4); + net->destroy(net); + mask->s_addr = htonl(0xffffffffU << (32 - bits)); + return TRUE; + } + return FALSE; +} + +/** + * Convert an (IPv4) host to an address with mask + */ +static bool host2in(host_t *host, struct in_addr *addr, struct in_addr *mask) +{ + if (host->get_family(host) == AF_INET) + { + memcpy(&addr->s_addr, host->get_address(host).ptr, 4); + mask->s_addr = ~0; + return TRUE; + } + return FALSE; +} + +/** + * Add or remove a rule to/from the specified chain + */ +static bool manage_rule(struct iptc_handle *ipth, const char *chain, + bool add, struct ipt_entry *e) +{ + if (add) + { + if (!iptc_insert_entry(chain, e, 0, ipth)) + { + DBG1(DBG_CFG, "appending %s rule failed: %s", + chain, iptc_strerror(errno)); + return FALSE; + } + } + else + { + if (!iptc_delete_entry(chain, e, "", ipth)) + { + DBG1(DBG_CFG, "deleting %s rule failed: %s", + chain, iptc_strerror(errno)); + return FALSE; + } + } + return TRUE; +} + +/** + * Add rule marking UDP-encapsulated ESP packets to match the correct policy + */ +static bool manage_pre_esp_in_udp(struct iptc_handle *ipth, + entry_t *entry, bool add) +{ + struct { + struct ipt_entry e; + struct ipt_entry_match m; + struct xt_udp udp; + struct ipt_entry_target t; + struct xt_mark_tginfo2 tm; + } ipt = { + .e = { + .target_offset = XT_ALIGN(sizeof(ipt.e) + sizeof(ipt.m) + + sizeof(ipt.udp)), + .next_offset = sizeof(ipt), + .ip = { + .proto = IPPROTO_UDP, + }, + }, + .m = { + .u = { + .user = { + .match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.udp)), + .name = "udp", + }, + }, + }, + .udp = { + .spts = { + entry->rhost->get_port(entry->rhost), + entry->rhost->get_port(entry->lhost) + }, + .dpts = { + entry->lhost->get_port(entry->lhost), + entry->lhost->get_port(entry->lhost) + }, + }, + .t = { + .u = { + .user = { + .target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.tm)), + .name = "MARK", + .revision = 2, + }, + }, + }, + .tm = { + .mark = entry->mark, + .mask = ~0, + }, + }; + + if (!host2in(entry->lhost, &ipt.e.ip.dst, &ipt.e.ip.dmsk) || + !host2in(entry->rhost, &ipt.e.ip.src, &ipt.e.ip.smsk)) + { + return FALSE; + } + return manage_rule(ipth, "PREROUTING", add, &ipt.e); +} + +/** + * Add rule marking non-encapsulated ESP packets to match the correct policy + */ +static bool manage_pre_esp(struct iptc_handle *ipth, entry_t *entry, bool add) +{ + struct { + struct ipt_entry e; + struct ipt_entry_match m; + struct xt_esp esp; + struct ipt_entry_target t; + struct xt_mark_tginfo2 tm; + } ipt = { + .e = { + .target_offset = XT_ALIGN(sizeof(ipt.e) + sizeof(ipt.m) + + sizeof(ipt.esp)), + .next_offset = sizeof(ipt), + .ip = { + .proto = IPPROTO_ESP, + }, + }, + .m = { + .u = { + .user = { + .match_size = XT_ALIGN(sizeof(ipt.m) + sizeof(ipt.esp)), + .name = "esp", + }, + }, + }, + .esp = { + .spis = { htonl(entry->spi), htonl(entry->spi) }, + }, + .t = { + .u = { + .user = { + .target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.tm)), + .name = "MARK", + .revision = 2, + }, + }, + }, + .tm = { + .mark = entry->mark, + .mask = ~0, + }, + }; + + if (!host2in(entry->lhost, &ipt.e.ip.dst, &ipt.e.ip.dmsk) || + !host2in(entry->rhost, &ipt.e.ip.src, &ipt.e.ip.smsk)) + { + return FALSE; + } + return manage_rule(ipth, "PREROUTING", add, &ipt.e); +} + +/** + * Add rule marking ESP packets to match the correct policy + */ +static bool manage_pre(struct iptc_handle *ipth, entry_t *entry, bool add) +{ + if (entry->encap) + { + return manage_pre_esp_in_udp(ipth, entry, add); + } + return manage_pre_esp(ipth, entry, add); +} + +/** + * Add rule handling outbound traffic to use correct mark + */ +static bool manage_out(struct iptc_handle *ipth, entry_t *entry, bool add) +{ + struct { + struct ipt_entry e; + struct ipt_entry_target t; + struct xt_mark_tginfo2 m; + } ipt = { + .e = { + .target_offset = XT_ALIGN(sizeof(ipt.e)), + .next_offset = sizeof(ipt), + }, + .t = { + .u.user.target_size = XT_ALIGN(sizeof(ipt.t) + sizeof(ipt.m)), + .u.user.name = "MARK", + .u.user.revision = 2, + }, + .m = { + .mark = entry->mark, + .mask = ~0, + }, + }; + enumerator_t *enumerator; + traffic_selector_t *ts; + + enumerator = array_create_enumerator(entry->rts); + while (enumerator->enumerate(enumerator, &ts)) + { + if (!ts2in(ts, &ipt.e.ip.dst, &ipt.e.ip.dmsk)) + { + continue; + } + if (ipt.e.ip.dst.s_addr == 0xffffffff || + ipt.e.ip.dst.s_addr == entry->broadcast || + memeq(&ipt.e.ip.dst.s_addr, "\xe0", 1)) + { + /* skip broadcast/multicast selectors, they are shared and the mark + * is set by the socket we use for reinjection */ + continue; + } + if (!manage_rule(ipth, "PREROUTING", add, &ipt.e) || + !manage_rule(ipth, "OUTPUT", add, &ipt.e)) + { + enumerator->destroy(enumerator); + return FALSE; + } + } + enumerator->destroy(enumerator); + + return TRUE; +} + +/** + * Check if config is whitelisted to reinject traffic + */ +static bool is_reinject_config(private_forecast_listener_t *this, char *name) +{ + enumerator_t *enumerator; + bool reinject = FALSE; + char *token; + + enumerator = enumerator_create_token(this->reinject_configs, ",", " "); + while (enumerator->enumerate(enumerator, &token)) + { + if (streq(token, name)) + { + reinject = TRUE; + break; + } + } + enumerator->destroy(enumerator); + + return reinject; +} + +/** + * Add rules and entry for given CHILD_SA + */ +static bool add_entry(private_forecast_listener_t *this, + struct iptc_handle *ipth, host_t *lhost, host_t *rhost, + child_sa_t *child_sa, bool encap) +{ + enumerator_t *enumerator; + traffic_selector_t *ts; + entry_t *entry; + + INIT(entry, + .lts = array_create(0, 0), + .rts = array_create(0, 0), + .lhost = lhost->clone(lhost), + .rhost = rhost->clone(rhost), + .spi = child_sa->get_spi(child_sa, TRUE), + .encap = encap, + .mark = child_sa->get_mark(child_sa, TRUE).value, + .reinject = is_reinject_config(this, child_sa->get_name(child_sa)), + .broadcast = this->broadcast, + ); + + enumerator = child_sa->create_ts_enumerator(child_sa, TRUE); + while (enumerator->enumerate(enumerator, &ts)) + { + array_insert(entry->lts, ARRAY_TAIL, ts->clone(ts)); + } + enumerator->destroy(enumerator); + + enumerator = child_sa->create_ts_enumerator(child_sa, FALSE); + while (enumerator->enumerate(enumerator, &ts)) + { + array_insert(entry->rts, ARRAY_TAIL, ts->clone(ts)); + } + enumerator->destroy(enumerator); + + if (manage_pre(ipth, entry, TRUE) && + manage_out(ipth, entry, TRUE)) + { + this->lock->write_lock(this->lock); + this->entries->insert_last(this->entries, entry); + this->lock->unlock(this->lock); + return TRUE; + } + entry_destroy(entry); + return FALSE; +} + +/** + * Remove an entry and rules for a given mark + */ +static bool remove_entry(private_forecast_listener_t *this, + struct iptc_handle *ipth, child_sa_t *child_sa) +{ + enumerator_t *enumerator; + entry_t *entry; + bool done = FALSE; + + this->lock->write_lock(this->lock); + enumerator = this->entries->create_enumerator(this->entries); + while (enumerator->enumerate(enumerator, &entry)) + { + if (entry->mark == child_sa->get_mark(child_sa, TRUE).value) + { + this->entries->remove_at(this->entries, enumerator); + if (manage_pre(ipth, entry, FALSE) && + manage_out(ipth, entry, FALSE)) + { + done = TRUE; + } + entry_destroy(entry); + break; + } + } + enumerator->destroy(enumerator); + this->lock->unlock(this->lock); + + return done; +} + +/** + * Initialize iptables handle, log error + */ +static struct iptc_handle* init_handle() +{ + struct iptc_handle *ipth; + + ipth = iptc_init("mangle"); + if (ipth) + { + return ipth; + } + DBG1(DBG_CFG, "initializing iptables failed: %s", iptc_strerror(errno)); + return NULL; +} + +/** + * Commit iptables rules, log error + */ +static bool commit_handle(struct iptc_handle *ipth) +{ + if (iptc_commit(ipth)) + { + return TRUE; + } + DBG1(DBG_CFG, "forecast iptables commit failed: %s", iptc_strerror(errno)); + return FALSE; +} + +/** + * Check if we should handle the given CHILD_SA + */ +static bool handle_sa(child_sa_t *child_sa) +{ + return child_sa->get_mark(child_sa, TRUE).value && + child_sa->get_mark(child_sa, FALSE).value; +} + +METHOD(listener_t, child_updown, bool, + private_forecast_listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, + bool up) +{ + struct iptc_handle *ipth; + host_t *lhost, *rhost; + bool encap; + + lhost = ike_sa->get_my_host(ike_sa); + rhost = ike_sa->get_other_host(ike_sa); + encap = child_sa->has_encap(child_sa); + + if (handle_sa(child_sa)) + { + ipth = init_handle(); + if (ipth) + { + if (up) + { + if (add_entry(this, ipth, lhost, rhost, child_sa, encap)) + { + commit_handle(ipth); + } + } + else + { + if (remove_entry(this, ipth, child_sa)) + { + commit_handle(ipth); + } + } + iptc_free(ipth); + } + } + return TRUE; +} + +METHOD(listener_t, child_rekey, bool, + private_forecast_listener_t *this, ike_sa_t *ike_sa, + child_sa_t *old, child_sa_t *new) +{ + struct iptc_handle *ipth;; + host_t *lhost, *rhost; + + lhost = ike_sa->get_my_host(ike_sa); + rhost = ike_sa->get_other_host(ike_sa); + + if (handle_sa(old)) + { + ipth = init_handle(); + if (ipth) + { + if (remove_entry(this, ipth, old) && + add_entry(this, ipth, lhost, rhost, new, new->has_encap(new))) + { + commit_handle(ipth); + } + iptc_free(ipth); + } + } + return TRUE; +} + +METHOD(listener_t, ike_update, bool, + private_forecast_listener_t *this, ike_sa_t *ike_sa, + bool local, host_t *new) +{ + struct iptc_handle *ipth; + enumerator_t *enumerator; + child_sa_t *child_sa; + host_t *lhost, *rhost; + bool encap; + + if (local) + { + lhost = new; + rhost = ike_sa->get_other_host(ike_sa); + } + else + { + lhost = ike_sa->get_my_host(ike_sa); + rhost = new; + } + /* during ike_update(), has_encap() on the CHILD_SA has not yet been + * updated, but shows the old state. */ + encap = ike_sa->has_condition(ike_sa, COND_NAT_ANY); + + enumerator = ike_sa->create_child_sa_enumerator(ike_sa); + while (enumerator->enumerate(enumerator, &child_sa)) + { + if (handle_sa(child_sa)) + { + ipth = init_handle(); + if (ipth) + { + if (remove_entry(this, ipth, child_sa) && + add_entry(this, ipth, lhost, rhost, child_sa, encap)) + { + commit_handle(ipth); + } + iptc_free(ipth); + } + } + } + enumerator->destroy(enumerator); + + return TRUE; +} + +/** + * Filter to map entries to ts/mark + */ +static bool ts_filter(entry_t *entry, traffic_selector_t **ts, + traffic_selector_t **out, void *dummy, u_int32_t *mark, + void *dummy2, bool *reinject) +{ + *out = *ts; + *mark = entry->mark; + *reinject = entry->reinject; + return TRUE; +} + +/** + * Create inner enumerator over local traffic selectors + */ +static enumerator_t* create_inner_local(entry_t *entry, rwlock_t *lock) +{ + return enumerator_create_filter(array_create_enumerator(entry->lts), + (void*)ts_filter, entry, NULL); +} + +/** + * Create inner enumerator over remote traffic selectors + */ +static enumerator_t* create_inner_remote(entry_t *entry, rwlock_t *lock) +{ + return enumerator_create_filter(array_create_enumerator(entry->rts), + (void*)ts_filter, entry, NULL); +} + +METHOD(forecast_listener_t, create_enumerator, enumerator_t*, + private_forecast_listener_t *this, bool local) +{ + this->lock->read_lock(this->lock); + return enumerator_create_nested( + this->entries->create_enumerator(this->entries), + (void*)(local ? create_inner_local : create_inner_remote), + this->lock, (void*)this->lock->unlock); +} + +METHOD(forecast_listener_t, set_broadcast, void, + private_forecast_listener_t *this, host_t *bcast) +{ + if (bcast->get_family(bcast) == AF_INET) + { + struct sockaddr_in *in; + + in = (struct sockaddr_in*)bcast->get_sockaddr(bcast); + this->broadcast = in->sin_addr.s_addr; + } +} + +METHOD(forecast_listener_t, destroy, void, + private_forecast_listener_t *this) +{ + this->entries->destroy(this->entries); + this->lock->destroy(this->lock); + free(this); +} + +/** + * See header + */ +forecast_listener_t *forecast_listener_create() +{ + private_forecast_listener_t *this; + + INIT(this, + .public = { + .listener = { + .ike_update = _ike_update, + .child_updown = _child_updown, + .child_rekey = _child_rekey, + }, + .create_enumerator = _create_enumerator, + .set_broadcast = _set_broadcast, + .destroy = _destroy, + }, + .entries = linked_list_create(), + .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), + .reinject_configs = lib->settings->get_str(lib->settings, + "%s.plugins.forecast.reinject", "", lib->ns), + ); + + return &this->public; +} diff --git a/src/libcharon/plugins/forecast/forecast_listener.h b/src/libcharon/plugins/forecast/forecast_listener.h new file mode 100644 index 000000000..49827ecb1 --- /dev/null +++ b/src/libcharon/plugins/forecast/forecast_listener.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2010-2014 Martin Willi + * Copyright (C) 2010-2014 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup forecast_listener forecast_listener + * @{ @ingroup forecast + */ + +#ifndef FORECAST_LISTENER_H_ +#define FORECAST_LISTENER_H_ + +#include <bus/listeners/listener.h> + +typedef struct forecast_listener_t forecast_listener_t; + +/** + * Listener to register the set of IPs we forward received multi/broadcasts to. + */ +struct forecast_listener_t { + + /** + * Implements listener_t interface. + */ + listener_t listener; + + /** + * Create an enumerator over active tunnels. + * + * The enumerator enumerates over local or remote traffic selectors, + * associated firewall marks and if decasulated packets should get + * reinjected into other tunnels. + * + * @param local TRUE to enumerate local, FALSE to enumerate remote TS + * @return enumerator over (traffic_selector_t*, u_int, bool) + */ + enumerator_t* (*create_enumerator)(forecast_listener_t *this, bool local); + + /** + * Set the broadcast address of the LAN interface. + * + * @param bcast broadcast address + */ + void (*set_broadcast)(forecast_listener_t *this, host_t *bcast); + + /** + * Destroy a forecast_listener_t. + */ + void (*destroy)(forecast_listener_t *this); +}; + +/** + * Create a forecast_listener instance. + */ +forecast_listener_t *forecast_listener_create(); + +#endif /** FORECAST_LISTENER_H_ @}*/ diff --git a/src/libcharon/plugins/forecast/forecast_plugin.c b/src/libcharon/plugins/forecast/forecast_plugin.c new file mode 100644 index 000000000..a129b76b2 --- /dev/null +++ b/src/libcharon/plugins/forecast/forecast_plugin.c @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2010-2014 Martin Willi + * Copyright (C) 2010-2014 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "forecast_plugin.h" +#include "forecast_listener.h" +#include "forecast_forwarder.h" + +#include <daemon.h> + +typedef struct private_forecast_plugin_t private_forecast_plugin_t; + +/** + * Private data of forecast plugin + */ +struct private_forecast_plugin_t { + + /** + * implements plugin interface + */ + forecast_plugin_t public; + + /** + * Listener registering active tunnels + */ + forecast_listener_t *listener; + + /** + * Broadcast/Multicast sniffer and forwarder + */ + forecast_forwarder_t *forwarder; +}; + +METHOD(plugin_t, get_name, char*, + private_forecast_plugin_t *this) +{ + return "forecast"; +} + +/** + * Register plugin features + */ +static bool register_forecast(private_forecast_plugin_t *this, + plugin_feature_t *feature, bool reg, void *data) +{ + if (reg) + { + this->forwarder = forecast_forwarder_create(this->listener); + if (!this->forwarder) + { + return FALSE; + } + charon->bus->add_listener(charon->bus, &this->listener->listener); + } + else + { + charon->bus->remove_listener(charon->bus, &this->listener->listener); + this->forwarder->destroy(this->forwarder); + } + return TRUE; +} + +METHOD(plugin_t, get_features, int, + private_forecast_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK((plugin_feature_callback_t)register_forecast, NULL), + PLUGIN_PROVIDE(CUSTOM, "forecast"), + }; + *features = f; + return countof(f); +} + +METHOD(plugin_t, destroy, void, + private_forecast_plugin_t *this) +{ + this->listener->destroy(this->listener); + free(this); +} + +/** + * Plugin constructor + */ +plugin_t *forecast_plugin_create() +{ + private_forecast_plugin_t *this; + + if (!lib->caps->keep(lib->caps, CAP_NET_RAW)) + { + DBG1(DBG_NET, "forecast plugin requires CAP_NET_RAW capability"); + return NULL; + } + + INIT(this, + .public = { + .plugin = { + .get_name = _get_name, + .get_features = _get_features, + .reload = (void*)return_false, + .destroy = _destroy, + }, + }, + .listener = forecast_listener_create(), + ); + + return &this->public.plugin; +} diff --git a/src/libcharon/plugins/forecast/forecast_plugin.h b/src/libcharon/plugins/forecast/forecast_plugin.h new file mode 100644 index 000000000..739ca4d79 --- /dev/null +++ b/src/libcharon/plugins/forecast/forecast_plugin.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2010-2014 Martin Willi + * Copyright (C) 2010-2014 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup forecast forecast + * @ingroup cplugins + * + * @defgroup forecast_plugin forecast_plugin + * @{ @ingroup forecast + */ + +#ifndef FORECAST_PLUGIN_H_ +#define FORECAST_PLUGIN_H_ + +#include <plugins/plugin.h> + +typedef struct forecast_plugin_t forecast_plugin_t; + +/** + * Broadcast/Multicast forwarding plugin. + */ +struct forecast_plugin_t { + + /** + * Implements plugin interface. + */ + plugin_t plugin; +}; + +#endif /** FORECAST_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/ha/Makefile.in b/src/libcharon/plugins/ha/Makefile.in index aa5bdb747..de74f88cc 100644 --- a/src/libcharon/plugins/ha/Makefile.in +++ b/src/libcharon/plugins/ha/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/ha/ha_attribute.c b/src/libcharon/plugins/ha/ha_attribute.c index dd55fae8b..2b271a8e7 100644 --- a/src/libcharon/plugins/ha/ha_attribute.c +++ b/src/libcharon/plugins/ha/ha_attribute.c @@ -170,7 +170,7 @@ static bool responsible_for(private_ha_attribute_t *this, int bit) } METHOD(attribute_provider_t, acquire_address, host_t*, - private_ha_attribute_t *this, linked_list_t *pools, identification_t *id, + private_ha_attribute_t *this, linked_list_t *pools, ike_sa_t *ike_sa, host_t *requested) { enumerator_t *enumerator; @@ -233,7 +233,7 @@ METHOD(attribute_provider_t, acquire_address, host_t*, METHOD(attribute_provider_t, release_address, bool, private_ha_attribute_t *this, linked_list_t *pools, host_t *address, - identification_t *id) + ike_sa_t *ike_sa) { enumerator_t *enumerator; pool_t *pool; diff --git a/src/libcharon/plugins/ha/ha_cache.c b/src/libcharon/plugins/ha/ha_cache.c index 60e75fc7e..6c1b3471d 100644 --- a/src/libcharon/plugins/ha/ha_cache.c +++ b/src/libcharon/plugins/ha/ha_cache.c @@ -196,9 +196,26 @@ static status_t rekey_children(ike_sa_t *ike_sa) enumerator_t *enumerator; child_sa_t *child_sa; status_t status = SUCCESS; + linked_list_t *children; + struct { + protocol_id_t protocol; + u_int32_t spi; + } *info; + children = linked_list_create(); enumerator = ike_sa->create_child_sa_enumerator(ike_sa); - while (enumerator->enumerate(enumerator, (void**)&child_sa)) + while (enumerator->enumerate(enumerator, &child_sa)) + { + INIT(info, + .protocol = child_sa->get_protocol(child_sa), + .spi = child_sa->get_spi(child_sa, TRUE), + ); + children->insert_last(children, info); + } + enumerator->destroy(enumerator); + + enumerator = children->create_enumerator(children); + while (enumerator->enumerate(enumerator, &info)) { if (ike_sa->supports_extension(ike_sa, EXT_MS_WINDOWS) && ike_sa->has_condition(ike_sa, COND_NAT_THERE)) @@ -207,17 +224,13 @@ static status_t rekey_children(ike_sa_t *ike_sa) * with an "invalid situation" error. We just close the CHILD_SA, * Windows will reestablish it immediately if required. */ DBG1(DBG_CFG, "resyncing CHILD_SA using a delete"); - status = ike_sa->delete_child_sa(ike_sa, - child_sa->get_protocol(child_sa), - child_sa->get_spi(child_sa, TRUE), + status = ike_sa->delete_child_sa(ike_sa, info->protocol, info->spi, FALSE); } else { DBG1(DBG_CFG, "resyncing CHILD_SA using a rekey"); - status = ike_sa->rekey_child_sa(ike_sa, - child_sa->get_protocol(child_sa), - child_sa->get_spi(child_sa, TRUE)); + status = ike_sa->rekey_child_sa(ike_sa, info->protocol, info->spi); } if (status == DESTROY_ME) { @@ -225,6 +238,8 @@ static status_t rekey_children(ike_sa_t *ike_sa) } } enumerator->destroy(enumerator); + children->destroy_function(children, free); + return status; } diff --git a/src/libcharon/plugins/ha/ha_child.c b/src/libcharon/plugins/ha/ha_child.c index c166d72ac..17f2d50d1 100644 --- a/src/libcharon/plugins/ha/ha_child.c +++ b/src/libcharon/plugins/ha/ha_child.c @@ -97,7 +97,7 @@ METHOD(listener_t, child_keys, bool, } m->add_attribute(m, HA_NONCE_I, nonce_i); m->add_attribute(m, HA_NONCE_R, nonce_r); - if (dh && dh->get_shared_secret(dh, &secret) == SUCCESS) + if (dh && dh->get_shared_secret(dh, &secret)) { m->add_attribute(m, HA_SECRET, secret); chunk_clear(&secret); @@ -128,7 +128,7 @@ METHOD(listener_t, child_keys, bool, ike_sa->get_other_host(ike_sa), child_sa->get_spi(child_sa, FALSE)); DBG1(DBG_CFG, "handling HA CHILD_SA %s{%d} %#R=== %#R " "(segment in: %d%s, out: %d%s)", child_sa->get_name(child_sa), - child_sa->get_reqid(child_sa), local_ts, remote_ts, + child_sa->get_unique_id(child_sa), local_ts, remote_ts, seg_i, this->segments->is_active(this->segments, seg_i) ? "*" : "", seg_o, this->segments->is_active(this->segments, seg_o) ? "*" : ""); diff --git a/src/libcharon/plugins/ha/ha_dispatcher.c b/src/libcharon/plugins/ha/ha_dispatcher.c index e20e872c1..31eeb934e 100644 --- a/src/libcharon/plugins/ha/ha_dispatcher.c +++ b/src/libcharon/plugins/ha/ha_dispatcher.c @@ -81,17 +81,18 @@ struct ha_diffie_hellman_t { chunk_t pub; }; -METHOD(diffie_hellman_t, dh_get_shared_secret, status_t, +METHOD(diffie_hellman_t, dh_get_shared_secret, bool, ha_diffie_hellman_t *this, chunk_t *secret) { *secret = chunk_clone(this->secret); - return SUCCESS; + return TRUE; } -METHOD(diffie_hellman_t, dh_get_my_public_value, void, +METHOD(diffie_hellman_t, dh_get_my_public_value, bool, ha_diffie_hellman_t *this, chunk_t *value) { *value = chunk_clone(this->pub); + return TRUE; } METHOD(diffie_hellman_t, dh_destroy, void, @@ -373,6 +374,9 @@ static void process_ike_update(private_ha_dispatcher_t *this, else { DBG1(DBG_IKE, "HA is missing nodes peer configuration"); + charon->ike_sa_manager->checkin_and_destroy( + charon->ike_sa_manager, ike_sa); + ike_sa = NULL; } break; case HA_EXTENSIONS: @@ -718,7 +722,8 @@ static void process_child_add(private_ha_dispatcher_t *this, child_sa = child_sa_create(ike_sa->get_my_host(ike_sa), ike_sa->get_other_host(ike_sa), config, 0, - ike_sa->has_condition(ike_sa, COND_NAT_ANY)); + ike_sa->has_condition(ike_sa, COND_NAT_ANY), + 0, 0); child_sa->set_mode(child_sa, mode); child_sa->set_protocol(child_sa, PROTO_ESP); child_sa->set_ipcomp(child_sa, ipcomp); @@ -835,7 +840,7 @@ static void process_child_add(private_ha_dispatcher_t *this, DBG1(DBG_CFG, "installed HA CHILD_SA %s{%d} %#R=== %#R " "(segment in: %d%s, out: %d%s)", child_sa->get_name(child_sa), - child_sa->get_reqid(child_sa), local_ts, remote_ts, + child_sa->get_unique_id(child_sa), local_ts, remote_ts, seg_i, this->segments->is_active(this->segments, seg_i) ? "*" : "", seg_o, this->segments->is_active(this->segments, seg_o) ? "*" : ""); child_sa->add_policies(child_sa, local_ts, remote_ts); diff --git a/src/libcharon/plugins/ha/ha_ike.c b/src/libcharon/plugins/ha/ha_ike.c index 442a3a23d..6b4b53c9c 100644 --- a/src/libcharon/plugins/ha/ha_ike.c +++ b/src/libcharon/plugins/ha/ha_ike.c @@ -84,7 +84,7 @@ METHOD(listener_t, ike_keys, bool, { /* do not sync SA between nodes */ return TRUE; } - if (dh->get_shared_secret(dh, &secret) != SUCCESS) + if (!dh->get_shared_secret(dh, &secret)) { return TRUE; } @@ -127,9 +127,11 @@ METHOD(listener_t, ike_keys, bool, chunk_clear(&secret); if (ike_sa->get_version(ike_sa) == IKEV1) { - dh->get_my_public_value(dh, &secret); - m->add_attribute(m, HA_LOCAL_DH, secret); - chunk_free(&secret); + if (dh->get_my_public_value(dh, &secret)) + { + m->add_attribute(m, HA_LOCAL_DH, secret); + chunk_free(&secret); + } m->add_attribute(m, HA_REMOTE_DH, dh_other); if (shared) { diff --git a/src/libcharon/plugins/ha/ha_plugin.c b/src/libcharon/plugins/ha/ha_plugin.c index 493cad5ec..a58377bab 100644 --- a/src/libcharon/plugins/ha/ha_plugin.c +++ b/src/libcharon/plugins/ha/ha_plugin.c @@ -25,7 +25,6 @@ #include "ha_attribute.h" #include <daemon.h> -#include <hydra.h> #include <config/child_cfg.h> typedef struct private_ha_plugin_t private_ha_plugin_t; @@ -108,13 +107,13 @@ static bool plugin_cb(private_ha_plugin_t *this, charon->bus->add_listener(charon->bus, &this->segments->listener); charon->bus->add_listener(charon->bus, &this->ike->listener); charon->bus->add_listener(charon->bus, &this->child->listener); - hydra->attributes->add_provider(hydra->attributes, - &this->attr->provider); + charon->attributes->add_provider(charon->attributes, + &this->attr->provider); } else { - hydra->attributes->remove_provider(hydra->attributes, - &this->attr->provider); + charon->attributes->remove_provider(charon->attributes, + &this->attr->provider); charon->bus->remove_listener(charon->bus, &this->segments->listener); charon->bus->remove_listener(charon->bus, &this->ike->listener); charon->bus->remove_listener(charon->bus, &this->child->listener); @@ -224,4 +223,3 @@ plugin_t *ha_plugin_create() return &this->public.plugin; } - diff --git a/src/libcharon/plugins/ipseckey/Makefile.in b/src/libcharon/plugins/ipseckey/Makefile.in index bd3fd63aa..f98e78ffc 100644 --- a/src/libcharon/plugins/ipseckey/Makefile.in +++ b/src/libcharon/plugins/ipseckey/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/kernel_iph/Makefile.in b/src/libcharon/plugins/kernel_iph/Makefile.in index 7e1f79bd8..7a2583d06 100644 --- a/src/libcharon/plugins/kernel_iph/Makefile.in +++ b/src/libcharon/plugins/kernel_iph/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/kernel_libipsec/Makefile.in b/src/libcharon/plugins/kernel_libipsec/Makefile.in index c961c0bd8..6b6c95688 100644 --- a/src/libcharon/plugins/kernel_libipsec/Makefile.in +++ b/src/libcharon/plugins/kernel_libipsec/Makefile.in @@ -231,6 +231,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c index bd07a67a2..6246dc505 100644 --- a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c +++ b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c @@ -222,10 +222,10 @@ static inline bool policy_entry_equals(policy_entry_t *a, /** * Expiration callback */ -static void expire(u_int32_t reqid, u_int8_t protocol, u_int32_t spi, bool hard) +static void expire(u_int8_t protocol, u_int32_t spi, host_t *dst, bool hard) { - hydra->kernel_interface->expire(hydra->kernel_interface, reqid, protocol, - spi, hard); + hydra->kernel_interface->expire(hydra->kernel_interface, protocol, + spi, dst, hard); } METHOD(kernel_ipsec_t, get_features, kernel_feature_t, @@ -236,14 +236,14 @@ METHOD(kernel_ipsec_t, get_features, kernel_feature_t, METHOD(kernel_ipsec_t, get_spi, status_t, private_kernel_libipsec_ipsec_t *this, host_t *src, host_t *dst, - u_int8_t protocol, u_int32_t reqid, u_int32_t *spi) + u_int8_t protocol, u_int32_t *spi) { - return ipsec->sas->get_spi(ipsec->sas, src, dst, protocol, reqid, spi); + return ipsec->sas->get_spi(ipsec->sas, src, dst, protocol, spi); } METHOD(kernel_ipsec_t, get_cpi, status_t, private_kernel_libipsec_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t reqid, u_int16_t *cpi) + u_int16_t *cpi) { return NOT_SUPPORTED; } @@ -254,13 +254,13 @@ METHOD(kernel_ipsec_t, add_sa, status_t, u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key, u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window, - bool initiator, bool encap, bool esn, bool inbound, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts) + bool initiator, bool encap, bool esn, bool inbound, bool update, + linked_list_t *src_ts, linked_list_t *dst_ts) { return ipsec->sas->add_sa(ipsec->sas, src, dst, spi, protocol, reqid, mark, tfc, lifetime, enc_alg, enc_key, int_alg, int_key, - mode, ipcomp, cpi, initiator, encap, esn, inbound, - src_ts, dst_ts); + mode, ipcomp, cpi, initiator, encap, esn, + inbound, update); } METHOD(kernel_ipsec_t, update_sa, status_t, diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c index 6ce1d4eb0..830954e11 100644 --- a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c +++ b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_router.c @@ -131,35 +131,6 @@ static void deliver_plain(private_kernel_libipsec_router_t *this, } /** - * Create an FD set covering all TUN devices and the read end of the notify pipe - */ -static int collect_fds(private_kernel_libipsec_router_t *this, fd_set *fds) -{ - enumerator_t *enumerator; - tun_entry_t *entry; - int maxfd; - - FD_ZERO(fds); - FD_SET(this->notify[0], fds); - maxfd = this->notify[0]; - - FD_SET(this->tun.fd, fds); - maxfd = max(maxfd, this->tun.fd); - - this->lock->read_lock(this->lock); - enumerator = this->tuns->create_enumerator(this->tuns); - while (enumerator->enumerate(enumerator, NULL, &entry)) - { - FD_SET(entry->fd, fds); - maxfd = max(maxfd, entry->fd); - } - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); - - return maxfd + 1; -} - -/** * Read and process outbound plaintext packet for the given TUN device */ static void process_plain(tun_device_t *tun) @@ -183,29 +154,20 @@ static void process_plain(tun_device_t *tun) } /** - * Handle waiting data for any TUN device + * Find flagged revents in a pollfd set by fd */ -static void handle_tuns(private_kernel_libipsec_router_t *this, fd_set *fds) +static int find_revents(struct pollfd *pfd, int count, int fd) { - enumerator_t *enumerator; - tun_entry_t *entry; + int i; - if (FD_ISSET(this->tun.fd, fds)) + for (i = 0; i < count; i++) { - process_plain(this->tun.tun); - } - - this->lock->read_lock(this->lock); - enumerator = this->tuns->create_enumerator(this->tuns); - while (enumerator->enumerate(enumerator, NULL, &entry)) - { - if (FD_ISSET(entry->fd, fds)) + if (pfd[i].fd == fd) { - process_plain(entry->tun); + return pfd[i].revents; } } - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); + return 0; } /** @@ -213,28 +175,68 @@ static void handle_tuns(private_kernel_libipsec_router_t *this, fd_set *fds) */ static job_requeue_t handle_plain(private_kernel_libipsec_router_t *this) { + enumerator_t *enumerator; + tun_entry_t *entry; bool oldstate; - fd_set fds; - int maxfd; + int count = 0; + char buf[1]; + struct pollfd *pfd; + + this->lock->read_lock(this->lock); - maxfd = collect_fds(this, &fds); + pfd = alloca(sizeof(*pfd) * (this->tuns->get_count(this->tuns) + 2)); + pfd[count].fd = this->notify[0]; + pfd[count].events = POLLIN; + count++; + pfd[count].fd = this->tun.fd; + pfd[count].events = POLLIN; + count++; + + enumerator = this->tuns->create_enumerator(this->tuns); + while (enumerator->enumerate(enumerator, NULL, &entry)) + { + pfd[count].fd = entry->fd; + pfd[count].events = POLLIN; + count++; + } + enumerator->destroy(enumerator); + this->lock->unlock(this->lock); oldstate = thread_cancelability(TRUE); - if (select(maxfd, &fds, NULL, NULL, NULL) <= 0) + if (poll(pfd, count, -1) <= 0) { thread_cancelability(oldstate); return JOB_REQUEUE_FAIR; } thread_cancelability(oldstate); - if (FD_ISSET(this->notify[0], &fds)) - { /* list of TUN devices changed, read notification data, rebuild FDs */ - char buf[1]; - while (read(this->notify[0], &buf, sizeof(buf)) == sizeof(buf)); + if (pfd[0].revents & POLLIN) + { + /* list of TUN devices changed, read notification data, rebuild FDs */ + while (read(this->notify[0], &buf, sizeof(buf)) == sizeof(buf)) + { + /* nop */ + } return JOB_REQUEUE_DIRECT; } - handle_tuns(this, &fds); + if (pfd[1].revents & POLLIN) + { + process_plain(this->tun.tun); + } + + this->lock->read_lock(this->lock); + enumerator = this->tuns->create_enumerator(this->tuns); + while (enumerator->enumerate(enumerator, NULL, &entry)) + { + if (find_revents(pfd, count, entry->fd) & POLLIN) + { + process_plain(entry->tun); + } + } + enumerator->destroy(enumerator); + this->lock->unlock(this->lock); + return JOB_REQUEUE_DIRECT; } diff --git a/src/libcharon/plugins/kernel_wfp/Makefile.in b/src/libcharon/plugins/kernel_wfp/Makefile.in index 1c92e30fc..efb214b88 100644 --- a/src/libcharon/plugins/kernel_wfp/Makefile.in +++ b/src/libcharon/plugins/kernel_wfp/Makefile.in @@ -237,6 +237,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -297,10 +298,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -374,6 +377,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.c b/src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.c index 41f85ba5c..2e31aa151 100644 --- a/src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.c +++ b/src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.c @@ -54,6 +54,24 @@ const GUID FWPM_LAYER_IPFORWARD_V4 = { const GUID FWPM_LAYER_IPFORWARD_V6 = { 0x7b964818, 0x19c7, 0x493a, { 0xb7,0x1f,0x83,0x2c,0x36,0x84,0xd2,0x8c } }; +const GUID FWPM_LAYER_ALE_AUTH_CONNECT_V4 = { + 0xc38d57d1, 0x05a7, 0x4c33, { 0x90,0x4f,0x7f,0xbc,0xee,0xe6,0x0e,0x82 } +}; +const GUID FWPM_LAYER_ALE_AUTH_CONNECT_V6 = { + 0x4a72393b, 0x319f, 0x44bc, { 0x84,0xc3,0xba,0x54,0xdc,0xb3,0xb6,0xb4 } +}; +const GUID FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4 = { + 0xe1cd9fe7, 0xf4b5, 0x4273, { 0x96,0xc0,0x59,0x2e,0x48,0x7b,0x86,0x50 } +}; +const GUID FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6 = { + 0xa3b42c97, 0x9f04, 0x4672, { 0xb8,0x7e,0xce,0xe9,0xc4,0x83,0x25,0x7f } +}; +const GUID FWPM_SUBLAYER_IPSEC_TUNNEL = { + 0x83f299ed, 0x9ff4, 0x4967, { 0xaf,0xf4,0xc3,0x09,0xf4,0xda,0xb8,0x27 } +}; +const GUID FWPM_SUBLAYER_IPSEC_FORWARD_OUTBOUND_TUNNEL = { + 0xa5082e73, 0x8f71, 0x4559, { 0x8a,0x9a,0x10,0x1c,0xea,0x04,0xef,0x87 } +}; const GUID FWPM_CALLOUT_IPSEC_INBOUND_TRANSPORT_V4 = { 0x5132900d, 0x5e84, 0x4b5f, { 0x80,0xe4,0x01,0x74,0x1e,0x81,0xff,0x10 } }; @@ -90,6 +108,24 @@ const GUID FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V4 = { const GUID FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V6 = { 0xdae640cc, 0xe021, 0x4bee, { 0x9e,0xb6,0xa4,0x8b,0x27,0x5c,0x8c,0x1d } }; +const GUID FWPM_CALLOUT_IPSEC_ALE_CONNECT_V4 = { + 0x6ac141fc, 0xf75d, 0x4203, { 0xb9,0xc8,0x48,0xe6,0x14,0x9c,0x27,0x12 } +}; +const GUID FWPM_CALLOUT_IPSEC_ALE_CONNECT_V6 = { + 0x4c0dda05, 0xe31f, 0x4666, { 0x90,0xb0,0xb3,0xdf,0xad,0x34,0x12,0x9a } +}; +const GUID FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_ALE_ACCEPT_V4 = { + 0x3df6e7de, 0xfd20, 0x48f2, { 0x9f,0x26,0xf8,0x54,0x44,0x4c,0xba,0x79 } +}; +const GUID FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_ALE_ACCEPT_V6 = { + 0xa1e392d3, 0x72ac, 0x47bb, { 0x87,0xa7,0x01,0x22,0xc6,0x94,0x34,0xab } +}; +const GUID FWPM_CALLOUT_IPSEC_INBOUND_INITIATE_SECURE_V4 = { + 0x7dff309b, 0xba7d, 0x4aba, { 0x91,0xaa,0xae,0x5c,0x66,0x40,0xc9,0x44 } +}; +const GUID FWPM_CALLOUT_IPSEC_INBOUND_INITIATE_SECURE_V6 = { + 0xa9a0d6d9, 0xc58c, 0x474e, { 0x8a,0xeb,0x3c,0xfe,0x99,0xd6,0xd5,0x3d } +}; /** * Load a function symbol from a loaded dll diff --git a/src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.h b/src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.h index 50a89a007..a553a0986 100644 --- a/src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.h +++ b/src/libcharon/plugins/kernel_wfp/kernel_wfp_compat.h @@ -127,6 +127,10 @@ const GUID FWPM_LAYER_OUTBOUND_TRANSPORT_V4; const GUID FWPM_LAYER_OUTBOUND_TRANSPORT_V6; const GUID FWPM_LAYER_IPFORWARD_V4; const GUID FWPM_LAYER_IPFORWARD_V6; +const GUID FWPM_LAYER_ALE_AUTH_CONNECT_V4; +const GUID FWPM_LAYER_ALE_AUTH_CONNECT_V6; +const GUID FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4; +const GUID FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6; const GUID FWPM_SUBLAYER_IPSEC_TUNNEL; const GUID FWPM_SUBLAYER_IPSEC_FORWARD_OUTBOUND_TUNNEL; const GUID FWPM_CALLOUT_IPSEC_INBOUND_TRANSPORT_V4; @@ -141,6 +145,12 @@ const GUID FWPM_CALLOUT_IPSEC_FORWARD_INBOUND_TUNNEL_V4; const GUID FWPM_CALLOUT_IPSEC_FORWARD_INBOUND_TUNNEL_V6; const GUID FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V4; const GUID FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V6; +const GUID FWPM_CALLOUT_IPSEC_ALE_CONNECT_V4; +const GUID FWPM_CALLOUT_IPSEC_ALE_CONNECT_V6; +const GUID FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_ALE_ACCEPT_V4; +const GUID FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_ALE_ACCEPT_V6; +const GUID FWPM_CALLOUT_IPSEC_INBOUND_INITIATE_SECURE_V4; +const GUID FWPM_CALLOUT_IPSEC_INBOUND_INITIATE_SECURE_V6; /* integrity config, missing in some MinGW versions */ #ifndef IPSEC_AUTH_CONFIG_HMAC_MD5_96 diff --git a/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c b/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c index c788bfb10..b38ded846 100644 --- a/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c +++ b/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c @@ -26,6 +26,8 @@ #include <collections/hashtable.h> #include <processing/jobs/callback_job.h> +#define IPPROTO_IPIP 4 +#define IPPROTO_IPV6 41 typedef struct private_kernel_wfp_ipsec_t private_kernel_wfp_ipsec_t; @@ -188,6 +190,14 @@ typedef struct { u_int64_t provider; /** WFP allocated LUID for SA context */ u_int64_t sa_id; + /** WFP allocated LUID for tunnel mode IP-IPv4 inbound filter */ + u_int64_t ip_ipv4_in; + /** WFP allocated LUID for tunnel mode IP-IPv4 outbound filter */ + u_int64_t ip_ipv4_out; + /** WFP allocated LUID for tunnel mode IP-IPv6 inbound filter */ + u_int64_t ip_ipv6_in; + /** WFP allocated LUID for tunnel mode IP-IPv6 outbound filter */ + u_int64_t ip_ipv6_out; } entry_t; /** @@ -285,6 +295,22 @@ static void cleanup_policies(private_kernel_wfp_ipsec_t *this, entry_t *entry) */ static void entry_destroy(private_kernel_wfp_ipsec_t *this, entry_t *entry) { + if (entry->ip_ipv4_in) + { + FwpmFilterDeleteById0(this->handle, entry->ip_ipv4_in); + } + if (entry->ip_ipv4_out) + { + FwpmFilterDeleteById0(this->handle, entry->ip_ipv4_out); + } + if (entry->ip_ipv6_in) + { + FwpmFilterDeleteById0(this->handle, entry->ip_ipv6_in); + } + if (entry->ip_ipv6_out) + { + FwpmFilterDeleteById0(this->handle, entry->ip_ipv6_out); + } if (entry->sa_id) { IPsecSaContextDeleteById0(this->handle, entry->sa_id); @@ -553,49 +579,58 @@ static void free_conditions(FWPM_FILTER_CONDITION0 *conds, int count) * Find the callout GUID for given parameters */ static bool find_callout(bool tunnel, bool v6, bool inbound, bool forward, - GUID *layer, GUID *sublayer, GUID *callout) + bool ale, GUID *layer, GUID *sublayer, GUID *callout) { struct { bool tunnel; bool v6; bool inbound; bool forward; + bool ale; const GUID *layer; const GUID *sublayer; const GUID *callout; } map[] = { - { 0, 0, 0, 0, &FWPM_LAYER_OUTBOUND_TRANSPORT_V4, NULL, - &FWPM_CALLOUT_IPSEC_OUTBOUND_TRANSPORT_V4 }, - { 0, 0, 1, 0, &FWPM_LAYER_INBOUND_TRANSPORT_V4, NULL, - &FWPM_CALLOUT_IPSEC_INBOUND_TRANSPORT_V4 }, - { 0, 1, 0, 0, &FWPM_LAYER_OUTBOUND_TRANSPORT_V6, NULL, - &FWPM_CALLOUT_IPSEC_OUTBOUND_TRANSPORT_V6 }, - { 0, 1, 1, 0, &FWPM_LAYER_INBOUND_TRANSPORT_V6, NULL, - &FWPM_CALLOUT_IPSEC_INBOUND_TRANSPORT_V6 }, - { 1, 0, 0, 0, &FWPM_LAYER_OUTBOUND_TRANSPORT_V4, - &FWPM_SUBLAYER_IPSEC_TUNNEL, - &FWPM_CALLOUT_IPSEC_OUTBOUND_TUNNEL_V4 }, - { 1, 0, 0, 1, &FWPM_LAYER_IPFORWARD_V4, - &FWPM_SUBLAYER_IPSEC_FORWARD_OUTBOUND_TUNNEL, - &FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V4 }, - { 1, 0, 1, 0, &FWPM_LAYER_INBOUND_TRANSPORT_V4, - &FWPM_SUBLAYER_IPSEC_TUNNEL, - &FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_V4 }, - { 1, 0, 1, 1, &FWPM_LAYER_IPFORWARD_V4, - &FWPM_SUBLAYER_IPSEC_TUNNEL, - &FWPM_CALLOUT_IPSEC_FORWARD_INBOUND_TUNNEL_V4 }, - { 1, 1, 0, 0, &FWPM_LAYER_OUTBOUND_TRANSPORT_V6, - &FWPM_SUBLAYER_IPSEC_TUNNEL, - &FWPM_CALLOUT_IPSEC_OUTBOUND_TUNNEL_V6 }, - { 1, 1, 0, 1, &FWPM_LAYER_IPFORWARD_V6, - &FWPM_SUBLAYER_IPSEC_TUNNEL, - &FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V6 }, - { 1, 1, 1, 0, &FWPM_LAYER_INBOUND_TRANSPORT_V6, - &FWPM_SUBLAYER_IPSEC_TUNNEL, - &FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_V6 }, - { 1, 1, 1, 1, &FWPM_LAYER_IPFORWARD_V6, - &FWPM_SUBLAYER_IPSEC_TUNNEL, - &FWPM_CALLOUT_IPSEC_FORWARD_INBOUND_TUNNEL_V6 }, + { 0, 0, 0, 0, 0, &FWPM_LAYER_OUTBOUND_TRANSPORT_V4, NULL, + &FWPM_CALLOUT_IPSEC_OUTBOUND_TRANSPORT_V4 }, + { 0, 0, 1, 0, 0, &FWPM_LAYER_INBOUND_TRANSPORT_V4, NULL, + &FWPM_CALLOUT_IPSEC_INBOUND_TRANSPORT_V4 }, + { 0, 1, 0, 0, 0, &FWPM_LAYER_OUTBOUND_TRANSPORT_V6, NULL, + &FWPM_CALLOUT_IPSEC_OUTBOUND_TRANSPORT_V6 }, + { 0, 1, 1, 0, 0, &FWPM_LAYER_INBOUND_TRANSPORT_V6, NULL, + &FWPM_CALLOUT_IPSEC_INBOUND_TRANSPORT_V6 }, + { 1, 0, 0, 0, 0, &FWPM_LAYER_OUTBOUND_TRANSPORT_V4, + &FWPM_SUBLAYER_IPSEC_TUNNEL, + &FWPM_CALLOUT_IPSEC_OUTBOUND_TUNNEL_V4 }, + { 1, 0, 0, 1, 0, &FWPM_LAYER_IPFORWARD_V4, + &FWPM_SUBLAYER_IPSEC_FORWARD_OUTBOUND_TUNNEL, + &FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V4 }, + { 1, 0, 1, 0, 0, &FWPM_LAYER_INBOUND_TRANSPORT_V4, + &FWPM_SUBLAYER_IPSEC_TUNNEL, + &FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_V4 }, + { 1, 0, 1, 1, 0, &FWPM_LAYER_IPFORWARD_V4, + &FWPM_SUBLAYER_IPSEC_TUNNEL, + &FWPM_CALLOUT_IPSEC_FORWARD_INBOUND_TUNNEL_V4 }, + { 1, 0, 0, 0, 1, &FWPM_LAYER_ALE_AUTH_CONNECT_V4, NULL, + &FWPM_CALLOUT_IPSEC_ALE_CONNECT_V4 }, + { 1, 0, 1, 0, 1, &FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V4, NULL, + &FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_ALE_ACCEPT_V4}, + { 1, 1, 0, 0, 0, &FWPM_LAYER_OUTBOUND_TRANSPORT_V6, + &FWPM_SUBLAYER_IPSEC_TUNNEL, + &FWPM_CALLOUT_IPSEC_OUTBOUND_TUNNEL_V6 }, + { 1, 1, 0, 1, 0, &FWPM_LAYER_IPFORWARD_V6, + &FWPM_SUBLAYER_IPSEC_FORWARD_OUTBOUND_TUNNEL, + &FWPM_CALLOUT_IPSEC_FORWARD_OUTBOUND_TUNNEL_V6 }, + { 1, 1, 1, 0, 0, &FWPM_LAYER_INBOUND_TRANSPORT_V6, + &FWPM_SUBLAYER_IPSEC_TUNNEL, + &FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_V6 }, + { 1, 1, 1, 1, 0, &FWPM_LAYER_IPFORWARD_V6, + &FWPM_SUBLAYER_IPSEC_TUNNEL, + &FWPM_CALLOUT_IPSEC_FORWARD_INBOUND_TUNNEL_V6 }, + { 1, 1, 0, 0, 1, &FWPM_LAYER_ALE_AUTH_CONNECT_V6, NULL, + &FWPM_CALLOUT_IPSEC_ALE_CONNECT_V6 }, + { 1, 1, 1, 0, 1, &FWPM_LAYER_ALE_AUTH_RECV_ACCEPT_V6, NULL, + &FWPM_CALLOUT_IPSEC_INBOUND_TUNNEL_ALE_ACCEPT_V6}, }; int i; @@ -604,7 +639,8 @@ static bool find_callout(bool tunnel, bool v6, bool inbound, bool forward, if (tunnel == map[i].tunnel && v6 == map[i].v6 && inbound == map[i].inbound && - forward == map[i].forward) + forward == map[i].forward && + ale == map[i].ale) { *callout = *map[i].callout; *layer = *map[i].layer; @@ -647,7 +683,7 @@ static bool install_sp(private_kernel_wfp_ipsec_t *this, sp_entry_t *sp, } v6 = sp->src->get_type(sp->src) == TS_IPV6_ADDR_RANGE; - if (!find_callout(context != NULL, v6, inbound, fwd, + if (!find_callout(context != NULL, v6, inbound, fwd, FALSE, &filter.layerKey, &filter.subLayerKey, &filter.action.calloutKey)) { @@ -688,8 +724,73 @@ static bool install_sp(private_kernel_wfp_ipsec_t *this, sp_entry_t *sp, free_conditions(conds, count); if (res != ERROR_SUCCESS) { - DBG1(DBG_KNL, "installing %s%sbound WFP filter failed: 0x%08x", - fwd ? "forward " : "", inbound ? "in" : "out", res); + DBG1(DBG_KNL, "installing IPv%d %s%sbound %s WFP filter failed: 0x%08x", + v6 ? 6 : 4, fwd ? "forward " : "", inbound ? "in" : "out", + context ? "tunnel" : "transport", res); + return FALSE; + } + return TRUE; +} + +/** + * Install an IP-IP allow filter for SA specific hosts + */ +static bool install_ipip_ale(private_kernel_wfp_ipsec_t *this, + host_t *local, host_t *remote, GUID *context, + bool inbound, int proto, u_int64_t *filter_id) +{ + traffic_selector_t *lts, *rts; + FWPM_FILTER_CONDITION0 *conds = NULL; + int count = 0; + bool v6; + DWORD res; + FWPM_FILTER0 filter = { + .displayData = { + .name = L"charon IPsec IP-in-IP ALE policy", + }, + .action = { + .type = FWP_ACTION_CALLOUT_TERMINATING, + }, + }; + + if (context) + { + filter.flags |= FWPM_FILTER_FLAG_HAS_PROVIDER_CONTEXT; + filter.providerKey = (GUID*)&this->provider.providerKey; + filter.providerContextKey = *context; + } + + v6 = local->get_family(local) == AF_INET6; + if (!find_callout(TRUE, v6, inbound, FALSE, TRUE, &filter.layerKey, + &filter.subLayerKey, &filter.action.calloutKey)) + { + return FALSE; + } + + lts = traffic_selector_create_from_subnet(local->clone(local), + v6 ? 128 : 32 , proto, 0, 65535); + rts = traffic_selector_create_from_subnet(remote->clone(remote), + v6 ? 128 : 32 , proto, 0, 65535); + if (!ts2condition(lts, &FWPM_CONDITION_IP_LOCAL_ADDRESS, &conds, &count) || + !ts2condition(rts, &FWPM_CONDITION_IP_REMOTE_ADDRESS, &conds, &count)) + { + free_conditions(conds, count); + lts->destroy(lts); + rts->destroy(rts); + return FALSE; + } + lts->destroy(lts); + rts->destroy(rts); + + filter.numFilterConditions = count; + filter.filterCondition = conds; + + res = FwpmFilterAdd0(this->handle, &filter, NULL, filter_id); + free_conditions(conds, count); + if (res != ERROR_SUCCESS) + { + DBG1(DBG_KNL, "installing IP-IPv%d %s ALE WFP filter failed: 0x%08x", + v6 ? 6 : 4, inbound ? "inbound" : "outbound", res); return FALSE; } return TRUE; @@ -703,10 +804,21 @@ static bool install_sps(private_kernel_wfp_ipsec_t *this, { enumerator_t *enumerator; sp_entry_t *sp; + bool has_v4 = FALSE, has_v6 = FALSE; enumerator = array_create_enumerator(entry->sps); while (enumerator->enumerate(enumerator, &sp)) { + switch (sp->src->get_type(sp->src)) + { + case TS_IPV4_ADDR_RANGE: + has_v4 = TRUE; + break; + case TS_IPV6_ADDR_RANGE: + has_v6 = TRUE; + break; + } + /* inbound policy */ if (!install_sp(this, sp, context, TRUE, FALSE, &sp->policy_in)) { @@ -719,21 +831,22 @@ static bool install_sps(private_kernel_wfp_ipsec_t *this, enumerator->destroy(enumerator); return FALSE; } + if (context) { if (!sp->src->is_host(sp->src, entry->local) || !sp->dst->is_host(sp->dst, entry->remote)) { /* inbound forward policy, from decapsulation */ - if (!install_sp(this, sp, context, - TRUE, TRUE, &sp->policy_fwd_in)) + if (!install_sp(this, sp, context, TRUE, TRUE, + &sp->policy_fwd_in)) { enumerator->destroy(enumerator); return FALSE; } /* outbound forward policy, to encapsulate */ - if (!install_sp(this, sp, context, - FALSE, TRUE, &sp->policy_fwd_out)) + if (!install_sp(this, sp, context, FALSE, TRUE, + &sp->policy_fwd_out)) { enumerator->destroy(enumerator); return FALSE; @@ -743,6 +856,38 @@ static bool install_sps(private_kernel_wfp_ipsec_t *this, } enumerator->destroy(enumerator); + if (context) + { + /* In tunnel mode, Windows does firewall filtering on decrypted but + * non-unwrapped packets: It sees them as IP-in-IP packets. When using + * a default-drop policy, we need to allow such packets explicitly. */ + if (has_v4) + { + if (!install_ipip_ale(this, entry->local, entry->remote, context, + TRUE, IPPROTO_IPIP, &entry->ip_ipv4_in)) + { + return FALSE; + } + if (!install_ipip_ale(this, entry->local, entry->remote, NULL, + FALSE, IPPROTO_IPIP, &entry->ip_ipv4_out)) + { + return FALSE; + } + } + if (has_v6) + { + if (!install_ipip_ale(this, entry->local, entry->remote, context, + TRUE, IPPROTO_IPV6, &entry->ip_ipv6_in)) + { + return FALSE; + } + if (!install_ipip_ale(this, entry->local, entry->remote, NULL, + FALSE, IPPROTO_IPV6, &entry->ip_ipv6_out)) + { + return FALSE; + } + } + } return TRUE; } @@ -1583,8 +1728,20 @@ static void WINAPI event_callback(void *user, const FWPM_NET_EVENT1 *event) acquire(this, event->classifyDrop->filterId, local, remote); break; case FWPM_NET_EVENT_TYPE_IKEEXT_MM_FAILURE: + DBG1(DBG_KNL, "WFP MM failure: %R === %R, 0x%08x, filterId %llu", + local, remote, event->ikeMmFailure->failureErrorCode, + event->ikeMmFailure->mmFilterId); + break; case FWPM_NET_EVENT_TYPE_IKEEXT_QM_FAILURE: + DBG1(DBG_KNL, "WFP QM failure: %R === %R, 0x%08x, filterId %llu", + local, remote, event->ikeQmFailure->failureErrorCode, + event->ikeQmFailure->qmFilterId); + break; case FWPM_NET_EVENT_TYPE_IKEEXT_EM_FAILURE: + DBG1(DBG_KNL, "WFP EM failure: %R === %R, 0x%08x, filterId %llu", + local, remote, event->ikeEmFailure->failureErrorCode, + event->ikeEmFailure->qmFilterId); + break; case FWPM_NET_EVENT_TYPE_IPSEC_KERNEL_DROP: DBG1(DBG_KNL, "IPsec kernel drop: %R === %R, error 0x%08x, " "SPI 0x%08x, %s filterId %llu", local, remote, @@ -1824,7 +1981,7 @@ static u_int permute(u_int x, u_int p) METHOD(kernel_ipsec_t, get_spi, status_t, private_kernel_wfp_ipsec_t *this, host_t *src, host_t *dst, - u_int8_t protocol, u_int32_t reqid, u_int32_t *spi) + u_int8_t protocol, u_int32_t *spi) { /* To avoid sequencial SPIs, we use a one-to-one permuation function on * an incrementing counter, that is a full period PRNG for the range we @@ -1841,7 +1998,7 @@ METHOD(kernel_ipsec_t, get_spi, status_t, METHOD(kernel_ipsec_t, get_cpi, status_t, private_kernel_wfp_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t reqid, u_int16_t *cpi) + u_int16_t *cpi) { return NOT_SUPPORTED; } @@ -1875,9 +2032,8 @@ static void expire_data_destroy(expire_data_t *data) static job_requeue_t expire_job(expire_data_t *data) { private_kernel_wfp_ipsec_t *this = data->this; - u_int32_t reqid = 0; u_int8_t protocol; - entry_t *entry; + entry_t *entry = NULL; sa_entry_t key = { .spi = data->spi, .dst = data->dst, @@ -1891,7 +2047,6 @@ static job_requeue_t expire_job(expire_data_t *data) if (entry) { protocol = entry->isa.protocol; - reqid = entry->reqid; if (entry->osa.dst) { key.dst = entry->osa.dst; @@ -1908,15 +2063,14 @@ static job_requeue_t expire_job(expire_data_t *data) if (entry) { protocol = entry->isa.protocol; - reqid = entry->reqid; } this->mutex->unlock(this->mutex); } - if (reqid) + if (entry) { - hydra->kernel_interface->expire(hydra->kernel_interface, - reqid, protocol, data->spi, data->hard); + hydra->kernel_interface->expire(hydra->kernel_interface, protocol, + data->spi, data->dst, data->hard); } return JOB_REQUEUE_NONE; @@ -1949,8 +2103,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t, u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key, u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window, - bool initiator, bool encap, bool esn, bool inbound, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts) + bool initiator, bool encap, bool esn, bool inbound, bool update, + linked_list_t *src_ts, linked_list_t *dst_ts) { host_t *local, *remote; entry_t *entry; diff --git a/src/libcharon/plugins/led/Makefile.in b/src/libcharon/plugins/led/Makefile.in index db4552dde..7942868f6 100644 --- a/src/libcharon/plugins/led/Makefile.in +++ b/src/libcharon/plugins/led/Makefile.in @@ -226,6 +226,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/load_tester/Makefile.in b/src/libcharon/plugins/load_tester/Makefile.in index 418dccba5..52dbec53f 100644 --- a/src/libcharon/plugins/load_tester/Makefile.in +++ b/src/libcharon/plugins/load_tester/Makefile.in @@ -239,6 +239,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -299,10 +300,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -376,6 +379,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/load_tester/load_tester_config.c b/src/libcharon/plugins/load_tester/load_tester_config.c index bc7c0ffbc..8a500635c 100644 --- a/src/libcharon/plugins/load_tester/load_tester_config.c +++ b/src/libcharon/plugins/load_tester/load_tester_config.c @@ -394,6 +394,28 @@ static void generate_auth_cfg(private_load_tester_config_t *this, char *str, } } } + else if (strpfx(str, "xauth")) + { /* XAuth, use a username */ + class = AUTH_CLASS_XAUTH; + if (*(str + strlen("xauth")) == '-') + { + auth->add(auth, AUTH_RULE_XAUTH_BACKEND, str + strlen("xauth-")); + } + if (!id) + { + if (local && num) + { + snprintf(buf, sizeof(buf), "cli-%.6d-%.2d", num, rnd); + id = identification_create_from_string(buf); + } + else + { + id = identification_create_from_encoding(ID_ANY, chunk_empty); + } + } + /* additionally set the ID as XAuth identity */ + auth->add(auth, AUTH_RULE_XAUTH_IDENTITY, id->clone(id)); + } else { if (!streq(str, "pubkey")) @@ -618,7 +640,7 @@ static host_t *allocate_addr(private_load_tester_config_t *this, uint num) enumerator = this->pools->create_enumerator(this->pools); while (enumerator->enumerate(enumerator, &pool)) { - found = pool->acquire_address(pool, id, requested, MEM_POOL_NEW); + found = pool->acquire_address(pool, id, requested, MEM_POOL_NEW, NULL); if (found) { iface = (char*)pool->get_name(pool); diff --git a/src/libcharon/plugins/load_tester/load_tester_diffie_hellman.c b/src/libcharon/plugins/load_tester/load_tester_diffie_hellman.c index d5ec3599b..e1c7c0e0b 100644 --- a/src/libcharon/plugins/load_tester/load_tester_diffie_hellman.c +++ b/src/libcharon/plugins/load_tester/load_tester_diffie_hellman.c @@ -15,33 +15,38 @@ #include "load_tester_diffie_hellman.h" -/** - * Implementation of gmp_diffie_hellman_t.get_my_public_value. - */ -static void get_my_public_value(load_tester_diffie_hellman_t *this, - chunk_t *value) +METHOD(diffie_hellman_t, get_my_public_value, bool, + load_tester_diffie_hellman_t *this, chunk_t *value) { *value = chunk_empty; + return TRUE; } -/** - * Implementation of gmp_diffie_hellman_t.get_shared_secret. - */ -static status_t get_shared_secret(load_tester_diffie_hellman_t *this, - chunk_t *secret) +METHOD(diffie_hellman_t, set_other_public_value, bool, + load_tester_diffie_hellman_t *this, chunk_t value) +{ + return TRUE; +} + +METHOD(diffie_hellman_t, get_shared_secret, bool, + load_tester_diffie_hellman_t *this, chunk_t *secret) { *secret = chunk_empty; - return SUCCESS; + return TRUE; } -/** - * Implementation of gmp_diffie_hellman_t.get_dh_group. - */ -static diffie_hellman_group_t get_dh_group(load_tester_diffie_hellman_t *this) +METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, + load_tester_diffie_hellman_t *this) { return MODP_NULL; } +METHOD(diffie_hellman_t, destroy, void, + load_tester_diffie_hellman_t *this) +{ + free(this); +} + /** * See header */ @@ -55,13 +60,15 @@ load_tester_diffie_hellman_t *load_tester_diffie_hellman_create( return NULL; } - this = malloc_thing(load_tester_diffie_hellman_t); - - this->dh.get_shared_secret = (status_t (*)(diffie_hellman_t *, chunk_t *))get_shared_secret; - this->dh.set_other_public_value = (void (*)(diffie_hellman_t *, chunk_t ))nop; - this->dh.get_my_public_value = (void (*)(diffie_hellman_t *, chunk_t *))get_my_public_value; - this->dh.get_dh_group = (diffie_hellman_group_t (*)(diffie_hellman_t *))get_dh_group; - this->dh.destroy = (void (*)(diffie_hellman_t *))free; + INIT(this, + .dh = { + .get_shared_secret = _get_shared_secret, + .set_other_public_value = _set_other_public_value, + .get_my_public_value = _get_my_public_value, + .get_dh_group = _get_dh_group, + .destroy = _destroy, + } + ); return this; } diff --git a/src/libcharon/plugins/load_tester/load_tester_ipsec.c b/src/libcharon/plugins/load_tester/load_tester_ipsec.c index 3f256ddd0..62d43e302 100644 --- a/src/libcharon/plugins/load_tester/load_tester_ipsec.c +++ b/src/libcharon/plugins/load_tester/load_tester_ipsec.c @@ -36,7 +36,7 @@ struct private_load_tester_ipsec_t { METHOD(kernel_ipsec_t, get_spi, status_t, private_load_tester_ipsec_t *this, host_t *src, host_t *dst, - u_int8_t protocol, u_int32_t reqid, u_int32_t *spi) + u_int8_t protocol, u_int32_t *spi) { *spi = (uint32_t)ref_get(&this->spi); return SUCCESS; @@ -44,7 +44,7 @@ METHOD(kernel_ipsec_t, get_spi, status_t, METHOD(kernel_ipsec_t, get_cpi, status_t, private_load_tester_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t reqid, u_int16_t *cpi) + u_int16_t *cpi) { return FAILED; } @@ -55,8 +55,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t, u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key, u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window, - bool initiator, bool encap, bool esn, bool inbound, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts) + bool initiator, bool encap, bool esn, bool inbound, bool update, + linked_list_t *src_ts, linked_list_t *dst_ts) { return SUCCESS; } diff --git a/src/libcharon/plugins/lookip/Makefile.in b/src/libcharon/plugins/lookip/Makefile.in index f0f2c75f4..264c58ff5 100644 --- a/src/libcharon/plugins/lookip/Makefile.in +++ b/src/libcharon/plugins/lookip/Makefile.in @@ -235,6 +235,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -295,10 +296,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -372,6 +375,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/maemo/Makefile.in b/src/libcharon/plugins/maemo/Makefile.in index 3a866e968..76c9012b2 100644 --- a/src/libcharon/plugins/maemo/Makefile.in +++ b/src/libcharon/plugins/maemo/Makefile.in @@ -231,6 +231,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/medcli/Makefile.in b/src/libcharon/plugins/medcli/Makefile.in index e0f70ce44..35740c369 100644 --- a/src/libcharon/plugins/medcli/Makefile.in +++ b/src/libcharon/plugins/medcli/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/medsrv/Makefile.in b/src/libcharon/plugins/medsrv/Makefile.in index adb61e817..8fe160ef3 100644 --- a/src/libcharon/plugins/medsrv/Makefile.in +++ b/src/libcharon/plugins/medsrv/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/osx_attr/Makefile.in b/src/libcharon/plugins/osx_attr/Makefile.in index a0c21c442..9a5e438e1 100644 --- a/src/libcharon/plugins/osx_attr/Makefile.in +++ b/src/libcharon/plugins/osx_attr/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/osx_attr/osx_attr_handler.c b/src/libcharon/plugins/osx_attr/osx_attr_handler.c index 9a3b2701d..d974b57ce 100644 --- a/src/libcharon/plugins/osx_attr/osx_attr_handler.c +++ b/src/libcharon/plugins/osx_attr/osx_attr_handler.c @@ -169,7 +169,7 @@ static bool manage_dns(int family, chunk_t data, bool add) } METHOD(attribute_handler_t, handle, bool, - private_osx_attr_handler_t *this, identification_t *id, + private_osx_attr_handler_t *this, ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data) { switch (type) @@ -182,7 +182,7 @@ METHOD(attribute_handler_t, handle, bool, } METHOD(attribute_handler_t, release, void, - private_osx_attr_handler_t *this, identification_t *server, + private_osx_attr_handler_t *this, ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data) { switch (type) @@ -206,7 +206,7 @@ METHOD(enumerator_t, enumerate_dns, bool, } METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *, - private_osx_attr_handler_t *this, identification_t *id, + private_osx_attr_handler_t *this, ike_sa_t *ike_sa, linked_list_t *vips) { enumerator_t *enumerator; diff --git a/src/libcharon/plugins/osx_attr/osx_attr_plugin.c b/src/libcharon/plugins/osx_attr/osx_attr_plugin.c index 380483c23..4be9eda5e 100644 --- a/src/libcharon/plugins/osx_attr/osx_attr_plugin.c +++ b/src/libcharon/plugins/osx_attr/osx_attr_plugin.c @@ -16,7 +16,6 @@ #include "osx_attr_plugin.h" #include "osx_attr_handler.h" -#include <hydra.h> #include <daemon.h> typedef struct private_osx_attr_plugin_t private_osx_attr_plugin_t; @@ -51,13 +50,13 @@ static bool plugin_cb(private_osx_attr_plugin_t *this, { if (reg) { - hydra->attributes->add_handler(hydra->attributes, - &this->handler->handler); + charon->attributes->add_handler(charon->attributes, + &this->handler->handler); } else { - hydra->attributes->remove_handler(hydra->attributes, - &this->handler->handler); + charon->attributes->remove_handler(charon->attributes, + &this->handler->handler); } return TRUE; } diff --git a/src/libcharon/plugins/radattr/Makefile.in b/src/libcharon/plugins/radattr/Makefile.in index 14abba99a..baff3fc76 100644 --- a/src/libcharon/plugins/radattr/Makefile.in +++ b/src/libcharon/plugins/radattr/Makefile.in @@ -230,6 +230,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -290,10 +291,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -367,6 +370,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libhydra/plugins/resolve/Makefile.am b/src/libcharon/plugins/resolve/Makefile.am index 33c3e70fc..9cfc370c0 100644 --- a/src/libhydra/plugins/resolve/Makefile.am +++ b/src/libcharon/plugins/resolve/Makefile.am @@ -1,6 +1,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon \ -DRESOLV_CONF=\"${resolv_conf}\" AM_CFLAGS = \ diff --git a/src/libhydra/plugins/resolve/Makefile.in b/src/libcharon/plugins/resolve/Makefile.in index 5b4c7bc6a..91479bf52 100644 --- a/src/libhydra/plugins/resolve/Makefile.in +++ b/src/libcharon/plugins/resolve/Makefile.in @@ -78,7 +78,7 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -subdir = src/libhydra/plugins/resolve +subdir = src/libcharon/plugins/resolve DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ @@ -427,6 +432,7 @@ xml_LIBS = @xml_LIBS@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon \ -DRESOLV_CONF=\"${resolv_conf}\" AM_CFLAGS = \ @@ -452,9 +458,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libhydra/plugins/resolve/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/resolve/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/libhydra/plugins/resolve/Makefile + $(AUTOMAKE) --gnu src/libcharon/plugins/resolve/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ diff --git a/src/libhydra/plugins/resolve/resolve_handler.c b/src/libcharon/plugins/resolve/resolve_handler.c index 069466ab5..74c3960ff 100644 --- a/src/libhydra/plugins/resolve/resolve_handler.c +++ b/src/libcharon/plugins/resolve/resolve_handler.c @@ -185,9 +185,10 @@ static bool invoke_resolvconf(private_resolve_handler_t *this, } METHOD(attribute_handler_t, handle, bool, - private_resolve_handler_t *this, identification_t *server, + private_resolve_handler_t *this, ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data) { + identification_t *server; host_t *addr; bool handled; @@ -208,6 +209,7 @@ METHOD(attribute_handler_t, handle, bool, DESTROY_IF(addr); return FALSE; } + server = ike_sa->get_other_id(ike_sa); this->mutex->lock(this->mutex); if (this->use_resolvconf) @@ -229,9 +231,10 @@ METHOD(attribute_handler_t, handle, bool, } METHOD(attribute_handler_t, release, void, - private_resolve_handler_t *this, identification_t *server, + private_resolve_handler_t *this, ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data) { + identification_t *server; host_t *addr; int family; @@ -247,6 +250,7 @@ METHOD(attribute_handler_t, release, void, return; } addr = host_create_from_chunk(family, data, 0); + server = ike_sa->get_other_id(ike_sa); this->mutex->lock(this->mutex); if (this->use_resolvconf) @@ -319,7 +323,7 @@ static bool has_host_family(linked_list_t *list, int family) } METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, - private_resolve_handler_t *this, identification_t *server, + private_resolve_handler_t *this, ike_sa_t *ike_sa, linked_list_t *vips) { attribute_enumerator_t *enumerator; @@ -374,4 +378,3 @@ resolve_handler_t *resolve_handler_create() return &this->public; } - diff --git a/src/libhydra/plugins/resolve/resolve_handler.h b/src/libcharon/plugins/resolve/resolve_handler.h index 77bf9781c..77bf9781c 100644 --- a/src/libhydra/plugins/resolve/resolve_handler.h +++ b/src/libcharon/plugins/resolve/resolve_handler.h diff --git a/src/libhydra/plugins/resolve/resolve_plugin.c b/src/libcharon/plugins/resolve/resolve_plugin.c index 2fef09a49..193c5b602 100644 --- a/src/libhydra/plugins/resolve/resolve_plugin.c +++ b/src/libcharon/plugins/resolve/resolve_plugin.c @@ -16,7 +16,7 @@ #include "resolve_plugin.h" #include "resolve_handler.h" -#include <hydra.h> +#include <daemon.h> typedef struct private_resolve_plugin_t private_resolve_plugin_t; @@ -50,13 +50,13 @@ static bool plugin_cb(private_resolve_plugin_t *this, { if (reg) { - hydra->attributes->add_handler(hydra->attributes, - &this->handler->handler); + charon->attributes->add_handler(charon->attributes, + &this->handler->handler); } else { - hydra->attributes->remove_handler(hydra->attributes, - &this->handler->handler); + charon->attributes->remove_handler(charon->attributes, + &this->handler->handler); } return TRUE; } @@ -99,4 +99,3 @@ plugin_t *resolve_plugin_create() return &this->public.plugin; } - diff --git a/src/libhydra/plugins/resolve/resolve_plugin.h b/src/libcharon/plugins/resolve/resolve_plugin.h index 0148b10d7..0148b10d7 100644 --- a/src/libhydra/plugins/resolve/resolve_plugin.h +++ b/src/libcharon/plugins/resolve/resolve_plugin.h diff --git a/src/libcharon/plugins/smp/Makefile.in b/src/libcharon/plugins/smp/Makefile.in index 7c5b030f4..572e7fc2f 100644 --- a/src/libcharon/plugins/smp/Makefile.in +++ b/src/libcharon/plugins/smp/Makefile.in @@ -227,6 +227,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/socket_default/Makefile.in b/src/libcharon/plugins/socket_default/Makefile.in index 548524a38..25b40995b 100644 --- a/src/libcharon/plugins/socket_default/Makefile.in +++ b/src/libcharon/plugins/socket_default/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/socket_default/socket_default_socket.c b/src/libcharon/plugins/socket_default/socket_default_socket.c index 9cc39955b..dbfddbb81 100644 --- a/src/libcharon/plugins/socket_default/socket_default_socket.c +++ b/src/libcharon/plugins/socket_default/socket_default_socket.c @@ -141,6 +141,11 @@ struct private_socket_default_socket_t { * TRUE if the source address should be set on outbound packets */ bool set_source; + + /** + * A counter to implement round-robin selection of read sockets + */ + u_int rr_counter; }; METHOD(socket_t, receiver, status_t, @@ -150,66 +155,43 @@ METHOD(socket_t, receiver, status_t, chunk_t data; packet_t *pkt; host_t *source = NULL, *dest = NULL; - int bytes_read = 0; + int i, rr, index, bytes_read = 0, selected = -1; bool oldstate; - - fd_set rfds; - int max_fd = 0, selected = 0; u_int16_t port = 0; - - FD_ZERO(&rfds); - - if (this->ipv4 != -1) - { - FD_SET(this->ipv4, &rfds); - max_fd = max(max_fd, this->ipv4); - } - if (this->ipv4_natt != -1) - { - FD_SET(this->ipv4_natt, &rfds); - max_fd = max(max_fd, this->ipv4_natt); - } - if (this->ipv6 != -1) - { - FD_SET(this->ipv6, &rfds); - max_fd = max(max_fd, this->ipv6); - } - if (this->ipv6_natt != -1) - { - FD_SET(this->ipv6_natt, &rfds); - max_fd = max(max_fd, this->ipv6_natt); - } + struct pollfd pfd[] = { + { .fd = this->ipv4, .events = POLLIN }, + { .fd = this->ipv4_natt, .events = POLLIN }, + { .fd = this->ipv6, .events = POLLIN }, + { .fd = this->ipv6_natt, .events = POLLIN }, + }; + int ports[] = { + /* port numbers associated to pollfds */ + this->port, this->natt, this->port, this->natt, + }; DBG2(DBG_NET, "waiting for data on sockets"); oldstate = thread_cancelability(TRUE); - if (select(max_fd + 1, &rfds, NULL, NULL, NULL) <= 0) + if (poll(pfd, countof(pfd), -1) <= 0) { thread_cancelability(oldstate); return FAILED; } thread_cancelability(oldstate); - if (this->ipv4 != -1 && FD_ISSET(this->ipv4, &rfds)) + rr = this->rr_counter++; + for (i = 0; i < countof(pfd); i++) { - port = this->port; - selected = this->ipv4; - } - if (this->ipv4_natt != -1 && FD_ISSET(this->ipv4_natt, &rfds)) - { - port = this->natt; - selected = this->ipv4_natt; - } - if (this->ipv6 != -1 && FD_ISSET(this->ipv6, &rfds)) - { - port = this->port; - selected = this->ipv6; - } - if (this->ipv6_natt != -1 && FD_ISSET(this->ipv6_natt, &rfds)) - { - port = this->natt; - selected = this->ipv6_natt; + /* To serve all ports with equal priority, we use a round-robin + * scheme to choose the one to process in this invocation */ + index = (rr + i) % countof(pfd); + if (pfd[index].revents & POLLIN) + { + selected = pfd[index].fd; + port = ports[index]; + break; + } } - if (selected) + if (selected != -1) { struct msghdr msg; struct cmsghdr *cmsgptr; diff --git a/src/libcharon/plugins/socket_dynamic/Makefile.in b/src/libcharon/plugins/socket_dynamic/Makefile.in index 892549c6c..5c010a59a 100644 --- a/src/libcharon/plugins/socket_dynamic/Makefile.in +++ b/src/libcharon/plugins/socket_dynamic/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/socket_win/Makefile.in b/src/libcharon/plugins/socket_win/Makefile.in index 88b2ac3f0..0c3bf31b9 100644 --- a/src/libcharon/plugins/socket_win/Makefile.in +++ b/src/libcharon/plugins/socket_win/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/sql/Makefile.in b/src/libcharon/plugins/sql/Makefile.in index 3c132457b..f74257af2 100644 --- a/src/libcharon/plugins/sql/Makefile.in +++ b/src/libcharon/plugins/sql/Makefile.in @@ -227,6 +227,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/stroke/Makefile.in b/src/libcharon/plugins/stroke/Makefile.in index d4680186a..a316f5c25 100644 --- a/src/libcharon/plugins/stroke/Makefile.in +++ b/src/libcharon/plugins/stroke/Makefile.in @@ -231,6 +231,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/stroke/stroke_attribute.c b/src/libcharon/plugins/stroke/stroke_attribute.c index 0f3c38986..cd1b4d093 100644 --- a/src/libcharon/plugins/stroke/stroke_attribute.c +++ b/src/libcharon/plugins/stroke/stroke_attribute.c @@ -94,7 +94,7 @@ static mem_pool_t *find_pool(private_stroke_attribute_t *this, char *name) */ static host_t *find_addr(private_stroke_attribute_t *this, linked_list_t *pools, identification_t *id, host_t *requested, - mem_pool_op_t operation) + mem_pool_op_t operation, host_t *peer) { host_t *addr = NULL; enumerator_t *enumerator; @@ -107,7 +107,7 @@ static host_t *find_addr(private_stroke_attribute_t *this, linked_list_t *pools, pool = find_pool(this, name); if (pool) { - addr = pool->acquire_address(pool, id, requested, operation); + addr = pool->acquire_address(pool, id, requested, operation, peer); if (addr) { break; @@ -120,20 +120,24 @@ static host_t *find_addr(private_stroke_attribute_t *this, linked_list_t *pools, } METHOD(attribute_provider_t, acquire_address, host_t*, - private_stroke_attribute_t *this, linked_list_t *pools, identification_t *id, + private_stroke_attribute_t *this, linked_list_t *pools, ike_sa_t *ike_sa, host_t *requested) { - host_t *addr; + identification_t *id; + host_t *addr, *peer; + + id = ike_sa->get_other_eap_id(ike_sa); + peer = ike_sa->get_other_host(ike_sa); this->lock->read_lock(this->lock); - addr = find_addr(this, pools, id, requested, MEM_POOL_EXISTING); + addr = find_addr(this, pools, id, requested, MEM_POOL_EXISTING, peer); if (!addr) { - addr = find_addr(this, pools, id, requested, MEM_POOL_NEW); + addr = find_addr(this, pools, id, requested, MEM_POOL_NEW, peer); if (!addr) { - addr = find_addr(this, pools, id, requested, MEM_POOL_REASSIGN); + addr = find_addr(this, pools, id, requested, MEM_POOL_REASSIGN, peer); } } @@ -144,13 +148,16 @@ METHOD(attribute_provider_t, acquire_address, host_t*, METHOD(attribute_provider_t, release_address, bool, private_stroke_attribute_t *this, linked_list_t *pools, host_t *address, - identification_t *id) + ike_sa_t *ike_sa) { enumerator_t *enumerator; + identification_t *id; mem_pool_t *pool; bool found = FALSE; char *name; + id = ike_sa->get_other_eap_id(ike_sa); + enumerator = pools->create_enumerator(pools); this->lock->read_lock(this->lock); while (enumerator->enumerate(enumerator, &name)) @@ -197,9 +204,8 @@ static bool attr_filter(void *lock, host_t **in, METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, private_stroke_attribute_t *this, linked_list_t *pools, - identification_t *id, linked_list_t *vips) + ike_sa_t *ike_sa, linked_list_t *vips) { - ike_sa_t *ike_sa; peer_cfg_t *peer_cfg; enumerator_t *enumerator; attributes_t *attr; @@ -413,4 +419,3 @@ stroke_attribute_t *stroke_attribute_create() return &this->public; } - diff --git a/src/libcharon/plugins/stroke/stroke_ca.c b/src/libcharon/plugins/stroke/stroke_ca.c index f8026875f..b470b81c6 100644 --- a/src/libcharon/plugins/stroke/stroke_ca.c +++ b/src/libcharon/plugins/stroke/stroke_ca.c @@ -120,6 +120,84 @@ static void ca_section_destroy(ca_section_t *this) } /** + * Data for the certificate enumerator + */ +typedef struct { + private_stroke_ca_t *this; + certificate_type_t cert; + key_type_t key; + identification_t *id; +} cert_data_t; + +/** + * destroy cert_data + */ +static void cert_data_destroy(cert_data_t *data) +{ + data->this->lock->unlock(data->this->lock); + free(data); +} + +/** + * filter function for certs enumerator + */ +static bool certs_filter(cert_data_t *data, ca_section_t **in, + certificate_t **out) +{ + public_key_t *public; + certificate_t *cert = (*in)->cert; + + if (data->cert == CERT_ANY || data->cert == cert->get_type(cert)) + { + public = cert->get_public_key(cert); + if (public) + { + if (data->key == KEY_ANY || data->key == public->get_type(public)) + { + if (data->id && public->has_fingerprint(public, + data->id->get_encoding(data->id))) + { + public->destroy(public); + *out = cert; + return TRUE; + } + } + public->destroy(public); + } + else if (data->key != KEY_ANY) + { + return FALSE; + } + if (data->id == NULL || cert->has_subject(cert, data->id)) + { + *out = cert; + return TRUE; + } + } + return FALSE; +} + +METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, + private_stroke_ca_t *this, certificate_type_t cert, key_type_t key, + identification_t *id, bool trusted) +{ + enumerator_t *enumerator; + cert_data_t *data; + + INIT(data, + .this = this, + .cert = cert, + .key = key, + .id = id, + ); + + this->lock->read_lock(this->lock); + enumerator = this->sections->create_enumerator(this->sections); + return enumerator_create_filter(enumerator, (void*)certs_filter, data, + (void*)cert_data_destroy); +} + +/** * data to pass to create_inner_cdp */ typedef struct { @@ -438,7 +516,7 @@ stroke_ca_t *stroke_ca_create(stroke_cred_t *cred) .public = { .set = { .create_private_enumerator = (void*)return_null, - .create_cert_enumerator = (void*)return_null, + .create_cert_enumerator = _create_cert_enumerator, .create_shared_enumerator = (void*)return_null, .create_cdp_enumerator = _create_cdp_enumerator, .cache_cert = (void*)nop, @@ -456,4 +534,3 @@ stroke_ca_t *stroke_ca_create(stroke_cred_t *cred) return &this->public; } - diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c index 62967b006..55ec7cdc9 100644 --- a/src/libcharon/plugins/stroke/stroke_config.c +++ b/src/libcharon/plugins/stroke/stroke_config.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2012-2014 Tobias Brunner * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -301,7 +301,8 @@ static void build_crl_policy(auth_cfg_t *cfg, bool local, int policy) static void parse_pubkey_constraints(char *auth, auth_cfg_t *cfg) { enumerator_t *enumerator; - bool rsa = FALSE, ecdsa = FALSE, rsa_len = FALSE, ecdsa_len = FALSE; + bool rsa = FALSE, ecdsa = FALSE, bliss = FALSE, + rsa_len = FALSE, ecdsa_len = FALSE, bliss_strength = FALSE; int strength; char *token; @@ -328,9 +329,12 @@ static void parse_pubkey_constraints(char *auth, auth_cfg_t *cfg) { "sha256", SIGN_ECDSA_256, KEY_ECDSA, }, { "sha384", SIGN_ECDSA_384, KEY_ECDSA, }, { "sha512", SIGN_ECDSA_521, KEY_ECDSA, }, + { "sha256", SIGN_BLISS_WITH_SHA256, KEY_BLISS, }, + { "sha384", SIGN_BLISS_WITH_SHA384, KEY_BLISS, }, + { "sha512", SIGN_BLISS_WITH_SHA512, KEY_BLISS, }, }; - if (rsa_len || ecdsa_len) + if (rsa_len || ecdsa_len || bliss_strength) { /* expecting a key strength token */ strength = atoi(token); if (strength) @@ -343,8 +347,12 @@ static void parse_pubkey_constraints(char *auth, auth_cfg_t *cfg) { cfg->add(cfg, AUTH_RULE_ECDSA_STRENGTH, (uintptr_t)strength); } + else if (bliss_strength) + { + cfg->add(cfg, AUTH_RULE_BLISS_STRENGTH, (uintptr_t)strength); + } } - rsa_len = ecdsa_len = FALSE; + rsa_len = ecdsa_len = bliss_strength = FALSE; if (strength) { continue; @@ -360,6 +368,11 @@ static void parse_pubkey_constraints(char *auth, auth_cfg_t *cfg) ecdsa = ecdsa_len = TRUE; continue; } + if (streq(token, "bliss")) + { + bliss = bliss_strength = TRUE; + continue; + } if (streq(token, "pubkey")) { continue; @@ -376,7 +389,8 @@ static void parse_pubkey_constraints(char *auth, auth_cfg_t *cfg) */ if ((rsa && schemes[i].key == KEY_RSA) || (ecdsa && schemes[i].key == KEY_ECDSA) || - (!rsa && !ecdsa)) + (bliss && schemes[i].key == KEY_BLISS) || + (!rsa && !ecdsa && !bliss)) { cfg->add(cfg, AUTH_RULE_SIGNATURE_SCHEME, (uintptr_t)schemes[i].scheme); @@ -590,7 +604,8 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this, /* authentication metod (class, actually) */ if (strpfx(auth, "pubkey") || strpfx(auth, "rsa") || - strpfx(auth, "ecdsa")) + strpfx(auth, "ecdsa") || + strpfx(auth, "bliss")) { cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY); build_crl_policy(cfg, local, msg->add_conn.crl_policy); @@ -620,9 +635,16 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this, else if (strpfx(auth, "eap")) { eap_vendor_type_t *type; + char *pos; cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP); - + /* check for public key constraints for EAP-TLS etc. */ + pos = strchr(auth, ':'); + if (pos) + { + *pos = 0; + parse_pubkey_constraints(pos + 1, cfg); + } type = eap_vendor_type_from_string(auth); if (type) { @@ -667,6 +689,24 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this, } /** + * build a mem_pool_t from an address range + */ +static mem_pool_t *create_pool_range(char *str) +{ + mem_pool_t *pool; + host_t *from, *to; + + if (!host_create_from_range(str, &from, &to)) + { + return NULL; + } + pool = mem_pool_create_range(str, from, to); + from->destroy(from); + to->destroy(to); + return pool; +} + +/** * build a peer_cfg from a stroke msg */ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this, @@ -789,17 +829,25 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this, } else { - /* in-memory pool, named using CIDR notation */ + /* in-memory pool, using range or CIDR notation */ + mem_pool_t *pool; host_t *base; int bits; - base = host_create_from_subnet(token, &bits); - if (base) + pool = create_pool_range(token); + if (!pool) + { + base = host_create_from_subnet(token, &bits); + if (base) + { + pool = mem_pool_create(token, base, bits); + base->destroy(base); + } + } + if (pool) { - this->attributes->add_pool(this->attributes, - mem_pool_create(token, base, bits)); + this->attributes->add_pool(this->attributes, pool); peer_cfg->add_pool(peer_cfg, token); - base->destroy(base); } else { diff --git a/src/libcharon/plugins/stroke/stroke_control.c b/src/libcharon/plugins/stroke/stroke_control.c index f770d7c9e..0084fbf93 100644 --- a/src/libcharon/plugins/stroke/stroke_control.c +++ b/src/libcharon/plugins/stroke/stroke_control.c @@ -352,7 +352,7 @@ METHOD(stroke_control_t, terminate, void, if (streq(name, child_sa->get_name(child_sa))) { child_list->insert_last(child_list, - (void*)(uintptr_t)child_sa->get_reqid(child_sa)); + (void*)(uintptr_t)child_sa->get_unique_id(child_sa)); if (!all) { break; @@ -432,13 +432,13 @@ METHOD(stroke_control_t, rekey, void, while (children->enumerate(children, (void**)&child_sa)) { if ((name && streq(name, child_sa->get_name(child_sa))) || - (id && id == child_sa->get_reqid(child_sa))) + (id && id == child_sa->get_unique_id(child_sa))) { lib->processor->queue_job(lib->processor, (job_t*)rekey_child_sa_job_create( - child_sa->get_reqid(child_sa), child_sa->get_protocol(child_sa), - child_sa->get_spi(child_sa, TRUE))); + child_sa->get_spi(child_sa, TRUE), + ike_sa->get_my_host(ike_sa))); if (!all) { finished = TRUE; diff --git a/src/libcharon/plugins/stroke/stroke_cred.c b/src/libcharon/plugins/stroke/stroke_cred.c index 83431d17c..5e423f1de 100644 --- a/src/libcharon/plugins/stroke/stroke_cred.c +++ b/src/libcharon/plugins/stroke/stroke_cred.c @@ -70,11 +70,21 @@ struct private_stroke_cred_t { char *secrets_file; /** - * credentials + * credentials: end entity certs, attribute certs, CRLs, etc. */ mem_cred_t *creds; /** + * CA certificates + */ + mem_cred_t *cacerts; + + /** + * Attribute Authority certificates + */ + mem_cred_t *aacerts; + + /** * ignore missing CA basic constraint (i.e. treat all certificates in * ipsec.conf ca sections and ipsec.d/cacerts as CA certificates) */ @@ -231,7 +241,7 @@ METHOD(stroke_cred_t, load_ca, certificate_t*, } DBG1(DBG_CFG, " loaded ca certificate \"%Y\" from '%s'", cert->get_subject(cert), filename); - return this->creds->add_cert_ref(this->creds, TRUE, cert); + return this->creds->get_cert_ref(this->creds, cert); } return NULL; } @@ -374,133 +384,183 @@ METHOD(stroke_cred_t, load_pubkey, certificate_t*, } /** - * load trusted certificates from a directory + * Load a CA certificate from disk */ -static void load_certdir(private_stroke_cred_t *this, char *path, - certificate_type_t type, x509_flag_t flag) +static void load_x509_ca(private_stroke_cred_t *this, char *file) { - struct stat st; - char *file; - - enumerator_t *enumerator = enumerator_create_directory(path); + certificate_t *cert; - if (!enumerator) + if (this->force_ca_cert) + { /* treat certificate as CA cert even it has no CA basic constraint */ + cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, + BUILD_FROM_FILE, file, + BUILD_X509_FLAG, X509_CA, BUILD_END); + } + else { - DBG1(DBG_CFG, " reading directory failed"); - return; + cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, + BUILD_FROM_FILE, file, BUILD_END); } - - while (enumerator->enumerate(enumerator, NULL, &file, &st)) + if (cert) { - certificate_t *cert; + x509_t *x509 = (x509_t*)cert; - if (!S_ISREG(st.st_mode)) + if (!(x509->get_flags(x509) & X509_CA)) { - /* skip special file */ - continue; + DBG1(DBG_CFG, " ca certificate \"%Y\" lacks ca basic constraint, " + "discarded", cert->get_subject(cert)); + cert->destroy(cert); } - switch (type) + else { - case CERT_X509: - if (flag & X509_CA) - { - if (this->force_ca_cert) - { /* treat this certificate as CA cert even it has no - * CA basic constraint */ - cert = lib->creds->create(lib->creds, - CRED_CERTIFICATE, CERT_X509, - BUILD_FROM_FILE, file, BUILD_X509_FLAG, - X509_CA, BUILD_END); - } - else - { - cert = lib->creds->create(lib->creds, - CRED_CERTIFICATE, CERT_X509, - BUILD_FROM_FILE, file, BUILD_END); - } - if (cert) - { - x509_t *x509 = (x509_t*)cert; - - if (!(x509->get_flags(x509) & X509_CA)) - { - DBG1(DBG_CFG, " ca certificate \"%Y\" lacks " - "ca basic constraint, discarded", - cert->get_subject(cert)); - cert->destroy(cert); - cert = NULL; - } - else - { - DBG1(DBG_CFG, " loaded ca certificate \"%Y\" " - "from '%s'", cert->get_subject(cert), file); - } - } - else + DBG1(DBG_CFG, " loaded ca certificate \"%Y\" from '%s'", + cert->get_subject(cert), file); + this->cacerts->add_cert(this->cacerts, TRUE, cert); + } + } + else + { + DBG1(DBG_CFG, " loading ca certificate from '%s' failed", file); + } +} + +/** + * Load AA certificate with flags from disk + */ +static void load_x509_aa(private_stroke_cred_t *this, char *file) +{ + certificate_t *cert; + + cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, + BUILD_FROM_FILE, file, + BUILD_X509_FLAG, X509_AA, BUILD_END); + if (cert) + { + DBG1(DBG_CFG, " loaded AA certificate \"%Y\" from '%s'", + cert->get_subject(cert), file); + this->aacerts->add_cert(this->aacerts, TRUE, cert); + } + else + { + DBG1(DBG_CFG, " loading AA certificate from '%s' failed", file); + } +} + +/** + * Load a certificate with flags from disk + */ +static void load_x509(private_stroke_cred_t *this, char *file, x509_flag_t flag) +{ + certificate_t *cert; + + /* for all other flags, we add them to the certificate. */ + cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, + BUILD_FROM_FILE, file, + BUILD_X509_FLAG, flag, BUILD_END); + if (cert) + { + DBG1(DBG_CFG, " loaded certificate \"%Y\" from '%s'", + cert->get_subject(cert), file); + this->creds->add_cert(this->creds, TRUE, cert); + } + else + { + DBG1(DBG_CFG, " loading certificate from '%s' failed", file); + } +} + +/** + * Load a CRL from a file + */ +static void load_x509_crl(private_stroke_cred_t *this, char *file) +{ + certificate_t *cert; + + cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL, + BUILD_FROM_FILE, file, BUILD_END); + if (cert) + { + this->creds->add_crl(this->creds, (crl_t*)cert); + DBG1(DBG_CFG, " loaded crl from '%s'", file); + } + else + { + DBG1(DBG_CFG, " loading crl from '%s' failed", file); + } +} + +/** + * Load an attribute certificate from a file + */ +static void load_x509_ac(private_stroke_cred_t *this, char *file) +{ + certificate_t *cert; + + cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_AC, + BUILD_FROM_FILE, file, BUILD_END); + if (cert) + { + DBG1(DBG_CFG, " loaded attribute certificate from '%s'", file); + this->creds->add_cert(this->creds, FALSE, cert); + } + else + { + DBG1(DBG_CFG, " loading attribute certificate from '%s' failed", file); + } +} + +/** + * load trusted certificates from a directory + */ +static void load_certdir(private_stroke_cred_t *this, char *path, + certificate_type_t type, x509_flag_t flag) +{ + enumerator_t *enumerator; + struct stat st; + char *file; + + enumerator = enumerator_create_directory(path); + if (enumerator) + { + while (enumerator->enumerate(enumerator, NULL, &file, &st)) + { + if (!S_ISREG(st.st_mode)) + { + /* skip special file */ + continue; + } + switch (type) + { + case CERT_X509: + if (flag & X509_CA) { - DBG1(DBG_CFG, " loading ca certificate from '%s' " - "failed", file); + load_x509_ca(this, file); } - } - else - { /* for all other flags, we add them to the certificate. */ - cert = lib->creds->create(lib->creds, - CRED_CERTIFICATE, CERT_X509, - BUILD_FROM_FILE, file, - BUILD_X509_FLAG, flag, BUILD_END); - if (cert) + else if (flag & X509_AA) { - DBG1(DBG_CFG, " loaded certificate \"%Y\" from '%s'", - cert->get_subject(cert), file); + load_x509_aa(this, file); } else { - DBG1(DBG_CFG, " loading certificate from '%s' " - "failed", file); + load_x509(this, file, flag); } - } - if (cert) - { - this->creds->add_cert(this->creds, TRUE, cert); - } - break; - case CERT_X509_CRL: - cert = lib->creds->create(lib->creds, - CRED_CERTIFICATE, CERT_X509_CRL, - BUILD_FROM_FILE, file, - BUILD_END); - if (cert) - { - this->creds->add_crl(this->creds, (crl_t*)cert); - DBG1(DBG_CFG, " loaded crl from '%s'", file); - } - else - { - DBG1(DBG_CFG, " loading crl from '%s' failed", file); - } - break; - case CERT_X509_AC: - cert = lib->creds->create(lib->creds, - CRED_CERTIFICATE, CERT_X509_AC, - BUILD_FROM_FILE, file, - BUILD_END); - if (cert) - { - this->creds->add_cert(this->creds, FALSE, cert); - DBG1(DBG_CFG, " loaded attribute certificate from '%s'", - file); - } - else - { - DBG1(DBG_CFG, " loading attribute certificate from '%s' " - "failed", file); - } - break; - default: - break; + break; + case CERT_X509_CRL: + load_x509_crl(this, file); + break; + case CERT_X509_AC: + load_x509_ac(this, file); + break; + default: + break; + } } + enumerator->destroy(enumerator); + } + else + { + DBG1(DBG_CFG, " reading directory failed"); } - enumerator->destroy(enumerator); } METHOD(stroke_cred_t, cache_cert, void, @@ -1124,6 +1184,7 @@ static void load_secrets(private_stroke_cred_t *this, mem_cred_t *secrets, while (fetchline(src, &line)) { chunk_t ids, token; + key_type_t key_type; shared_key_type_t type; line_nr++; @@ -1222,10 +1283,22 @@ static void load_secrets(private_stroke_cred_t *this, mem_cred_t *secrets, DBG1(DBG_CFG, "line %d: missing token", line_nr); break; } - if (match("RSA", &token) || match("ECDSA", &token)) + if (match("RSA", &token) || match("ECDSA", &token) || + match("BLISS", &token)) { - if (!load_private(secrets, line, line_nr, prompt, - match("RSA", &token) ? KEY_RSA : KEY_ECDSA)) + if (match("RSA", &token)) + { + key_type = KEY_RSA; + } + else if (match("ECDSA", &token)) + { + key_type = KEY_ECDSA; + } + else + { + key_type = KEY_BLISS; + } + if (!load_private(secrets, line, line_nr, prompt, key_type)) { break; } @@ -1256,8 +1329,8 @@ static void load_secrets(private_stroke_cred_t *this, mem_cred_t *secrets, } else { - DBG1(DBG_CFG, "line %d: token must be either " - "RSA, ECDSA, P12, PIN, PSK, EAP, XAUTH or NTLM", line_nr); + DBG1(DBG_CFG, "line %d: token must be either RSA, ECDSA, BLISS, " + "P12, PIN, PSK, EAP, XAUTH or NTLM", line_nr); break; } } @@ -1308,6 +1381,8 @@ METHOD(stroke_cred_t, reread, void, { DBG1(DBG_CFG, "rereading ca certificates from '%s'", CA_CERTIFICATE_DIR); + this->cacerts->clear(this->cacerts); + lib->credmgr->flush_cache(lib->credmgr, CERT_X509); load_certdir(this, CA_CERTIFICATE_DIR, CERT_X509, X509_CA); } if (msg->reread.flags & REREAD_OCSPCERTS) @@ -1321,6 +1396,8 @@ METHOD(stroke_cred_t, reread, void, { DBG1(DBG_CFG, "rereading aa certificates from '%s'", AA_CERTIFICATE_DIR); + this->aacerts->clear(this->aacerts); + lib->credmgr->flush_cache(lib->credmgr, CERT_X509); load_certdir(this, AA_CERTIFICATE_DIR, CERT_X509, X509_AA); } if (msg->reread.flags & REREAD_ACERTS) @@ -1346,7 +1423,11 @@ METHOD(stroke_cred_t, add_shared, void, METHOD(stroke_cred_t, destroy, void, private_stroke_cred_t *this) { + lib->credmgr->remove_set(lib->credmgr, &this->aacerts->set); + lib->credmgr->remove_set(lib->credmgr, &this->cacerts->set); lib->credmgr->remove_set(lib->credmgr, &this->creds->set); + this->aacerts->destroy(this->aacerts); + this->cacerts->destroy(this->cacerts); this->creds->destroy(this->creds); free(this); } @@ -1379,9 +1460,13 @@ stroke_cred_t *stroke_cred_create() "%s.plugins.stroke.secrets_file", SECRETS_FILE, lib->ns), .creds = mem_cred_create(), + .cacerts = mem_cred_create(), + .aacerts = mem_cred_create(), ); lib->credmgr->add_set(lib->credmgr, &this->creds->set); + lib->credmgr->add_set(lib->credmgr, &this->cacerts->set); + lib->credmgr->add_set(lib->credmgr, &this->aacerts->set); this->force_ca_cert = lib->settings->get_bool(lib->settings, "%s.plugins.stroke.ignore_missing_ca_basic_constraint", diff --git a/src/libcharon/plugins/stroke/stroke_cred.h b/src/libcharon/plugins/stroke/stroke_cred.h index f6fbb96d3..9434629ef 100644 --- a/src/libcharon/plugins/stroke/stroke_cred.h +++ b/src/libcharon/plugins/stroke/stroke_cred.h @@ -50,10 +50,13 @@ struct stroke_cred_t { void (*reread)(stroke_cred_t *this, stroke_msg_t *msg, FILE *prompt); /** - * Load a CA certificate, and serve it through the credential_set. + * Load a CA certificate. + * + * This method does not add the loaded CA certificate to the internal + * credentail set, but returns it only. * * @param filename file to load CA cert from - * @return reference to loaded certificate, or NULL + * @return loaded certificate, or NULL */ certificate_t* (*load_ca)(stroke_cred_t *this, char *filename); diff --git a/src/libcharon/plugins/stroke/stroke_handler.c b/src/libcharon/plugins/stroke/stroke_handler.c index fef8cab67..d0cc9afab 100644 --- a/src/libcharon/plugins/stroke/stroke_handler.c +++ b/src/libcharon/plugins/stroke/stroke_handler.c @@ -94,10 +94,9 @@ static bool attr_filter(void *lock, host_t **in, } METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, - private_stroke_handler_t *this, identification_t *server, + private_stroke_handler_t *this, ike_sa_t *ike_sa, linked_list_t *vips) { - ike_sa_t *ike_sa; peer_cfg_t *peer_cfg; enumerator_t *enumerator; attributes_t *attr; diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c index 1aa49ce0d..68b8232bc 100644 --- a/src/libcharon/plugins/stroke/stroke_list.c +++ b/src/libcharon/plugins/stroke/stroke_list.c @@ -214,11 +214,12 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) config = child_sa->get_config(child_sa); now = time_monotonic(NULL); - fprintf(out, "%12s{%d}: %N, %N%s", - child_sa->get_name(child_sa), child_sa->get_reqid(child_sa), + fprintf(out, "%12s{%d}: %N, %N%s, reqid %u", + child_sa->get_name(child_sa), child_sa->get_unique_id(child_sa), child_sa_state_names, child_sa->get_state(child_sa), ipsec_mode_names, child_sa->get_mode(child_sa), - config->use_proxy_mode(config) ? "_PROXY" : ""); + config->use_proxy_mode(config) ? "_PROXY" : "", + child_sa->get_reqid(child_sa)); if (child_sa->get_state(child_sa) == CHILD_INSTALLED) { @@ -238,7 +239,7 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) if (all) { fprintf(out, "\n%12s{%d}: ", child_sa->get_name(child_sa), - child_sa->get_reqid(child_sa)); + child_sa->get_unique_id(child_sa)); proposal = child_sa->get_proposal(child_sa); if (proposal) @@ -322,7 +323,8 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) } } - else if (child_sa->get_state(child_sa) == CHILD_REKEYING) + else if (child_sa->get_state(child_sa) == CHILD_REKEYING || + child_sa->get_state(child_sa) == CHILD_REKEYED) { rekey = child_sa->get_lifetime(child_sa, TRUE); fprintf(out, ", expires in %V", &now, &rekey); @@ -333,7 +335,7 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) other_ts = linked_list_create_from_enumerator( child_sa->create_ts_enumerator(child_sa, FALSE)); fprintf(out, "\n%12s{%d}: %#R=== %#R\n", - child_sa->get_name(child_sa), child_sa->get_reqid(child_sa), + child_sa->get_name(child_sa), child_sa->get_unique_id(child_sa), my_ts, other_ts); my_ts->destroy(my_ts); other_ts->destroy(other_ts); @@ -496,7 +498,7 @@ METHOD(stroke_list_t, status, void, { struct mallinfo mi = mallinfo(); - fprintf(out, " malloc: sbrk %d, mmap %d, used %d, free %d\n", + fprintf(out, " malloc: sbrk %u, mmap %u, used %u, free %u\n", mi.arena, mi.hblkhd, mi.uordblks, mi.fordblks); } #endif /* HAVE_MALLINFO */ diff --git a/src/libcharon/plugins/stroke/stroke_plugin.c b/src/libcharon/plugins/stroke/stroke_plugin.c index 31df1f99b..f64b99f08 100644 --- a/src/libcharon/plugins/stroke/stroke_plugin.c +++ b/src/libcharon/plugins/stroke/stroke_plugin.c @@ -69,6 +69,7 @@ METHOD(plugin_t, get_features, int, PLUGIN_SDEPEND(PRIVKEY, KEY_RSA), PLUGIN_SDEPEND(PRIVKEY, KEY_ECDSA), PLUGIN_SDEPEND(PRIVKEY, KEY_DSA), + PLUGIN_SDEPEND(PRIVKEY, KEY_BLISS), PLUGIN_SDEPEND(CERT_DECODE, CERT_ANY), PLUGIN_SDEPEND(CERT_DECODE, CERT_X509), PLUGIN_SDEPEND(CERT_DECODE, CERT_X509_CRL), diff --git a/src/libcharon/plugins/stroke/stroke_socket.c b/src/libcharon/plugins/stroke/stroke_socket.c index 54dd56e91..db7e66f14 100644 --- a/src/libcharon/plugins/stroke/stroke_socket.c +++ b/src/libcharon/plugins/stroke/stroke_socket.c @@ -24,7 +24,6 @@ #include <unistd.h> #include <errno.h> -#include <hydra.h> #include <daemon.h> #include "stroke_config.h" @@ -747,8 +746,10 @@ METHOD(stroke_socket_t, destroy, void, lib->credmgr->remove_set(lib->credmgr, &this->ca->set); lib->credmgr->remove_set(lib->credmgr, &this->cred->set); charon->backends->remove_backend(charon->backends, &this->config->backend); - hydra->attributes->remove_provider(hydra->attributes, &this->attribute->provider); - hydra->attributes->remove_handler(hydra->attributes, &this->handler->handler); + charon->attributes->remove_provider(charon->attributes, + &this->attribute->provider); + charon->attributes->remove_handler(charon->attributes, + &this->handler->handler); charon->bus->remove_listener(charon->bus, &this->counter->listener); this->cred->destroy(this->cred); this->ca->destroy(this->ca); @@ -790,8 +791,10 @@ stroke_socket_t *stroke_socket_create() lib->credmgr->add_set(lib->credmgr, &this->ca->set); lib->credmgr->add_set(lib->credmgr, &this->cred->set); charon->backends->add_backend(charon->backends, &this->config->backend); - hydra->attributes->add_provider(hydra->attributes, &this->attribute->provider); - hydra->attributes->add_handler(hydra->attributes, &this->handler->handler); + charon->attributes->add_provider(charon->attributes, + &this->attribute->provider); + charon->attributes->add_handler(charon->attributes, + &this->handler->handler); charon->bus->add_listener(charon->bus, &this->counter->listener); max_concurrent = lib->settings->get_int(lib->settings, diff --git a/src/libcharon/plugins/systime_fix/Makefile.in b/src/libcharon/plugins/systime_fix/Makefile.in index 0e477f9f3..be148b6c3 100644 --- a/src/libcharon/plugins/systime_fix/Makefile.in +++ b/src/libcharon/plugins/systime_fix/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/tnc_ifmap/Makefile.in b/src/libcharon/plugins/tnc_ifmap/Makefile.in index 3f2952c4b..17cc341c5 100644 --- a/src/libcharon/plugins/tnc_ifmap/Makefile.in +++ b/src/libcharon/plugins/tnc_ifmap/Makefile.in @@ -232,6 +232,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -292,10 +293,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -369,6 +372,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/tnc_pdp/Makefile.in b/src/libcharon/plugins/tnc_pdp/Makefile.in index 97c479632..ef05275b7 100644 --- a/src/libcharon/plugins/tnc_pdp/Makefile.in +++ b/src/libcharon/plugins/tnc_pdp/Makefile.in @@ -233,6 +233,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -293,10 +294,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -370,6 +373,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/tnc_pdp/tnc_pdp.c b/src/libcharon/plugins/tnc_pdp/tnc_pdp.c index 109c216d5..91456f8da 100644 --- a/src/libcharon/plugins/tnc_pdp/tnc_pdp.c +++ b/src/libcharon/plugins/tnc_pdp/tnc_pdp.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2013 Andreas Steffen + * Copyright (C) 2012-2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -646,8 +646,8 @@ static bool pt_tls_receive(private_tnc_pdp_t *this, int fd, watcher_event_t even int pt_tls_fd; struct sockaddr_storage addr; socklen_t addrlen = sizeof(addr); - identification_t *peer; - host_t *host; + identification_t *client_id; + host_t *server_ip, *client_ip; pt_tls_server_t *pt_tls; tnccs_t *tnccs; pt_tls_auth_t auth = PT_TLS_AUTH_TLS_OR_SASL; @@ -658,17 +658,22 @@ static bool pt_tls_receive(private_tnc_pdp_t *this, int fd, watcher_event_t even DBG1(DBG_TNC, "accepting PT-TLS stream failed: %s", strerror(errno)); return FALSE; } - host = host_create_from_sockaddr((sockaddr_t*)&addr); - DBG1(DBG_TNC, "accepting PT-TLS stream from %H", host); - host->destroy(host); + client_ip = host_create_from_sockaddr((sockaddr_t*)&addr); + DBG1(DBG_TNC, "accepting PT-TLS stream from %H", client_ip); + + /* Currently we do not determine the IP address of the server interface */ + server_ip = host_create_any(client_ip->get_family(client_ip)); - /* At this moment the peer identity is not known yet */ - peer = identification_create_from_encoding(ID_ANY, chunk_empty), + /* At this moment the client identity is not known yet */ + client_id = identification_create_from_encoding(ID_ANY, chunk_empty), tnccs = tnc->tnccs->create_instance(tnc->tnccs, TNCCS_2_0, TRUE, - this->server, peer, TNC_IFT_TLS_2_0, + this->server, client_id, server_ip, + client_ip, TNC_IFT_TLS_2_0, (tnccs_cb_t)get_recommendation); - peer->destroy(peer); + client_id->destroy(client_id); + server_ip->destroy(server_ip); + client_ip->destroy(client_ip); if (!tnccs) { diff --git a/src/libcharon/plugins/uci/Makefile.in b/src/libcharon/plugins/uci/Makefile.in index 5e16c3c35..2c031383a 100644 --- a/src/libcharon/plugins/uci/Makefile.in +++ b/src/libcharon/plugins/uci/Makefile.in @@ -227,6 +227,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/unit_tester/Makefile.am b/src/libcharon/plugins/unit_tester/Makefile.am deleted file mode 100644 index b7f8fc319..000000000 --- a/src/libcharon/plugins/unit_tester/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -AM_CPPFLAGS = \ - -I$(top_srcdir)/src/libstrongswan \ - -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon - -AM_CFLAGS = \ - $(PLUGIN_CFLAGS) - -if MONOLITHIC -noinst_LTLIBRARIES = libstrongswan-unit-tester.la -else -plugin_LTLIBRARIES = libstrongswan-unit-tester.la -endif - -libstrongswan_unit_tester_la_SOURCES = \ - unit_tester.c unit_tester.h tests.h \ - tests/test_auth_info.c \ - tests/test_curl.c \ - tests/test_mysql.c \ - tests/test_sqlite.c \ - tests/test_cert.c \ - tests/test_med_db.c \ - tests/test_pool.c \ - tests/test_agent.c - -libstrongswan_unit_tester_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/unit_tester/tests/test_agent.c b/src/libcharon/plugins/unit_tester/tests/test_agent.c deleted file mode 100644 index baab629be..000000000 --- a/src/libcharon/plugins/unit_tester/tests/test_agent.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2008 Martin Willi - * Hochschule fuer Technik Rapperswil - * - * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program 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. - */ - -#include <library.h> -#include <daemon.h> - -/******************************************************************************* - * SSH agent signature creation and verification - ******************************************************************************/ -bool test_agent() -{ - char *path; - chunk_t sig, data = chunk_from_chars(0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08); - private_key_t *private; - public_key_t *public; - - path = getenv("SSH_AUTH_SOCK"); - if (!path) - { - DBG1(DBG_CFG, "ssh-agent not found."); - return FALSE; - } - - private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, - BUILD_AGENT_SOCKET, path, BUILD_END); - if (!private) - { - return FALSE; - } - if (!private->sign(private, SIGN_RSA_EMSA_PKCS1_SHA1, data, &sig)) - { - return FALSE; - } - public = private->get_public_key(private); - if (!public) - { - return FALSE;; - } - if (!public->verify(public, SIGN_RSA_EMSA_PKCS1_SHA1, data, sig)) - { - return FALSE; - } - free(sig.ptr); - data.ptr[1] = 0x01; /* fake it */ - if (public->verify(public, SIGN_RSA_EMSA_PKCS1_SHA1, data, sig)) - { - return FALSE; - } - - private->destroy(private); - public->destroy(public); - - return TRUE; -} - diff --git a/src/libcharon/plugins/unit_tester/tests/test_auth_info.c b/src/libcharon/plugins/unit_tester/tests/test_auth_info.c deleted file mode 100644 index c250c356f..000000000 --- a/src/libcharon/plugins/unit_tester/tests/test_auth_info.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2007 Martin Willi - * Hochschule fuer Technik Rapperswil - * - * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program 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. - */ - -#include <daemon.h> -#include <library.h> -#include <credentials/auth_cfg.h> - - -static chunk_t certchunk = chunk_from_chars( - 0x30,0x82,0x02,0xfa,0x30,0x82,0x01,0xe2,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,0x5a, - 0xf2,0x65,0xae,0x78,0xff,0x23,0xde,0xf7,0xa6,0xa3,0x94,0x8c,0x3f,0xa0,0xc1,0x30, - 0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x39, - 0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48,0x31,0x19,0x30, - 0x17,0x06,0x03,0x55,0x04,0x0a,0x13,0x10,0x4c,0x69,0x6e,0x75,0x78,0x20,0x73,0x74, - 0x72,0x6f,0x6e,0x67,0x53,0x77,0x61,0x6e,0x31,0x0f,0x30,0x0d,0x06,0x03,0x55,0x04, - 0x03,0x13,0x06,0x6d,0x61,0x72,0x74,0x69,0x6e,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30, - 0x34,0x32,0x37,0x30,0x37,0x31,0x34,0x32,0x36,0x5a,0x17,0x0d,0x31,0x32,0x30,0x34, - 0x32,0x35,0x30,0x37,0x31,0x34,0x32,0x36,0x5a,0x30,0x39,0x31,0x0b,0x30,0x09,0x06, - 0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04, - 0x0a,0x13,0x10,0x4c,0x69,0x6e,0x75,0x78,0x20,0x73,0x74,0x72,0x6f,0x6e,0x67,0x53, - 0x77,0x61,0x6e,0x31,0x0f,0x30,0x0d,0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x6d,0x61, - 0x72,0x74,0x69,0x6e,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86, - 0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a, - 0x02,0x82,0x01,0x01,0x00,0xd7,0xb9,0xba,0x4d,0xe2,0x3b,0x3d,0x35,0x7a,0x3f,0x88, - 0x67,0x95,0xe7,0xfd,0x9f,0xe9,0x0a,0x0d,0x79,0x3a,0x9e,0x21,0x8f,0xcb,0xe4,0x67, - 0x24,0xae,0x0c,0xda,0xb3,0xcc,0xec,0x36,0xb4,0xa8,0x4d,0xf1,0x3d,0xad,0xe4,0x8c, - 0x63,0x92,0x54,0xb7,0xb2,0x02,0xa2,0x00,0x62,0x8b,0x04,0xac,0xa0,0x17,0xad,0x17, - 0x9a,0x05,0x0d,0xd7,0xb3,0x08,0x02,0xc5,0x26,0xcf,0xdd,0x05,0x42,0xfc,0x13,0x6d, - 0x9f,0xb1,0xf3,0x4f,0x82,0x1d,0xef,0x01,0xc9,0x91,0xea,0x37,0x1b,0x79,0x28,0xfa, - 0xbf,0x9f,0xb3,0xeb,0x82,0x4f,0x10,0xc6,0x4b,0xa4,0x08,0xf7,0x8e,0xf2,0x00,0xea, - 0x04,0x97,0x80,0x9f,0x65,0x86,0xde,0x6b,0xc7,0xda,0x83,0xfc,0xad,0x4a,0xaf,0x52, - 0x8b,0x4d,0x33,0xee,0x49,0x87,0x2f,0x3b,0x60,0x45,0x66,0x8f,0xe6,0x89,0xcc,0xb1, - 0x92,0x02,0x17,0x2b,0x7b,0x8e,0x90,0x47,0x84,0x84,0x59,0x95,0x81,0xd8,0xe0,0xf3, - 0x87,0xe0,0x04,0x09,0xfd,0xcc,0x3a,0x21,0x34,0xfa,0xec,0xbe,0xf5,0x9c,0xcf,0x55, - 0x80,0x7b,0xe3,0x75,0x9d,0x36,0x68,0xab,0x83,0xe3,0xad,0x01,0x53,0x0d,0x8a,0x9a, - 0xa6,0xb0,0x15,0xc9,0xc5,0xf8,0x9b,0x51,0x32,0xcf,0x97,0x6c,0xfe,0x4a,0x56,0x3c, - 0xc8,0x8f,0x4a,0x70,0x23,0x4f,0xf6,0xf7,0xe6,0x9f,0x09,0xcd,0x8f,0xea,0x20,0x7d, - 0x34,0xc0,0xc5,0xc0,0x34,0x06,0x6f,0x8b,0xeb,0x04,0x54,0x3f,0x0e,0xcd,0xe2,0x85, - 0xab,0x94,0x3e,0x91,0x6c,0x18,0x6f,0x96,0x5d,0xf2,0x8b,0x10,0xe9,0x90,0x43,0xb0, - 0x61,0x52,0xac,0xcf,0x75,0x02,0x03,0x01,0x00,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86, - 0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x09,0x63, - 0x42,0xad,0xe5,0xa3,0xf6,0xc9,0x5d,0x08,0xf2,0x78,0x7b,0xeb,0x8a,0xef,0x50,0x00, - 0xc8,0xeb,0xe9,0x26,0x94,0xcb,0x84,0x10,0x7e,0x42,0x6b,0x86,0x38,0x57,0xa6,0x02, - 0x98,0x5a,0x2c,0x8f,0x44,0x32,0x1b,0x97,0x8c,0x7e,0x4b,0xd8,0xe8,0xe8,0x0f,0x4a, - 0xb9,0x31,0x9f,0xf6,0x9f,0x0e,0x67,0x26,0x05,0x2a,0x99,0x14,0x35,0x41,0x47,0x9a, - 0xfa,0x12,0x94,0x0b,0xe9,0x27,0x7c,0x71,0x20,0xd7,0x8d,0x3b,0x97,0x19,0x2d,0x15, - 0xff,0xa4,0xf3,0x89,0x8d,0x29,0x5f,0xf6,0x3f,0x93,0xaf,0x78,0x61,0xe4,0xe1,0x2e, - 0x75,0xc1,0x2c,0xc4,0x76,0x95,0x19,0xf8,0x37,0xdc,0xd8,0x00,0x7a,0x3c,0x0f,0x49, - 0x2e,0x88,0x09,0x16,0xb3,0x92,0x33,0xdf,0x77,0x83,0x4f,0xb5,0x9e,0x30,0x8c,0x48, - 0x1d,0xd8,0x84,0xfb,0xf1,0xb9,0xa0,0xbe,0x25,0xff,0x4c,0xeb,0xef,0x2b,0xcd,0xfa, - 0x0b,0x94,0x66,0x3b,0x28,0x08,0x3f,0x3a,0xda,0x41,0xd0,0x6b,0xab,0x5e,0xbb,0x8a, - 0x9f,0xdc,0x98,0x3e,0x59,0x37,0x48,0xbe,0x69,0xde,0x85,0x82,0xf2,0x53,0x8b,0xe4, - 0x44,0xe4,0x71,0x91,0x14,0x85,0x0e,0x1e,0x79,0xdd,0x62,0xf5,0xdc,0x25,0x89,0xab, - 0x50,0x5b,0xaa,0xae,0xe3,0x64,0x6a,0x23,0x34,0xd7,0x30,0xe2,0x2a,0xc8,0x81,0x0c, - 0xec,0xd2,0x31,0xc6,0x1e,0xb6,0xc0,0x57,0xd9,0xe1,0x14,0x06,0x9b,0xf8,0x51,0x69, - 0x47,0xf0,0x9c,0xcd,0x69,0xef,0x8e,0x5f,0x62,0xda,0x10,0xf7,0x3c,0x6d,0x0f,0x33, - 0xec,0x6f,0xfd,0x94,0x07,0x16,0x41,0x32,0x06,0xa4,0xe1,0x08,0x31,0x87, -); - -/******************************************************************************* - * auth info test - ******************************************************************************/ -bool test_auth_cfg() -{ - auth_cfg_t *auth = auth_cfg_create(), *auth2; - certificate_t *c1, *c2; - enumerator_t *enumerator; - int round = 0; - void *value; - auth_rule_t type; - - c1 = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, - BUILD_BLOB_ASN1_DER, certchunk, - BUILD_END); - if (!c1) - { - return FALSE; - } - - auth->add(auth, AUTH_RULE_SUBJECT_CERT, c1->get_ref(c1)); - c2 = auth->get(auth, AUTH_RULE_SUBJECT_CERT); - if (!c2) - { - return FALSE; - } - if (!c1->equals(c1, c2)) - { - return FALSE; - } - - enumerator = auth->create_enumerator(auth); - while (enumerator->enumerate(enumerator, &type, &value)) - { - round++; - if (round == 1 && type == AUTH_RULE_SUBJECT_CERT && value == c1) - { - continue; - } - return FALSE; - } - enumerator->destroy(enumerator); - - auth2 = auth_cfg_create(); - auth2->add(auth2, AUTH_RULE_CA_CERT, c1->get_ref(c1)); - auth2->merge(auth2, auth, FALSE); - - round = 0; - enumerator = auth2->create_enumerator(auth2); - while (enumerator->enumerate(enumerator, &type, &value)) - { - round++; - if (round == 1 && type == AUTH_RULE_CA_CERT && value == c1) - { - continue; - } - if (round == 2 && type == AUTH_RULE_SUBJECT_CERT && value == c1) - { - continue; - } - return FALSE; - } - enumerator->destroy(enumerator); - auth->destroy(auth); - auth2->destroy(auth2); - c1->destroy(c1); - return TRUE; -} - diff --git a/src/libcharon/plugins/unit_tester/tests/test_cert.c b/src/libcharon/plugins/unit_tester/tests/test_cert.c deleted file mode 100644 index f4410a688..000000000 --- a/src/libcharon/plugins/unit_tester/tests/test_cert.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2008 Martin Willi - * Hochschule fuer Technik Rapperswil - * - * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program 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. - */ - -#include <library.h> -#include <daemon.h> -#include <credentials/certificates/x509.h> - -/******************************************************************************* - * X509 certificate generation and parsing - ******************************************************************************/ -bool test_cert_x509() -{ - private_key_t *ca_key, *peer_key; - public_key_t *public; - certificate_t *ca_cert, *peer_cert, *parsed; - identification_t *issuer, *subject; - u_int32_t serial = htonl(0); - chunk_t encoding; - - issuer = identification_create_from_string("CN=CA, OU=Test, O=strongSwan"); - subject = identification_create_from_string("CN=Peer, OU=Test, O=strongSwan"); - - ca_key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, - BUILD_KEY_SIZE, 1024, BUILD_END); - peer_key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, - BUILD_KEY_SIZE, 1024, BUILD_END); - if (!ca_key) - { - return FALSE; - } - ca_cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, - BUILD_SIGNING_KEY, ca_key, - BUILD_SUBJECT, issuer, - BUILD_SERIAL, chunk_from_thing(serial), - BUILD_X509_FLAG, X509_CA, - BUILD_END); - if (!ca_cert) - { - return FALSE; - } - - ca_cert->get_encoding(ca_cert, CERT_ASN1_DER, &encoding); - parsed = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, - BUILD_BLOB_ASN1_DER, encoding, - BUILD_END); - chunk_free(&encoding); - if (!parsed) - { - return FALSE; - } - if (!parsed->issued_by(parsed, ca_cert, NULL)) - { - return FALSE; - } - parsed->destroy(parsed); - - serial = htonl(ntohl(serial) + 1); - public = peer_key->get_public_key(peer_key); - peer_cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, - BUILD_SIGNING_KEY, ca_key, - BUILD_SIGNING_CERT, ca_cert, - BUILD_PUBLIC_KEY, public, - BUILD_SUBJECT, subject, - BUILD_SERIAL, chunk_from_thing(serial), - BUILD_END); - public->destroy(public); - if (!peer_cert) - { - return FALSE; - } - - peer_cert->get_encoding(peer_cert, CERT_ASN1_DER, &encoding); - parsed = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, - BUILD_BLOB_ASN1_DER, encoding, - BUILD_END); - chunk_free(&encoding); - if (!parsed) - { - return FALSE; - } - if (!parsed->issued_by(parsed, ca_cert, NULL)) - { - return FALSE; - } - parsed->destroy(parsed); - - ca_cert->destroy(ca_cert); - ca_key->destroy(ca_key); - peer_cert->destroy(peer_cert); - peer_key->destroy(peer_key); - issuer->destroy(issuer); - subject->destroy(subject); - return TRUE; -} - - diff --git a/src/libcharon/plugins/unit_tester/tests/test_curl.c b/src/libcharon/plugins/unit_tester/tests/test_curl.c deleted file mode 100644 index 21656a94e..000000000 --- a/src/libcharon/plugins/unit_tester/tests/test_curl.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2007 Martin Willi - * Hochschule fuer Technik Rapperswil - * - * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program 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. - */ - -#include <daemon.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netdb.h> - -/******************************************************************************* - * curl get test - ******************************************************************************/ - -bool test_curl_get() -{ - chunk_t chunk; - - if (lib->fetcher->fetch(lib->fetcher, "http://www.strongswan.org", - &chunk, FETCH_END) != SUCCESS) - { - return FALSE; - } - free(chunk.ptr); - - if (lib->fetcher->fetch(lib->fetcher, "http://www.google.com", - &chunk, FETCH_END) != SUCCESS) - { - return FALSE; - } - free(chunk.ptr); - return TRUE; -} - diff --git a/src/libcharon/plugins/unit_tester/tests/test_med_db.c b/src/libcharon/plugins/unit_tester/tests/test_med_db.c deleted file mode 100644 index 75244ab8f..000000000 --- a/src/libcharon/plugins/unit_tester/tests/test_med_db.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2008 Martin Willi - * Hochschule fuer Technik Rapperswil - * - * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program 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. - */ - -#include <library.h> -#include <daemon.h> -#include <collections/enumerator.h> - -#include <unistd.h> - -/******************************************************************************* - * fetch public key from mediation database - ******************************************************************************/ - -bool test_med_db() -{ - chunk_t found, keyid = chunk_from_chars( - 0xed,0x90,0xe6,0x4f,0xec,0xa2,0x1f,0x4b, - 0x68,0x97,0x99,0x24,0x22,0xe0,0xde,0x21, - 0xb9,0xd6,0x26,0x29 - ); - identification_t *id; - enumerator_t *enumerator; - public_key_t *public; - auth_cfg_t *auth; - bool good = FALSE; - - id = identification_create_from_encoding(ID_KEY_ID, keyid); - enumerator = lib->credmgr->create_public_enumerator(lib->credmgr, - KEY_ANY, id, NULL); - while (enumerator->enumerate(enumerator, &public, &auth)) - { - good = public->get_fingerprint(public, KEYID_PUBKEY_SHA1, &found); - if (good) - { - good = chunk_equals(id->get_encoding(id), found); - } - } - enumerator->destroy(enumerator); - id->destroy(id); - return good; -} - diff --git a/src/libcharon/plugins/unit_tester/tests/test_mysql.c b/src/libcharon/plugins/unit_tester/tests/test_mysql.c deleted file mode 100644 index eda238623..000000000 --- a/src/libcharon/plugins/unit_tester/tests/test_mysql.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2008 Martin Willi - * Hochschule fuer Technik Rapperswil - * - * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program 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. - */ - -#include <library.h> -#include <daemon.h> -#include <collections/enumerator.h> - -/******************************************************************************* - * mysql simple test - ******************************************************************************/ -bool test_mysql() -{ - database_t *db; - char *txt = "I'm a superduper test"; - chunk_t data = chunk_from_chars(0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08); - int row; - chunk_t qdata; - char *qtxt; - bool good = FALSE; - enumerator_t *enumerator; - - db = lib->db->create(lib->db, "mysql://testuser:testpass@localhost/test"); - if (!db) - { - return FALSE; - } - if (db->execute(db, NULL, "CREATE TABLE test (" - "id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, " - "txt TEXT, data BLOB)") < 0) - { - return FALSE; - } - if (db->execute(db, &row, "INSERT INTO test (txt, data) VALUES (?,?)", - DB_TEXT, txt, DB_BLOB, data) < 0) - { - return FALSE; - } - if (row != 1) - { - return FALSE; - } - enumerator = db->query(db, "SELECT txt, data FROM test WHERE id = ?", - DB_INT, row, - DB_TEXT, DB_BLOB); - if (!enumerator) - { - return FALSE; - } - while (enumerator->enumerate(enumerator, &qtxt, &qdata)) - { - if (good) - { /* only one row */ - good = FALSE; - break; - } - if (streq(qtxt, txt) && chunk_equals(data, qdata)) - { - good = TRUE; - } - } - enumerator->destroy(enumerator); - if (!good) - { - return FALSE; - } - if (db->execute(db, NULL, "DELETE FROM test WHERE id = ?", DB_INT, row) != 1) - { - return FALSE; - } - if (db->execute(db, NULL, "DROP TABLE test") < 0) - { - return FALSE; - } - db->destroy(db); - return TRUE; -} - diff --git a/src/libcharon/plugins/unit_tester/tests/test_pool.c b/src/libcharon/plugins/unit_tester/tests/test_pool.c deleted file mode 100644 index f36953f3a..000000000 --- a/src/libcharon/plugins/unit_tester/tests/test_pool.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2008 Martin Willi - * Hochschule fuer Technik Rapperswil - * - * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program 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. - */ - -#include <time.h> - -#include <library.h> -#include <threading/thread.h> -#include <hydra.h> - -#define ALLOCS 1000 -#define THREADS 20 - -static void* testing(void *thread) -{ - int i; - host_t *addr[ALLOCS]; - identification_t *id[ALLOCS]; - linked_list_t *pools; - - /* prepare identities */ - for (i = 0; i < ALLOCS; i++) - { - char buf[256]; - - snprintf(buf, sizeof(buf), "%d-%d@strongswan.org", (uintptr_t)thread, i); - id[i] = identification_create_from_string(buf); - } - - pools = linked_list_create(); - pools->insert_last(pools, "test"); - - /* allocate addresses */ - for (i = 0; i < ALLOCS; i++) - { - addr[i] = hydra->attributes->acquire_address(hydra->attributes, - pools, id[i], NULL); - if (!addr[i]) - { - pools->destroy(pools); - return (void*)FALSE; - } - } - - /* release addresses */ - for (i = 0; i < ALLOCS; i++) - { - hydra->attributes->release_address(hydra->attributes, - pools, addr[i], id[i]); - } - - pools->destroy(pools); - - /* cleanup */ - for (i = 0; i < ALLOCS; i++) - { - addr[i]->destroy(addr[i]); - id[i]->destroy(id[i]); - } - return (void*)TRUE; -} - - -/******************************************************************************* - * SQL pool performance test - ******************************************************************************/ -bool test_pool() -{ - thread_t *threads[THREADS]; - uintptr_t i; - - for (i = 0; i < THREADS; i++) - { - if (!(threads[i] = thread_create((thread_main_t)testing, (void*)i))) - { - return FALSE; - } - } - for (i = 0; i < THREADS; i++) - { - bool *res = threads[i]->join(threads[i]); - if (!res) - { - return FALSE; - } - } - return TRUE; -} - diff --git a/src/libcharon/plugins/unit_tester/tests/test_sqlite.c b/src/libcharon/plugins/unit_tester/tests/test_sqlite.c deleted file mode 100644 index 99490b566..000000000 --- a/src/libcharon/plugins/unit_tester/tests/test_sqlite.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2008 Martin Willi - * Hochschule fuer Technik Rapperswil - * - * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program 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. - */ - -#include <library.h> -#include <daemon.h> -#include <collections/enumerator.h> - -#include <unistd.h> - - -#define DBFILE "/tmp/strongswan-test.db" - -/******************************************************************************* - * sqlite simple test - ******************************************************************************/ -bool test_sqlite() -{ - database_t *db; - char *txt = "I'm a superduper test"; - chunk_t data = chunk_from_chars(0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08); - int row; - chunk_t qdata; - char *qtxt; - bool good = FALSE; - enumerator_t *enumerator; - - db = lib->db->create(lib->db, "sqlite://" DBFILE); - if (!db) - { - return FALSE; - } - if (db->execute(db, NULL, "CREATE TABLE test (txt TEXT, data BLOB)") < 0) - { - return FALSE; - } - if (db->execute(db, &row, "INSERT INTO test (txt, data) VALUES (?,?)", - DB_TEXT, txt, DB_BLOB, data) < 0) - { - return FALSE; - } - if (row != 1) - { - return FALSE; - } - enumerator = db->query(db, "SELECT txt, data FROM test WHERE oid = ?", - DB_INT, row, - DB_TEXT, DB_BLOB); - if (!enumerator) - { - return FALSE; - } - while (enumerator->enumerate(enumerator, &qtxt, &qdata)) - { - if (good) - { /* only one row */ - good = FALSE; - break; - } - if (streq(qtxt, txt) && chunk_equals(data, qdata)) - { - good = TRUE; - } - } - enumerator->destroy(enumerator); - if (!good) - { - return FALSE; - } - if (db->execute(db, NULL, "DELETE FROM test WHERE oid = ?", DB_INT, row) != 1) - { - return FALSE; - } - if (db->execute(db, NULL, "DROP TABLE test") < 0) - { - return FALSE; - } - db->destroy(db); - unlink(DBFILE); - return TRUE; -} - diff --git a/src/libcharon/plugins/unit_tester/unit_tester.c b/src/libcharon/plugins/unit_tester/unit_tester.c deleted file mode 100644 index ea7ffca04..000000000 --- a/src/libcharon/plugins/unit_tester/unit_tester.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (C) 2013 Tobias Brunner - * Copyright (C) 2007 Martin Willi - * Hochschule fuer Technik Rapperswil - * - * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program 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. - */ - -#include "unit_tester.h" - -#include <daemon.h> - -typedef struct private_unit_tester_t private_unit_tester_t; -typedef struct unit_test_t unit_test_t; -typedef enum test_status_t test_status_t; - -/** - * private data of unit_tester - */ -struct private_unit_tester_t { - - /** - * public functions - */ - unit_tester_t public; -}; - -struct unit_test_t { - - /** - * name of the test - */ - char *name; - - /** - * test function - */ - bool (*test)(void); - - /** - * run the test? - */ - bool enabled; -}; - -#undef DEFINE_TEST -#define DEFINE_TEST(name, function, enabled) bool function(); -#include <plugins/unit_tester/tests.h> -#undef DEFINE_TEST -#define DEFINE_TEST(name, function, enabled) {name, function, enabled}, -static unit_test_t tests[] = { -#include <plugins/unit_tester/tests.h> -}; - -static void run_tests(private_unit_tester_t *this) -{ - int i, run = 0, failed = 0, success = 0, skipped = 0; - - DBG1(DBG_CFG, "running unit tests, %d tests registered", - sizeof(tests)/sizeof(unit_test_t)); - - for (i = 0; i < sizeof(tests)/sizeof(unit_test_t); i++) - { - if (tests[i].enabled) - { - run++; - if (tests[i].test()) - { - DBG1(DBG_CFG, "test '%s' successful", tests[i].name); - success++; - } - else - { - DBG1(DBG_CFG, "test '%s' failed", tests[i].name); - failed++; - } - } - else - { - DBG1(DBG_CFG, "test '%s' disabled", tests[i].name); - skipped++; - } - } - DBG1(DBG_CFG, "%d/%d tests successful (%d failed, %d disabled)", - success, run, failed, skipped); -} - -METHOD(plugin_t, get_name, char*, - private_unit_tester_t *this) -{ - return "unit-tester"; -} - -/** - * We currently don't depend explicitly on any plugin features. But in case - * activated tests depend on such features we at least try to run them in plugin - * order. - */ -static bool plugin_cb(private_unit_tester_t *this, - plugin_feature_t *feature, bool reg, void *cb_data) -{ - if (reg) - { - run_tests(this); - } - return TRUE; -} - -METHOD(plugin_t, get_features, int, - private_unit_tester_t *this, plugin_feature_t *features[]) -{ - static plugin_feature_t f[] = { - PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL), - PLUGIN_PROVIDE(CUSTOM, "unit-tester"), - }; - *features = f; - return countof(f); -} - -METHOD(plugin_t, destroy, void, - private_unit_tester_t *this) -{ - free(this); -} - -/* - * see header file - */ -plugin_t *unit_tester_plugin_create() -{ - private_unit_tester_t *this; - - INIT(this, - .public = { - .plugin = { - .get_name = _get_name, - .get_features = _get_features, - .destroy = _destroy, - }, - }, - ); - - return &this->public.plugin; -} diff --git a/src/libcharon/plugins/unity/Makefile.in b/src/libcharon/plugins/unity/Makefile.in index 1e04ebced..4f0a7e736 100644 --- a/src/libcharon/plugins/unity/Makefile.in +++ b/src/libcharon/plugins/unity/Makefile.in @@ -228,6 +228,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -288,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -365,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/unity/unity_handler.c b/src/libcharon/plugins/unity/unity_handler.c index bcef0dc25..9fc9be61a 100644 --- a/src/libcharon/plugins/unity/unity_handler.c +++ b/src/libcharon/plugins/unity/unity_handler.c @@ -50,8 +50,8 @@ struct private_unity_handler_t { * Traffic selector entry for networks to include under a given IKE_SA */ typedef struct { - /** associated IKE_SA, unique ID */ - u_int32_t sa; + /** associated IKE_SA COOKIEs */ + ike_sa_id_t *id; /** traffic selector to include/exclude */ traffic_selector_t *ts; } entry_t; @@ -61,6 +61,7 @@ typedef struct { */ static void entry_destroy(entry_t *this) { + this->id->destroy(this->id); this->ts->destroy(this->ts); free(this); } @@ -131,9 +132,10 @@ static bool add_include(private_unity_handler_t *this, chunk_t data) while (list->remove_first(list, (void**)&ts) == SUCCESS) { INIT(entry, - .sa = ike_sa->get_unique_id(ike_sa), + .id = ike_sa->get_id(ike_sa), .ts = ts, ); + entry->id = entry->id->clone(entry->id); this->mutex->lock(this->mutex); this->include->insert_last(this->include, entry); @@ -171,7 +173,7 @@ static bool remove_include(private_unity_handler_t *this, chunk_t data) enumerator = this->include->create_enumerator(this->include); while (enumerator->enumerate(enumerator, &entry)) { - if (entry->sa == ike_sa->get_unique_id(ike_sa) && + if (entry->id->equals(entry->id, ike_sa->get_id(ike_sa)) && ts->equals(ts, entry->ts)) { this->include->remove_at(this->include, enumerator); @@ -209,8 +211,7 @@ static job_requeue_t add_exclude_async(entry_t *entry) char name[128]; host_t *host; - ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager, - entry->sa, FALSE); + ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, entry->id); if (ike_sa) { create_shunt_name(ike_sa, entry->ts, name, sizeof(name)); @@ -267,9 +268,10 @@ static bool add_exclude(private_unity_handler_t *this, chunk_t data) while (list->remove_first(list, (void**)&ts) == SUCCESS) { INIT(entry, - .sa = ike_sa->get_unique_id(ike_sa), + .id = ike_sa->get_id(ike_sa), .ts = ts, ); + entry->id = entry->id->clone(entry->id); /* we can't install the shunt policy yet, as we don't know the virtual IP. * Defer installation using an async callback. */ @@ -315,7 +317,7 @@ static bool remove_exclude(private_unity_handler_t *this, chunk_t data) } METHOD(attribute_handler_t, handle, bool, - private_unity_handler_t *this, identification_t *id, + private_unity_handler_t *this, ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data) { switch (type) @@ -330,7 +332,7 @@ METHOD(attribute_handler_t, handle, bool, } METHOD(attribute_handler_t, release, void, - private_unity_handler_t *this, identification_t *server, + private_unity_handler_t *this, ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data) { switch (type) @@ -378,10 +380,9 @@ METHOD(enumerator_t, enumerate_attributes, bool, } METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *, - unity_handler_t *this, identification_t *id, linked_list_t *vips) + unity_handler_t *this, ike_sa_t *ike_sa, linked_list_t *vips) { attribute_enumerator_t *enumerator; - ike_sa_t *ike_sa; ike_sa = charon->bus->get_sa(charon->bus); if (!ike_sa || ike_sa->get_version(ike_sa) != IKEV1 || @@ -402,7 +403,7 @@ typedef struct { /** mutex to unlock */ mutex_t *mutex; /** IKE_SA ID to filter for */ - u_int32_t id; + ike_sa_id_t *id; } include_filter_t; /** @@ -411,7 +412,7 @@ typedef struct { static bool include_filter(include_filter_t *data, entry_t **entry, traffic_selector_t **ts) { - if ((*entry)->sa == data->id) + if (data->id->equals(data->id, (*entry)->id)) { *ts = (*entry)->ts; return TRUE; @@ -429,7 +430,7 @@ static void destroy_filter(include_filter_t *data) } METHOD(unity_handler_t, create_include_enumerator, enumerator_t*, - private_unity_handler_t *this, u_int32_t id) + private_unity_handler_t *this, ike_sa_id_t *id) { include_filter_t *data; diff --git a/src/libcharon/plugins/unity/unity_handler.h b/src/libcharon/plugins/unity/unity_handler.h index 8656fd372..18efe293b 100644 --- a/src/libcharon/plugins/unity/unity_handler.h +++ b/src/libcharon/plugins/unity/unity_handler.h @@ -21,6 +21,7 @@ #ifndef UNITY_HANDLER_H_ #define UNITY_HANDLER_H_ +#include <sa/ike_sa_id.h> #include <attributes/attribute_handler.h> typedef struct unity_handler_t unity_handler_t; @@ -38,11 +39,11 @@ struct unity_handler_t { /** * Create an enumerator over Split-Include attributes received for an IKE_SA. * - * @param id IKE_SA unique ID to get Split-Includes for + * @param id IKE_SA ID to get Split-Includes for * @return enumerator over traffic_selector_t* */ enumerator_t* (*create_include_enumerator)(unity_handler_t *this, - u_int32_t id); + ike_sa_id_t *id); /** * Destroy a unity_handler_t. diff --git a/src/libcharon/plugins/unity/unity_narrow.c b/src/libcharon/plugins/unity/unity_narrow.c index 52a2c7f24..227d24be8 100644 --- a/src/libcharon/plugins/unity/unity_narrow.c +++ b/src/libcharon/plugins/unity/unity_narrow.c @@ -1,4 +1,7 @@ /* + * Copyright (C) 2014 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2012 Martin Willi * Copyright (C) 2012 revosec AG * @@ -16,6 +19,8 @@ #include "unity_narrow.h" #include <daemon.h> +#include <encoding/payloads/id_payload.h> +#include <collections/hashtable.h> typedef struct private_unity_narrow_t private_unity_narrow_t; @@ -33,6 +38,11 @@ struct private_unity_narrow_t { * Unity attribute handler */ unity_handler_t *handler; + + /** + * IKE_SAs for which we received 0.0.0.0/0 as remote traffic selector + */ + hashtable_t *wildcard_ts; }; /** @@ -65,7 +75,7 @@ static void narrow_initiator(private_unity_narrow_t *this, ike_sa_t *ike_sa, enumerator_t *enumerator; enumerator = this->handler->create_include_enumerator(this->handler, - ike_sa->get_unique_id(ike_sa)); + ike_sa->get_id(ike_sa)); while (enumerator->enumerate(enumerator, ¤t)) { if (orig == NULL) @@ -149,7 +159,7 @@ static bool has_split_includes(private_unity_narrow_t *this, ike_sa_t *ike_sa) bool has; enumerator = this->handler->create_include_enumerator(this->handler, - ike_sa->get_unique_id(ike_sa)); + ike_sa->get_id(ike_sa)); has = enumerator->enumerate(enumerator, &ts); enumerator->destroy(enumerator); @@ -191,11 +201,19 @@ METHOD(listener_t, narrow, bool, { case NARROW_INITIATOR_PRE_AUTH: case NARROW_RESPONDER: - narrow_pre(local, "us"); + if (this->wildcard_ts->get(this->wildcard_ts, ike_sa)) + { + narrow_pre(local, "us"); + + } break; case NARROW_INITIATOR_POST_AUTH: case NARROW_RESPONDER_POST: - narrow_responder_post(child_sa->get_config(child_sa), local); + if (this->wildcard_ts->get(this->wildcard_ts, ike_sa)) + { + narrow_responder_post(child_sa->get_config(child_sa), + local); + } break; default: break; @@ -205,9 +223,69 @@ METHOD(listener_t, narrow, bool, return TRUE; } +METHOD(listener_t, message, bool, + private_unity_narrow_t *this, ike_sa_t *ike_sa, message_t *message, + bool incoming, bool plain) +{ + traffic_selector_t *tsr = NULL, *wildcard; + enumerator_t *enumerator; + id_payload_t *id_payload; + payload_t *payload; + bool first = TRUE; + + if (!incoming || !plain || + message->get_exchange_type(message) != QUICK_MODE || + !ike_sa || !ike_sa->supports_extension(ike_sa, EXT_CISCO_UNITY)) + { + return TRUE; + } + enumerator = message->create_payload_enumerator(message); + while (enumerator->enumerate(enumerator, &payload)) + { + if (payload->get_type(payload) == PLV1_ID) + { + if (!first) + { + id_payload = (id_payload_t*)payload; + tsr = id_payload->get_ts(id_payload); + break; + } + first = FALSE; + } + } + enumerator->destroy(enumerator); + if (!tsr) + { + return TRUE; + } + wildcard = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535); + if (tsr->equals(tsr, wildcard)) + { + this->wildcard_ts->put(this->wildcard_ts, ike_sa, ike_sa); + } + else + { + this->wildcard_ts->remove(this->wildcard_ts, ike_sa); + } + wildcard->destroy(wildcard); + tsr->destroy(tsr); + return TRUE; +} + +METHOD(listener_t, ike_updown, bool, + private_unity_narrow_t *this, ike_sa_t *ike_sa, bool up) +{ + if (!up) + { + this->wildcard_ts->remove(this->wildcard_ts, ike_sa); + } + return TRUE; +} + METHOD(unity_narrow_t, destroy, void, private_unity_narrow_t *this) { + this->wildcard_ts->destroy(this->wildcard_ts); free(this); } @@ -222,10 +300,14 @@ unity_narrow_t *unity_narrow_create(unity_handler_t *handler) .public = { .listener = { .narrow = _narrow, + .message = _message, + .ike_updown = _ike_updown, }, .destroy = _destroy, }, .handler = handler, + .wildcard_ts = hashtable_create(hashtable_hash_ptr, + hashtable_equals_ptr, 4), ); return &this->public; diff --git a/src/libcharon/plugins/unity/unity_plugin.c b/src/libcharon/plugins/unity/unity_plugin.c index 9e4571d34..b7a3fee2e 100644 --- a/src/libcharon/plugins/unity/unity_plugin.c +++ b/src/libcharon/plugins/unity/unity_plugin.c @@ -19,7 +19,6 @@ #include "unity_provider.h" #include <daemon.h> -#include <hydra.h> typedef struct private_unity_plugin_t private_unity_plugin_t; @@ -63,19 +62,19 @@ static bool plugin_cb(private_unity_plugin_t *this, { if (reg) { - hydra->attributes->add_handler(hydra->attributes, - &this->handler->handler); - hydra->attributes->add_provider(hydra->attributes, - &this->provider->provider); + charon->attributes->add_handler(charon->attributes, + &this->handler->handler); + charon->attributes->add_provider(charon->attributes, + &this->provider->provider); charon->bus->add_listener(charon->bus, &this->narrower->listener); } else { charon->bus->remove_listener(charon->bus, &this->narrower->listener); - hydra->attributes->remove_handler(hydra->attributes, - &this->handler->handler); - hydra->attributes->remove_provider(hydra->attributes, - &this->provider->provider); + charon->attributes->remove_handler(charon->attributes, + &this->handler->handler); + charon->attributes->remove_provider(charon->attributes, + &this->provider->provider); } return TRUE; diff --git a/src/libcharon/plugins/unity/unity_provider.c b/src/libcharon/plugins/unity/unity_provider.c index 86f81fcfb..1e297a39e 100644 --- a/src/libcharon/plugins/unity/unity_provider.c +++ b/src/libcharon/plugins/unity/unity_provider.c @@ -135,19 +135,17 @@ static bool use_ts(traffic_selector_t *ts) } METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, - private_unity_provider_t *this, linked_list_t *pools, identification_t *id, + private_unity_provider_t *this, linked_list_t *pools, ike_sa_t *ike_sa, linked_list_t *vips) { attribute_enumerator_t *attr_enum; enumerator_t *enumerator; linked_list_t *list, *current; traffic_selector_t *ts; - ike_sa_t *ike_sa; peer_cfg_t *peer_cfg; child_cfg_t *child_cfg; - ike_sa = charon->bus->get_sa(charon->bus); - if (!ike_sa || ike_sa->get_version(ike_sa) != IKEV1 || + if (ike_sa->get_version(ike_sa) != IKEV1 || !ike_sa->supports_extension(ike_sa, EXT_CISCO_UNITY) || !vips->get_count(vips)) { diff --git a/src/libcharon/plugins/updown/Makefile.in b/src/libcharon/plugins/updown/Makefile.in index 834d373f3..619d17a0e 100644 --- a/src/libcharon/plugins/updown/Makefile.in +++ b/src/libcharon/plugins/updown/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/updown/updown_handler.c b/src/libcharon/plugins/updown/updown_handler.c index 0894d2d07..72d7f7da3 100644 --- a/src/libcharon/plugins/updown/updown_handler.c +++ b/src/libcharon/plugins/updown/updown_handler.c @@ -62,19 +62,13 @@ static void attributes_destroy(attributes_t *this) } METHOD(attribute_handler_t, handle, bool, - private_updown_handler_t *this, identification_t *server, + private_updown_handler_t *this, ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data) { attributes_t *current, *attr = NULL; enumerator_t *enumerator; - ike_sa_t *ike_sa; host_t *host; - ike_sa = charon->bus->get_sa(charon->bus); - if (!ike_sa) - { - return FALSE; - } switch (type) { case INTERNAL_IP4_DNS: @@ -117,12 +111,11 @@ METHOD(attribute_handler_t, handle, bool, } METHOD(attribute_handler_t, release, void, - private_updown_handler_t *this, identification_t *server, + private_updown_handler_t *this, ike_sa_t *ike_sa, configuration_attribute_type_t type, chunk_t data) { attributes_t *attr; enumerator_t *enumerator, *servers; - ike_sa_t *ike_sa; host_t *host; bool found = FALSE; int family; @@ -139,43 +132,39 @@ METHOD(attribute_handler_t, release, void, return; } - ike_sa = charon->bus->get_sa(charon->bus); - if (ike_sa) + this->lock->write_lock(this->lock); + enumerator = this->attrs->create_enumerator(this->attrs); + while (enumerator->enumerate(enumerator, &attr)) { - this->lock->write_lock(this->lock); - enumerator = this->attrs->create_enumerator(this->attrs); - while (enumerator->enumerate(enumerator, &attr)) + if (attr->id == ike_sa->get_unique_id(ike_sa)) { - if (attr->id == ike_sa->get_unique_id(ike_sa)) + servers = attr->dns->create_enumerator(attr->dns); + while (servers->enumerate(servers, &host)) { - servers = attr->dns->create_enumerator(attr->dns); - while (servers->enumerate(servers, &host)) + if (host->get_family(host) == family && + chunk_equals(data, host->get_address(host))) { - if (host->get_family(host) == family && - chunk_equals(data, host->get_address(host))) - { - attr->dns->remove_at(attr->dns, servers); - host->destroy(host); - found = TRUE; - break; - } - } - servers->destroy(servers); - if (attr->dns->get_count(attr->dns) == 0) - { - this->attrs->remove_at(this->attrs, enumerator); - attributes_destroy(attr); + attr->dns->remove_at(attr->dns, servers); + host->destroy(host); + found = TRUE; break; } } - if (found) + servers->destroy(servers); + if (attr->dns->get_count(attr->dns) == 0) { + this->attrs->remove_at(this->attrs, enumerator); + attributes_destroy(attr); break; } } - enumerator->destroy(enumerator); - this->lock->unlock(this->lock); + if (found) + { + break; + } } + enumerator->destroy(enumerator); + this->lock->unlock(this->lock); } METHOD(updown_handler_t, create_dns_enumerator, enumerator_t*, diff --git a/src/libcharon/plugins/updown/updown_listener.c b/src/libcharon/plugins/updown/updown_listener.c index 1d15cc55e..be65d599f 100644 --- a/src/libcharon/plugins/updown/updown_listener.c +++ b/src/libcharon/plugins/updown/updown_listener.c @@ -243,6 +243,7 @@ static void invoke_once(private_updown_listener_t *this, ike_sa_t *ike_sa, me = ike_sa->get_my_host(ike_sa); other = ike_sa->get_other_host(ike_sa); + push_env(envp, countof(envp), "PATH=%s", getenv("PATH")); push_env(envp, countof(envp), "PLUTO_VERSION=1.1"); is_host = my_ts->is_host(my_ts, me); if (is_host) diff --git a/src/libcharon/plugins/updown/updown_plugin.c b/src/libcharon/plugins/updown/updown_plugin.c index d30267dee..60ecfcce6 100644 --- a/src/libcharon/plugins/updown/updown_plugin.c +++ b/src/libcharon/plugins/updown/updown_plugin.c @@ -18,7 +18,6 @@ #include "updown_handler.h" #include <daemon.h> -#include <hydra.h> typedef struct private_updown_plugin_t private_updown_plugin_t; @@ -61,8 +60,8 @@ static bool plugin_cb(private_updown_plugin_t *this, "%s.plugins.updown.dns_handler", FALSE, lib->ns)) { this->handler = updown_handler_create(); - hydra->attributes->add_handler(hydra->attributes, - &this->handler->handler); + charon->attributes->add_handler(charon->attributes, + &this->handler->handler); } this->listener = updown_listener_create(this->handler); charon->bus->add_listener(charon->bus, &this->listener->listener); @@ -74,8 +73,8 @@ static bool plugin_cb(private_updown_plugin_t *this, if (this->handler) { this->handler->destroy(this->handler); - hydra->attributes->remove_handler(hydra->attributes, - &this->handler->handler); + charon->attributes->remove_handler(charon->attributes, + &this->handler->handler); } } return TRUE; diff --git a/src/libcharon/plugins/vici/Makefile.am b/src/libcharon/plugins/vici/Makefile.am index da71de394..b25396085 100644 --- a/src/libcharon/plugins/vici/Makefile.am +++ b/src/libcharon/plugins/vici/Makefile.am @@ -74,3 +74,7 @@ SUBDIRS = if USE_RUBY_GEMS SUBDIRS += ruby endif + +if USE_PYTHON_EGGS +SUBDIRS += python +endif diff --git a/src/libcharon/plugins/vici/Makefile.in b/src/libcharon/plugins/vici/Makefile.in index 34546b905..b63226daa 100644 --- a/src/libcharon/plugins/vici/Makefile.in +++ b/src/libcharon/plugins/vici/Makefile.in @@ -81,6 +81,7 @@ host_triplet = @host@ TESTS = vici_tests$(EXEEXT) check_PROGRAMS = $(am__EXEEXT_1) @USE_RUBY_GEMS_TRUE@am__append_1 = ruby +@USE_PYTHON_EGGS_TRUE@am__append_2 = python subdir = src/libcharon/plugins/vici DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp @@ -269,7 +270,7 @@ am__tty_colors = { \ std='[m'; \ fi; \ } -DIST_SUBDIRS = ruby +DIST_SUBDIRS = ruby python DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -321,6 +322,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -381,10 +383,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -458,6 +462,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ @@ -571,7 +577,7 @@ vici_tests_LDADD = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ $(top_builddir)/src/libstrongswan/tests/libtest.la -SUBDIRS = $(am__append_1) +SUBDIRS = $(am__append_1) $(am__append_2) all: all-recursive .SUFFIXES: diff --git a/src/libcharon/plugins/vici/README.md b/src/libcharon/plugins/vici/README.md index 272491052..0ce4271b0 100644 --- a/src/libcharon/plugins/vici/README.md +++ b/src/libcharon/plugins/vici/README.md @@ -145,25 +145,25 @@ the following C array: char msg[] = { /* key1 = value1 */ - 2, 4,'k','e','y','1', 0,6,'v','a','l','u','e','1', + 3, 4,'k','e','y','1', 0,6,'v','a','l','u','e','1', /* section1 */ - 0, 8,'s','e','c','t','i','o','n','1', + 1, 8,'s','e','c','t','i','o','n','1', /* sub-section */ - 0, 11,'s','u','b','-','s','e','c','t','i','o','n', + 1, 11,'s','u','b','-','s','e','c','t','i','o','n', /* key2 = value2 */ - 2, 4,'k','e','y','2', 0,6,'v','a','l','u','e','2', + 3, 4,'k','e','y','2', 0,6,'v','a','l','u','e','2', /* sub-section end */ - 1, + 2, /* list1 */ - 3, 5, 'l','i','s','t','1', + 4, 5, 'l','i','s','t','1', /* item1 */ - 4, 0,5,'i','t','e','m','1', + 5, 0,5,'i','t','e','m','1', /* item2 */ - 4, 0,5,'i','t','e','m','2', + 5, 0,5,'i','t','e','m','2', /* list1 end */ - 5, + 6, /* section1 end */ - 1, + 2, }; ## Client-initiated commands ## @@ -559,6 +559,7 @@ command. ] child-sas = { <child-sa-name>* = { + uniqueid = <unique CHILD_SA identifier> reqid = <reqid of CHILD_SA> state = <state string of CHILD_SA> mode = <IPsec mode, tunnel|transport|beet> @@ -820,9 +821,9 @@ during encoding. ## Connecting to the daemon ## -To create a connection to the daemon, a socket must be passed to the -_Connection_ constructor. There is no default, but on Unix systems usually -a Unix socket over _/var/run/charon.vici_ is used: +To create a connection to the daemon, a socket can be passed to the +_Connection_ constructor. If none is passed, a default Unix socket at +_/var/run/charon.vici_ is used: require "vici" require "socket" @@ -854,3 +855,73 @@ _list-conns_ command and implicitly the _list-conn_ event: For more details about the ruby gem refer to the comments in the gem source code or the generated documentation. + +# vici Python egg # + +The _vici Python egg_ is a pure Python implementation of the VICI protocol to +implement client applications. It is provided in the _python_ subdirectory, and +gets built and installed if strongSwan has been _./configure_'d with +_--enable-vici_ and _--enable-python-eggs_. + +The _vici_ module provides a _Session()_ constructor for a high level interface, +the underlying classes are usually not required to build Python applications +using VICI. The _Session_ class provides methods for the supported VICI +commands. + +To represent the VICI message data tree, the library converts the binary +encoding to Python data types. The _Session_ class takes and returns Python +objects for the exchanged message data: + * Sections get encoded as OrderedDict, containing other sections, or + * Key/Values, where the values are strings as dictionary values + * Lists get encoded as Python Lists with string values +Values that do not conform to Python dict or list get converted to strings using +str(). + +## Connecting to the daemon ## + +To create a connection to the daemon, a socket can be passed to the _Session_ +constructor. If none is passed, a default Unix socket at _/var/run/charon.vici_ +is used: + + import vici + import socket + + s = socket.socket(socket.AF_UNIX) + s.connect("/var/run/charon.vici") + v = vici.Session(s) + +## A simple client request ## + +An example to print the daemon version information is as simple as: + + ver = v.version() + + print "{daemon} {version} ({sysname}, {release}, {machine})".format(**ver) + +## A request with response iteration ## + +The _Session_ class returns an iterable Python generator for streamed events to +continuously stream objects to the caller. The following example lists all +loaded connections using the _list-conns_ command and implicitly the _list-conn_ +event: + + for conn in v.list_conns(): + for key in conn: + print key + +Please note that if the returned generator is not iterated completely, it must +be closed using _close()_. This is implicitly done when breaking from a loop, +but an explicit call may be required when directly iterating the generator with +_next()_. + +## Sorting in dictionaries ## + +In VICI, in some message trees the order of objects in dictionary matters. In +contrast to ruby Hashes, Python dictionaries do not preserve order of added +objects. It is therefore recommended to use OrderedDicts instead of the default +dictionaries. Objects returned by the library use OrderedDicts. + +## API documentation ## + +For more details about the Python egg refer to the comments in the Python source +code. diff --git a/src/libcharon/plugins/vici/libvici.c b/src/libcharon/plugins/vici/libvici.c index c0205ccb6..7c98c8b69 100644 --- a/src/libcharon/plugins/vici/libvici.c +++ b/src/libcharon/plugins/vici/libvici.c @@ -427,14 +427,8 @@ vici_res_t* vici_submit(vici_req_t *req, vici_conn_t *conn) void vici_free_req(vici_req_t *req) { - vici_message_t *message; - free(req->name); - message = req->b->finalize(req->b); - if (message) - { - message->destroy(message); - } + req->b->destroy(req->b); free(req); } diff --git a/src/libcharon/plugins/vici/python/LICENSE b/src/libcharon/plugins/vici/python/LICENSE new file mode 100644 index 000000000..111523ca8 --- /dev/null +++ b/src/libcharon/plugins/vici/python/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015 Björn Schuberg + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/src/libcharon/plugins/vici/python/MANIFEST.in b/src/libcharon/plugins/vici/python/MANIFEST.in new file mode 100644 index 000000000..1aba38f67 --- /dev/null +++ b/src/libcharon/plugins/vici/python/MANIFEST.in @@ -0,0 +1 @@ +include LICENSE diff --git a/src/libcharon/plugins/vici/python/Makefile.am b/src/libcharon/plugins/vici/python/Makefile.am new file mode 100644 index 000000000..f51737870 --- /dev/null +++ b/src/libcharon/plugins/vici/python/Makefile.am @@ -0,0 +1,33 @@ +EXTRA_DIST = LICENSE MANIFEST.in \ + setup.py.in \ + vici/test/__init__.py \ + vici/test/test_protocol.py \ + vici/__init__.py \ + vici/compat.py \ + vici/exception.py \ + vici/protocol.py \ + vici/session.py + +setup.py: $(srcdir)/setup.py.in + $(AM_V_GEN) sed \ + -e "s:@EGG_VERSION@:$(PACKAGE_VERSION):" \ + $(srcdir)/setup.py.in > $@ + +all-local: dist/vici-$(PACKAGE_VERSION)-py$(PYTHON_VERSION).egg + +dist/vici-$(PACKAGE_VERSION)-py$(PYTHON_VERSION).egg: $(EXTRA_DIST) setup.py + (cd $(srcdir); $(PYTHON) setup.py bdist_egg \ + -b $(shell readlink -f $(builddir))/build \ + -d $(shell readlink -f $(builddir))/dist) + +clean-local: setup.py + $(PYTHON) setup.py clean -a + rm -rf vici.egg-info dist setup.py + +install-exec-local: dist/vici-$(PACKAGE_VERSION)-py$(PYTHON_VERSION).egg + $(EASY_INSTALL) $(PYTHONEGGINSTALLDIR) \ + dist/vici-$(PACKAGE_VERSION)-py$(PYTHON_VERSION).egg + +if USE_PY_TEST + TESTS = $(PY_TEST) +endif diff --git a/src/_updown_espmark/Makefile.in b/src/libcharon/plugins/vici/python/Makefile.in index 51a0d9a13..3a5e5ea72 100644 --- a/src/_updown_espmark/Makefile.in +++ b/src/libcharon/plugins/vici/python/Makefile.in @@ -13,7 +13,6 @@ # PARTICULAR PURPOSE. @SET_MAKE@ - VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ @@ -78,9 +77,8 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -subdir = src/_updown_espmark -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(dist_ipsec_SCRIPTS) $(dist_man8_MANS) +subdir = src/libcharon/plugins/vici/python +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ $(top_srcdir)/m4/config/ltoptions.m4 \ @@ -98,35 +96,6 @@ mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__installdirs = "$(DESTDIR)$(ipsecdir)" "$(DESTDIR)$(man8dir)" -SCRIPTS = $(dist_ipsec_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -146,10 +115,29 @@ am__can_run_installinfo = \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac -man8dir = $(mandir)/man8 -NROFF = nroff -MANS = $(dist_man8_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red='[0;31m'; \ + grn='[0;32m'; \ + lgn='[1;32m'; \ + blu='[1;34m'; \ + mgn='[0;35m'; \ + brg='[1m'; \ + std='[m'; \ + fi; \ +} DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ @@ -176,6 +164,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -236,10 +225,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -313,6 +304,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ @@ -371,8 +364,17 @@ top_srcdir = @top_srcdir@ urandom_device = @urandom_device@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ -dist_ipsec_SCRIPTS = _updown_espmark -dist_man8_MANS = _updown_espmark.8 +EXTRA_DIST = LICENSE MANIFEST.in \ + setup.py.in \ + vici/test/__init__.py \ + vici/test/test_protocol.py \ + vici/__init__.py \ + vici/compat.py \ + vici/exception.py \ + vici/protocol.py \ + vici/session.py + +@USE_PY_TEST_TRUE@TESTS = $(PY_TEST) all: all-am .SUFFIXES: @@ -385,9 +387,9 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/_updown_espmark/Makefile'; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/plugins/vici/python/Makefile'; \ $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/_updown_espmark/Makefile + $(AUTOMAKE) --gnu src/libcharon/plugins/vici/python/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ @@ -406,88 +408,12 @@ $(top_srcdir)/configure: $(am__configure_deps) $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -install-dist_ipsecSCRIPTS: $(dist_ipsec_SCRIPTS) - @$(NORMAL_INSTALL) - @list='$(dist_ipsec_SCRIPTS)'; test -n "$(ipsecdir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(ipsecdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(ipsecdir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n' \ - -e 'h;s|.*|.|' \ - -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) { files[d] = files[d] " " $$1; \ - if (++n[d] == $(am__install_max)) { \ - print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ - else { print "f", d "/" $$4, $$1 } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(ipsecdir)$$dir'"; \ - $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(ipsecdir)$$dir" || exit $$?; \ - } \ - ; done - -uninstall-dist_ipsecSCRIPTS: - @$(NORMAL_UNINSTALL) - @list='$(dist_ipsec_SCRIPTS)'; test -n "$(ipsecdir)" || exit 0; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 's,.*/,,;$(transform)'`; \ - dir='$(DESTDIR)$(ipsecdir)'; $(am__uninstall_files_from_dir) mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -install-man8: $(dist_man8_MANS) - @$(NORMAL_INSTALL) - @list1='$(dist_man8_MANS)'; \ - list2=''; \ - test -n "$(man8dir)" \ - && test -n "`echo $$list1$$list2`" \ - || exit 0; \ - echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \ - { for i in $$list1; do echo "$$i"; done; \ - if test -n "$$list2"; then \ - for i in $$list2; do echo "$$i"; done \ - | sed -n '/\.8[a-z]*$$/p'; \ - fi; \ - } | while read p; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; echo "$$p"; \ - done | \ - sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ - sed 'N;N;s,\n, ,g' | { \ - list=; while read file base inst; do \ - if test "$$base" = "$$inst"; then list="$$list $$file"; else \ - echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ - $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ - fi; \ - done; \ - for i in $$list; do echo "$$i"; done | $(am__base_list) | \ - while read files; do \ - test -z "$$files" || { \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ - done; } - -uninstall-man8: - @$(NORMAL_UNINSTALL) - @list='$(dist_man8_MANS)'; test -n "$(man8dir)" || exit 0; \ - files=`{ for i in $$list; do echo "$$i"; done; \ - } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: @@ -495,6 +421,99 @@ ctags CTAGS: cscope cscopelist: +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ + test "$$failed" -eq 0; \ + else :; fi + distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -526,12 +545,10 @@ distdir: $(DISTFILES) fi; \ done check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am -all-am: Makefile $(SCRIPTS) $(MANS) +all-am: Makefile all-local installdirs: - for dir in "$(DESTDIR)$(ipsecdir)" "$(DESTDIR)$(man8dir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done install: install-am install-exec: install-exec-am install-data: install-data-am @@ -564,7 +581,7 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-generic clean-libtool mostlyclean-am +clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile @@ -582,13 +599,13 @@ info: info-am info-am: -install-data-am: install-dist_ipsecSCRIPTS install-man +install-data-am: install-dvi: install-dvi-am install-dvi-am: -install-exec-am: +install-exec-am: install-exec-local install-html: install-html-am @@ -598,7 +615,7 @@ install-info: install-info-am install-info-am: -install-man: install-man8 +install-man: install-pdf: install-pdf-am @@ -626,26 +643,43 @@ ps: ps-am ps-am: -uninstall-am: uninstall-dist_ipsecSCRIPTS uninstall-man +uninstall-am: -uninstall-man: uninstall-man8 +.MAKE: check-am install-am install-strip -.MAKE: install-am install-strip - -.PHONY: all all-am check check-am clean clean-generic clean-libtool \ - cscopelist-am ctags-am distclean distclean-generic \ - distclean-libtool distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am \ - install-dist_ipsecSCRIPTS install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-man8 \ +.PHONY: all all-am all-local check check-TESTS check-am clean \ + clean-generic clean-libtool clean-local cscopelist-am ctags-am \ + distclean distclean-generic distclean-libtool distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-exec-local install-html \ + install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags-am uninstall uninstall-am uninstall-dist_ipsecSCRIPTS \ - uninstall-man uninstall-man8 + tags-am uninstall uninstall-am + + +setup.py: $(srcdir)/setup.py.in + $(AM_V_GEN) sed \ + -e "s:@EGG_VERSION@:$(PACKAGE_VERSION):" \ + $(srcdir)/setup.py.in > $@ + +all-local: dist/vici-$(PACKAGE_VERSION)-py$(PYTHON_VERSION).egg + +dist/vici-$(PACKAGE_VERSION)-py$(PYTHON_VERSION).egg: $(EXTRA_DIST) setup.py + (cd $(srcdir); $(PYTHON) setup.py bdist_egg \ + -b $(shell readlink -f $(builddir))/build \ + -d $(shell readlink -f $(builddir))/dist) + +clean-local: setup.py + $(PYTHON) setup.py clean -a + rm -rf vici.egg-info dist setup.py +install-exec-local: dist/vici-$(PACKAGE_VERSION)-py$(PYTHON_VERSION).egg + $(EASY_INSTALL) $(PYTHONEGGINSTALLDIR) \ + dist/vici-$(PACKAGE_VERSION)-py$(PYTHON_VERSION).egg # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/src/libcharon/plugins/vici/python/setup.py.in b/src/libcharon/plugins/vici/python/setup.py.in new file mode 100644 index 000000000..0e4ad8236 --- /dev/null +++ b/src/libcharon/plugins/vici/python/setup.py.in @@ -0,0 +1,34 @@ +from setuptools import setup + + +long_description = ( + "The strongSwan VICI protocol allows external application to monitor, " + "configure and control the IKE daemon charon. This python package provides " + "a native client side implementation of the VICI protocol, well suited to " + "script automated tasks in a reliable way." +) + +setup( + name="vici", + version="@EGG_VERSION@", + description="Native python interface for strongSwan VICI", + author="Bjorn Schuberg", + url="https://wiki.strongswan.org/projects/strongswan/wiki/Vici", + license="MIT", + packages=["vici"], + long_description=long_description, + include_package_data=True, + classifiers=( + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "Intended Audience :: System Administrators", + "License :: OSI Approved :: MIT License", + "Natural Language :: English", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3.2", + "Programming Language :: Python :: 3.3", + "Programming Language :: Python :: 3.4", + "Topic :: Security", + "Topic :: Software Development :: Libraries", + ) +) diff --git a/src/libcharon/plugins/vici/python/vici/__init__.py b/src/libcharon/plugins/vici/python/vici/__init__.py new file mode 100644 index 000000000..d314325b6 --- /dev/null +++ b/src/libcharon/plugins/vici/python/vici/__init__.py @@ -0,0 +1 @@ +from .session import Session diff --git a/src/libcharon/plugins/vici/python/vici/compat.py b/src/libcharon/plugins/vici/python/vici/compat.py new file mode 100644 index 000000000..b5f46992e --- /dev/null +++ b/src/libcharon/plugins/vici/python/vici/compat.py @@ -0,0 +1,14 @@ +# Help functions for compatibility between python version 2 and 3 + + +# From http://legacy.python.org/dev/peps/pep-0469 +try: + dict.iteritems +except AttributeError: + # python 3 + def iteritems(d): + return iter(d.items()) +else: + # python 2 + def iteritems(d): + return d.iteritems() diff --git a/src/libcharon/plugins/vici/python/vici/exception.py b/src/libcharon/plugins/vici/python/vici/exception.py new file mode 100644 index 000000000..36384e556 --- /dev/null +++ b/src/libcharon/plugins/vici/python/vici/exception.py @@ -0,0 +1,10 @@ +"""Exception types that may be thrown by this library.""" + +class DeserializationException(Exception): + """Encountered an unexpected byte sequence or missing element type.""" + +class SessionException(Exception): + """Session request exception.""" + +class CommandException(Exception): + """Command result exception.""" diff --git a/src/libcharon/plugins/vici/python/vici/protocol.py b/src/libcharon/plugins/vici/python/vici/protocol.py new file mode 100644 index 000000000..855a7b2e2 --- /dev/null +++ b/src/libcharon/plugins/vici/python/vici/protocol.py @@ -0,0 +1,196 @@ +import io +import socket +import struct + +from collections import namedtuple +from collections import OrderedDict + +from .compat import iteritems +from .exception import DeserializationException + + +class Transport(object): + HEADER_LENGTH = 4 + MAX_SEGMENT = 512 * 1024 + + def __init__(self, sock): + self.socket = sock + + def send(self, packet): + self.socket.sendall(struct.pack("!I", len(packet)) + packet) + + def receive(self): + raw_length = self.socket.recv(self.HEADER_LENGTH) + length, = struct.unpack("!I", raw_length) + payload = self.socket.recv(length) + return payload + + def close(self): + self.socket.shutdown(socket.SHUT_RDWR) + self.socket.close() + + +class Packet(object): + CMD_REQUEST = 0 # Named request message + CMD_RESPONSE = 1 # Unnamed response message for a request + CMD_UNKNOWN = 2 # Unnamed response if requested command is unknown + EVENT_REGISTER = 3 # Named event registration request + EVENT_UNREGISTER = 4 # Named event de-registration request + EVENT_CONFIRM = 5 # Unnamed confirmation for event (de-)registration + EVENT_UNKNOWN = 6 # Unnamed response if event (de-)registration failed + EVENT = 7 # Named event message + + ParsedPacket = namedtuple( + "ParsedPacket", + ["response_type", "payload"] + ) + + ParsedEventPacket = namedtuple( + "ParsedEventPacket", + ["response_type", "event_type", "payload"] + ) + + @classmethod + def _named_request(cls, request_type, request, message=None): + request = request.encode() + payload = struct.pack("!BB", request_type, len(request)) + request + if message is not None: + return payload + message + else: + return payload + + @classmethod + def request(cls, command, message=None): + return cls._named_request(cls.CMD_REQUEST, command, message) + + @classmethod + def register_event(cls, event_type): + return cls._named_request(cls.EVENT_REGISTER, event_type) + + @classmethod + def unregister_event(cls, event_type): + return cls._named_request(cls.EVENT_UNREGISTER, event_type) + + @classmethod + def parse(cls, packet): + stream = FiniteStream(packet) + response_type, = struct.unpack("!B", stream.read(1)) + + if response_type == cls.EVENT: + length, = struct.unpack("!B", stream.read(1)) + event_type = stream.read(length) + return cls.ParsedEventPacket(response_type, event_type, stream) + else: + return cls.ParsedPacket(response_type, stream) + + +class Message(object): + SECTION_START = 1 # Begin a new section having a name + SECTION_END = 2 # End a previously started section + KEY_VALUE = 3 # Define a value for a named key in the section + LIST_START = 4 # Begin a named list for list items + LIST_ITEM = 5 # Define an unnamed item value in the current list + LIST_END = 6 # End a previously started list + + @classmethod + def serialize(cls, message): + def encode_named_type(marker, name): + name = name.encode() + return struct.pack("!BB", marker, len(name)) + name + + def encode_blob(value): + if not isinstance(value, bytes): + value = str(value).encode() + return struct.pack("!H", len(value)) + value + + def serialize_list(lst): + segment = bytes() + for item in lst: + segment += struct.pack("!B", cls.LIST_ITEM) + encode_blob(item) + return segment + + def serialize_dict(d): + segment = bytes() + for key, value in iteritems(d): + if isinstance(value, dict): + segment += ( + encode_named_type(cls.SECTION_START, key) + + serialize_dict(value) + + struct.pack("!B", cls.SECTION_END) + ) + elif isinstance(value, list): + segment += ( + encode_named_type(cls.LIST_START, key) + + serialize_list(value) + + struct.pack("!B", cls.LIST_END) + ) + else: + segment += ( + encode_named_type(cls.KEY_VALUE, key) + + encode_blob(value) + ) + return segment + + return serialize_dict(message) + + @classmethod + def deserialize(cls, stream): + def decode_named_type(stream): + length, = struct.unpack("!B", stream.read(1)) + return stream.read(length).decode() + + def decode_blob(stream): + length, = struct.unpack("!H", stream.read(2)) + return stream.read(length) + + def decode_list_item(stream): + marker, = struct.unpack("!B", stream.read(1)) + while marker == cls.LIST_ITEM: + yield decode_blob(stream) + marker, = struct.unpack("!B", stream.read(1)) + + if marker != cls.LIST_END: + raise DeserializationException( + "Expected end of list at {pos}".format(pos=stream.tell()) + ) + + section = OrderedDict() + section_stack = [] + while stream.has_more(): + element_type, = struct.unpack("!B", stream.read(1)) + if element_type == cls.SECTION_START: + section_name = decode_named_type(stream) + new_section = OrderedDict() + section[section_name] = new_section + section_stack.append(section) + section = new_section + + elif element_type == cls.LIST_START: + list_name = decode_named_type(stream) + section[list_name] = [item for item in decode_list_item(stream)] + + elif element_type == cls.KEY_VALUE: + key = decode_named_type(stream) + section[key] = decode_blob(stream) + + elif element_type == cls.SECTION_END: + if len(section_stack): + section = section_stack.pop() + else: + raise DeserializationException( + "Unexpected end of section at {pos}".format( + pos=stream.tell() + ) + ) + + if len(section_stack): + raise DeserializationException("Expected end of section") + return section + + +class FiniteStream(io.BytesIO): + def __len__(self): + return len(self.getvalue()) + + def has_more(self): + return self.tell() < len(self) diff --git a/src/libcharon/plugins/vici/python/vici/session.py b/src/libcharon/plugins/vici/python/vici/session.py new file mode 100644 index 000000000..dee58699d --- /dev/null +++ b/src/libcharon/plugins/vici/python/vici/session.py @@ -0,0 +1,327 @@ +import collections +import socket + +from .exception import SessionException, CommandException +from .protocol import Transport, Packet, Message + + +class Session(object): + def __init__(self, sock=None): + if sock is None: + sock = socket.socket(socket.AF_UNIX) + sock.connect("/var/run/charon.vici") + self.handler = SessionHandler(Transport(sock)) + + def version(self): + """Retrieve daemon and system specific version information. + + :return: daemon and system specific version information + :rtype: dict + """ + return self.handler.request("version") + + def stats(self): + """Retrieve IKE daemon statistics and load information. + + :return: IKE daemon statistics and load information + :rtype: dict + """ + return self.handler.request("stats") + + def reload_settings(self): + """Reload strongswan.conf settings and any plugins supporting reload. + """ + self.handler.request("reload-settings") + + def initiate(self, sa): + """Initiate an SA. + + :param sa: the SA to initiate + :type sa: dict + :return: generator for logs emitted as dict + :rtype: generator + """ + return self.handler.streamed_request("initiate", "control-log", sa) + + def terminate(self, sa): + """Terminate an SA. + + :param sa: the SA to terminate + :type sa: dict + :return: generator for logs emitted as dict + :rtype: generator + """ + return self.handler.streamed_request("terminate", "control-log", sa) + + def install(self, policy): + """Install a trap, drop or bypass policy defined by a CHILD_SA config. + + :param policy: policy to install + :type policy: dict + """ + self.handler.request("install", policy) + + def uninstall(self, policy): + """Uninstall a trap, drop or bypass policy defined by a CHILD_SA config. + + :param policy: policy to uninstall + :type policy: dict + """ + self.handler.request("uninstall", policy) + + def list_sas(self, filters=None): + """Retrieve active IKE_SAs and associated CHILD_SAs. + + :param filters: retrieve only matching IKE_SAs (optional) + :type filters: dict + :return: generator for active IKE_SAs and associated CHILD_SAs as dict + :rtype: generator + """ + return self.handler.streamed_request("list-sas", "list-sa", filters) + + def list_policies(self, filters=None): + """Retrieve installed trap, drop and bypass policies. + + :param filters: retrieve only matching policies (optional) + :type filters: dict + :return: generator for installed trap, drop and bypass policies as dict + :rtype: generator + """ + return self.handler.streamed_request("list-policies", "list-policy", + filters) + + def list_conns(self, filters=None): + """Retrieve loaded connections. + + :param filters: retrieve only matching configuration names (optional) + :type filters: dict + :return: generator for loaded connections as dict + :rtype: generator + """ + return self.handler.streamed_request("list-conns", "list-conn", + filters) + + def get_conns(self): + """Retrieve connection names loaded exclusively over vici. + + :return: connection names + :rtype: dict + """ + return self.handler.request("get-conns") + + def list_certs(self, filters=None): + """Retrieve loaded certificates. + + :param filters: retrieve only matching certificates (optional) + :type filters: dict + :return: generator for loaded certificates as dict + :rtype: generator + """ + return self.handler.streamed_request("list-certs", "list-cert", filters) + + def load_conn(self, connection): + """Load a connection definition into the daemon. + + :param connection: connection definition + :type connection: dict + """ + self.handler.request("load-conn", connection) + + def unload_conn(self, name): + """Unload a connection definition. + + :param name: connection definition name + :type name: dict + """ + self.handler.request("unload-conn", name) + + def load_cert(self, certificate): + """Load a certificate into the daemon. + + :param certificate: PEM or DER encoded certificate + :type certificate: dict + """ + self.handler.request("load-cert", certificate) + + def load_key(self, private_key): + """Load a private key into the daemon. + + :param private_key: PEM or DER encoded key + """ + self.handler.request("load-key", private_key) + + def load_shared(self, secret): + """Load a shared IKE PSK, EAP or XAuth secret into the daemon. + + :param secret: shared IKE PSK, EAP or XAuth secret + :type secret: dict + """ + self.handler.request("load-shared", secret) + + def clear_creds(self): + """Clear credentials loaded over vici. + + Clear all loaded certificate, private key and shared key credentials. + This affects only credentials loaded over vici, but additionally + flushes the credential cache. + """ + self.handler.request("clear-creds") + + def load_pool(self, pool): + """Load a virtual IP pool. + + Load an in-memory virtual IP and configuration attribute pool. + Existing pools with the same name get updated, if possible. + + :param pool: virtual IP and configuration attribute pool + :type pool: dict + """ + return self.handler.request("load-pool", pool) + + def unload_pool(self, pool_name): + """Unload a virtual IP pool. + + Unload a previously loaded virtual IP and configuration attribute pool. + Unloading fails for pools with leases currently online. + + :param pool_name: pool by name + :type pool_name: dict + """ + self.handler.request("unload-pool", pool_name) + + def get_pools(self): + """Retrieve loaded pools. + + :return: loaded pools + :rtype: dict + """ + return self.handler.request("get-pools") + + +class SessionHandler(object): + """Handles client command execution requests over vici.""" + + def __init__(self, transport): + self.transport = transport + + def _communicate(self, packet): + """Send packet over transport and parse response. + + :param packet: packet to send + :type packet: :py:class:`vici.protocol.Packet` + :return: parsed packet in a tuple with message type and payload + :rtype: :py:class:`collections.namedtuple` + """ + self.transport.send(packet) + return Packet.parse(self.transport.receive()) + + def request(self, command, message=None): + """Send request with an optional message. + + :param command: command to send + :type command: str + :param message: message (optional) + :type message: str + :return: command result + :rtype: dict + """ + if message is not None: + message = Message.serialize(message) + packet = Packet.request(command, message) + response = self._communicate(packet) + + if response.response_type != Packet.CMD_RESPONSE: + raise SessionException( + "Unexpected response type {type}, " + "expected '{response}' (CMD_RESPONSE)".format( + type=response.response_type, + response=Packet.CMD_RESPONSE + ) + ) + + command_response = Message.deserialize(response.payload) + if "success" in command_response: + if command_response["success"] != b"yes": + raise CommandException( + "Command failed: {errmsg}".format( + errmsg=command_response["errmsg"] + ) + ) + + return command_response + + def streamed_request(self, command, event_stream_type, message=None): + """Send command request and collect and return all emitted events. + + :param command: command to send + :type command: str + :param event_stream_type: event type emitted on command execution + :type event_stream_type: str + :param message: message (optional) + :type message: str + :return: generator for streamed event responses as dict + :rtype: generator + """ + if message is not None: + message = Message.serialize(message) + + # subscribe to event stream + packet = Packet.register_event(event_stream_type) + response = self._communicate(packet) + + if response.response_type != Packet.EVENT_CONFIRM: + raise SessionException( + "Unexpected response type {type}, " + "expected '{confirm}' (EVENT_CONFIRM)".format( + type=response.response_type, + confirm=Packet.EVENT_CONFIRM, + ) + ) + + # issue command, and read any event messages + packet = Packet.request(command, message) + self.transport.send(packet) + exited = False + while True: + response = Packet.parse(self.transport.receive()) + if response.response_type == Packet.EVENT: + if not exited: + try: + yield Message.deserialize(response.payload) + except GeneratorExit: + exited = True + pass + else: + break + + if response.response_type == Packet.CMD_RESPONSE: + command_response = Message.deserialize(response.payload) + else: + raise SessionException( + "Unexpected response type {type}, " + "expected '{response}' (CMD_RESPONSE)".format( + type=response.response_type, + response=Packet.CMD_RESPONSE + ) + ) + + # unsubscribe from event stream + packet = Packet.unregister_event(event_stream_type) + response = self._communicate(packet) + if response.response_type != Packet.EVENT_CONFIRM: + raise SessionException( + "Unexpected response type {type}, " + "expected '{confirm}' (EVENT_CONFIRM)".format( + type=response.response_type, + confirm=Packet.EVENT_CONFIRM, + ) + ) + + # evaluate command result, if any + if "success" in command_response: + if command_response["success"] != b"yes": + raise CommandException( + "Command failed: {errmsg}".format( + errmsg=command_response["errmsg"] + ) + ) diff --git a/src/libcharon/plugins/vici/python/vici/test/__init__.py b/src/libcharon/plugins/vici/python/vici/test/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/src/libcharon/plugins/vici/python/vici/test/__init__.py diff --git a/src/libcharon/plugins/vici/python/vici/test/test_protocol.py b/src/libcharon/plugins/vici/python/vici/test/test_protocol.py new file mode 100644 index 000000000..a1f202d79 --- /dev/null +++ b/src/libcharon/plugins/vici/python/vici/test/test_protocol.py @@ -0,0 +1,144 @@ +import pytest + +from ..protocol import Packet, Message, FiniteStream +from ..exception import DeserializationException + + +class TestPacket(object): + # test data definitions for outgoing packet types + cmd_request = b"\x00\x0c" b"command_type" + cmd_request_msg = b"\x00\x07" b"command" b"payload" + event_register = b"\x03\x0a" b"event_type" + event_unregister = b"\x04\x0a" b"event_type" + + # test data definitions for incoming packet types + cmd_response = b"\x01" b"reply" + cmd_unknown = b"\x02" + event_confirm = b"\x05" + event_unknown = b"\x06" + event = b"\x07\x03" b"log" b"message" + + def test_request(self): + assert Packet.request("command_type") == self.cmd_request + assert Packet.request("command", b"payload") == self.cmd_request_msg + + def test_register_event(self): + assert Packet.register_event("event_type") == self.event_register + + def test_unregister_event(self): + assert Packet.unregister_event("event_type") == self.event_unregister + + def test_parse(self): + parsed_cmd_response = Packet.parse(self.cmd_response) + assert parsed_cmd_response.response_type == Packet.CMD_RESPONSE + assert parsed_cmd_response.payload.getvalue() == self.cmd_response + + parsed_cmd_unknown = Packet.parse(self.cmd_unknown) + assert parsed_cmd_unknown.response_type == Packet.CMD_UNKNOWN + assert parsed_cmd_unknown.payload.getvalue() == self.cmd_unknown + + parsed_event_confirm = Packet.parse(self.event_confirm) + assert parsed_event_confirm.response_type == Packet.EVENT_CONFIRM + assert parsed_event_confirm.payload.getvalue() == self.event_confirm + + parsed_event_unknown = Packet.parse(self.event_unknown) + assert parsed_event_unknown.response_type == Packet.EVENT_UNKNOWN + assert parsed_event_unknown.payload.getvalue() == self.event_unknown + + parsed_event = Packet.parse(self.event) + assert parsed_event.response_type == Packet.EVENT + assert parsed_event.payload.getvalue() == self.event + + +class TestMessage(object): + """Message (de)serialization test.""" + + # data definitions for test of de(serialization) + # serialized messages holding a section + ser_sec_unclosed = b"\x01\x08unclosed" + ser_sec_single = b"\x01\x07section\x02" + ser_sec_nested = b"\x01\x05outer\x01\x0asubsection\x02\x02" + + # serialized messages holding a list + ser_list_invalid = b"\x04\x07invalid\x05\x00\x02e1\x02\x03sec\x06" + ser_list_0_item = b"\x04\x05empty\x06" + ser_list_1_item = b"\x04\x01l\x05\x00\x02e1\x06" + ser_list_2_item = b"\x04\x01l\x05\x00\x02e1\x05\x00\x02e2\x06" + + # serialized messages with key value pairs + ser_kv_pair = b"\x03\x03key\x00\x05value" + ser_kv_zero = b"\x03\x0azerolength\x00\x00" + + # deserialized messages holding a section + des_sec_single = { "section": {} } + des_sec_nested = { "outer": { "subsection": {} } } + + # deserialized messages holding a list + des_list_0_item = { "empty": [] } + des_list_1_item = { "l": [ b"e1" ] } + des_list_2_item = { "l": [ b"e1", b"e2" ] } + + # deserialized messages with key value pairs + des_kv_pair = { "key": b"value" } + des_kv_zero = { "zerolength": b"" } + + def test_section_serialization(self): + assert Message.serialize(self.des_sec_single) == self.ser_sec_single + assert Message.serialize(self.des_sec_nested) == self.ser_sec_nested + + def test_list_serialization(self): + assert Message.serialize(self.des_list_0_item) == self.ser_list_0_item + assert Message.serialize(self.des_list_1_item) == self.ser_list_1_item + assert Message.serialize(self.des_list_2_item) == self.ser_list_2_item + + def test_key_serialization(self): + assert Message.serialize(self.des_kv_pair) == self.ser_kv_pair + assert Message.serialize(self.des_kv_zero) == self.ser_kv_zero + + def test_section_deserialization(self): + single = Message.deserialize(FiniteStream(self.ser_sec_single)) + nested = Message.deserialize(FiniteStream(self.ser_sec_nested)) + + assert single == self.des_sec_single + assert nested == self.des_sec_nested + + with pytest.raises(DeserializationException): + Message.deserialize(FiniteStream(self.ser_sec_unclosed)) + + def test_list_deserialization(self): + l0 = Message.deserialize(FiniteStream(self.ser_list_0_item)) + l1 = Message.deserialize(FiniteStream(self.ser_list_1_item)) + l2 = Message.deserialize(FiniteStream(self.ser_list_2_item)) + + assert l0 == self.des_list_0_item + assert l1 == self.des_list_1_item + assert l2 == self.des_list_2_item + + with pytest.raises(DeserializationException): + Message.deserialize(FiniteStream(self.ser_list_invalid)) + + def test_key_deserialization(self): + pair = Message.deserialize(FiniteStream(self.ser_kv_pair)) + zerolength = Message.deserialize(FiniteStream(self.ser_kv_zero)) + + assert pair == self.des_kv_pair + assert zerolength == self.des_kv_zero + + def test_roundtrip(self): + message = { + "key1": "value1", + "section1": { + "sub-section": { + "key2": b"value2", + }, + "list1": [ "item1", "item2" ], + }, + } + serialized_message = FiniteStream(Message.serialize(message)) + deserialized_message = Message.deserialize(serialized_message) + + # ensure that list items and key values remain as undecoded bytes + deserialized_section = deserialized_message["section1"] + assert deserialized_message["key1"] == b"value1" + assert deserialized_section["sub-section"]["key2"] == b"value2" + assert deserialized_section["list1"] == [ b"item1", b"item2" ] diff --git a/src/libcharon/plugins/vici/ruby/Makefile.am b/src/libcharon/plugins/vici/ruby/Makefile.am index ce38e1c3d..3e12f86cc 100644 --- a/src/libcharon/plugins/vici/ruby/Makefile.am +++ b/src/libcharon/plugins/vici/ruby/Makefile.am @@ -5,8 +5,10 @@ vici.gemspec: $(srcdir)/vici.gemspec.in -e "s:@GEM_VERSION@:$(PACKAGE_VERSION):" \ $(srcdir)/vici.gemspec.in > $@ -vici-$(PACKAGE_VERSION).gem: vici.gemspec - $(GEM) build vici.gemspec +vici-$(PACKAGE_VERSION).gem: vici.gemspec $(EXTRA_DIST) + (cd $(srcdir); $(GEM) build $(abs_builddir)/vici.gemspec) + [ "$(srcdir)" = "$(builddir)" ] || \ + mv $(srcdir)/vici-$(PACKAGE_VERSION).gem $(builddir) all-local: vici-$(PACKAGE_VERSION).gem diff --git a/src/libcharon/plugins/vici/ruby/Makefile.in b/src/libcharon/plugins/vici/ruby/Makefile.in index c8a8c11fb..f37c09ea2 100644 --- a/src/libcharon/plugins/vici/ruby/Makefile.in +++ b/src/libcharon/plugins/vici/ruby/Makefile.in @@ -142,6 +142,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -202,10 +203,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -279,6 +282,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ @@ -535,8 +540,10 @@ vici.gemspec: $(srcdir)/vici.gemspec.in -e "s:@GEM_VERSION@:$(PACKAGE_VERSION):" \ $(srcdir)/vici.gemspec.in > $@ -vici-$(PACKAGE_VERSION).gem: vici.gemspec - $(GEM) build vici.gemspec +vici-$(PACKAGE_VERSION).gem: vici.gemspec $(EXTRA_DIST) + (cd $(srcdir); $(GEM) build $(abs_builddir)/vici.gemspec) + [ "$(srcdir)" = "$(builddir)" ] || \ + mv $(srcdir)/vici-$(PACKAGE_VERSION).gem $(builddir) all-local: vici-$(PACKAGE_VERSION).gem diff --git a/src/libcharon/plugins/vici/ruby/lib/vici.rb b/src/libcharon/plugins/vici/ruby/lib/vici.rb index e8a9ddca9..f87e46e69 100644 --- a/src/libcharon/plugins/vici/ruby/lib/vici.rb +++ b/src/libcharon/plugins/vici/ruby/lib/vici.rb @@ -243,6 +243,25 @@ module Vici end ## + # Receive data from socket, until len bytes read + def recv_all(len) + encoding = "" + while encoding.length < len do + encoding << @socket.recv(len - encoding.length) + end + encoding + end + + ## + # Send data to socket, until all bytes sent + def send_all(encoding) + len = 0 + while len < encoding.length do + len += @socket.send(encoding[len..-1], 0) + end + end + + ## # Write a packet prefixed by its length over the transport socket. Type # specifies the message, the optional label and message get appended. def write(type, label, message) @@ -253,15 +272,15 @@ module Vici if message encoding << message.encoding end - @socket.send([encoding.length + 1, type].pack("Nc") + encoding, 0) + send_all([encoding.length + 1, type].pack("Nc") + encoding) end ## # Read a packet from the transport socket. Returns the packet type, and # if available in the packet a label and the contained message. def read - len = @socket.recv(4).unpack("N")[0] - encoding = @socket.recv(len) + len = recv_all(4).unpack("N")[0] + encoding = recv_all(len) type = encoding.unpack("c")[0] len = 1 case type @@ -371,7 +390,10 @@ module Vici # during encoding. class Connection - def initialize(socket) + def initialize(socket = nil) + if socket == nil + socket = UNIXSocket.new("/var/run/charon.vici") + end @transp = Transport.new(socket) end diff --git a/src/libcharon/plugins/vici/ruby/vici.gemspec.in b/src/libcharon/plugins/vici/ruby/vici.gemspec.in index 5ad61c0a0..2bd2b3d88 100644 --- a/src/libcharon/plugins/vici/ruby/vici.gemspec.in +++ b/src/libcharon/plugins/vici/ruby/vici.gemspec.in @@ -2,7 +2,7 @@ Gem::Specification.new do |s| s.name = "vici" s.version = "@GEM_VERSION@" s.authors = ["Martin Willi"] - s.email = ["martin@strongswan.ch"] + s.email = ["martin@strongswan.org"] s.description = %q{ The strongSwan VICI protocol allows external application to monitor, configure and control the IKE daemon charon. This ruby gem provides a diff --git a/src/libcharon/plugins/vici/vici_attribute.c b/src/libcharon/plugins/vici/vici_attribute.c index 2178116c9..f04bae774 100644 --- a/src/libcharon/plugins/vici/vici_attribute.c +++ b/src/libcharon/plugins/vici/vici_attribute.c @@ -1,4 +1,7 @@ /* + * Copyright (C) 2014 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2014 Martin Willi * Copyright (C) 2014 revosec AG * @@ -93,7 +96,8 @@ static void pool_destroy(pool_t *pool) * Find an existing or not yet existing lease */ static host_t *find_addr(private_vici_attribute_t *this, linked_list_t *pools, - identification_t *id, host_t *requested, mem_pool_op_t op) + identification_t *id, host_t *requested, + mem_pool_op_t op, host_t *peer) { enumerator_t *enumerator; host_t *addr = NULL; @@ -106,7 +110,8 @@ static host_t *find_addr(private_vici_attribute_t *this, linked_list_t *pools, pool = this->pools->get(this->pools, name); if (pool) { - addr = pool->vips->acquire_address(pool->vips, id, requested, op); + addr = pool->vips->acquire_address(pool->vips, id, requested, + op, peer); if (addr) { break; @@ -119,20 +124,24 @@ static host_t *find_addr(private_vici_attribute_t *this, linked_list_t *pools, } METHOD(attribute_provider_t, acquire_address, host_t*, - private_vici_attribute_t *this, linked_list_t *pools, identification_t *id, + private_vici_attribute_t *this, linked_list_t *pools, ike_sa_t *ike_sa, host_t *requested) { - host_t *addr; + identification_t *id; + host_t *addr, *peer; + + id = ike_sa->get_other_eap_id(ike_sa); + peer = ike_sa->get_other_host(ike_sa); this->lock->read_lock(this->lock); - addr = find_addr(this, pools, id, requested, MEM_POOL_EXISTING); + addr = find_addr(this, pools, id, requested, MEM_POOL_EXISTING, peer); if (!addr) { - addr = find_addr(this, pools, id, requested, MEM_POOL_NEW); + addr = find_addr(this, pools, id, requested, MEM_POOL_NEW, peer); if (!addr) { - addr = find_addr(this, pools, id, requested, MEM_POOL_REASSIGN); + addr = find_addr(this, pools, id, requested, MEM_POOL_REASSIGN, peer); } } @@ -143,13 +152,16 @@ METHOD(attribute_provider_t, acquire_address, host_t*, METHOD(attribute_provider_t, release_address, bool, private_vici_attribute_t *this, linked_list_t *pools, host_t *address, - identification_t *id) + ike_sa_t *ike_sa) { enumerator_t *enumerator; + identification_t *id; bool found = FALSE; pool_t *pool; char *name; + id = ike_sa->get_other_eap_id(ike_sa); + this->lock->read_lock(this->lock); enumerator = pools->create_enumerator(pools); @@ -256,7 +268,7 @@ static bool have_vips_from_pool(mem_pool_t *pool, linked_list_t *vips) METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, private_vici_attribute_t *this, linked_list_t *pools, - identification_t *id, linked_list_t *vips) + ike_sa_t *ike_sa, linked_list_t *vips) { enumerator_t *enumerator; nested_data_t *data; @@ -355,6 +367,24 @@ static vici_message_t* create_reply(char *fmt, ...) } /** + * Parse a range definition of an address pool + */ +static mem_pool_t *create_pool_range(char *name, char *buf) +{ + mem_pool_t *pool; + host_t *from, *to; + + if (!host_create_from_range(buf, &from, &to)) + { + return NULL; + } + pool = mem_pool_create_range(name, from, to); + from->destroy(from); + to->destroy(to); + return pool; +} + +/** * Parse callback data, passed to each callback */ typedef struct { @@ -490,7 +520,8 @@ CALLBACK(pool_kv, bool, if (streq(name, "addrs")) { char buf[128]; - host_t *base; + mem_pool_t *pool; + host_t *base = NULL; int bits; if (data->pool->vips) @@ -503,14 +534,22 @@ CALLBACK(pool_kv, bool, data->request->reply = create_reply("invalid addrs value"); return FALSE; } - base = host_create_from_subnet(buf, &bits); - if (!base) + pool = create_pool_range(data->name, buf); + if (!pool) + { + base = host_create_from_subnet(buf, &bits); + if (base) + { + pool = mem_pool_create(data->name, base, bits); + base->destroy(base); + } + } + if (!pool) { data->request->reply = create_reply("invalid addrs value: %s", buf); return FALSE; } - data->pool->vips = mem_pool_create(data->name, base, bits); - base->destroy(base); + data->pool->vips = pool; return TRUE; } data->request->reply = create_reply("invalid attribute: %s", name); diff --git a/src/libcharon/plugins/vici/vici_builder.c b/src/libcharon/plugins/vici/vici_builder.c index 561632049..82f12c9da 100644 --- a/src/libcharon/plugins/vici/vici_builder.c +++ b/src/libcharon/plugins/vici/vici_builder.c @@ -84,6 +84,8 @@ METHOD(vici_builder_t, add, void, if (value.len > 0xffff) { + DBG1(DBG_ENC, "vici value exceeds size limit (%zu > %u)", + value.len, 0xffff); this->error++; return; } @@ -125,24 +127,58 @@ METHOD(vici_builder_t, add, void, } } -METHOD(vici_builder_t, vadd_kv, void, - private_vici_builder_t *this, char *key, char *fmt, va_list args) +/** + * Add a list item or a key/value, if key given + */ +static void vadd_kv_or_li(private_vici_builder_t *this, char *key, + char *fmt, va_list args) { - char buf[2048]; + u_char buf[512]; + chunk_t value; ssize_t len; + va_list copy; - len = vsnprintf(buf, sizeof(buf), fmt, args); - if (len < 0 || len >= sizeof(buf)) + va_copy(copy, args); + len = vsnprintf(buf, sizeof(buf), fmt, copy); + va_end(copy); + if (len >= sizeof(buf)) { - DBG1(DBG_ENC, "vici builder format buffer exceeds limit"); + value = chunk_alloc(len + 1); + len = vsnprintf(value.ptr, value.len, fmt, args); + } + else + { + value = chunk_create(buf, len); + } + + if (len < 0) + { + DBG1(DBG_ENC, "vici builder format print failed"); this->error++; } else { - add(this, VICI_KEY_VALUE, key, chunk_create(buf, len)); + if (key) + { + add(this, VICI_KEY_VALUE, key, value); + } + else + { + add(this, VICI_LIST_ITEM, value); + } + } + if (value.ptr != buf) + { + free(value.ptr); } } +METHOD(vici_builder_t, vadd_kv, void, + private_vici_builder_t *this, char *key, char *fmt, va_list args) +{ + vadd_kv_or_li(this, key, fmt, args); +} + METHOD(vici_builder_t, add_kv, void, private_vici_builder_t *this, char *key, char *fmt, ...) { @@ -153,23 +189,10 @@ METHOD(vici_builder_t, add_kv, void, va_end(args); } - METHOD(vici_builder_t, vadd_li, void, private_vici_builder_t *this, char *fmt, va_list args) { - char buf[2048]; - ssize_t len; - - len = vsnprintf(buf, sizeof(buf), fmt, args); - if (len < 0 || len >= sizeof(buf)) - { - DBG1(DBG_ENC, "vici builder format buffer exceeds limit"); - this->error++; - } - else - { - add(this, VICI_LIST_ITEM, chunk_create(buf, len)); - } + vadd_kv_or_li(this, NULL, fmt, args); } METHOD(vici_builder_t, add_li, void, @@ -206,6 +229,13 @@ METHOD(vici_builder_t, end_list, void, add(this, VICI_LIST_END); } +METHOD(vici_builder_t, destroy, void, + private_vici_builder_t *this) +{ + this->writer->destroy(this->writer); + free(this); +} + METHOD(vici_builder_t, finalize, vici_message_t*, private_vici_builder_t *this) { @@ -215,14 +245,12 @@ METHOD(vici_builder_t, finalize, vici_message_t*, { DBG1(DBG_ENC, "vici builder error: %u errors (section: %u, list %u)", this->error, this->section, this->list); - this->writer->destroy(this->writer); - free(this); + destroy(this); return NULL; } product = vici_message_create_from_data( this->writer->extract_buf(this->writer), TRUE); - this->writer->destroy(this->writer); - free(this); + destroy(this); return product; } @@ -245,6 +273,7 @@ vici_builder_t *vici_builder_create() .begin_list = _begin_list, .end_list = _end_list, .finalize = _finalize, + .destroy = _destroy, }, .writer = bio_writer_create(0), ); diff --git a/src/libcharon/plugins/vici/vici_builder.h b/src/libcharon/plugins/vici/vici_builder.h index 5a5cc8a03..f7d21eb8f 100644 --- a/src/libcharon/plugins/vici/vici_builder.h +++ b/src/libcharon/plugins/vici/vici_builder.h @@ -119,6 +119,14 @@ struct vici_builder_t { * @return vici message, NULL on error */ vici_message_t* (*finalize)(vici_builder_t *this); + + /** + * Destroy a vici builder without finalization. + * + * Note that finalize() already destroys the message, and calling destroy() + * is required only if the message does not get finalize()d. + */ + void (*destroy)(vici_builder_t *this); }; /** diff --git a/src/libcharon/plugins/vici/vici_config.c b/src/libcharon/plugins/vici/vici_config.c index 113d48084..649161020 100644 --- a/src/libcharon/plugins/vici/vici_config.c +++ b/src/libcharon/plugins/vici/vici_config.c @@ -1551,8 +1551,8 @@ static void clear_start_action(private_vici_config_t *this, enumerator_t *enumerator, *children; child_sa_t *child_sa; ike_sa_t *ike_sa; - u_int32_t reqid = 0, *del; - array_t *reqids = NULL; + u_int32_t id = 0, *del; + array_t *ids = NULL; char *name; name = child_cfg->get_name(child_cfg); @@ -1568,23 +1568,23 @@ static void clear_start_action(private_vici_config_t *this, { if (streq(name, child_sa->get_name(child_sa))) { - reqid = child_sa->get_reqid(child_sa); - array_insert_create(&reqids, ARRAY_TAIL, &reqid); + id = child_sa->get_unique_id(child_sa); + array_insert_create(&ids, ARRAY_TAIL, &id); } } children->destroy(children); } enumerator->destroy(enumerator); - if (array_count(reqids)) + if (array_count(ids)) { - while (array_remove(reqids, ARRAY_HEAD, &del)) + while (array_remove(ids, ARRAY_HEAD, &del)) { DBG1(DBG_CFG, "closing '%s' #%u", name, *del); charon->controller->terminate_child(charon->controller, *del, NULL, NULL, 0); } - array_destroy(reqids); + array_destroy(ids); } break; case ACTION_ROUTE: @@ -1601,14 +1601,14 @@ static void clear_start_action(private_vici_config_t *this, { if (streq(name, child_sa->get_name(child_sa))) { - reqid = child_sa->get_reqid(child_sa); + id = child_sa->get_reqid(child_sa); break; } } enumerator->destroy(enumerator); - if (reqid) + if (id) { - charon->traps->uninstall(charon->traps, reqid); + charon->traps->uninstall(charon->traps, id); } break; } @@ -1751,7 +1751,8 @@ CALLBACK(config_sn, bool, .fragmentation = FRAGMENTATION_NO, .unique = UNIQUE_NO, .keyingtries = 1, - .rekey_time = LFT_DEFAULT_IKE_REKEY, + .rekey_time = LFT_UNDEFINED, + .reauth_time = LFT_UNDEFINED, .over_time = LFT_UNDEFINED, .rand_time = LFT_UNDEFINED, }; @@ -1809,6 +1810,20 @@ CALLBACK(config_sn, bool, peer.local_port = charon->socket->get_port(charon->socket, FALSE); } + if (peer.rekey_time == LFT_UNDEFINED && peer.reauth_time == LFT_UNDEFINED) + { + /* apply a default rekey time if no rekey/reauth time set */ + peer.rekey_time = LFT_DEFAULT_IKE_REKEY; + peer.reauth_time = 0; + } + if (peer.rekey_time == LFT_UNDEFINED) + { + peer.rekey_time = 0; + } + if (peer.reauth_time == LFT_UNDEFINED) + { + peer.reauth_time = 0; + } if (peer.over_time == LFT_UNDEFINED) { /* default over_time to 10% of rekey/reauth time if not given */ @@ -1816,9 +1831,17 @@ CALLBACK(config_sn, bool, } if (peer.rand_time == LFT_UNDEFINED) { - /* default rand_time to over_time if not given */ - peer.rand_time = min(peer.over_time, - max(peer.rekey_time, peer.reauth_time) / 2); + /* default rand_time to over_time if not given, but don't make it + * longer than half of rekey/rauth time */ + if (peer.rekey_time && peer.reauth_time) + { + peer.rand_time = min(peer.rekey_time, peer.reauth_time); + } + else + { + peer.rand_time = max(peer.rekey_time, peer.reauth_time); + } + peer.rand_time = min(peer.over_time, peer.rand_time / 2); } log_peer_data(&peer); diff --git a/src/libcharon/plugins/vici/vici_control.c b/src/libcharon/plugins/vici/vici_control.c index 292a40032..01d503644 100644 --- a/src/libcharon/plugins/vici/vici_control.c +++ b/src/libcharon/plugins/vici/vici_control.c @@ -264,11 +264,11 @@ CALLBACK(terminate, vici_message_t*, { continue; } - if (child_id && child_sa->get_reqid(child_sa) != child_id) + if (child_id && child_sa->get_unique_id(child_sa) != child_id) { continue; } - current = child_sa->get_reqid(child_sa); + current = child_sa->get_unique_id(child_sa); array_insert(ids, ARRAY_TAIL, ¤t); } csas->destroy(csas); diff --git a/src/libcharon/plugins/vici/vici_plugin.c b/src/libcharon/plugins/vici/vici_plugin.c index 8881feca9..af8bd283b 100644 --- a/src/libcharon/plugins/vici/vici_plugin.c +++ b/src/libcharon/plugins/vici/vici_plugin.c @@ -23,7 +23,6 @@ #include "vici_logger.h" #include <library.h> -#include <hydra.h> #include <daemon.h> typedef struct private_vici_plugin_t private_vici_plugin_t; @@ -104,8 +103,8 @@ static bool register_vici(private_vici_plugin_t *this, charon->backends->add_backend(charon->backends, &this->config->backend); - hydra->attributes->add_provider(hydra->attributes, - &this->attrs->provider); + charon->attributes->add_provider(charon->attributes, + &this->attrs->provider); charon->bus->add_logger(charon->bus, &this->logger->logger); return TRUE; } @@ -114,8 +113,8 @@ static bool register_vici(private_vici_plugin_t *this, else { charon->bus->remove_logger(charon->bus, &this->logger->logger); - hydra->attributes->remove_provider(hydra->attributes, - &this->attrs->provider); + charon->attributes->remove_provider(charon->attributes, + &this->attrs->provider); charon->backends->remove_backend(charon->backends, &this->config->backend); diff --git a/src/libcharon/plugins/vici/vici_query.c b/src/libcharon/plugins/vici/vici_query.c index 54833abde..3e0d73cdf 100644 --- a/src/libcharon/plugins/vici/vici_query.c +++ b/src/libcharon/plugins/vici/vici_query.c @@ -63,11 +63,13 @@ static void list_child(private_vici_query_t *this, vici_builder_t *b, enumerator_t *enumerator; traffic_selector_t *ts; + b->add_kv(b, "uniqueid", "%u", child->get_unique_id(child)); b->add_kv(b, "reqid", "%u", child->get_reqid(child)); b->add_kv(b, "state", "%N", child_sa_state_names, child->get_state(child)); b->add_kv(b, "mode", "%N", ipsec_mode_names, child->get_mode(child)); if (child->get_state(child) == CHILD_INSTALLED || - child->get_state(child) == CHILD_REKEYING) + child->get_state(child) == CHILD_REKEYING || + child->get_state(child) == CHILD_REKEYED) { b->add_kv(b, "protocol", "%N", protocol_id_names, child->get_protocol(child)); @@ -507,11 +509,14 @@ static void build_auth_cfgs(peer_cfg_t *peer_cfg, bool local, vici_builder_t *b) certificate_t *cert; char *str; } v; + char buf[32]; + int i = 0; enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, local); while (enumerator->enumerate(enumerator, &auth)) { - b->begin_section(b, local ? "local" : "remote"); + snprintf(buf, sizeof(buf), "%s-%d", local ? "local" : "remote", ++i); + b->begin_section(b, buf); rules = auth->create_enumerator(auth); while (rules->enumerate(rules, &rule, &v)) @@ -976,10 +981,10 @@ CALLBACK(stats, vici_message_t*, struct mallinfo mi = mallinfo(); b->begin_section(b, "mallinfo"); - b->add_kv(b, "sbrk", "%d", mi.arena); - b->add_kv(b, "mmap", "%d", mi.hblkhd); - b->add_kv(b, "used", "%d", mi.uordblks); - b->add_kv(b, "free", "%d", mi.fordblks); + b->add_kv(b, "sbrk", "%u", mi.arena); + b->add_kv(b, "mmap", "%u", mi.hblkhd); + b->add_kv(b, "used", "%u", mi.uordblks); + b->add_kv(b, "free", "%u", mi.fordblks); b->end_section(b); } #endif /* HAVE_MALLINFO */ diff --git a/src/libcharon/plugins/whitelist/Makefile.in b/src/libcharon/plugins/whitelist/Makefile.in index b1cc1d118..e400d9f35 100644 --- a/src/libcharon/plugins/whitelist/Makefile.in +++ b/src/libcharon/plugins/whitelist/Makefile.in @@ -236,6 +236,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -296,10 +297,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -373,6 +376,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/xauth_eap/Makefile.in b/src/libcharon/plugins/xauth_eap/Makefile.in index e393ee163..a9684455d 100644 --- a/src/libcharon/plugins/xauth_eap/Makefile.in +++ b/src/libcharon/plugins/xauth_eap/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/xauth_generic/Makefile.in b/src/libcharon/plugins/xauth_generic/Makefile.in index f0e772700..5170c924f 100644 --- a/src/libcharon/plugins/xauth_generic/Makefile.in +++ b/src/libcharon/plugins/xauth_generic/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/xauth_noauth/Makefile.in b/src/libcharon/plugins/xauth_noauth/Makefile.in index a4c1aaeb2..087f5b350 100644 --- a/src/libcharon/plugins/xauth_noauth/Makefile.in +++ b/src/libcharon/plugins/xauth_noauth/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/plugins/xauth_pam/Makefile.in b/src/libcharon/plugins/xauth_pam/Makefile.in index 296ccaa1c..29441bcb5 100644 --- a/src/libcharon/plugins/xauth_pam/Makefile.in +++ b/src/libcharon/plugins/xauth_pam/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libcharon/processing/jobs/adopt_children_job.c b/src/libcharon/processing/jobs/adopt_children_job.c index fb480eee2..c8a9c17de 100644 --- a/src/libcharon/processing/jobs/adopt_children_job.c +++ b/src/libcharon/processing/jobs/adopt_children_job.c @@ -1,4 +1,7 @@ /* + * Copyright (C) 2015 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2012 Martin Willi * Copyright (C) 2012 revosec AG * @@ -54,10 +57,10 @@ METHOD(job_t, execute, job_requeue_t, private_adopt_children_job_t *this) { identification_t *my_id, *other_id, *xauth; - host_t *me, *other; + host_t *me, *other, *vip; peer_cfg_t *cfg; - linked_list_t *children; - enumerator_t *enumerator, *childenum; + linked_list_t *children, *vips; + enumerator_t *enumerator, *subenum; ike_sa_id_t *id; ike_sa_t *ike_sa; child_sa_t *child_sa; @@ -81,7 +84,8 @@ METHOD(job_t, execute, job_requeue_t, charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); - /* find old SA to adopt children from */ + /* find old SA to adopt children and virtual IPs from */ + vips = linked_list_create(); children = linked_list_create(); enumerator = charon->ike_sa_manager->create_id_enumerator( charon->ike_sa_manager, my_id, xauth, @@ -102,18 +106,29 @@ METHOD(job_t, execute, job_requeue_t, other_id->equals(other_id, ike_sa->get_other_id(ike_sa)) && cfg->equals(cfg, ike_sa->get_peer_cfg(ike_sa))) { - childenum = ike_sa->create_child_sa_enumerator(ike_sa); - while (childenum->enumerate(childenum, &child_sa)) + subenum = ike_sa->create_child_sa_enumerator(ike_sa); + while (subenum->enumerate(subenum, &child_sa)) { - ike_sa->remove_child_sa(ike_sa, childenum); + ike_sa->remove_child_sa(ike_sa, subenum); children->insert_last(children, child_sa); } - childenum->destroy(childenum); - if (children->get_count(children)) + subenum->destroy(subenum); + + subenum = ike_sa->create_virtual_ip_enumerator(ike_sa, FALSE); + while (subenum->enumerate(subenum, &vip)) + { + vips->insert_last(vips, vip->clone(vip)); + } + subenum->destroy(subenum); + /* this does not release the addresses, which is good, but + * it does trigger an assign_vips(FALSE) event, so we also + * trigger one below */ + ike_sa->clear_virtual_ips(ike_sa, FALSE); + if (children->get_count(children) || vips->get_count(vips)) { DBG1(DBG_IKE, "detected reauth of existing IKE_SA, " - "adopting %d children", - children->get_count(children)); + "adopting %d children and %d virtual IPs", + children->get_count(children), vips->get_count(vips)); } ike_sa->set_state(ike_sa, IKE_DELETING); charon->bus->ike_updown(charon->bus, ike_sa, FALSE); @@ -125,7 +140,7 @@ METHOD(job_t, execute, job_requeue_t, charon->ike_sa_manager->checkin( charon->ike_sa_manager, ike_sa); } - if (children->get_count(children)) + if (children->get_count(children) || vips->get_count(vips)) { break; } @@ -140,7 +155,7 @@ METHOD(job_t, execute, job_requeue_t, xauth->destroy(xauth); cfg->destroy(cfg); - if (children->get_count(children)) + if (children->get_count(children) || vips->get_count(vips)) { /* adopt children by new SA */ ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, @@ -152,10 +167,27 @@ METHOD(job_t, execute, job_requeue_t, { ike_sa->add_child_sa(ike_sa, child_sa); } + if (vips->get_count(vips)) + { + while (vips->remove_first(vips, (void**)&vip) == SUCCESS) + { + ike_sa->add_virtual_ip(ike_sa, FALSE, vip); + vip->destroy(vip); + } + charon->bus->assign_vips(charon->bus, ike_sa, TRUE); + } charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); } } children->destroy_offset(children, offsetof(child_sa_t, destroy)); + /* FIXME: If we still have addresses here it means we weren't able to + * find the new SA anymore (while not very likely during a proper + * reauthentication, this theoretically could happen because the SA is + * not locked while we search for the old one). So the addresses here + * should be released properly to avoid leaking these leases. This is + * currently not possible, though, due to the changed interface of + * release_address(), which now takes a complete IKE_SA object. */ + vips->destroy_offset(vips, offsetof(host_t, destroy)); if (array_count(this->tasks)) { diff --git a/src/libcharon/processing/jobs/delete_child_sa_job.c b/src/libcharon/processing/jobs/delete_child_sa_job.c index 9afbac02b..0d85883be 100644 --- a/src/libcharon/processing/jobs/delete_child_sa_job.c +++ b/src/libcharon/processing/jobs/delete_child_sa_job.c @@ -31,11 +31,6 @@ struct private_delete_child_sa_job_t { delete_child_sa_job_t public; /** - * reqid of the CHILD_SA - */ - u_int32_t reqid; - - /** * protocol of the CHILD_SA (ESP/AH) */ protocol_id_t protocol; @@ -46,6 +41,11 @@ struct private_delete_child_sa_job_t { u_int32_t spi; /** + * SA destination address + */ + host_t *dst; + + /** * Delete for an expired CHILD_SA */ bool expired; @@ -54,6 +54,7 @@ struct private_delete_child_sa_job_t { METHOD(job_t, destroy, void, private_delete_child_sa_job_t *this) { + this->dst->destroy(this->dst); free(this); } @@ -62,12 +63,12 @@ METHOD(job_t, execute, job_requeue_t, { ike_sa_t *ike_sa; - ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager, - this->reqid, TRUE); + ike_sa = charon->child_sa_manager->checkout(charon->child_sa_manager, + this->protocol, this->spi, this->dst, NULL); if (ike_sa == NULL) { - DBG1(DBG_JOB, "CHILD_SA with reqid %d not found for delete", - this->reqid); + DBG1(DBG_JOB, "CHILD_SA %N/0x%08x/%H not found for delete", + protocol_id_names, this->protocol, htonl(this->spi), this->dst); } else { @@ -87,8 +88,8 @@ METHOD(job_t, get_priority, job_priority_t, /* * Described in header */ -delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid, - protocol_id_t protocol, u_int32_t spi, bool expired) +delete_child_sa_job_t *delete_child_sa_job_create(protocol_id_t protocol, + u_int32_t spi, host_t *dst, bool expired) { private_delete_child_sa_job_t *this; @@ -100,12 +101,11 @@ delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid, .destroy = _destroy, }, }, - .reqid = reqid, .protocol = protocol, .spi = spi, + .dst = dst->clone(dst), .expired = expired, ); return &this->public; } - diff --git a/src/libcharon/processing/jobs/delete_child_sa_job.h b/src/libcharon/processing/jobs/delete_child_sa_job.h index be6d578bc..6fa53644c 100644 --- a/src/libcharon/processing/jobs/delete_child_sa_job.h +++ b/src/libcharon/processing/jobs/delete_child_sa_job.h @@ -44,16 +44,13 @@ struct delete_child_sa_job_t { /** * Creates a job of type DELETE_CHILD_SA. * - * The CHILD_SA is identified by its reqid, protocol (AH/ESP) and its - * inbound SPI. - * - * @param reqid reqid of the CHILD_SA, as used in kernel * @param protocol protocol of the CHILD_SA * @param spi security parameter index of the CHILD_SA + * @param dst SA destination address * @param expired TRUE if CHILD_SA already expired * @return delete_child_sa_job_t object */ -delete_child_sa_job_t *delete_child_sa_job_create(u_int32_t reqid, - protocol_id_t protocol, u_int32_t spi, bool expired); +delete_child_sa_job_t *delete_child_sa_job_create(protocol_id_t protocol, + u_int32_t spi, host_t *dst, bool expired); #endif /** DELETE_CHILD_SA_JOB_H_ @}*/ diff --git a/src/libcharon/processing/jobs/dpd_timeout_job.c b/src/libcharon/processing/jobs/dpd_timeout_job.c index 9cdce5cab..4c88c13e2 100644 --- a/src/libcharon/processing/jobs/dpd_timeout_job.c +++ b/src/libcharon/processing/jobs/dpd_timeout_job.c @@ -63,6 +63,12 @@ METHOD(job_t, execute, job_requeue_t, this->ike_sa_id); if (ike_sa) { + if (ike_sa->get_state(ike_sa) == IKE_PASSIVE) + { + charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); + return JOB_REQUEUE_NONE; + } + use_time = ike_sa->get_statistic(ike_sa, STAT_INBOUND); enumerator = ike_sa->create_child_sa_enumerator(ike_sa); diff --git a/src/libcharon/processing/jobs/inactivity_job.c b/src/libcharon/processing/jobs/inactivity_job.c index 197733979..f0f90eedf 100644 --- a/src/libcharon/processing/jobs/inactivity_job.c +++ b/src/libcharon/processing/jobs/inactivity_job.c @@ -30,9 +30,9 @@ struct private_inactivity_job_t { inactivity_job_t public; /** - * Reqid of CHILD_SA to check + * Unique CHILD_SA identifier to check */ - u_int32_t reqid; + u_int32_t id; /** * Inactivity timeout @@ -57,8 +57,8 @@ METHOD(job_t, execute, job_requeue_t, ike_sa_t *ike_sa; u_int32_t reschedule = 0; - ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager, - this->reqid, TRUE); + ike_sa = charon->child_sa_manager->checkout_by_id(charon->child_sa_manager, + this->id, NULL); if (ike_sa) { enumerator_t *enumerator; @@ -69,9 +69,9 @@ METHOD(job_t, execute, job_requeue_t, status_t status = SUCCESS; enumerator = ike_sa->create_child_sa_enumerator(ike_sa); - while (enumerator->enumerate(enumerator, (void**)&child_sa)) + while (enumerator->enumerate(enumerator, &child_sa)) { - if (child_sa->get_reqid(child_sa) == this->reqid) + if (child_sa->get_unique_id(child_sa) == this->id) { time_t in, out, install, diff; @@ -136,7 +136,7 @@ METHOD(job_t, get_priority, job_priority_t, /** * See header */ -inactivity_job_t *inactivity_job_create(u_int32_t reqid, u_int32_t timeout, +inactivity_job_t *inactivity_job_create(u_int32_t unique_id, u_int32_t timeout, bool close_ike) { private_inactivity_job_t *this; @@ -149,7 +149,7 @@ inactivity_job_t *inactivity_job_create(u_int32_t reqid, u_int32_t timeout, .destroy = _destroy, }, }, - .reqid = reqid, + .id = unique_id, .timeout = timeout, .close_ike = close_ike, ); diff --git a/src/libcharon/processing/jobs/inactivity_job.h b/src/libcharon/processing/jobs/inactivity_job.h index 890f7704b..ff19fe560 100644 --- a/src/libcharon/processing/jobs/inactivity_job.h +++ b/src/libcharon/processing/jobs/inactivity_job.h @@ -42,12 +42,12 @@ struct inactivity_job_t { /** * Create a inactivity_job instance. * - * @param reqid reqid of CHILD_SA to check for inactivity + * @param unique_id unique CHILD_SA identifier to check for inactivity * @param timeout inactivity timeout in s * @param close_ike close IKE_SA if the last remaining CHILD_SA is inactive? * @return inactivity checking job */ -inactivity_job_t *inactivity_job_create(u_int32_t reqid, u_int32_t timeout, +inactivity_job_t *inactivity_job_create(u_int32_t unique_id, u_int32_t timeout, bool close_ike); #endif /** INACTIVITY_JOB_H_ @}*/ diff --git a/src/libcharon/processing/jobs/initiate_tasks_job.c b/src/libcharon/processing/jobs/initiate_tasks_job.c new file mode 100644 index 000000000..001e71fd1 --- /dev/null +++ b/src/libcharon/processing/jobs/initiate_tasks_job.c @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2015 Martin Willi + * Copyright (C) 2015 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include <stdlib.h> + +#include "initiate_tasks_job.h" + +#include <sa/ike_sa.h> +#include <daemon.h> + + +typedef struct private_initiate_tasks_job_t private_initiate_tasks_job_t; + +/** + * Private data of an initiate_tasks_job_t Object + */ +struct private_initiate_tasks_job_t { + + /** + * Public initiate_tasks_job_t interface + */ + initiate_tasks_job_t public; + + /** + * ID of the IKE_SA to trigger task initiation + */ + ike_sa_id_t *ike_sa_id; +}; + +METHOD(job_t, destroy, void, + private_initiate_tasks_job_t *this) +{ + this->ike_sa_id->destroy(this->ike_sa_id); + free(this); +} + +METHOD(job_t, execute, job_requeue_t, + private_initiate_tasks_job_t *this) +{ + ike_sa_t *ike_sa; + + ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, + this->ike_sa_id); + if (ike_sa) + { + if (ike_sa->initiate(ike_sa, NULL, 0, NULL, NULL) == DESTROY_ME) + { + charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, + ike_sa); + } + else + { + charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); + } + } + return JOB_REQUEUE_NONE; +} + +METHOD(job_t, get_priority, job_priority_t, + private_initiate_tasks_job_t *this) +{ + return JOB_PRIO_MEDIUM; +} + +/* + * Described in header + */ +initiate_tasks_job_t *initiate_tasks_job_create(ike_sa_id_t *ike_sa_id) +{ + private_initiate_tasks_job_t *this; + + INIT(this, + .public = { + .job_interface = { + .execute = _execute, + .get_priority = _get_priority, + .destroy = _destroy, + }, + }, + .ike_sa_id = ike_sa_id->clone(ike_sa_id), + ); + + return &this->public; +} diff --git a/src/libcharon/processing/jobs/initiate_tasks_job.h b/src/libcharon/processing/jobs/initiate_tasks_job.h new file mode 100644 index 000000000..071497843 --- /dev/null +++ b/src/libcharon/processing/jobs/initiate_tasks_job.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2015 Martin Willi + * Copyright (C) 2015 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup initiate_tasks_job initiate_tasks_job + * @{ @ingroup cjobs + */ + +#ifndef INITIATE_TASKS_JOB_H_ +#define INITIATE_TASKS_JOB_H_ + +typedef struct initiate_tasks_job_t initiate_tasks_job_t; + +#include <library.h> +#include <processing/jobs/job.h> +#include <sa/ike_sa_id.h> + +/** + * Job triggering initiation of any queued IKE_SA tasks. + */ +struct initiate_tasks_job_t { + + /** + * Implements job_t interface + */ + job_t job_interface; +}; + +/** + * Creates a job to trigger IKE_SA task initiation. + * + * @param ike_sa_id ID of IKE_SA to trigger tasks for (gets cloned) + * @return job instance + */ +initiate_tasks_job_t *initiate_tasks_job_create(ike_sa_id_t *ike_sa_id); + +#endif /** INITIATE_TASKS_JOB_H_ @}*/ diff --git a/src/libcharon/processing/jobs/migrate_job.c b/src/libcharon/processing/jobs/migrate_job.c index 2ebfc6714..097dbdffd 100644 --- a/src/libcharon/processing/jobs/migrate_job.c +++ b/src/libcharon/processing/jobs/migrate_job.c @@ -70,29 +70,34 @@ METHOD(job_t, destroy, void, METHOD(job_t, execute, job_requeue_t, private_migrate_job_t *this) { - ike_sa_t *ike_sa = NULL; + enumerator_t *ike_sas, *children; + ike_sa_t *ike_sa; - if (this->reqid) + ike_sas = charon->ike_sa_manager->create_enumerator(charon->ike_sa_manager, + TRUE); + while (ike_sas->enumerate(ike_sas, &ike_sa)) { - ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager, - this->reqid, TRUE); - } - if (ike_sa) - { - enumerator_t *children, *enumerator; - child_sa_t *child_sa; - host_t *host; + child_sa_t *current, *child_sa = NULL; linked_list_t *vips; + status_t status; + host_t *host; children = ike_sa->create_child_sa_enumerator(ike_sa); - while (children->enumerate(children, (void**)&child_sa)) + while (children->enumerate(children, ¤t)) { - if (child_sa->get_reqid(child_sa) == this->reqid) + if (current->get_reqid(current) == this->reqid) { + child_sa = current; break; } } children->destroy(children); + + if (!child_sa) + { + continue; + } + DBG2(DBG_JOB, "found CHILD_SA with reqid {%d}", this->reqid); ike_sa->set_kmaddress(ike_sa, this->local, this->remote); @@ -105,27 +110,28 @@ METHOD(job_t, execute, job_requeue_t, host->set_port(host, IKEV2_UDP_PORT); ike_sa->set_other_host(ike_sa, host); - vips = linked_list_create(); - enumerator = ike_sa->create_virtual_ip_enumerator(ike_sa, TRUE); - while (enumerator->enumerate(enumerator, &host)) - { - vips->insert_last(vips, host); - } - enumerator->destroy(enumerator); + vips = linked_list_create_from_enumerator( + ike_sa->create_virtual_ip_enumerator(ike_sa, TRUE)); - if (child_sa->update(child_sa, this->local, this->remote, vips, - ike_sa->has_condition(ike_sa, COND_NAT_ANY)) == NOT_SUPPORTED) + status = child_sa->update(child_sa, this->local, this->remote, vips, + ike_sa->has_condition(ike_sa, COND_NAT_ANY)); + switch (status) { - ike_sa->rekey_child_sa(ike_sa, child_sa->get_protocol(child_sa), - child_sa->get_spi(child_sa, TRUE)); + case NOT_SUPPORTED: + ike_sa->rekey_child_sa(ike_sa, child_sa->get_protocol(child_sa), + child_sa->get_spi(child_sa, TRUE)); + break; + case SUCCESS: + charon->child_sa_manager->remove(charon->child_sa_manager, + child_sa); + charon->child_sa_manager->add(charon->child_sa_manager, + child_sa, ike_sa); + default: + break; } - charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); vips->destroy(vips); } - else - { - DBG1(DBG_JOB, "no CHILD_SA found with reqid {%d}", this->reqid); - } + ike_sas->destroy(ike_sas); return JOB_REQUEUE_NONE; } diff --git a/src/libcharon/processing/jobs/migrate_job.h b/src/libcharon/processing/jobs/migrate_job.h index 30c0ad0ac..0f2b9aaad 100644 --- a/src/libcharon/processing/jobs/migrate_job.h +++ b/src/libcharon/processing/jobs/migrate_job.h @@ -46,7 +46,7 @@ struct migrate_job_t { * * We use the reqid or the traffic selectors to find a matching CHILD_SA. * - * @param reqid reqid of the CHILD_SA to acquire + * @param reqid reqid of the CHILD_SA to migrate * @param src_ts source traffic selector to be used in the policy * @param dst_ts destination traffic selector to be used in the policy * @param dir direction of the policy (in|out) diff --git a/src/libcharon/processing/jobs/rekey_child_sa_job.c b/src/libcharon/processing/jobs/rekey_child_sa_job.c index 1bf8dc0cb..8f17d39ab 100644 --- a/src/libcharon/processing/jobs/rekey_child_sa_job.c +++ b/src/libcharon/processing/jobs/rekey_child_sa_job.c @@ -24,17 +24,13 @@ typedef struct private_rekey_child_sa_job_t private_rekey_child_sa_job_t; * Private data of an rekey_child_sa_job_t object. */ struct private_rekey_child_sa_job_t { + /** * Public rekey_child_sa_job_t interface. */ rekey_child_sa_job_t public; /** - * reqid of the child to rekey - */ - u_int32_t reqid; - - /** * protocol of the CHILD_SA (ESP/AH) */ protocol_id_t protocol; @@ -43,11 +39,17 @@ struct private_rekey_child_sa_job_t { * inbound SPI of the CHILD_SA */ u_int32_t spi; + + /** + * SA destination address + */ + host_t *dst; }; METHOD(job_t, destroy, void, private_rekey_child_sa_job_t *this) { + this->dst->destroy(this->dst); free(this); } @@ -56,12 +58,12 @@ METHOD(job_t, execute, job_requeue_t, { ike_sa_t *ike_sa; - ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager, - this->reqid, TRUE); + ike_sa = charon->child_sa_manager->checkout(charon->child_sa_manager, + this->protocol, this->spi, this->dst, NULL); if (ike_sa == NULL) { - DBG2(DBG_JOB, "CHILD_SA with reqid %d not found for rekeying", - this->reqid); + DBG1(DBG_JOB, "CHILD_SA %N/0x%08x/%H not found for rekey", + protocol_id_names, this->protocol, htonl(this->spi), this->dst); } else { @@ -80,9 +82,8 @@ METHOD(job_t, get_priority, job_priority_t, /* * Described in header */ -rekey_child_sa_job_t *rekey_child_sa_job_create(u_int32_t reqid, - protocol_id_t protocol, - u_int32_t spi) +rekey_child_sa_job_t *rekey_child_sa_job_create(protocol_id_t protocol, + u_int32_t spi, host_t *dst) { private_rekey_child_sa_job_t *this; @@ -94,9 +95,9 @@ rekey_child_sa_job_t *rekey_child_sa_job_create(u_int32_t reqid, .destroy = _destroy, }, }, - .reqid = reqid, .protocol = protocol, .spi = spi, + .dst = dst->clone(dst), ); return &this->public; diff --git a/src/libcharon/processing/jobs/rekey_child_sa_job.h b/src/libcharon/processing/jobs/rekey_child_sa_job.h index fcbe65a06..364bb5ae7 100644 --- a/src/libcharon/processing/jobs/rekey_child_sa_job.h +++ b/src/libcharon/processing/jobs/rekey_child_sa_job.h @@ -43,15 +43,11 @@ struct rekey_child_sa_job_t { /** * Creates a job of type REKEY_CHILD_SA. * - * The CHILD_SA is identified by its protocol (AH/ESP) and its - * inbound SPI. - * - * @param reqid reqid of the CHILD_SA to rekey * @param protocol protocol of the CHILD_SA * @param spi security parameter index of the CHILD_SA + * @param dst SA destination address * @return rekey_child_sa_job_t object */ -rekey_child_sa_job_t *rekey_child_sa_job_create(u_int32_t reqid, - protocol_id_t protocol, - u_int32_t spi); +rekey_child_sa_job_t *rekey_child_sa_job_create(protocol_id_t protocol, + u_int32_t spi, host_t *dst); #endif /** REKEY_CHILD_SA_JOB_H_ @}*/ diff --git a/src/libcharon/processing/jobs/rekey_ike_sa_job.c b/src/libcharon/processing/jobs/rekey_ike_sa_job.c index 516dc5dd5..403d826a3 100644 --- a/src/libcharon/processing/jobs/rekey_ike_sa_job.c +++ b/src/libcharon/processing/jobs/rekey_ike_sa_job.c @@ -67,7 +67,8 @@ static u_int32_t get_retry_delay(ike_sa_t *ike_sa) enumerator = ike_sa->create_child_sa_enumerator(ike_sa); while (enumerator->enumerate(enumerator, &child_sa)) { - if (child_sa->get_state(child_sa) != CHILD_INSTALLED) + if (child_sa->get_state(child_sa) != CHILD_INSTALLED && + child_sa->get_state(child_sa) != CHILD_REKEYED) { retry = RETRY_INTERVAL - (random() % RETRY_JITTER); DBG1(DBG_IKE, "unable to reauthenticate in CHILD_SA %N state, " diff --git a/src/libcharon/processing/jobs/update_sa_job.c b/src/libcharon/processing/jobs/update_sa_job.c index e6d7da2c6..862506d90 100644 --- a/src/libcharon/processing/jobs/update_sa_job.c +++ b/src/libcharon/processing/jobs/update_sa_job.c @@ -27,15 +27,26 @@ typedef struct private_update_sa_job_t private_update_sa_job_t; * Private data of an update_sa_job_t Object */ struct private_update_sa_job_t { + /** * public update_sa_job_t interface */ update_sa_job_t public; /** - * reqid of the CHILD_SA + * protocol of the CHILD_SA (ESP/AH) + */ + protocol_id_t protocol; + + /** + * SPI of the CHILD_SA */ - u_int32_t reqid; + u_int32_t spi; + + /** + * Old SA destination address + */ + host_t *dst; /** * New SA address and port @@ -46,6 +57,7 @@ struct private_update_sa_job_t { METHOD(job_t, destroy, void, private_update_sa_job_t *this) { + this->dst->destroy(this->dst); this->new->destroy(this->new); free(this); } @@ -55,11 +67,12 @@ METHOD(job_t, execute, job_requeue_t, { ike_sa_t *ike_sa; - ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager, - this->reqid, TRUE); + ike_sa = charon->child_sa_manager->checkout(charon->child_sa_manager, + this->protocol, this->spi, this->dst, NULL); if (ike_sa == NULL) { - DBG1(DBG_JOB, "CHILD_SA with reqid %d not found for update", this->reqid); + DBG1(DBG_JOB, "CHILD_SA %N/0x%08x/%H not found for update", + protocol_id_names, this->protocol, htonl(this->spi), this->dst); } else { @@ -78,7 +91,8 @@ METHOD(job_t, get_priority, job_priority_t, /* * Described in header */ -update_sa_job_t *update_sa_job_create(u_int32_t reqid, host_t *new) +update_sa_job_t *update_sa_job_create(protocol_id_t protocol, + u_int32_t spi, host_t *dst, host_t *new) { private_update_sa_job_t *this; @@ -90,10 +104,11 @@ update_sa_job_t *update_sa_job_create(u_int32_t reqid, host_t *new) .destroy = _destroy, }, }, - .reqid = reqid, - .new = new, + .protocol = protocol, + .spi = spi, + .dst = dst->clone(dst), + .new = new->clone(new), ); return &this->public; } - diff --git a/src/libcharon/processing/jobs/update_sa_job.h b/src/libcharon/processing/jobs/update_sa_job.h index 55a3df83e..9c19f5b6e 100644 --- a/src/libcharon/processing/jobs/update_sa_job.h +++ b/src/libcharon/processing/jobs/update_sa_job.h @@ -26,6 +26,7 @@ typedef struct update_sa_job_t update_sa_job_t; #include <library.h> #include <networking/host.h> #include <processing/jobs/job.h> +#include <config/proposal.h> /** * Update the addresses of an IKE and its CHILD_SAs. @@ -41,10 +42,13 @@ struct update_sa_job_t { /** * Creates a job to update IKE and CHILD_SA addresses. * - * @param reqid reqid of the CHILD_SA + * @param protocol IPsec protocol of SA to update + * @param spi SPI of SA to update + * @param dst old destination host of SA to update * @param new new address and port * @return update_sa_job_t object */ -update_sa_job_t *update_sa_job_create(u_int32_t reqid, host_t *new); +update_sa_job_t *update_sa_job_create(protocol_id_t protocol, + u_int32_t spi, host_t *dst, host_t *new); #endif /** UPDATE_SA_JOB_H_ @}*/ diff --git a/src/libcharon/sa/authenticator.c b/src/libcharon/sa/authenticator.c index 8571274ac..6c3681a2d 100644 --- a/src/libcharon/sa/authenticator.c +++ b/src/libcharon/sa/authenticator.c @@ -31,12 +31,14 @@ ENUM_BEGIN(auth_method_names, AUTH_RSA, AUTH_DSS, "RSA signature", "pre-shared key", "DSS signature"); -ENUM_NEXT(auth_method_names, AUTH_ECDSA_256, AUTH_GSPM, AUTH_DSS, +ENUM_NEXT(auth_method_names, AUTH_ECDSA_256, AUTH_DS, AUTH_DSS, "ECDSA-256 signature", "ECDSA-384 signature", "ECDSA-521 signature", - "secure password method"); -ENUM_NEXT(auth_method_names, AUTH_XAUTH_INIT_PSK, AUTH_HYBRID_RESP_RSA, AUTH_GSPM, + "secure password method", + "NULL authentication", + "digital signature"); +ENUM_NEXT(auth_method_names, AUTH_XAUTH_INIT_PSK, AUTH_HYBRID_RESP_RSA, AUTH_DS, "XAuthInitPSK", "XAuthRespPSK", "XAuthInitRSA", @@ -99,6 +101,7 @@ authenticator_t *authenticator_create_verifier( case AUTH_ECDSA_256: case AUTH_ECDSA_384: case AUTH_ECDSA_521: + case AUTH_DS: return (authenticator_t*)pubkey_authenticator_create_verifier(ike_sa, sent_nonce, received_init, reserved); case AUTH_PSK: diff --git a/src/libcharon/sa/authenticator.h b/src/libcharon/sa/authenticator.h index 914f42d9d..97c042e71 100644 --- a/src/libcharon/sa/authenticator.h +++ b/src/libcharon/sa/authenticator.h @@ -80,6 +80,16 @@ enum auth_method_t { AUTH_GSPM = 12, /** + * NULL Authentication Method as specified in draft-ietf-ipsecme-ikev2-null-auth + */ + AUTH_NULL = 13, + + /** + * Digital Signature as specified in RFC 7427 + */ + AUTH_DS = 14, + + /** * IKEv1 initiator XAUTH with PSK, outside of IANA range */ AUTH_XAUTH_INIT_PSK = 256, diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c index a96ab4e90..e0db2e655 100644 --- a/src/libcharon/sa/child_sa.c +++ b/src/libcharon/sa/child_sa.c @@ -34,6 +34,8 @@ ENUM(child_sa_state_names, CHILD_CREATED, CHILD_DESTROYING, "INSTALLED", "UPDATING", "REKEYING", + "REKEYED", + "RETRYING", "DELETING", "DESTROYING", ); @@ -100,6 +102,16 @@ struct private_child_sa_t { u_int32_t reqid; /** + * Did we allocate/confirm and must release the reqid? + */ + bool reqid_allocated; + + /* + * Unique CHILD_SA identifier + */ + u_int32_t unique_id; + + /** * inbound mark used for this child_sa */ mark_t mark_in; @@ -228,6 +240,12 @@ METHOD(child_sa_t, get_reqid, u_int32_t, return this->reqid; } +METHOD(child_sa_t, get_unique_id, u_int32_t, + private_child_sa_t *this) +{ + return this->unique_id; +} + METHOD(child_sa_t, get_config, child_cfg_t*, private_child_sa_t *this) { @@ -602,7 +620,7 @@ METHOD(child_sa_t, alloc_spi, u_int32_t, { if (hydra->kernel_interface->get_spi(hydra->kernel_interface, this->other_addr, this->my_addr, - proto_ike2ip(protocol), this->reqid, + proto_ike2ip(protocol), &this->my_spi) == SUCCESS) { /* if we allocate a SPI, but then are unable to establish the SA, we @@ -618,7 +636,7 @@ METHOD(child_sa_t, alloc_cpi, u_int16_t, { if (hydra->kernel_interface->get_cpi(hydra->kernel_interface, this->other_addr, this->my_addr, - this->reqid, &this->my_cpi) == SUCCESS) + &this->my_cpi) == SUCCESS) { return this->my_cpi; } @@ -632,7 +650,7 @@ METHOD(child_sa_t, install, status_t, { u_int16_t enc_alg = ENCR_UNDEFINED, int_alg = AUTH_UNDEFINED, size; u_int16_t esn = NO_EXT_SEQ_NUMBERS; - traffic_selector_t *src_ts = NULL, *dst_ts = NULL; + linked_list_t *src_ts = NULL, *dst_ts = NULL; time_t now; lifetime_cfg_t *lifetime; u_int32_t tfc = 0; @@ -680,6 +698,18 @@ METHOD(child_sa_t, install, status_t, this->proposal->get_algorithm(this->proposal, EXTENDED_SEQUENCE_NUMBERS, &esn, NULL); + if (!this->reqid_allocated) + { + status = hydra->kernel_interface->alloc_reqid(hydra->kernel_interface, + my_ts, other_ts, this->mark_in, this->mark_out, + &this->reqid); + if (status != SUCCESS) + { + return status; + } + this->reqid_allocated = TRUE; + } + lifetime = this->config->get_lifetime(this->config); now = time_monotonic(NULL); @@ -704,18 +734,16 @@ METHOD(child_sa_t, install, status_t, lifetime->time.rekey = 0; } - /* BEET requires the bound address from the traffic selectors. - * TODO: We add just the first traffic selector for now, as the - * kernel accepts a single TS per SA only */ + /* BEET requires the bound address from the traffic selectors */ if (inbound) { - my_ts->get_first(my_ts, (void**)&dst_ts); - other_ts->get_first(other_ts, (void**)&src_ts); + dst_ts = my_ts; + src_ts = other_ts; } else { - my_ts->get_first(my_ts, (void**)&src_ts); - other_ts->get_first(other_ts, (void**)&dst_ts); + src_ts = my_ts; + dst_ts = other_ts; } status = hydra->kernel_interface->add_sa(hydra->kernel_interface, @@ -723,7 +751,7 @@ METHOD(child_sa_t, install, status_t, inbound ? this->mark_in : this->mark_out, tfc, lifetime, enc_alg, encr, int_alg, integ, this->mode, this->ipcomp, cpi, this->config->get_replay_window(this->config), - initiator, this->encap, esn, update, src_ts, dst_ts); + initiator, this->encap, esn, inbound, update, src_ts, dst_ts); free(lifetime); @@ -798,6 +826,19 @@ METHOD(child_sa_t, add_policies, status_t, traffic_selector_t *my_ts, *other_ts; status_t status = SUCCESS; + if (!this->reqid_allocated) + { + /* trap policy, get or confirm reqid */ + status = hydra->kernel_interface->alloc_reqid( + hydra->kernel_interface, my_ts_list, other_ts_list, + this->mark_in, this->mark_out, &this->reqid); + if (status != SUCCESS) + { + return status; + } + this->reqid_allocated = TRUE; + } + /* apply traffic selectors */ enumerator = my_ts_list->create_enumerator(my_ts_list); while (enumerator->enumerate(enumerator, &my_ts)) @@ -805,12 +846,15 @@ METHOD(child_sa_t, add_policies, status_t, array_insert(this->my_ts, ARRAY_TAIL, my_ts->clone(my_ts)); } enumerator->destroy(enumerator); + array_sort(this->my_ts, (void*)traffic_selector_cmp, NULL); + enumerator = other_ts_list->create_enumerator(other_ts_list); while (enumerator->enumerate(enumerator, &other_ts)) { array_insert(this->other_ts, ARRAY_TAIL, other_ts->clone(other_ts)); } enumerator->destroy(enumerator); + array_sort(this->other_ts, (void*)traffic_selector_cmp, NULL); if (this->config->install_policy(this->config)) { @@ -1071,6 +1115,22 @@ METHOD(child_sa_t, destroy, void, set_state(this, CHILD_DESTROYING); + if (this->config->install_policy(this->config)) + { + /* delete all policies in the kernel */ + enumerator = create_policy_enumerator(this); + while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) + { + del_policies_internal(this, my_ts, other_ts, priority); + if (priority == POLICY_PRIORITY_DEFAULT && require_policy_update()) + { + del_policies_internal(this, my_ts, other_ts, + POLICY_PRIORITY_FALLBACK); + } + } + enumerator->destroy(enumerator); + } + /* delete SAs in the kernel, if they are set up */ if (this->my_spi) { @@ -1087,20 +1147,13 @@ METHOD(child_sa_t, destroy, void, this->mark_out); } - if (this->config->install_policy(this->config)) + if (this->reqid_allocated) { - /* delete all policies in the kernel */ - enumerator = create_policy_enumerator(this); - while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) + if (hydra->kernel_interface->release_reqid(hydra->kernel_interface, + this->reqid, this->mark_in, this->mark_out) != SUCCESS) { - del_policies_internal(this, my_ts, other_ts, priority); - if (priority == POLICY_PRIORITY_DEFAULT && require_policy_update()) - { - del_policies_internal(this, my_ts, other_ts, - POLICY_PRIORITY_FALLBACK); - } + DBG1(DBG_CHD, "releasing reqid %u failed", this->reqid); } - enumerator->destroy(enumerator); } array_destroy_offset(this->my_ts, offsetof(traffic_selector_t, destroy)); @@ -1151,15 +1204,17 @@ static host_t* get_proxy_addr(child_cfg_t *config, host_t *ike, bool local) * Described in header. */ child_sa_t * child_sa_create(host_t *me, host_t* other, - child_cfg_t *config, u_int32_t rekey, bool encap) + child_cfg_t *config, u_int32_t rekey, bool encap, + u_int mark_in, u_int mark_out) { - static refcount_t reqid = 0; private_child_sa_t *this; + static refcount_t unique_id = 0, unique_mark = 0, mark; INIT(this, .public = { .get_name = _get_name, .get_reqid = _get_reqid, + .get_unique_id = _get_unique_id, .get_config = _get_config, .get_state = _get_state, .set_state = _set_state, @@ -1201,6 +1256,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other, .close_action = config->get_close_action(config), .dpd_action = config->get_dpd_action(config), .reqid = config->get_reqid(config), + .unique_id = ref_get(&unique_id), .mark_in = config->get_mark(config, TRUE), .mark_out = config->get_mark(config, FALSE), .install_time = time_monotonic(NULL), @@ -1209,9 +1265,37 @@ child_sa_t * child_sa_create(host_t *me, host_t* other, this->config = config; config->get_ref(config); + if (mark_in) + { + this->mark_in.value = mark_in; + } + if (mark_out) + { + this->mark_out.value = mark_out; + } + if (this->mark_in.value == MARK_UNIQUE || + this->mark_out.value == MARK_UNIQUE) + { + mark = ref_get(&unique_mark); + if (this->mark_in.value == MARK_UNIQUE) + { + this->mark_in.value = mark; + } + if (this->mark_out.value == MARK_UNIQUE) + { + this->mark_out.value = mark; + } + } + if (!this->reqid) { - /* reuse old reqid if we are rekeying an existing CHILD_SA */ + /* reuse old reqid if we are rekeying an existing CHILD_SA. While the + * reqid cache would find the same reqid for our selectors, this does + * not work in a special case: If an SA is triggered by a trap policy, + * but the negotiated SA gets narrowed, we still must reuse the same + * reqid to successfully "trigger" the SA on the kernel level. Rekeying + * such an SA requires an explicit reqid, as the cache currently knows + * the original selectors only for that reqid. */ if (rekey) { this->reqid = rekey; @@ -1219,22 +1303,9 @@ child_sa_t * child_sa_create(host_t *me, host_t* other, else { this->reqid = charon->traps->find_reqid(charon->traps, config); - if (!this->reqid) - { - this->reqid = ref_get(&reqid); - } } } - if (this->mark_in.value == MARK_REQID) - { - this->mark_in.value = this->reqid; - } - if (this->mark_out.value == MARK_REQID) - { - this->mark_out.value = this->reqid; - } - /* MIPv6 proxy transport mode sets SA endpoints to TS hosts */ if (config->get_mode(config) == MODE_TRANSPORT && config->use_proxy_mode(config)) diff --git a/src/libcharon/sa/child_sa.h b/src/libcharon/sa/child_sa.h index a0c6c357f..debe8eb2c 100644 --- a/src/libcharon/sa/child_sa.h +++ b/src/libcharon/sa/child_sa.h @@ -68,6 +68,16 @@ enum child_sa_state_t { CHILD_REKEYING, /** + * CHILD_SA that was rekeyed, but stays installed + */ + CHILD_REKEYED, + + /** + * CHILD_SA negotiation failed, but gets retried + */ + CHILD_RETRYING, + + /** * CHILD_SA in progress of delete */ CHILD_DELETING, @@ -121,6 +131,16 @@ struct child_sa_t { u_int32_t (*get_reqid)(child_sa_t *this); /** + * Get the unique numerical identifier for this CHILD_SA. + * + * While the same reqid might be shared between multiple SAs, the unique_id + * is truly unique for all CHILD_SA instances. + * + * @return unique CHILD_SA identifier + */ + u_int32_t (*get_unique_id)(child_sa_t *this); + + /** * Get the config used to set up this child sa. * * @return child_cfg @@ -379,9 +399,12 @@ struct child_sa_t { * @param config config to use for this CHILD_SA * @param reqid reqid of old CHILD_SA when rekeying, 0 otherwise * @param encap TRUE to enable UDP encapsulation (NAT traversal) + * @param mark_in explicit inbound mark value to use, 0 for config + * @param mark_out explicit outbound mark value to use, 0 for config * @return child_sa_t object */ child_sa_t * child_sa_create(host_t *me, host_t *other, child_cfg_t *config, - u_int32_t reqid, bool encap); + u_int32_t reqid, bool encap, + u_int mark_in, u_int mark_out); #endif /** CHILD_SA_H_ @}*/ diff --git a/src/libcharon/sa/child_sa_manager.c b/src/libcharon/sa/child_sa_manager.c new file mode 100644 index 000000000..071a119da --- /dev/null +++ b/src/libcharon/sa/child_sa_manager.c @@ -0,0 +1,333 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "child_sa_manager.h" + +#include <daemon.h> +#include <threading/mutex.h> +#include <collections/hashtable.h> + +typedef struct private_child_sa_manager_t private_child_sa_manager_t; + +/** + * Private data of an child_sa_manager_t object. + */ +struct private_child_sa_manager_t { + + /** + * Public child_sa_manager_t interface. + */ + child_sa_manager_t public; + + /** + * CHILD_SAs by inbound SPI/dst, child_entry_t => child_entry_t + */ + hashtable_t *in; + + /** + * CHILD_SAs by outbound SPI/dst, child_entry_t => child_entry_t + */ + hashtable_t *out; + + /** + * CHILD_SAs by unique ID, child_entry_t => child_entry_t + */ + hashtable_t *ids; + + /** + * Mutex to access any hashtable + */ + mutex_t *mutex; +}; + +/** + * Hashtable entry for a known CHILD_SA + */ +typedef struct { + /** the associated IKE_SA */ + ike_sa_id_t *ike_id; + /** unique CHILD_SA identifier */ + u_int32_t unique_id; + /** inbound SPI */ + u_int32_t spi_in; + /** outbound SPI */ + u_int32_t spi_out; + /** inbound host address */ + host_t *host_in; + /** outbound host address and port */ + host_t *host_out; + /** IPsec protocol, AH|ESP */ + protocol_id_t proto; +} child_entry_t; + +/** + * Destroy a CHILD_SA entry + */ +static void child_entry_destroy(child_entry_t *entry) +{ + entry->ike_id->destroy(entry->ike_id); + entry->host_in->destroy(entry->host_in); + entry->host_out->destroy(entry->host_out); + free(entry); +} + +/** + * Hashtable hash function for inbound SAs + */ +static u_int hash_in(child_entry_t *entry) +{ + return chunk_hash_inc(chunk_from_thing(entry->spi_in), + chunk_hash_inc(entry->host_in->get_address(entry->host_in), + chunk_hash(chunk_from_thing(entry->proto)))); +} + +/** + * Hashtable equals function for inbound SAs + */ +static bool equals_in(child_entry_t *a, child_entry_t *b) +{ + return a->spi_in == b->spi_in && + a->proto == b->proto && + a->host_in->ip_equals(a->host_in, b->host_in); +} + +/** + * Hashtable hash function for outbound SAs + */ +static u_int hash_out(child_entry_t *entry) +{ + return chunk_hash_inc(chunk_from_thing(entry->spi_out), + chunk_hash_inc(entry->host_out->get_address(entry->host_out), + chunk_hash(chunk_from_thing(entry->proto)))); +} + +/** + * Hashtable equals function for outbound SAs + */ +static bool equals_out(child_entry_t *a, child_entry_t *b) +{ + return a->spi_out == b->spi_out && + a->proto == b->proto && + a->host_out->ip_equals(a->host_out, b->host_out); +} + +/** + * Hashtable hash function for SAs by unique ID + */ +static u_int hash_id(child_entry_t *entry) +{ + return chunk_hash(chunk_from_thing(entry->unique_id)); +} + +/** + * Hashtable equals function for SAs by unique ID + */ +static bool equals_id(child_entry_t *a, child_entry_t *b) +{ + return a->unique_id == b->unique_id; +} + +METHOD(child_sa_manager_t, add, void, + private_child_sa_manager_t *this, child_sa_t *child_sa, ike_sa_t *ike_sa) +{ + child_entry_t *entry; + host_t *in, *out; + ike_sa_id_t *id; + + id = ike_sa->get_id(ike_sa); + in = ike_sa->get_my_host(ike_sa); + out = ike_sa->get_other_host(ike_sa); + + INIT(entry, + .ike_id = id->clone(id), + .unique_id = child_sa->get_unique_id(child_sa), + .proto = child_sa->get_protocol(child_sa), + .spi_in = child_sa->get_spi(child_sa, TRUE), + .spi_out = child_sa->get_spi(child_sa, FALSE), + .host_in = in->clone(in), + .host_out = out->clone(out), + ); + + this->mutex->lock(this->mutex); + if (!this->in->get(this->in, entry) && + !this->out->get(this->out, entry)) + { + this->in->put(this->in, entry, entry); + this->out->put(this->out, entry, entry); + entry = this->ids->put(this->ids, entry, entry); + } + this->mutex->unlock(this->mutex); + + if (entry) + { + child_entry_destroy(entry); + } +} + +METHOD(child_sa_manager_t, remove_, void, + private_child_sa_manager_t *this, child_sa_t *child_sa) +{ + child_entry_t *entry, key = { + .unique_id = child_sa->get_unique_id(child_sa), + }; + + this->mutex->lock(this->mutex); + entry = this->ids->remove(this->ids, &key); + if (entry) + { + this->in->remove(this->in, entry); + this->out->remove(this->out, entry); + } + this->mutex->unlock(this->mutex); + + if (entry) + { + child_entry_destroy(entry); + } +} + +/** + * Check out an IKE_SA for a given CHILD_SA + */ +static ike_sa_t *checkout_ikesa(private_child_sa_manager_t *this, + ike_sa_id_t *id, u_int32_t unique_id, child_sa_t **child_sa) +{ + enumerator_t *enumerator; + child_sa_t *current; + ike_sa_t *ike_sa; + bool found = FALSE; + + ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager, id); + id->destroy(id); + if (ike_sa) + { + enumerator = ike_sa->create_child_sa_enumerator(ike_sa); + while (enumerator->enumerate(enumerator, ¤t)) + { + found = current->get_unique_id(current) == unique_id; + if (found) + { + if (child_sa) + { + *child_sa = current; + } + break; + } + } + enumerator->destroy(enumerator); + + if (found) + { + return ike_sa; + } + charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); + } + return NULL; +} + +METHOD(child_sa_manager_t, checkout_by_id, ike_sa_t*, + private_child_sa_manager_t *this, u_int32_t unique_id, + child_sa_t **child_sa) +{ + ike_sa_id_t *id; + child_entry_t *entry, key = { + .unique_id = unique_id, + }; + + this->mutex->lock(this->mutex); + entry = this->ids->get(this->ids, &key); + if (entry) + { + id = entry->ike_id->clone(entry->ike_id); + } + this->mutex->unlock(this->mutex); + + if (entry) + { + return checkout_ikesa(this, id, unique_id, child_sa); + } + return NULL; +} + +METHOD(child_sa_manager_t, checkout, ike_sa_t*, + private_child_sa_manager_t *this, protocol_id_t protocol, u_int32_t spi, + host_t *dst, child_sa_t **child_sa) +{ + ike_sa_id_t *id; + u_int32_t unique_id; + child_entry_t *entry, key = { + .spi_in = spi, + .spi_out = spi, + .host_in = dst, + .host_out = dst, + .proto = protocol, + }; + + this->mutex->lock(this->mutex); + entry = this->in->get(this->in, &key); + if (!entry) + { + entry = this->out->get(this->out, &key); + } + if (entry) + { + unique_id = entry->unique_id; + id = entry->ike_id->clone(entry->ike_id); + } + this->mutex->unlock(this->mutex); + + if (entry) + { + return checkout_ikesa(this, id, unique_id, child_sa); + } + return NULL; +} + +METHOD(child_sa_manager_t, destroy, void, + private_child_sa_manager_t *this) +{ + this->in->destroy(this->in); + this->out->destroy(this->out); + this->ids->destroy(this->ids); + this->mutex->destroy(this->mutex); + free(this); +} + +/** + * See header + */ +child_sa_manager_t *child_sa_manager_create() +{ + private_child_sa_manager_t *this; + + INIT(this, + .public = { + .add = _add, + .remove = _remove_, + .checkout = _checkout, + .checkout_by_id = _checkout_by_id, + .destroy = _destroy, + }, + .in = hashtable_create((hashtable_hash_t)hash_in, + (hashtable_equals_t)equals_in, 8), + .out = hashtable_create((hashtable_hash_t)hash_out, + (hashtable_equals_t)equals_out, 8), + .ids = hashtable_create((hashtable_hash_t)hash_id, + (hashtable_equals_t)equals_id, 8), + .mutex = mutex_create(MUTEX_TYPE_DEFAULT), + ); + + return &this->public; +} diff --git a/src/libcharon/sa/child_sa_manager.h b/src/libcharon/sa/child_sa_manager.h new file mode 100644 index 000000000..4d57528e8 --- /dev/null +++ b/src/libcharon/sa/child_sa_manager.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup child_sa_manager child_sa_manager + * @{ @ingroup sa + */ + +#ifndef CHILD_SA_MANAGER_H_ +#define CHILD_SA_MANAGER_H_ + +#include <sa/ike_sa.h> +#include <sa/child_sa.h> + +typedef struct child_sa_manager_t child_sa_manager_t; + +/** + * Handle CHILD_SA to IKE_SA relations + */ +struct child_sa_manager_t { + + /** + * Register a CHILD_SA/IKE_SA relation. + * + * @param child_sa CHILD_SA to register + * @param ike_sa IKE_SA owning the CHILD_SA + */ + void (*add)(child_sa_manager_t *this, child_sa_t *child_sa, ike_sa_t *ike_sa); + + /** + * Unregister a CHILD_SA/IKE_SA relation. + * + * @param child_sa CHILD_SA to unregister + */ + void (*remove)(child_sa_manager_t *this, child_sa_t *child_sa); + + /** + * Find a CHILD_SA and check out the associated IKE_SA by SPI. + * + * On success, the returned IKE_SA must be checked in after use to + * the IKE_SA manager. + * + * @param protocol IPsec protocol, AH|ESP + * @param spi SPI of CHILD_SA to check out + * @param dst SA destination host related to SPI + * @param child_sa returns CHILD_SA managed by IKE_SA + * @return IKE_SA, NULL if not found + */ + ike_sa_t *(*checkout)(child_sa_manager_t *this, + protocol_id_t protocol, u_int32_t spi, host_t *dst, + child_sa_t **child_sa); + + /** + * Find a CHILD_SA and check out the associated IKE_SA by unique_id. + * + * On success, the returned IKE_SA must be checked in after use to + * the IKE_SA manager. + * + * @param unique_id unique ID of CHILD_SA to check out + * @param child_sa returns CHILD_SA managed by IKE_SA + * @return IKE_SA, NULL if not found + */ + ike_sa_t *(*checkout_by_id)(child_sa_manager_t *this, u_int32_t unique_id, + child_sa_t **child_sa); + + /** + * Destroy a child_sa_manager_t. + */ + void (*destroy)(child_sa_manager_t *this); +}; + +/** + * Create a child_sa_manager instance. + */ +child_sa_manager_t *child_sa_manager_create(); + +#endif /** CHILD_SA_MANAGER_H_ @}*/ diff --git a/src/libcharon/sa/eap/eap_method.h b/src/libcharon/sa/eap/eap_method.h index 6242a5a6e..689c0f990 100644 --- a/src/libcharon/sa/eap/eap_method.h +++ b/src/libcharon/sa/eap/eap_method.h @@ -137,6 +137,18 @@ struct eap_method_t { void (*set_identifier) (eap_method_t *this, u_int8_t identifier); /** + * Get authentication details performed by this EAP method. + * + * After EAP completion, the auth data contains additional information + * of the authentication process, used certificates etc. + * This method is optional to implement, but if it is, it must return + * a valid auth_cfg. + * + * @return auth method, internal data + */ + auth_cfg_t* (*get_auth)(eap_method_t *this); + + /** * Destroys a eap_method_t object. */ void (*destroy) (eap_method_t *this); diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index d92b9df8e..3aafa4c13 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -932,6 +932,7 @@ METHOD(ike_sa_t, update_hosts, void, /* update our address in any case */ if (force && !me->equals(me, this->my_host)) { + charon->bus->ike_update(charon->bus, &this->public, TRUE, me); set_my_host(this, me->clone(me)); update = TRUE; } @@ -945,6 +946,7 @@ METHOD(ike_sa_t, update_hosts, void, (!has_condition(this, COND_NAT_HERE) || !has_condition(this, COND_ORIGINAL_INITIATOR))) { + charon->bus->ike_update(charon->bus, &this->public, FALSE, other); set_other_host(this, other->clone(other)); update = TRUE; } @@ -964,6 +966,10 @@ METHOD(ike_sa_t, update_hosts, void, enumerator = array_create_enumerator(this->child_sas); while (enumerator->enumerate(enumerator, &child_sa)) { + charon->child_sa_manager->remove(charon->child_sa_manager, child_sa); + charon->child_sa_manager->add(charon->child_sa_manager, + child_sa, &this->public); + if (child_sa->update(child_sa, this->my_host, this->other_host, vips, has_condition(this, COND_NAT_ANY)) == NOT_SUPPORTED) { @@ -971,6 +977,7 @@ METHOD(ike_sa_t, update_hosts, void, child_sa->get_protocol(child_sa), child_sa->get_spi(child_sa, TRUE)); } + } enumerator->destroy(enumerator); @@ -1444,6 +1451,8 @@ METHOD(ike_sa_t, add_child_sa, void, private_ike_sa_t *this, child_sa_t *child_sa) { array_insert_create(&this->child_sas, ARRAY_TAIL, child_sa); + charon->child_sa_manager->add(charon->child_sa_manager, + child_sa, &this->public); } METHOD(ike_sa_t, get_child_sa, child_sa_t*, @@ -1471,16 +1480,58 @@ METHOD(ike_sa_t, get_child_count, int, return array_count(this->child_sas); } +/** + * Private data of a create_child_sa_enumerator() + */ +typedef struct { + /** implements enumerator */ + enumerator_t public; + /** inner array enumerator */ + enumerator_t *inner; + /** current item */ + child_sa_t *current; +} child_enumerator_t; + +METHOD(enumerator_t, child_enumerate, bool, + child_enumerator_t *this, child_sa_t **child_sa) +{ + if (this->inner->enumerate(this->inner, &this->current)) + { + *child_sa = this->current; + return TRUE; + } + return FALSE; +} + +METHOD(enumerator_t, child_enumerator_destroy, void, + child_enumerator_t *this) +{ + this->inner->destroy(this->inner); + free(this); +} + METHOD(ike_sa_t, create_child_sa_enumerator, enumerator_t*, private_ike_sa_t *this) { - return array_create_enumerator(this->child_sas); + child_enumerator_t *enumerator; + + INIT(enumerator, + .public = { + .enumerate = (void*)_child_enumerate, + .destroy = _child_enumerator_destroy, + }, + .inner = array_create_enumerator(this->child_sas), + ); + return &enumerator->public; } METHOD(ike_sa_t, remove_child_sa, void, private_ike_sa_t *this, enumerator_t *enumerator) { - array_remove_at(this->child_sas, enumerator); + child_enumerator_t *ce = (child_enumerator_t*)enumerator; + + charon->child_sa_manager->remove(charon->child_sa_manager, ce->current); + array_remove_at(this->child_sas, ce->inner); } METHOD(ike_sa_t, rekey_child_sa, status_t, @@ -1513,13 +1564,13 @@ METHOD(ike_sa_t, destroy_child_sa, status_t, child_sa_t *child_sa; status_t status = NOT_FOUND; - enumerator = array_create_enumerator(this->child_sas); + enumerator = create_child_sa_enumerator(this); while (enumerator->enumerate(enumerator, (void**)&child_sa)) { if (child_sa->get_protocol(child_sa) == protocol && child_sa->get_spi(child_sa, TRUE) == spi) { - array_remove_at(this->child_sas, enumerator); + remove_child_sa(this, enumerator); child_sa->destroy(child_sa); status = SUCCESS; break; @@ -1771,7 +1822,7 @@ METHOD(ike_sa_t, reestablish, status_t, #endif /* ME */ { /* handle existing CHILD_SAs */ - enumerator = array_create_enumerator(this->child_sas); + enumerator = create_child_sa_enumerator(this); while (enumerator->enumerate(enumerator, (void**)&child_sa)) { if (has_condition(this, COND_REAUTHENTICATING)) @@ -1780,7 +1831,7 @@ METHOD(ike_sa_t, reestablish, status_t, { case CHILD_ROUTED: { /* move routed child directly */ - array_remove_at(this->child_sas, enumerator); + remove_child_sa(this, enumerator); new->add_child_sa(new, child_sa); action = ACTION_NONE; break; @@ -2209,6 +2260,12 @@ METHOD(ike_sa_t, inherit_post, void, array_insert_create(&this->other_vips, ARRAY_TAIL, vip); } + /* MOBIKE additional addresses */ + while (array_remove(other->peer_addresses, ARRAY_HEAD, &vip)) + { + array_insert_create(&this->peer_addresses, ARRAY_TAIL, vip); + } + /* authentication information */ enumerator = array_create_enumerator(other->my_auths); while (enumerator->enumerate(enumerator, &cfg)) @@ -2251,7 +2308,8 @@ METHOD(ike_sa_t, inherit_post, void, /* adopt all children */ while (array_remove(other->child_sas, ARRAY_HEAD, &child_sa)) { - array_insert_create(&this->child_sas, ARRAY_TAIL, child_sa); + charon->child_sa_manager->remove(charon->child_sa_manager, child_sa); + add_child_sa(this, child_sa); } /* move pending tasks to the new IKE_SA */ @@ -2296,8 +2354,8 @@ METHOD(ike_sa_t, destroy, void, { if (entry.handler) { - hydra->attributes->release(hydra->attributes, entry.handler, - this->other_id, entry.type, entry.data); + charon->attributes->release(charon->attributes, entry.handler, + &this->public, entry.type, entry.data); } free(entry.data.ptr); } @@ -2305,6 +2363,7 @@ METHOD(ike_sa_t, destroy, void, * routes that the CHILD_SA tries to uninstall. */ while (array_remove(this->child_sas, ARRAY_TAIL, &child_sa)) { + charon->child_sa_manager->remove(charon->child_sa_manager, child_sa); child_sa->destroy(child_sa); } while (array_remove(this->my_vips, ARRAY_TAIL, &vip)) @@ -2321,12 +2380,11 @@ METHOD(ike_sa_t, destroy, void, if (this->peer_cfg) { linked_list_t *pools; - identification_t *id; - id = get_other_eap_id(this); pools = linked_list_create_from_enumerator( this->peer_cfg->create_pool_enumerator(this->peer_cfg)); - hydra->attributes->release_address(hydra->attributes, pools, vip, id); + charon->attributes->release_address(charon->attributes, + pools, vip, &this->public); pools->destroy(pools); } vip->destroy(vip); diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h index c72d87367..9dbc805c9 100644 --- a/src/libcharon/sa/ike_sa.h +++ b/src/libcharon/sa/ike_sa.h @@ -131,6 +131,11 @@ enum ike_extension_t { * peer supports proprietary IKEv1 or standardized IKEv2 fragmentation */ EXT_IKE_FRAGMENTATION = (1<<11), + + /** + * Signature Authentication, RFC 7427 + */ + EXT_SIGNATURE_AUTH = (1<<12), }; /** @@ -936,8 +941,9 @@ struct ike_sa_t { /** * Reauthenticate the IKE_SA. * - * Create a completely new IKE_SA with authentication, recreates all children - * within the IKE_SA, closes this IKE_SA. + * Triggers a new IKE_SA that replaces this one. IKEv1 implicitly inherits + * all Quick Modes, while IKEv2 recreates all active and queued CHILD_SAs + * in the new IKE_SA. * * @return DESTROY_ME to destroy the IKE_SA */ diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c index bdabc59b5..13fc74ff7 100644 --- a/src/libcharon/sa/ike_sa_manager.c +++ b/src/libcharon/sa/ike_sa_manager.c @@ -1184,7 +1184,8 @@ METHOD(ike_sa_manager_t, checkout_by_message, ike_sa_t*, DBG2(DBG_MGR, "checkout IKE_SA by message"); - if (id->get_responder_spi(id) == 0) + if (id->get_responder_spi(id) == 0 && + message->get_message_id(message) == 0) { if (message->get_major_version(message) == IKEV2_MAJOR_VERSION) { @@ -1383,54 +1384,35 @@ METHOD(ike_sa_manager_t, checkout_by_config, ike_sa_t*, } METHOD(ike_sa_manager_t, checkout_by_id, ike_sa_t*, - private_ike_sa_manager_t *this, u_int32_t id, bool child) + private_ike_sa_manager_t *this, u_int32_t id) { - enumerator_t *enumerator, *children; + enumerator_t *enumerator; entry_t *entry; ike_sa_t *ike_sa = NULL; - child_sa_t *child_sa; u_int segment; - DBG2(DBG_MGR, "checkout IKE_SA by ID"); + DBG2(DBG_MGR, "checkout IKE_SA by ID %u", id); enumerator = create_table_enumerator(this); while (enumerator->enumerate(enumerator, &entry, &segment)) { if (wait_for_entry(this, entry, segment)) { - /* look for a child with such a reqid ... */ - if (child) - { - children = entry->ike_sa->create_child_sa_enumerator(entry->ike_sa); - while (children->enumerate(children, (void**)&child_sa)) - { - if (child_sa->get_reqid(child_sa) == id) - { - ike_sa = entry->ike_sa; - break; - } - } - children->destroy(children); - } - else /* ... or for a IKE_SA with such a unique id */ - { - if (entry->ike_sa->get_unique_id(entry->ike_sa) == id) - { - ike_sa = entry->ike_sa; - } - } - /* got one, return */ - if (ike_sa) + if (entry->ike_sa->get_unique_id(entry->ike_sa) == id) { + ike_sa = entry->ike_sa; entry->checked_out = TRUE; - DBG2(DBG_MGR, "IKE_SA %s[%u] successfully checked out", - ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa)); break; } } } enumerator->destroy(enumerator); + if (ike_sa) + { + DBG2(DBG_MGR, "IKE_SA %s[%u] successfully checked out", + ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa)); + } charon->bus->set_sa(charon->bus, ike_sa); return ike_sa; } @@ -1746,29 +1728,45 @@ METHOD(ike_sa_manager_t, create_id_enumerator, enumerator_t*, } /** - * Move all CHILD_SAs from old to new + * Move all CHILD_SAs and virtual IPs from old to new */ -static void adopt_children(ike_sa_t *old, ike_sa_t *new) +static void adopt_children_and_vips(ike_sa_t *old, ike_sa_t *new) { enumerator_t *enumerator; child_sa_t *child_sa; + host_t *vip; + int chcount = 0, vipcount = 0; + enumerator = old->create_child_sa_enumerator(old); while (enumerator->enumerate(enumerator, &child_sa)) { old->remove_child_sa(old, enumerator); new->add_child_sa(new, child_sa); + chcount++; } enumerator->destroy(enumerator); -} -/** - * Check if the replaced IKE_SA might get reauthenticated from host - */ -static bool is_ikev1_reauth(ike_sa_t *duplicate, host_t *host) -{ - return duplicate->get_version(duplicate) == IKEV1 && - host->equals(host, duplicate->get_other_host(duplicate)); + enumerator = old->create_virtual_ip_enumerator(old, FALSE); + while (enumerator->enumerate(enumerator, &vip)) + { + new->add_virtual_ip(new, FALSE, vip); + vipcount++; + } + enumerator->destroy(enumerator); + /* this does not release the addresses, which is good, but it does trigger + * an assign_vips(FALSE) event... */ + old->clear_virtual_ips(old, FALSE); + /* ...trigger the analogous event on the new SA */ + charon->bus->set_sa(charon->bus, new); + charon->bus->assign_vips(charon->bus, new, TRUE); + charon->bus->set_sa(charon->bus, old); + + if (chcount || vipcount) + { + DBG1(DBG_IKE, "detected reauth of existing IKE_SA, adopting %d " + "children and %d virtual IPs", chcount, vipcount); + } } /** @@ -1780,13 +1778,20 @@ static status_t enforce_replace(private_ike_sa_manager_t *this, { charon->bus->alert(charon->bus, ALERT_UNIQUE_REPLACE); - if (is_ikev1_reauth(duplicate, host)) + if (host->equals(host, duplicate->get_other_host(duplicate))) { /* looks like a reauthentication attempt */ - adopt_children(duplicate, new); + if (!new->has_condition(new, COND_INIT_CONTACT_SEEN) && + new->get_version(new) == IKEV1) + { + /* IKEv1 implicitly takes over children, IKEv2 recreates them + * explicitly. */ + adopt_children_and_vips(duplicate, new); + } /* For IKEv1 we have to delay the delete for the old IKE_SA. Some * peers need to complete the new SA first, otherwise the quick modes - * might get lost. */ + * might get lost. For IKEv2 we do the same, as we want overlapping + * CHILD_SAs to keep connectivity up. */ lib->scheduler->schedule_job(lib->scheduler, (job_t*) delete_ike_sa_job_create(duplicate->get_id(duplicate), TRUE), 10); return SUCCESS; @@ -1851,7 +1856,9 @@ METHOD(ike_sa_manager_t, check_uniqueness, bool, other, other_host); break; case UNIQUE_KEEP: - if (!is_ikev1_reauth(duplicate, other_host)) + /* potential reauthentication? */ + if (!other_host->equals(other_host, + duplicate->get_other_host(duplicate))) { cancel = TRUE; /* we keep the first IKE_SA and delete all diff --git a/src/libcharon/sa/ike_sa_manager.h b/src/libcharon/sa/ike_sa_manager.h index a68ae7763..f259d8e56 100644 --- a/src/libcharon/sa/ike_sa_manager.h +++ b/src/libcharon/sa/ike_sa_manager.h @@ -129,19 +129,15 @@ struct ike_sa_manager_t { /** * Check out an IKE_SA a unique ID. * - * Every IKE_SA and every CHILD_SA is uniquely identified by an ID. - * These checkout function uses, depending - * on the child parameter, the unique ID of the IKE_SA or the reqid - * of one of a IKE_SAs CHILD_SA. + * Every IKE_SA is uniquely identified by a numerical ID. This checkout + * function uses the unique ID of the IKE_SA to check it out. * * @param id unique ID of the object - * @param child TRUE to use CHILD, FALSE to use IKE_SA * @return * - checked out IKE_SA, if found * - NULL, if not found */ - ike_sa_t* (*checkout_by_id) (ike_sa_manager_t* this, u_int32_t id, - bool child); + ike_sa_t* (*checkout_by_id) (ike_sa_manager_t* this, u_int32_t id); /** * Check out an IKE_SA by the policy/connection name. diff --git a/src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.c b/src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.c index aa966cd5f..bb187f07c 100644 --- a/src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.c +++ b/src/libcharon/sa/ikev1/authenticators/psk_v1_authenticator.c @@ -74,7 +74,10 @@ METHOD(authenticator_t, build, status_t, keymat_v1_t *keymat; chunk_t hash, dh; - this->dh->get_my_public_value(this->dh, &dh); + if (!this->dh->get_my_public_value(this->dh, &dh)) + { + return FAILED; + } keymat = (keymat_v1_t*)this->ike_sa->get_keymat(this->ike_sa); if (!keymat->get_hash(keymat, this->initiator, dh, this->dh_value, this->ike_sa->get_id(this->ike_sa), this->sa_payload, @@ -108,7 +111,10 @@ METHOD(authenticator_t, process, status_t, return FAILED; } - this->dh->get_my_public_value(this->dh, &dh); + if (!this->dh->get_my_public_value(this->dh, &dh)) + { + return FAILED; + } keymat = (keymat_v1_t*)this->ike_sa->get_keymat(this->ike_sa); if (!keymat->get_hash(keymat, !this->initiator, this->dh_value, dh, this->ike_sa->get_id(this->ike_sa), this->sa_payload, diff --git a/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c b/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c index bfe5ff449..52228ef2e 100644 --- a/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c +++ b/src/libcharon/sa/ikev1/authenticators/pubkey_v1_authenticator.c @@ -94,7 +94,11 @@ METHOD(authenticator_t, build, status_t, return NOT_FOUND; } - this->dh->get_my_public_value(this->dh, &dh); + if (!this->dh->get_my_public_value(this->dh, &dh)) + { + private->destroy(private); + return FAILED; + } keymat = (keymat_v1_t*)this->ike_sa->get_keymat(this->ike_sa); if (!keymat->get_hash(keymat, this->initiator, dh, this->dh_value, this->ike_sa->get_id(this->ike_sa), this->sa_payload, @@ -152,7 +156,10 @@ METHOD(authenticator_t, process, status_t, } id = this->ike_sa->get_other_id(this->ike_sa); - this->dh->get_my_public_value(this->dh, &dh); + if (!this->dh->get_my_public_value(this->dh, &dh)) + { + return FAILED; + } keymat = (keymat_v1_t*)this->ike_sa->get_keymat(this->ike_sa); if (!keymat->get_hash(keymat, !this->initiator, this->dh_value, dh, this->ike_sa->get_id(this->ike_sa), this->sa_payload, diff --git a/src/libcharon/sa/ikev1/keymat_v1.c b/src/libcharon/sa/ikev1/keymat_v1.c index 619d197bd..f5a91dbeb 100644 --- a/src/libcharon/sa/ikev1/keymat_v1.c +++ b/src/libcharon/sa/ikev1/keymat_v1.c @@ -425,7 +425,7 @@ METHOD(keymat_v1_t, derive_ike_keys, bool, return FALSE; } - if (dh->get_shared_secret(dh, &g_xy) != SUCCESS) + if (!dh->get_shared_secret(dh, &g_xy)) { return FALSE; } @@ -560,7 +560,10 @@ METHOD(keymat_v1_t, derive_ike_keys, bool, return FALSE; } - dh->get_my_public_value(dh, &dh_me); + if (!dh->get_my_public_value(dh, &dh_me)) + { + return FALSE; + } g_xi = this->initiator ? dh_me : dh_other; g_xr = this->initiator ? dh_other : dh_me; @@ -661,7 +664,7 @@ METHOD(keymat_v1_t, derive_child_keys, bool, protocol = proposal->get_protocol(proposal); if (dh) { - if (dh->get_shared_secret(dh, &secret) != SUCCESS) + if (!dh->get_shared_secret(dh, &secret)) { return FALSE; } diff --git a/src/libcharon/sa/ikev1/phase1.c b/src/libcharon/sa/ikev1/phase1.c index d01a831f8..c968b2a9c 100644 --- a/src/libcharon/sa/ikev1/phase1.c +++ b/src/libcharon/sa/ikev1/phase1.c @@ -694,7 +694,13 @@ METHOD(phase1_t, add_nonce_ke, bool, nonce_gen_t *nonceg; chunk_t nonce; - ke_payload = ke_payload_create_from_diffie_hellman(PLV1_KEY_EXCHANGE, this->dh); + ke_payload = ke_payload_create_from_diffie_hellman(PLV1_KEY_EXCHANGE, + this->dh); + if (!ke_payload) + { + DBG1(DBG_IKE, "creating KE payload failed"); + return FALSE; + } message->add_payload(message, &ke_payload->payload_interface); nonceg = this->keymat->keymat.create_nonce_gen(&this->keymat->keymat); @@ -739,7 +745,11 @@ METHOD(phase1_t, get_nonce_ke, bool, return FALSE; } this->dh_value = chunk_clone(ke_payload->get_key_exchange_data(ke_payload)); - this->dh->set_other_public_value(this->dh, this->dh_value); + if (!this->dh->set_other_public_value(this->dh, this->dh_value)) + { + DBG1(DBG_IKE, "unable to apply received KE value"); + return FALSE; + } nonce_payload = (nonce_payload_t*)message->get_payload(message, PLV1_NONCE); if (!nonce_payload) diff --git a/src/libcharon/sa/ikev1/task_manager_v1.c b/src/libcharon/sa/ikev1/task_manager_v1.c index 0f8e8bc6d..cb22bf606 100644 --- a/src/libcharon/sa/ikev1/task_manager_v1.c +++ b/src/libcharon/sa/ikev1/task_manager_v1.c @@ -1596,7 +1596,8 @@ static bool is_redundant(private_task_manager_t *this, child_sa_t *child_sa) child_sa->get_lifetime(child_sa, FALSE)) { DBG1(DBG_IKE, "deleting redundant CHILD_SA %s{%d}", - child_sa->get_name(child_sa), child_sa->get_reqid(child_sa)); + child_sa->get_name(child_sa), + child_sa->get_unique_id(child_sa)); redundant = TRUE; break; } @@ -1647,6 +1648,8 @@ METHOD(task_manager_t, queue_child_rekey, void, task = quick_mode_create(this->ike_sa, cfg->get_ref(cfg), get_first_ts(child_sa, TRUE), get_first_ts(child_sa, FALSE)); task->use_reqid(task, child_sa->get_reqid(child_sa)); + task->use_marks(task, child_sa->get_mark(child_sa, TRUE).value, + child_sa->get_mark(child_sa, FALSE).value); task->rekey(task, child_sa->get_spi(child_sa, TRUE)); queue_task(this, &task->task); diff --git a/src/libcharon/sa/ikev1/tasks/isakmp_delete.c b/src/libcharon/sa/ikev1/tasks/isakmp_delete.c index bea0428c4..a56805afb 100644 --- a/src/libcharon/sa/ikev1/tasks/isakmp_delete.c +++ b/src/libcharon/sa/ikev1/tasks/isakmp_delete.c @@ -1,4 +1,7 @@ /* + * Copyright (C) 2015 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2011 Martin Willi * Copyright (C) 2011 revosec AG * @@ -74,6 +77,42 @@ METHOD(task_t, process_i, status_t, METHOD(task_t, process_r, status_t, private_isakmp_delete_t *this, message_t *message) { + enumerator_t *payloads; + payload_t *payload; + delete_payload_t *delete_payload; + ike_sa_id_t *id; + u_int64_t spi_i, spi_r; + bool found = FALSE; + + /* some peers send DELETE payloads for other IKE_SAs, e.g. those for expired + * ones after a rekeyeing, make sure the SPIs match */ + id = this->ike_sa->get_id(this->ike_sa); + payloads = message->create_payload_enumerator(message); + while (payloads->enumerate(payloads, &payload)) + { + if (payload->get_type(payload) == PLV1_DELETE) + { + delete_payload = (delete_payload_t*)payload; + if (!delete_payload->get_ike_spi(delete_payload, &spi_i, &spi_r)) + { + continue; + } + if (id->get_initiator_spi(id) == spi_i && + id->get_responder_spi(id) == spi_r) + { + found = TRUE; + break; + } + } + } + payloads->destroy(payloads); + + if (!found) + { + DBG1(DBG_IKE, "received DELETE for different IKE_SA, ignored"); + return SUCCESS; + } + DBG1(DBG_IKE, "received DELETE for IKE_SA %s[%d]", this->ike_sa->get_name(this->ike_sa), this->ike_sa->get_unique_id(this->ike_sa)); diff --git a/src/libcharon/sa/ikev1/tasks/main_mode.c b/src/libcharon/sa/ikev1/tasks/main_mode.c index 2fb4c6935..3ea4a2a85 100644 --- a/src/libcharon/sa/ikev1/tasks/main_mode.c +++ b/src/libcharon/sa/ikev1/tasks/main_mode.c @@ -205,6 +205,43 @@ static status_t send_delete(private_main_mode_t *this) return ALREADY_DONE; } +/** + * Add an INITIAL_CONTACT notify if first contact with peer + */ +static void add_initial_contact(private_main_mode_t *this, message_t *message, + identification_t *idi) +{ + identification_t *idr; + host_t *host; + notify_payload_t *notify; + ike_sa_id_t *ike_sa_id; + u_int64_t spi_i, spi_r; + chunk_t spi; + + idr = this->ph1->get_id(this->ph1, this->peer_cfg, FALSE); + if (idr && !idr->contains_wildcards(idr)) + { + if (this->peer_cfg->get_unique_policy(this->peer_cfg) != UNIQUE_NO && + this->peer_cfg->get_unique_policy(this->peer_cfg) != UNIQUE_NEVER) + { + host = this->ike_sa->get_other_host(this->ike_sa); + if (!charon->ike_sa_manager->has_contact(charon->ike_sa_manager, + idi, idr, host->get_family(host))) + { + notify = notify_payload_create_from_protocol_and_type( + PLV1_NOTIFY, PROTO_IKE, INITIAL_CONTACT_IKEV1); + ike_sa_id = this->ike_sa->get_id(this->ike_sa); + spi_i = ike_sa_id->get_initiator_spi(ike_sa_id); + spi_r = ike_sa_id->get_responder_spi(ike_sa_id); + spi = chunk_cata("cc", chunk_from_thing(spi_i), + chunk_from_thing(spi_r)); + notify->set_spi_data(notify, spi); + message->add_payload(message, (payload_t*)notify); + } + } + } +} + METHOD(task_t, build_i, status_t, private_main_mode_t *this, message_t *message) { @@ -311,6 +348,8 @@ METHOD(task_t, build_i, status_t, return send_notify(this, AUTHENTICATION_FAILED); } + add_initial_contact(this, message, id); + this->state = MM_AUTH; return NEED_MORE; } diff --git a/src/libcharon/sa/ikev1/tasks/mode_config.c b/src/libcharon/sa/ikev1/tasks/mode_config.c index 94026b9af..d0994a961 100644 --- a/src/libcharon/sa/ikev1/tasks/mode_config.c +++ b/src/libcharon/sa/ikev1/tasks/mode_config.c @@ -16,7 +16,6 @@ #include "mode_config.h" #include <daemon.h> -#include <hydra.h> #include <encoding/payloads/cp_payload.h> typedef struct private_mode_config_t private_mode_config_t; @@ -136,9 +135,8 @@ static void handle_attribute(private_mode_config_t *this, enumerator->destroy(enumerator); /* and pass it to the handle function */ - handler = hydra->attributes->handle(hydra->attributes, - this->ike_sa->get_other_id(this->ike_sa), handler, - ca->get_type(ca), ca->get_chunk(ca)); + handler = charon->attributes->handle(charon->attributes, + this->ike_sa, handler, ca->get_type(ca), ca->get_chunk(ca)); this->ike_sa->add_configuration_attribute(this->ike_sa, handler, ca->get_type(ca), ca->get_chunk(ca)); } @@ -326,9 +324,8 @@ static status_t build_request(private_mode_config_t *this, message_t *message) enumerator->destroy(enumerator); } - enumerator = hydra->attributes->create_initiator_enumerator( - hydra->attributes, - this->ike_sa->get_other_id(this->ike_sa), vips); + enumerator = charon->attributes->create_initiator_enumerator( + charon->attributes, this->ike_sa, vips); while (enumerator->enumerate(enumerator, &handler, &type, &data)) { add_attribute(this, cp, type, data, handler); @@ -353,7 +350,7 @@ static status_t build_set(private_mode_config_t *this, message_t *message) cp_payload_t *cp; peer_cfg_t *config; identification_t *id; - linked_list_t *pools; + linked_list_t *pools, *migrated, *vips; host_t *any4, *any6, *found; char *name; @@ -361,45 +358,62 @@ static status_t build_set(private_mode_config_t *this, message_t *message) id = this->ike_sa->get_other_eap_id(this->ike_sa); config = this->ike_sa->get_peer_cfg(this->ike_sa); - any4 = host_create_any(AF_INET); - any6 = host_create_any(AF_INET6); + /* if we migrated virtual IPs during reauthentication, reassign them */ + migrated = linked_list_create_from_enumerator( + this->ike_sa->create_virtual_ip_enumerator(this->ike_sa, + FALSE)); + vips = migrated->clone_offset(migrated, offsetof(host_t, clone)); + migrated->destroy(migrated); this->ike_sa->clear_virtual_ips(this->ike_sa, FALSE); /* in push mode, we ask each configured pool for an address */ - enumerator = config->create_pool_enumerator(config); - while (enumerator->enumerate(enumerator, &name)) + if (!vips->get_count(vips)) { - pools = linked_list_create_with_items(name, NULL); - /* try IPv4, then IPv6 */ - found = hydra->attributes->acquire_address(hydra->attributes, - pools, id, any4); - if (!found) - { - found = hydra->attributes->acquire_address(hydra->attributes, - pools, id, any6); - } - pools->destroy(pools); - if (found) + any4 = host_create_any(AF_INET); + any6 = host_create_any(AF_INET6); + enumerator = config->create_pool_enumerator(config); + while (enumerator->enumerate(enumerator, &name)) { - DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", found, id); - this->ike_sa->add_virtual_ip(this->ike_sa, FALSE, found); - cp->add_attribute(cp, build_vip(found)); - this->vips->insert_last(this->vips, found); + pools = linked_list_create_with_items(name, NULL); + /* try IPv4, then IPv6 */ + found = charon->attributes->acquire_address(charon->attributes, + pools, this->ike_sa, any4); + if (!found) + { + found = charon->attributes->acquire_address(charon->attributes, + pools, this->ike_sa, any6); + } + pools->destroy(pools); + if (found) + { + vips->insert_last(vips, found); + } } + enumerator->destroy(enumerator); + any4->destroy(any4); + any6->destroy(any6); } - enumerator->destroy(enumerator); - any4->destroy(any4); - any6->destroy(any6); + enumerator = vips->create_enumerator(vips); + while (enumerator->enumerate(enumerator, &found)) + { + DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", found, id); + this->ike_sa->add_virtual_ip(this->ike_sa, FALSE, found); + cp->add_attribute(cp, build_vip(found)); + this->vips->insert_last(this->vips, found); + vips->remove_at(vips, enumerator); + } + enumerator->destroy(enumerator); + vips->destroy(vips); charon->bus->assign_vips(charon->bus, this->ike_sa, TRUE); /* query registered providers for additional attributes to include */ pools = linked_list_create_from_enumerator( config->create_pool_enumerator(config)); - enumerator = hydra->attributes->create_responder_enumerator( - hydra->attributes, pools, id, this->vips); + enumerator = charon->attributes->create_responder_enumerator( + charon->attributes, pools, this->ike_sa, this->vips); while (enumerator->enumerate(enumerator, &type, &value)) { add_attribute(this, cp, type, value, NULL); @@ -458,6 +472,28 @@ METHOD(task_t, process_r, status_t, } /** + * Assign a migrated virtual IP + */ +static host_t *assign_migrated_vip(linked_list_t *migrated, host_t *requested) +{ + enumerator_t *enumerator; + host_t *found = NULL, *vip; + + enumerator = migrated->create_enumerator(migrated); + while (enumerator->enumerate(enumerator, &vip)) + { + if (vip->ip_equals(vip, requested)) + { + migrated->remove_at(migrated, enumerator); + found = vip; + break; + } + } + enumerator->destroy(enumerator); + return found; +} + +/** * Build CFG_REPLY message after receiving CFG_REQUEST */ static status_t build_reply(private_mode_config_t *this, message_t *message) @@ -468,29 +504,35 @@ static status_t build_reply(private_mode_config_t *this, message_t *message) cp_payload_t *cp; peer_cfg_t *config; identification_t *id; - linked_list_t *vips, *pools; - host_t *requested; + linked_list_t *vips, *pools, *migrated; + host_t *requested, *found; cp = cp_payload_create_type(PLV1_CONFIGURATION, CFG_REPLY); id = this->ike_sa->get_other_eap_id(this->ike_sa); config = this->ike_sa->get_peer_cfg(this->ike_sa); - vips = linked_list_create(); pools = linked_list_create_from_enumerator( config->create_pool_enumerator(config)); - + /* if we migrated virtual IPs during reauthentication, reassign them */ + vips = linked_list_create_from_enumerator( + this->ike_sa->create_virtual_ip_enumerator(this->ike_sa, + FALSE)); + migrated = vips->clone_offset(vips, offsetof(host_t, clone)); + vips->destroy(vips); this->ike_sa->clear_virtual_ips(this->ike_sa, FALSE); + vips = linked_list_create(); enumerator = this->vips->create_enumerator(this->vips); while (enumerator->enumerate(enumerator, &requested)) { - host_t *found = NULL; - - /* query all pools until we get an address */ DBG1(DBG_IKE, "peer requested virtual IP %H", requested); - found = hydra->attributes->acquire_address(hydra->attributes, - pools, id, requested); + found = assign_migrated_vip(migrated, requested); + if (!found) + { + found = charon->attributes->acquire_address(charon->attributes, + pools, this->ike_sa, requested); + } if (found) { DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", found, id); @@ -509,8 +551,8 @@ static status_t build_reply(private_mode_config_t *this, message_t *message) charon->bus->assign_vips(charon->bus, this->ike_sa, TRUE); /* query registered providers for additional attributes to include */ - enumerator = hydra->attributes->create_responder_enumerator( - hydra->attributes, pools, id, vips); + enumerator = charon->attributes->create_responder_enumerator( + charon->attributes, pools, this->ike_sa, vips); while (enumerator->enumerate(enumerator, &type, &value)) { cp->add_attribute(cp, @@ -518,6 +560,15 @@ static status_t build_reply(private_mode_config_t *this, message_t *message) type, value)); } enumerator->destroy(enumerator); + /* if a client did not re-request all adresses, release them */ + enumerator = migrated->create_enumerator(migrated); + while (enumerator->enumerate(enumerator, &found)) + { + charon->attributes->release_address(charon->attributes, + pools, found, this->ike_sa); + } + enumerator->destroy(enumerator); + migrated->destroy_offset(migrated, offsetof(host_t, destroy)); vips->destroy_offset(vips, offsetof(host_t, destroy)); pools->destroy(pools); diff --git a/src/libcharon/sa/ikev1/tasks/quick_delete.c b/src/libcharon/sa/ikev1/tasks/quick_delete.c index 499081caa..1b95a8b11 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_delete.c +++ b/src/libcharon/sa/ikev1/tasks/quick_delete.c @@ -105,7 +105,7 @@ static bool delete_child(private_quick_delete_t *this, protocol_id_t protocol, this->spi = spi = child_sa->get_spi(child_sa, TRUE); } - rekeyed = child_sa->get_state(child_sa) == CHILD_REKEYING; + rekeyed = child_sa->get_state(child_sa) == CHILD_REKEYED; child_sa->set_state(child_sa, CHILD_DELETING); my_ts = linked_list_create_from_enumerator( @@ -116,7 +116,7 @@ static bool delete_child(private_quick_delete_t *this, protocol_id_t protocol, { DBG0(DBG_IKE, "closing expired CHILD_SA %s{%d} " "with SPIs %.8x_i %.8x_o and TS %#R=== %#R", - child_sa->get_name(child_sa), child_sa->get_reqid(child_sa), + child_sa->get_name(child_sa), child_sa->get_unique_id(child_sa), ntohl(child_sa->get_spi(child_sa, TRUE)), ntohl(child_sa->get_spi(child_sa, FALSE)), my_ts, other_ts); } @@ -127,7 +127,7 @@ static bool delete_child(private_quick_delete_t *this, protocol_id_t protocol, DBG0(DBG_IKE, "closing CHILD_SA %s{%d} with SPIs " "%.8x_i (%llu bytes) %.8x_o (%llu bytes) and TS %#R=== %#R", - child_sa->get_name(child_sa), child_sa->get_reqid(child_sa), + child_sa->get_name(child_sa), child_sa->get_unique_id(child_sa), ntohl(child_sa->get_spi(child_sa, TRUE)), bytes_in, ntohl(child_sa->get_spi(child_sa, FALSE)), bytes_out, my_ts, other_ts); diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.c b/src/libcharon/sa/ikev1/tasks/quick_mode.c index 1133aab65..96edfd8d8 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_mode.c +++ b/src/libcharon/sa/ikev1/tasks/quick_mode.c @@ -156,6 +156,16 @@ struct private_quick_mode_t { u_int32_t reqid; /** + * Explicit inbound mark value to use, if any + */ + u_int mark_in; + + /** + * Explicit inbound mark value to use, if any + */ + u_int mark_out; + + /** * SPI of SA we rekey */ u_int32_t rekey; @@ -196,8 +206,8 @@ static void schedule_inactivity_timeout(private_quick_mode_t *this) close_ike = lib->settings->get_bool(lib->settings, "%s.inactivity_close_ike", FALSE, lib->ns); lib->scheduler->schedule_job(lib->scheduler, (job_t*) - inactivity_job_create(this->child_sa->get_reqid(this->child_sa), - timeout, close_ike), timeout); + inactivity_job_create(this->child_sa->get_unique_id(this->child_sa), + timeout, close_ike), timeout); } } @@ -375,7 +385,7 @@ static bool install(private_quick_mode_t *this) DBG0(DBG_IKE, "CHILD_SA %s{%d} established " "with SPIs %.8x_i %.8x_o and TS %#R=== %#R", this->child_sa->get_name(this->child_sa), - this->child_sa->get_reqid(this->child_sa), + this->child_sa->get_unique_id(this->child_sa), ntohl(this->child_sa->get_spi(this->child_sa, TRUE)), ntohl(this->child_sa->get_spi(this->child_sa, FALSE)), my_ts, other_ts); @@ -391,15 +401,14 @@ static bool install(private_quick_mode_t *this) if (old) { charon->bus->child_rekey(charon->bus, old, this->child_sa); + /* rekeyed CHILD_SAs stay installed until they expire */ + old->set_state(old, CHILD_REKEYED); } else { charon->bus->child_updown(charon->bus, this->child_sa, TRUE); } - if (!this->rekey) - { - schedule_inactivity_timeout(this); - } + schedule_inactivity_timeout(this); this->child_sa = NULL; return TRUE; } @@ -456,12 +465,19 @@ static bool get_nonce(private_quick_mode_t *this, chunk_t *nonce, /** * Add KE payload to message */ -static void add_ke(private_quick_mode_t *this, message_t *message) +static bool add_ke(private_quick_mode_t *this, message_t *message) { ke_payload_t *ke_payload; - ke_payload = ke_payload_create_from_diffie_hellman(PLV1_KEY_EXCHANGE, this->dh); + ke_payload = ke_payload_create_from_diffie_hellman(PLV1_KEY_EXCHANGE, + this->dh); + if (!ke_payload) + { + DBG1(DBG_IKE, "creating KE payload failed"); + return FALSE; + } message->add_payload(message, &ke_payload->payload_interface); + return TRUE; } /** @@ -477,8 +493,12 @@ static bool get_ke(private_quick_mode_t *this, message_t *message) DBG1(DBG_IKE, "KE payload missing"); return FALSE; } - this->dh->set_other_public_value(this->dh, - ke_payload->get_key_exchange_data(ke_payload)); + if (!this->dh->set_other_public_value(this->dh, + ke_payload->get_key_exchange_data(ke_payload))) + { + DBG1(DBG_IKE, "unable to apply received KE value"); + return FALSE; + } return TRUE; } @@ -788,7 +808,8 @@ METHOD(task_t, build_i, status_t, this->child_sa = child_sa_create( this->ike_sa->get_my_host(this->ike_sa), this->ike_sa->get_other_host(this->ike_sa), - this->config, this->reqid, this->udp); + this->config, this->reqid, this->udp, + this->mark_in, this->mark_out); if (this->udp && this->mode == MODE_TRANSPORT) { @@ -870,7 +891,10 @@ METHOD(task_t, build_i, status_t, } if (group != MODP_NONE) { - add_ke(this, message); + if (!add_ke(this, message)) + { + return FAILED; + } } if (!this->tsi) { @@ -964,6 +988,7 @@ static void check_for_rekeyed_child(private_quick_mode_t *this) { case CHILD_INSTALLED: case CHILD_REKEYING: + case CHILD_REKEYED: policies = child_sa->create_policy_enumerator(child_sa); if (policies->enumerate(policies, &local, &remote) && local->equals(local, this->tsr) && @@ -972,9 +997,14 @@ static void check_for_rekeyed_child(private_quick_mode_t *this) { this->reqid = child_sa->get_reqid(child_sa); this->rekey = child_sa->get_spi(child_sa, TRUE); + this->mark_in = child_sa->get_mark(child_sa, + TRUE).value; + this->mark_out = child_sa->get_mark(child_sa, + FALSE).value; child_sa->set_state(child_sa, CHILD_REKEYING); DBG1(DBG_IKE, "detected rekeying of CHILD_SA %s{%u}", - child_sa->get_name(child_sa), this->reqid); + child_sa->get_name(child_sa), + child_sa->get_unique_id(child_sa)); } policies->destroy(policies); break; @@ -1097,7 +1127,8 @@ METHOD(task_t, process_r, status_t, this->child_sa = child_sa_create( this->ike_sa->get_my_host(this->ike_sa), this->ike_sa->get_other_host(this->ike_sa), - this->config, this->reqid, this->udp); + this->config, this->reqid, this->udp, + this->mark_in, this->mark_out); tsi = linked_list_create_with_items(this->tsi, NULL); tsr = linked_list_create_with_items(this->tsr, NULL); @@ -1202,7 +1233,10 @@ METHOD(task_t, build_r, status_t, } if (this->dh) { - add_ke(this, message); + if (!add_ke(this, message)) + { + return FAILED; + } } add_ts(this, message); @@ -1307,6 +1341,13 @@ METHOD(quick_mode_t, use_reqid, void, this->reqid = reqid; } +METHOD(quick_mode_t, use_marks, void, + private_quick_mode_t *this, u_int in, u_int out) +{ + this->mark_in = in; + this->mark_out = out; +} + METHOD(quick_mode_t, rekey, void, private_quick_mode_t *this, u_int32_t spi) { @@ -1334,6 +1375,8 @@ METHOD(task_t, migrate, void, this->dh = NULL; this->spi_i = 0; this->spi_r = 0; + this->mark_in = 0; + this->mark_out = 0; if (!this->initiator) { @@ -1372,6 +1415,7 @@ quick_mode_t *quick_mode_create(ike_sa_t *ike_sa, child_cfg_t *config, .destroy = _destroy, }, .use_reqid = _use_reqid, + .use_marks = _use_marks, .rekey = _rekey, }, .ike_sa = ike_sa, diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.h b/src/libcharon/sa/ikev1/tasks/quick_mode.h index 0b80cb836..ee9b64d13 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_mode.h +++ b/src/libcharon/sa/ikev1/tasks/quick_mode.h @@ -45,6 +45,14 @@ struct quick_mode_t { void (*use_reqid)(quick_mode_t *this, u_int32_t reqid); /** + * Use specific mark values, overriding configuration. + * + * @param in inbound mark value + * @param out outbound mark value + */ + void (*use_marks)(quick_mode_t *this, u_int in, u_int out); + + /** * Set the SPI of the old SA, if rekeying. * * @param spi spi of SA to rekey diff --git a/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c b/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c index eed6d1996..ebef31930 100644 --- a/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c +++ b/src/libcharon/sa/ikev2/authenticators/eap_authenticator.c @@ -522,6 +522,13 @@ METHOD(authenticator_t, process_server, status_t, { return FAILED; } + if (this->method->get_auth) + { + auth_cfg_t *auth; + + auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE); + auth->merge(auth, this->method->get_auth(this->method), FALSE); + } return NEED_MORE; } diff --git a/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c b/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c index 6fb14bc06..151b49718 100644 --- a/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c +++ b/src/libcharon/sa/ikev2/authenticators/pubkey_authenticator.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Tobias Brunner + * Copyright (C) 2008-2015 Tobias Brunner * Copyright (C) 2005-2009 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -20,6 +20,9 @@ #include <daemon.h> #include <encoding/payloads/auth_payload.h> #include <sa/ikev2/keymat_v2.h> +#include <asn1/asn1.h> +#include <asn1/oid.h> +#include <collections/array.h> typedef struct private_pubkey_authenticator_t private_pubkey_authenticator_t; @@ -52,83 +55,303 @@ struct private_pubkey_authenticator_t { * Reserved bytes of ID payload */ char reserved[3]; + + /** + * Whether to store signature schemes on remote auth configs. + */ + bool store_signature_scheme; }; -METHOD(authenticator_t, build, status_t, - private_pubkey_authenticator_t *this, message_t *message) +/** + * Parse authentication data used for Signature Authentication as per RFC 7427 + */ +static bool parse_signature_auth_data(chunk_t *auth_data, key_type_t *key_type, + signature_scheme_t *scheme) { - chunk_t octets = chunk_empty, auth_data; - status_t status = FAILED; - private_key_t *private; - identification_t *id; - auth_cfg_t *auth; - auth_payload_t *auth_payload; - auth_method_t auth_method; + u_int8_t len; + int oid; + + if (!auth_data->len) + { + return FALSE; + } + len = auth_data->ptr[0]; + *auth_data = chunk_skip(*auth_data, 1); + /* we currently don't support schemes that require parameters */ + oid = asn1_parse_algorithmIdentifier(*auth_data, 1, NULL); + *scheme = signature_scheme_from_oid(oid); + if (*scheme == SIGN_UNKNOWN) + { + return FALSE; + } + *key_type = key_type_from_signature_scheme(*scheme); + *auth_data = chunk_skip(*auth_data, len); + return TRUE; +} + +/** + * Build authentication data used for Signature Authentication as per RFC 7427 + */ +static bool build_signature_auth_data(chunk_t *auth_data, + signature_scheme_t scheme) +{ + chunk_t data; + u_int8_t len; + int oid; + + oid = signature_scheme_to_oid(scheme); + if (oid == OID_UNKNOWN) + { + return FALSE; + } + data = asn1_algorithmIdentifier(oid); + len = data.len; + *auth_data = chunk_cat("cmm", chunk_from_thing(len), data, *auth_data); + return TRUE; +} + +/** + * Selects possible signature schemes based on our configuration, the other + * peer's capabilities and the private key + */ +static array_t *select_signature_schemes(keymat_v2_t *keymat, + auth_cfg_t *auth, private_key_t *private) +{ + enumerator_t *enumerator; signature_scheme_t scheme; + uintptr_t config; + auth_rule_t rule; + key_type_t key_type; + bool have_config = FALSE; + array_t *selected; + + selected = array_create(sizeof(signature_scheme_t), 0); + key_type = private->get_type(private); + enumerator = auth->create_enumerator(auth); + while (enumerator->enumerate(enumerator, &rule, &config)) + { + if (rule != AUTH_RULE_SIGNATURE_SCHEME) + { + continue; + } + have_config = TRUE; + if (key_type == key_type_from_signature_scheme(config) && + keymat->hash_algorithm_supported(keymat, + hasher_from_signature_scheme(config))) + { + scheme = config; + array_insert(selected, ARRAY_TAIL, &scheme); + } + } + enumerator->destroy(enumerator); + + if (!have_config) + { + /* if no specific configuration, find schemes appropriate for the key + * and supported by the other peer */ + enumerator = signature_schemes_for_key(key_type, + private->get_keysize(private)); + while (enumerator->enumerate(enumerator, &scheme)) + { + if (keymat->hash_algorithm_supported(keymat, + hasher_from_signature_scheme(scheme))) + { + array_insert(selected, ARRAY_TAIL, &scheme); + } + } + enumerator->destroy(enumerator); + + /* for RSA we tried at least SHA-512, also try other schemes down to + * what we'd use with classic authentication */ + if (key_type == KEY_RSA) + { + signature_scheme_t schemes[] = { + SIGN_RSA_EMSA_PKCS1_SHA384, + SIGN_RSA_EMSA_PKCS1_SHA256, + SIGN_RSA_EMSA_PKCS1_SHA1, + }, contained; + bool found; + int i, j; + + for (i = 0; i < countof(schemes); i++) + { + scheme = schemes[i]; + found = FALSE; + for (j = 0; j < array_count(selected); j++) + { + array_get(selected, j, &contained); + if (scheme == contained) + { + found = TRUE; + break; + } + } + if (!found && keymat->hash_algorithm_supported(keymat, + hasher_from_signature_scheme(scheme))) + { + array_insert(selected, ARRAY_TAIL, &scheme); + } + } + } + } + return selected; +} + +/** + * Create a signature using RFC 7427 signature authentication + */ +static status_t sign_signature_auth(private_pubkey_authenticator_t *this, + auth_cfg_t *auth, private_key_t *private, + identification_t *id, chunk_t *auth_data) +{ + enumerator_t *enumerator; keymat_v2_t *keymat; + signature_scheme_t scheme = SIGN_UNKNOWN, *schemep; + array_t *schemes; + chunk_t octets = chunk_empty; + status_t status = FAILED; - id = this->ike_sa->get_my_id(this->ike_sa); - auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE); - private = lib->credmgr->get_private(lib->credmgr, KEY_ANY, id, auth); - if (private == NULL) + keymat = (keymat_v2_t*)this->ike_sa->get_keymat(this->ike_sa); + schemes = select_signature_schemes(keymat, auth, private); + if (!array_count(schemes)) { - DBG1(DBG_IKE, "no private key found for '%Y'", id); - return NOT_FOUND; + DBG1(DBG_IKE, "no common hash algorithm found to create signature " + "with %N key", key_type_names, private->get_type(private)); + array_destroy(schemes); + return FAILED; } + if (keymat->get_auth_octets(keymat, FALSE, this->ike_sa_init, + this->nonce, id, this->reserved, &octets)) + { + enumerator = array_create_enumerator(schemes); + while (enumerator->enumerate(enumerator, &schemep)) + { + scheme = *schemep; + if (private->sign(private, scheme, octets, auth_data) && + build_signature_auth_data(auth_data, scheme)) + { + status = SUCCESS; + break; + } + else + { + DBG2(DBG_IKE, "unable to create %N signature for %N key", + signature_scheme_names, scheme, key_type_names, + private->get_type(private)); + } + } + enumerator->destroy(enumerator); + } + DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N %s", id, + signature_scheme_names, scheme, + status == SUCCESS ? "successful" : "failed"); + array_destroy(schemes); + chunk_free(&octets); + return status; +} + +/** + * Create a classic IKEv2 signature + */ +static status_t sign_classic(private_pubkey_authenticator_t *this, + auth_cfg_t *auth, private_key_t *private, + identification_t *id, auth_method_t *auth_method, + chunk_t *auth_data) +{ + signature_scheme_t scheme; + keymat_v2_t *keymat; + chunk_t octets = chunk_empty; + status_t status = FAILED; + switch (private->get_type(private)) { case KEY_RSA: - /* we currently use always SHA1 for signatures, - * TODO: support other hashes depending on configuration/auth */ scheme = SIGN_RSA_EMSA_PKCS1_SHA1; - auth_method = AUTH_RSA; + *auth_method = AUTH_RSA; break; case KEY_ECDSA: - /* we try to deduct the signature scheme from the keysize */ + /* deduct the signature scheme from the keysize */ switch (private->get_keysize(private)) { case 256: scheme = SIGN_ECDSA_256; - auth_method = AUTH_ECDSA_256; + *auth_method = AUTH_ECDSA_256; break; case 384: scheme = SIGN_ECDSA_384; - auth_method = AUTH_ECDSA_384; + *auth_method = AUTH_ECDSA_384; break; case 521: scheme = SIGN_ECDSA_521; - auth_method = AUTH_ECDSA_521; + *auth_method = AUTH_ECDSA_521; break; default: DBG1(DBG_IKE, "%d bit ECDSA private key size not supported", - private->get_keysize(private)); - return status; + private->get_keysize(private)); + return FAILED; } break; default: DBG1(DBG_IKE, "private key of type %N not supported", - key_type_names, private->get_type(private)); - return status; + key_type_names, private->get_type(private)); + return FAILED; } + keymat = (keymat_v2_t*)this->ike_sa->get_keymat(this->ike_sa); if (keymat->get_auth_octets(keymat, FALSE, this->ike_sa_init, this->nonce, id, this->reserved, &octets) && - private->sign(private, scheme, octets, &auth_data)) + private->sign(private, scheme, octets, auth_data)) { - auth_payload = auth_payload_create(); - auth_payload->set_auth_method(auth_payload, auth_method); - auth_payload->set_data(auth_payload, auth_data); - chunk_free(&auth_data); - message->add_payload(message, (payload_t*)auth_payload); status = SUCCESS; } DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N %s", id, - auth_method_names, auth_method, - (status == SUCCESS)? "successful":"failed"); + auth_method_names, *auth_method, + status == SUCCESS ? "successful" : "failed"); chunk_free(&octets); + return status; +} + +METHOD(authenticator_t, build, status_t, + private_pubkey_authenticator_t *this, message_t *message) +{ + private_key_t *private; + identification_t *id; + auth_cfg_t *auth; + chunk_t auth_data; + status_t status; + auth_payload_t *auth_payload; + auth_method_t auth_method; + + id = this->ike_sa->get_my_id(this->ike_sa); + auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE); + private = lib->credmgr->get_private(lib->credmgr, KEY_ANY, id, auth); + if (!private) + { + DBG1(DBG_IKE, "no private key found for '%Y'", id); + return NOT_FOUND; + } + + if (this->ike_sa->supports_extension(this->ike_sa, EXT_SIGNATURE_AUTH)) + { + auth_method = AUTH_DS; + status = sign_signature_auth(this, auth, private, id, &auth_data); + } + else + { + status = sign_classic(this, auth, private, id, &auth_method, + &auth_data); + } private->destroy(private); + if (status == SUCCESS) + { + auth_payload = auth_payload_create(); + auth_payload->set_auth_method(auth_payload, auth_method); + auth_payload->set_data(auth_payload, auth_data); + chunk_free(&auth_data); + message->add_payload(message, (payload_t*)auth_payload); + } return status; } @@ -153,11 +376,10 @@ METHOD(authenticator_t, process, status_t, return FAILED; } auth_method = auth_payload->get_auth_method(auth_payload); + auth_data = auth_payload->get_data(auth_payload); switch (auth_method) { case AUTH_RSA: - /* We currently accept SHA1 signatures only - * TODO: allow other hash algorithms and note it in "auth" */ key_type = KEY_RSA; scheme = SIGN_RSA_EMSA_PKCS1_SHA1; break; @@ -170,10 +392,15 @@ METHOD(authenticator_t, process, status_t, case AUTH_ECDSA_521: scheme = SIGN_ECDSA_521; break; + case AUTH_DS: + if (parse_signature_auth_data(&auth_data, &key_type, &scheme)) + { + break; + } + /* fall-through */ default: return INVALID_ARG; } - auth_data = auth_payload->get_data(auth_payload); id = this->ike_sa->get_other_id(this->ike_sa); keymat = (keymat_v2_t*)this->ike_sa->get_keymat(this->ike_sa); if (!keymat->get_auth_octets(keymat, TRUE, this->ike_sa_init, @@ -188,11 +415,16 @@ METHOD(authenticator_t, process, status_t, { if (public->verify(public, scheme, octets, auth_data)) { - DBG1(DBG_IKE, "authentication of '%Y' with %N successful", - id, auth_method_names, auth_method); + DBG1(DBG_IKE, "authentication of '%Y' with %N successful", id, + auth_method == AUTH_DS ? signature_scheme_names : auth_method_names, + auth_method == AUTH_DS ? scheme : auth_method); status = SUCCESS; auth->merge(auth, current_auth, FALSE); auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY); + if (this->store_signature_scheme) + { + auth->add(auth, AUTH_RULE_SIGNATURE_SCHEME, (uintptr_t)scheme); + } break; } else @@ -265,6 +497,8 @@ pubkey_authenticator_t *pubkey_authenticator_create_verifier(ike_sa_t *ike_sa, .ike_sa = ike_sa, .ike_sa_init = received_init, .nonce = sent_nonce, + .store_signature_scheme = lib->settings->get_bool(lib->settings, + "%s.signature_authentication_constraints", TRUE, lib->ns), ); memcpy(this->reserved, reserved, sizeof(this->reserved)); diff --git a/src/libcharon/sa/ikev2/keymat_v2.c b/src/libcharon/sa/ikev2/keymat_v2.c index 88ad14faf..f70f5cfed 100644 --- a/src/libcharon/sa/ikev2/keymat_v2.c +++ b/src/libcharon/sa/ikev2/keymat_v2.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2015 Tobias Brunner * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -17,6 +18,7 @@ #include <daemon.h> #include <crypto/prf_plus.h> +#include <crypto/hashers/hash_algorithm_set.h> typedef struct private_keymat_v2_t private_keymat_v2_t; @@ -69,6 +71,11 @@ struct private_keymat_v2_t { * Key to verify incoming authentication data (SKp) */ chunk_t skp_verify; + + /** + * Set of hash algorithms supported by peer for signature authentication + */ + hash_algorithm_set_t *hash_algorithms; }; METHOD(keymat_t, get_version, ike_version_t, @@ -293,7 +300,7 @@ METHOD(keymat_v2_t, derive_ike_keys, bool, spi_i = chunk_alloca(sizeof(u_int64_t)); spi_r = chunk_alloca(sizeof(u_int64_t)); - if (dh->get_shared_secret(dh, &secret) != SUCCESS) + if (!dh->get_shared_secret(dh, &secret)) { return FALSE; } @@ -547,7 +554,7 @@ METHOD(keymat_v2_t, derive_child_keys, bool, if (dh) { - if (dh->get_shared_secret(dh, &secret) != SUCCESS) + if (!dh->get_shared_secret(dh, &secret)) { return FALSE; } @@ -676,6 +683,26 @@ METHOD(keymat_v2_t, get_psk_sig, bool, return TRUE; } +METHOD(keymat_v2_t, hash_algorithm_supported, bool, + private_keymat_v2_t *this, hash_algorithm_t hash) +{ + if (!this->hash_algorithms) + { + return FALSE; + } + return this->hash_algorithms->contains(this->hash_algorithms, hash); +} + +METHOD(keymat_v2_t, add_hash_algorithm, void, + private_keymat_v2_t *this, hash_algorithm_t hash) +{ + if (!this->hash_algorithms) + { + this->hash_algorithms = hash_algorithm_set_create(); + } + this->hash_algorithms->add(this->hash_algorithms, hash); +} + METHOD(keymat_t, destroy, void, private_keymat_v2_t *this) { @@ -685,6 +712,7 @@ METHOD(keymat_t, destroy, void, chunk_clear(&this->skd); chunk_clear(&this->skp_verify); chunk_clear(&this->skp_build); + DESTROY_IF(this->hash_algorithms); free(this); } @@ -709,6 +737,9 @@ keymat_v2_t *keymat_v2_create(bool initiator) .get_skd = _get_skd, .get_auth_octets = _get_auth_octets, .get_psk_sig = _get_psk_sig, + .add_hash_algorithm = _add_hash_algorithm, + .hash_algorithm_supported = _hash_algorithm_supported, + }, .initiator = initiator, .prf_alg = PRF_UNDEFINED, diff --git a/src/libcharon/sa/ikev2/keymat_v2.h b/src/libcharon/sa/ikev2/keymat_v2.h index 04432f05b..927b62b03 100644 --- a/src/libcharon/sa/ikev2/keymat_v2.h +++ b/src/libcharon/sa/ikev2/keymat_v2.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Tobias Brunner + * Copyright (C) 2011-2015 Tobias Brunner * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -124,6 +124,22 @@ struct keymat_v2_t { bool (*get_psk_sig)(keymat_v2_t *this, bool verify, chunk_t ike_sa_init, chunk_t nonce, chunk_t secret, identification_t *id, char reserved[3], chunk_t *sig); + + /** + * Add a hash algorithm supported by the peer for signature authentication. + * + * @param hash hash algorithm + */ + void (*add_hash_algorithm)(keymat_v2_t *this, hash_algorithm_t hash); + + /** + * Check if a given hash algorithm is supported by the peer for signature + * authentication. + * + * @param hash hash algorithm + * @return TRUE if supported, FALSE otherwise + */ + bool (*hash_algorithm_supported)(keymat_v2_t *this, hash_algorithm_t hash); }; /** diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index eb7df3516..298167703 100644 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -29,6 +29,7 @@ #include <sa/ikev2/tasks/ike_cert_post.h> #include <sa/ikev2/tasks/ike_rekey.h> #include <sa/ikev2/tasks/ike_reauth.h> +#include <sa/ikev2/tasks/ike_reauth_complete.h> #include <sa/ikev2/tasks/ike_delete.h> #include <sa/ikev2/tasks/ike_config.h> #include <sa/ikev2/tasks/ike_dpd.h> @@ -171,6 +172,11 @@ struct private_task_manager_t { * Base to calculate retransmission timeout */ double retransmit_base; + + /** + * Use make-before-break instead of break-before-make reauth? + */ + bool make_before_break; }; /** @@ -510,6 +516,11 @@ METHOD(task_manager_t, initiate, status_t, break; } #endif /* ME */ + if (activate_task(this, TASK_IKE_REAUTH_COMPLETE)) + { + exchange = INFORMATIONAL; + break; + } case IKE_REKEYING: if (activate_task(this, TASK_IKE_DELETE)) { @@ -604,6 +615,11 @@ METHOD(task_manager_t, initiate, status_t, /* update exchange type if a task changed it */ this->initiating.type = message->get_exchange_type(message); + if (this->initiating.type == EXCHANGE_TYPE_UNDEFINED) + { + message->destroy(message); + return SUCCESS; + } if (!generate_message(this, message, &this->initiating.packets)) { @@ -1170,7 +1186,7 @@ static status_t parse_message(private_task_manager_t *this, message_t *msg) { unknown = (unknown_payload_t*)payload; type = payload->get_type(payload); - if (!payload_is_known(type) && + if (!payload_is_known(type, msg->get_major_version(msg)) && unknown->is_critical(unknown)) { DBG1(DBG_ENC, "payload type %N is not supported, " @@ -1288,17 +1304,16 @@ METHOD(task_manager_t, process_message, status_t, { if (mid == this->responding.mid) { - /* reject initial messages once established */ - if (msg->get_exchange_type(msg) == IKE_SA_INIT || - msg->get_exchange_type(msg) == IKE_AUTH) + /* reject initial messages if not received in specific states */ + if ((msg->get_exchange_type(msg) == IKE_SA_INIT && + this->ike_sa->get_state(this->ike_sa) != IKE_CREATED) || + (msg->get_exchange_type(msg) == IKE_AUTH && + this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING)) { - if (this->ike_sa->get_state(this->ike_sa) != IKE_CREATED && - this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING) - { - DBG1(DBG_IKE, "ignoring %N in established IKE_SA state", - exchange_type_names, msg->get_exchange_type(msg)); - return FAILED; - } + DBG1(DBG_IKE, "ignoring %N in IKE_SA state %N", + exchange_type_names, msg->get_exchange_type(msg), + ike_sa_state_names, this->ike_sa->get_state(this->ike_sa)); + return FAILED; } if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE)) { /* with MOBIKE, we do no implicit updates */ @@ -1339,10 +1354,6 @@ METHOD(task_manager_t, process_message, status_t, { DBG1(DBG_IKE, "received message ID %d, expected %d. Ignored", mid, this->responding.mid); - if (msg->get_exchange_type(msg) == IKE_SA_INIT) - { /* clean up IKE_SA state if IKE_SA_INIT has invalid msg ID */ - return DESTROY_ME; - } } } else @@ -1505,9 +1516,79 @@ METHOD(task_manager_t, queue_ike_rekey, void, queue_task(this, (task_t*)ike_rekey_create(this->ike_sa, TRUE)); } +/** + * Start reauthentication using make-before-break + */ +static void trigger_mbb_reauth(private_task_manager_t *this) +{ + enumerator_t *enumerator; + child_sa_t *child_sa; + child_cfg_t *cfg; + ike_sa_t *new; + host_t *host; + task_t *task; + + new = charon->ike_sa_manager->checkout_new(charon->ike_sa_manager, + this->ike_sa->get_version(this->ike_sa), TRUE); + if (!new) + { /* shouldn't happen */ + return; + } + + new->set_peer_cfg(new, this->ike_sa->get_peer_cfg(this->ike_sa)); + host = this->ike_sa->get_other_host(this->ike_sa); + new->set_other_host(new, host->clone(host)); + host = this->ike_sa->get_my_host(this->ike_sa); + new->set_my_host(new, host->clone(host)); + enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa, TRUE); + while (enumerator->enumerate(enumerator, &host)) + { + new->add_virtual_ip(new, TRUE, host); + } + enumerator->destroy(enumerator); + + enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa); + while (enumerator->enumerate(enumerator, &child_sa)) + { + cfg = child_sa->get_config(child_sa); + new->queue_task(new, &child_create_create(new, cfg->get_ref(cfg), + FALSE, NULL, NULL)->task); + } + enumerator->destroy(enumerator); + + enumerator = array_create_enumerator(this->queued_tasks); + while (enumerator->enumerate(enumerator, &task)) + { + if (task->get_type(task) == TASK_CHILD_CREATE) + { + task->migrate(task, new); + new->queue_task(new, task); + array_remove_at(this->queued_tasks, enumerator); + } + } + enumerator->destroy(enumerator); + + if (new->initiate(new, NULL, 0, NULL, NULL) != DESTROY_ME) + { + new->queue_task(new, (task_t*)ike_reauth_complete_create(new, + this->ike_sa->get_id(this->ike_sa))); + charon->ike_sa_manager->checkin(charon->ike_sa_manager, new); + } + else + { + charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, new); + DBG1(DBG_IKE, "reauthenticating IKE_SA failed"); + } + charon->bus->set_sa(charon->bus, this->ike_sa); +} + METHOD(task_manager_t, queue_ike_reauth, void, private_task_manager_t *this) { + if (this->make_before_break) + { + return trigger_mbb_reauth(this); + } queue_task(this, (task_t*)ike_reauth_create(this->ike_sa)); } @@ -1773,6 +1854,8 @@ task_manager_v2_t *task_manager_v2_create(ike_sa_t *ike_sa) "%s.retransmit_timeout", RETRANSMIT_TIMEOUT, lib->ns), .retransmit_base = lib->settings->get_double(lib->settings, "%s.retransmit_base", RETRANSMIT_BASE, lib->ns), + .make_before_break = lib->settings->get_bool(lib->settings, + "%s.make_before_break", FALSE, lib->ns), ); return &this->public; diff --git a/src/libcharon/sa/ikev2/tasks/child_create.c b/src/libcharon/sa/ikev2/tasks/child_create.c index a1f01c276..6d9132a68 100644 --- a/src/libcharon/sa/ikev2/tasks/child_create.c +++ b/src/libcharon/sa/ikev2/tasks/child_create.c @@ -105,6 +105,11 @@ struct private_child_create_t { diffie_hellman_t *dh; /** + * Applying DH public value failed? + */ + bool dh_failed; + + /** * group used for DH exchange */ diffie_hellman_group_t dh_group; @@ -160,6 +165,16 @@ struct private_child_create_t { u_int32_t reqid; /** + * Explicit inbound mark value + */ + u_int mark_in; + + /** + * Explicit outbound mark value + */ + u_int mark_out; + + /** * CHILD_SA which gets established */ child_sa_t *child_sa; @@ -286,7 +301,7 @@ static bool allocate_spi(private_child_create_t *this) */ static void schedule_inactivity_timeout(private_child_create_t *this) { - u_int32_t timeout; + u_int32_t timeout, id; bool close_ike; timeout = this->config->get_inactivity(this->config); @@ -294,9 +309,9 @@ static void schedule_inactivity_timeout(private_child_create_t *this) { close_ike = lib->settings->get_bool(lib->settings, "%s.inactivity_close_ike", FALSE, lib->ns); + id = this->child_sa->get_unique_id(this->child_sa); lib->scheduler->schedule_job(lib->scheduler, (job_t*) - inactivity_job_create(this->child_sa->get_reqid(this->child_sa), - timeout, close_ike), timeout); + inactivity_job_create(id, timeout, close_ike), timeout); } } @@ -683,10 +698,7 @@ static status_t select_and_install(private_child_create_t *this, this->ike_sa->add_child_sa(this->ike_sa, this->child_sa); this->established = TRUE; - if (!this->rekey) - { /* a rekeyed SA uses the same reqid, no need for a new job */ - schedule_inactivity_timeout(this); - } + schedule_inactivity_timeout(this); my_ts = linked_list_create_from_enumerator( this->child_sa->create_ts_enumerator(this->child_sa, TRUE)); @@ -696,7 +708,7 @@ static status_t select_and_install(private_child_create_t *this, DBG0(DBG_IKE, "CHILD_SA %s{%d} established " "with SPIs %.8x_i %.8x_o and TS %#R=== %#R", this->child_sa->get_name(this->child_sa), - this->child_sa->get_reqid(this->child_sa), + this->child_sa->get_unique_id(this->child_sa), ntohl(this->child_sa->get_spi(this->child_sa, TRUE)), ntohl(this->child_sa->get_spi(this->child_sa, FALSE)), my_ts, other_ts); @@ -709,7 +721,7 @@ static status_t select_and_install(private_child_create_t *this, /** * build the payloads for the message */ -static void build_payloads(private_child_create_t *this, message_t *message) +static bool build_payloads(private_child_create_t *this, message_t *message) { sa_payload_t *sa_payload; nonce_payload_t *nonce_payload; @@ -741,6 +753,11 @@ static void build_payloads(private_child_create_t *this, message_t *message) { ke_payload = ke_payload_create_from_diffie_hellman(PLV2_KEY_EXCHANGE, this->dh); + if (!ke_payload) + { + DBG1(DBG_IKE, "creating KE payload failed"); + return FALSE; + } message->add_payload(message, (payload_t*)ke_payload); } @@ -769,6 +786,7 @@ static void build_payloads(private_child_create_t *this, message_t *message) message->add_notify(message, FALSE, ESP_TFC_PADDING_NOT_SUPPORTED, chunk_empty); } + return TRUE; } /** @@ -880,7 +898,7 @@ static void process_payloads(private_child_create_t *this, message_t *message) } if (this->dh) { - this->dh->set_other_public_value(this->dh, + this->dh_failed = !this->dh->set_other_public_value(this->dh, ke_payload->get_key_exchange_data(ke_payload)); } break; @@ -996,7 +1014,8 @@ METHOD(task_t, build_i, status_t, this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa), this->ike_sa->get_other_host(this->ike_sa), this->config, this->reqid, - this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY)); + this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY), + this->mark_in, this->mark_out); if (!allocate_spi(this)) { @@ -1027,7 +1046,10 @@ METHOD(task_t, build_i, status_t, NARROW_INITIATOR_PRE_AUTH, this->tsi, this->tsr); } - build_payloads(this, message); + if (!build_payloads(this, message)) + { + return FAILED; + } this->tsi->destroy_offset(this->tsi, offsetof(traffic_selector_t, destroy)); this->tsr->destroy_offset(this->tsr, offsetof(traffic_selector_t, destroy)); @@ -1168,12 +1190,19 @@ METHOD(task_t, build_r, status_t, case IKE_SA_INIT: return get_nonce(message, &this->my_nonce); case CREATE_CHILD_SA: - if (generate_nonce(this) != SUCCESS) + if (generate_nonce(this) != SUCCESS ) { message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN, chunk_empty); return SUCCESS; } + if (this->dh_failed) + { + DBG1(DBG_IKE, "applying DH public value failed"); + message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN, + chunk_empty); + return SUCCESS; + } no_dh = FALSE; break; case IKE_AUTH: @@ -1241,7 +1270,8 @@ METHOD(task_t, build_r, status_t, this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa), this->ike_sa->get_other_host(this->ike_sa), this->config, this->reqid, - this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY)); + this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY), + this->mark_in, this->mark_out); if (this->ipcomp_received != IPCOMP_NONE) { @@ -1279,7 +1309,12 @@ METHOD(task_t, build_r, status_t, return SUCCESS; } - build_payloads(this, message); + if (!build_payloads(this, message)) + { + message->add_notify(message, FALSE, NO_PROPOSAL_CHOSEN, chunk_empty); + handle_child_sa_failure(this, message); + return SUCCESS; + } if (!this->rekey) { /* invoke the child_up() hook if we are not rekeying */ @@ -1408,6 +1443,7 @@ METHOD(task_t, process_i, status_t, this->dh_group, diffie_hellman_group_names, group); this->retry = TRUE; this->dh_group = group; + this->child_sa->set_state(this->child_sa, CHILD_RETRYING); this->public.task.migrate(&this->public.task, this->ike_sa); enumerator->destroy(enumerator); return NEED_MORE; @@ -1456,6 +1492,13 @@ METHOD(task_t, process_i, status_t, return delete_failed_sa(this); } + if (this->dh_failed) + { + DBG1(DBG_IKE, "applying DH public value failed"); + handle_child_sa_failure(this, message); + return delete_failed_sa(this); + } + if (select_and_install(this, no_dh, ike_auth) == SUCCESS) { if (!this->rekey) @@ -1477,6 +1520,13 @@ METHOD(child_create_t, use_reqid, void, this->reqid = reqid; } +METHOD(child_create_t, use_marks, void, + private_child_create_t *this, u_int in, u_int out) +{ + this->mark_in = in; + this->mark_out = out; +} + METHOD(child_create_t, get_child, child_sa_t*, private_child_create_t *this) { @@ -1526,6 +1576,7 @@ METHOD(task_t, migrate, void, DESTROY_IF(this->child_sa); DESTROY_IF(this->proposal); DESTROY_IF(this->dh); + this->dh_failed = FALSE; if (this->proposals) { this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy)); @@ -1544,6 +1595,8 @@ METHOD(task_t, migrate, void, this->ipcomp_received = IPCOMP_NONE; this->other_cpi = 0; this->reqid = 0; + this->mark_in = 0; + this->mark_out = 0; this->established = FALSE; } @@ -1592,6 +1645,7 @@ child_create_t *child_create_create(ike_sa_t *ike_sa, .set_config = _set_config, .get_lower_nonce = _get_lower_nonce, .use_reqid = _use_reqid, + .use_marks = _use_marks, .task = { .get_type = _get_type, .migrate = _migrate, diff --git a/src/libcharon/sa/ikev2/tasks/child_create.h b/src/libcharon/sa/ikev2/tasks/child_create.h index d29ba3d98..46d9403ee 100644 --- a/src/libcharon/sa/ikev2/tasks/child_create.h +++ b/src/libcharon/sa/ikev2/tasks/child_create.h @@ -52,6 +52,14 @@ struct child_create_t { void (*use_reqid) (child_create_t *this, u_int32_t reqid); /** + * Use specific mark values to override configuration. + * + * @param in inbound mark value + * @param out outbound mark value + */ + void (*use_marks)(child_create_t *this, u_int in, u_int out); + + /** * Get the lower of the two nonces, used for rekey collisions. * * @return lower nonce diff --git a/src/libcharon/sa/ikev2/tasks/child_delete.c b/src/libcharon/sa/ikev2/tasks/child_delete.c index 2b1697423..f0b11e291 100644 --- a/src/libcharon/sa/ikev2/tasks/child_delete.c +++ b/src/libcharon/sa/ikev2/tasks/child_delete.c @@ -267,7 +267,7 @@ static void log_children(private_child_delete_t *this) { DBG0(DBG_IKE, "closing expired CHILD_SA %s{%d} " "with SPIs %.8x_i %.8x_o and TS %#R=== %#R", - child_sa->get_name(child_sa), child_sa->get_reqid(child_sa), + child_sa->get_name(child_sa), child_sa->get_unique_id(child_sa), ntohl(child_sa->get_spi(child_sa, TRUE)), ntohl(child_sa->get_spi(child_sa, FALSE)), my_ts, other_ts); } @@ -278,7 +278,7 @@ static void log_children(private_child_delete_t *this) DBG0(DBG_IKE, "closing CHILD_SA %s{%d} with SPIs %.8x_i " "(%llu bytes) %.8x_o (%llu bytes) and TS %#R=== %#R", - child_sa->get_name(child_sa), child_sa->get_reqid(child_sa), + child_sa->get_name(child_sa), child_sa->get_unique_id(child_sa), ntohl(child_sa->get_spi(child_sa, TRUE)), bytes_in, ntohl(child_sa->get_spi(child_sa, FALSE)), bytes_out, my_ts, other_ts); diff --git a/src/libcharon/sa/ikev2/tasks/child_rekey.c b/src/libcharon/sa/ikev2/tasks/child_rekey.c index db872827d..c806e19ca 100644 --- a/src/libcharon/sa/ikev2/tasks/child_rekey.c +++ b/src/libcharon/sa/ikev2/tasks/child_rekey.c @@ -96,9 +96,9 @@ static void schedule_delayed_rekey(private_child_rekey_t *this) retry = RETRY_INTERVAL - (random() % RETRY_JITTER); job = (job_t*)rekey_child_sa_job_create( - this->child_sa->get_reqid(this->child_sa), this->child_sa->get_protocol(this->child_sa), - this->child_sa->get_spi(this->child_sa, TRUE)); + this->child_sa->get_spi(this->child_sa, TRUE), + this->ike_sa->get_my_host(this->ike_sa)); DBG1(DBG_IKE, "CHILD_SA rekeying failed, trying again in %d seconds", retry); this->child_sa->set_state(this->child_sa, CHILD_INSTALLED); lib->scheduler->schedule_job(lib->scheduler, job, retry); @@ -184,6 +184,9 @@ METHOD(task_t, build_i, status_t, } reqid = this->child_sa->get_reqid(this->child_sa); this->child_create->use_reqid(this->child_create, reqid); + this->child_create->use_marks(this->child_create, + this->child_sa->get_mark(this->child_sa, TRUE).value, + this->child_sa->get_mark(this->child_sa, FALSE).value); if (this->child_create->task.build(&this->child_create->task, message) != NEED_MORE) @@ -224,6 +227,9 @@ METHOD(task_t, build_r, status_t, /* let the CHILD_CREATE task build the response */ reqid = this->child_sa->get_reqid(this->child_sa); this->child_create->use_reqid(this->child_create, reqid); + this->child_create->use_marks(this->child_create, + this->child_sa->get_mark(this->child_sa, TRUE).value, + this->child_sa->get_mark(this->child_sa, FALSE).value); config = this->child_sa->get_config(this->child_sa); this->child_create->set_config(this->child_create, config->get_ref(config)); this->child_create->task.build(&this->child_create->task, message); diff --git a/src/libcharon/sa/ikev2/tasks/ike_cert_pre.c b/src/libcharon/sa/ikev2/tasks/ike_cert_pre.c index 0dac975e7..ca17494de 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_cert_pre.c +++ b/src/libcharon/sa/ikev2/tasks/ike_cert_pre.c @@ -229,12 +229,12 @@ static void process_x509(cert_payload_t *payload, auth_cfg_t *auth, return; } url = strdup(url); - if (first) + if (*first) { /* first URL is for an end entity certificate */ DBG1(DBG_IKE, "received hash-and-url for end entity cert \"%s\"", url); auth->add(auth, AUTH_HELPER_SUBJECT_HASH_URL, url); - first = FALSE; + *first = FALSE; } else { diff --git a/src/libcharon/sa/ikev2/tasks/ike_config.c b/src/libcharon/sa/ikev2/tasks/ike_config.c index da06e2a36..646f20c61 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_config.c +++ b/src/libcharon/sa/ikev2/tasks/ike_config.c @@ -17,7 +17,6 @@ #include "ike_config.h" #include <daemon.h> -#include <hydra.h> #include <encoding/payloads/cp_payload.h> typedef struct private_ike_config_t private_ike_config_t; @@ -127,9 +126,8 @@ static void handle_attribute(private_ike_config_t *this, enumerator->destroy(enumerator); /* and pass it to the handle function */ - handler = hydra->attributes->handle(hydra->attributes, - this->ike_sa->get_other_id(this->ike_sa), handler, - ca->get_type(ca), ca->get_chunk(ca)); + handler = charon->attributes->handle(charon->attributes, + this->ike_sa, handler, ca->get_type(ca), ca->get_chunk(ca)); this->ike_sa->add_configuration_attribute(this->ike_sa, handler, ca->get_type(ca), ca->get_chunk(ca)); } @@ -274,9 +272,8 @@ METHOD(task_t, build_i, status_t, enumerator->destroy(enumerator); } - enumerator = hydra->attributes->create_initiator_enumerator( - hydra->attributes, - this->ike_sa->get_other_id(this->ike_sa), vips); + enumerator = charon->attributes->create_initiator_enumerator( + charon->attributes, this->ike_sa, vips); while (enumerator->enumerate(enumerator, &handler, &type, &data)) { configuration_attribute_t *ca; @@ -352,8 +349,8 @@ METHOD(task_t, build_r, status_t, /* query all pools until we get an address */ DBG1(DBG_IKE, "peer requested virtual IP %H", requested); - found = hydra->attributes->acquire_address(hydra->attributes, - pools, id, requested); + found = charon->attributes->acquire_address(charon->attributes, + pools, this->ike_sa, requested); if (found) { DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", found, id); @@ -398,8 +395,8 @@ METHOD(task_t, build_r, status_t, } /* query registered providers for additional attributes to include */ - enumerator = hydra->attributes->create_responder_enumerator( - hydra->attributes, pools, id, vips); + enumerator = charon->attributes->create_responder_enumerator( + charon->attributes, pools, this->ike_sa, vips); while (enumerator->enumerate(enumerator, &type, &value)) { if (!cp) diff --git a/src/libcharon/sa/ikev2/tasks/ike_init.c b/src/libcharon/sa/ikev2/tasks/ike_init.c index 71c5f22fa..0d5700ef2 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_init.c +++ b/src/libcharon/sa/ikev2/tasks/ike_init.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2009 Tobias Brunner + * Copyright (C) 2008-2015 Tobias Brunner * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -20,8 +20,11 @@ #include <string.h> #include <daemon.h> +#include <bio/bio_reader.h> +#include <bio/bio_writer.h> #include <sa/ikev2/keymat_v2.h> #include <crypto/diffie_hellman.h> +#include <crypto/hashers/hash_algorithm_set.h> #include <encoding/payloads/sa_payload.h> #include <encoding/payloads/ke_payload.h> #include <encoding/payloads/nonce_payload.h> @@ -67,6 +70,11 @@ struct private_ike_init_t { diffie_hellman_t *dh; /** + * Applying DH public value failed? + */ + bool dh_failed; + + /** * Keymat derivation (from IKE_SA) */ keymat_v2_t *keymat; @@ -100,12 +108,114 @@ struct private_ike_init_t { * retries done so far after failure (cookie or bad dh group) */ u_int retry; + + /** + * Whether to use Signature Authentication as per RFC 7427 + */ + bool signature_authentication; }; /** + * Notify the peer about the hash algorithms we support or expect, + * as per RFC 7427 + */ +static void send_supported_hash_algorithms(private_ike_init_t *this, + message_t *message) +{ + hash_algorithm_set_t *algos; + enumerator_t *enumerator, *rounds; + bio_writer_t *writer; + hash_algorithm_t hash; + peer_cfg_t *peer; + auth_cfg_t *auth; + auth_rule_t rule; + uintptr_t config; + char *plugin_name; + + algos = hash_algorithm_set_create(); + peer = this->ike_sa->get_peer_cfg(this->ike_sa); + if (peer) + { + rounds = peer->create_auth_cfg_enumerator(peer, FALSE); + while (rounds->enumerate(rounds, &auth)) + { + enumerator = auth->create_enumerator(auth); + while (enumerator->enumerate(enumerator, &rule, &config)) + { + if (rule == AUTH_RULE_SIGNATURE_SCHEME) + { + hash = hasher_from_signature_scheme(config); + if (hasher_algorithm_for_ikev2(hash)) + { + algos->add(algos, hash); + } + } + } + enumerator->destroy(enumerator); + } + rounds->destroy(rounds); + } + + if (!algos->count(algos)) + { + enumerator = lib->crypto->create_hasher_enumerator(lib->crypto); + while (enumerator->enumerate(enumerator, &hash, &plugin_name)) + { + if (hasher_algorithm_for_ikev2(hash)) + { + algos->add(algos, hash); + } + } + enumerator->destroy(enumerator); + } + + if (algos->count(algos)) + { + writer = bio_writer_create(0); + enumerator = algos->create_enumerator(algos); + while (enumerator->enumerate(enumerator, &hash)) + { + writer->write_uint16(writer, hash); + } + enumerator->destroy(enumerator); + message->add_notify(message, FALSE, SIGNATURE_HASH_ALGORITHMS, + writer->get_buf(writer)); + writer->destroy(writer); + } + algos->destroy(algos); +} + +/** + * Store algorithms supported by other peer + */ +static void handle_supported_hash_algorithms(private_ike_init_t *this, + notify_payload_t *notify) +{ + bio_reader_t *reader; + u_int16_t algo; + bool added = FALSE; + + reader = bio_reader_create(notify->get_notification_data(notify)); + while (reader->remaining(reader) >= 2 && reader->read_uint16(reader, &algo)) + { + if (hasher_algorithm_for_ikev2(algo)) + { + this->keymat->add_hash_algorithm(this->keymat, algo); + added = TRUE; + } + } + reader->destroy(reader); + + if (added) + { + this->ike_sa->enable_extension(this->ike_sa, EXT_SIGNATURE_AUTH); + } +} + +/** * build the payloads for the message */ -static void build_payloads(private_ike_init_t *this, message_t *message) +static bool build_payloads(private_ike_init_t *this, message_t *message) { sa_payload_t *sa_payload; ke_payload_t *ke_payload; @@ -149,7 +259,13 @@ static void build_payloads(private_ike_init_t *this, message_t *message) nonce_payload = nonce_payload_create(PLV2_NONCE); nonce_payload->set_nonce(nonce_payload, this->my_nonce); - ke_payload = ke_payload_create_from_diffie_hellman(PLV2_KEY_EXCHANGE, this->dh); + ke_payload = ke_payload_create_from_diffie_hellman(PLV2_KEY_EXCHANGE, + this->dh); + if (!ke_payload) + { + DBG1(DBG_IKE, "creating KE payload failed"); + return FALSE; + } if (this->old_sa) { /* payload order differs if we are rekeying */ @@ -174,6 +290,17 @@ static void build_payloads(private_ike_init_t *this, message_t *message) chunk_empty); } } + /* submit supported hash algorithms for signature authentication */ + if (!this->old_sa && this->signature_authentication) + { + if (this->initiator || + this->ike_sa->supports_extension(this->ike_sa, + EXT_SIGNATURE_AUTH)) + { + send_supported_hash_algorithms(this, message); + } + } + return TRUE; } /** @@ -183,6 +310,7 @@ static void process_payloads(private_ike_init_t *this, message_t *message) { enumerator_t *enumerator; payload_t *payload; + ke_payload_t *ke_payload = NULL; enumerator = message->create_payload_enumerator(message); while (enumerator->enumerate(enumerator, &payload)) @@ -211,19 +339,9 @@ static void process_payloads(private_ike_init_t *this, message_t *message) } case PLV2_KEY_EXCHANGE: { - ke_payload_t *ke_payload = (ke_payload_t*)payload; + ke_payload = (ke_payload_t*)payload; this->dh_group = ke_payload->get_dh_group_number(ke_payload); - if (!this->initiator) - { - this->dh = this->keymat->keymat.create_dh( - &this->keymat->keymat, this->dh_group); - } - if (this->dh) - { - this->dh->set_other_public_value(this->dh, - ke_payload->get_key_exchange_data(ke_payload)); - } break; } case PLV2_NONCE: @@ -237,17 +355,44 @@ static void process_payloads(private_ike_init_t *this, message_t *message) { notify_payload_t *notify = (notify_payload_t*)payload; - if (notify->get_notify_type(notify) == FRAGMENTATION_SUPPORTED) + switch (notify->get_notify_type(notify)) { - this->ike_sa->enable_extension(this->ike_sa, - EXT_IKE_FRAGMENTATION); + case FRAGMENTATION_SUPPORTED: + this->ike_sa->enable_extension(this->ike_sa, + EXT_IKE_FRAGMENTATION); + break; + case SIGNATURE_HASH_ALGORITHMS: + if (this->signature_authentication) + { + handle_supported_hash_algorithms(this, notify); + } + break; + default: + /* other notifies are handled elsewhere */ + break; } + } default: break; } } enumerator->destroy(enumerator); + + if (ke_payload && this->proposal && + this->proposal->has_dh_group(this->proposal, this->dh_group)) + { + if (!this->initiator) + { + this->dh = this->keymat->keymat.create_dh( + &this->keymat->keymat, this->dh_group); + } + if (this->dh) + { + this->dh_failed = !this->dh->set_other_public_value(this->dh, + ke_payload->get_key_exchange_data(ke_payload)); + } + } } METHOD(task_t, build_i, status_t, @@ -305,7 +450,10 @@ METHOD(task_t, build_i, status_t, message->add_notify(message, FALSE, COOKIE, this->cookie); } - build_payloads(this, message); + if (!build_payloads(this, message)) + { + return FAILED; + } #ifdef ME { @@ -433,13 +581,24 @@ METHOD(task_t, build_r, status_t, return FAILED; } + if (this->dh_failed) + { + DBG1(DBG_IKE, "applying DH public value failed"); + message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty); + return FAILED; + } + if (!derive_keys(this, this->other_nonce, this->my_nonce)) { DBG1(DBG_IKE, "key derivation failed"); message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty); return FAILED; } - build_payloads(this, message); + if (!build_payloads(this, message)) + { + message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty); + return FAILED; + } return SUCCESS; } @@ -554,6 +713,12 @@ METHOD(task_t, process_i, status_t, return FAILED; } + if (this->dh_failed) + { + DBG1(DBG_IKE, "applying DH public value failed"); + return FAILED; + } + if (!derive_keys(this, this->my_nonce, this->other_nonce)) { DBG1(DBG_IKE, "key derivation failed"); @@ -577,6 +742,7 @@ METHOD(task_t, migrate, void, this->ike_sa = ike_sa; this->keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa); this->proposal = NULL; + this->dh_failed = FALSE; if (this->dh && this->dh->get_dh_group(this->dh) != this->dh_group) { /* reset DH value only if group changed (INVALID_KE_PAYLOAD) */ this->dh->destroy(this->dh); @@ -631,6 +797,8 @@ ike_init_t *ike_init_create(ike_sa_t *ike_sa, bool initiator, ike_sa_t *old_sa) .dh_group = MODP_NONE, .keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa), .old_sa = old_sa, + .signature_authentication = lib->settings->get_bool(lib->settings, + "%s.signature_authentication", TRUE, lib->ns), ); if (initiator) diff --git a/src/libcharon/sa/ikev2/tasks/ike_mobike.c b/src/libcharon/sa/ikev2/tasks/ike_mobike.c index d91fa5862..6295d7960 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_mobike.c +++ b/src/libcharon/sa/ikev2/tasks/ike_mobike.c @@ -256,6 +256,7 @@ static void update_children(private_ike_mobike_t *this) enumerator_t *enumerator; child_sa_t *child_sa; linked_list_t *vips; + status_t status; host_t *host; vips = linked_list_create(); @@ -270,15 +271,25 @@ static void update_children(private_ike_mobike_t *this) enumerator = this->ike_sa->create_child_sa_enumerator(this->ike_sa); while (enumerator->enumerate(enumerator, (void**)&child_sa)) { - if (child_sa->update(child_sa, - this->ike_sa->get_my_host(this->ike_sa), - this->ike_sa->get_other_host(this->ike_sa), vips, - this->ike_sa->has_condition(this->ike_sa, - COND_NAT_ANY)) == NOT_SUPPORTED) + status = child_sa->update(child_sa, + this->ike_sa->get_my_host(this->ike_sa), + this->ike_sa->get_other_host(this->ike_sa), vips, + this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY)); + switch (status) { - this->ike_sa->rekey_child_sa(this->ike_sa, - child_sa->get_protocol(child_sa), - child_sa->get_spi(child_sa, TRUE)); + case NOT_SUPPORTED: + this->ike_sa->rekey_child_sa(this->ike_sa, + child_sa->get_protocol(child_sa), + child_sa->get_spi(child_sa, TRUE)); + break; + case SUCCESS: + charon->child_sa_manager->remove(charon->child_sa_manager, + child_sa); + charon->child_sa_manager->add(charon->child_sa_manager, + child_sa, this->ike_sa); + break; + default: + break; } } enumerator->destroy(enumerator); diff --git a/src/libcharon/sa/ikev2/tasks/ike_reauth.h b/src/libcharon/sa/ikev2/tasks/ike_reauth.h index 781b463a7..e2e48f0d4 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_reauth.h +++ b/src/libcharon/sa/ikev2/tasks/ike_reauth.h @@ -29,6 +29,8 @@ typedef struct ike_reauth_t ike_reauth_t; /** * Task of type ike_reauth, reestablishes an IKE_SA. + * + * This task implements break-before-make reauthentication. */ struct ike_reauth_t { diff --git a/src/libcharon/sa/ikev2/tasks/ike_reauth_complete.c b/src/libcharon/sa/ikev2/tasks/ike_reauth_complete.c new file mode 100644 index 000000000..a01489c03 --- /dev/null +++ b/src/libcharon/sa/ikev2/tasks/ike_reauth_complete.c @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "ike_reauth_complete.h" + +#include <daemon.h> +#include <processing/jobs/delete_ike_sa_job.h> + + +typedef struct private_ike_reauth_complete_t private_ike_reauth_complete_t; + +/** + * Private members of a ike_reauth_complete_t task. + */ +struct private_ike_reauth_complete_t { + + /** + * Public methods and task_t interface. + */ + ike_reauth_complete_t public; + + /** + * Assigned IKE_SA. + */ + ike_sa_t *ike_sa; + + /** + * Reauthenticated IKE_SA identifier + */ + ike_sa_id_t *id; +}; + +METHOD(task_t, build_i, status_t, + private_ike_reauth_complete_t *this, message_t *message) +{ + message->set_exchange_type(message, EXCHANGE_TYPE_UNDEFINED); + lib->processor->queue_job(lib->processor, + (job_t*)delete_ike_sa_job_create(this->id, TRUE)); + return SUCCESS; +} + +METHOD(task_t, process_i, status_t, + private_ike_reauth_complete_t *this, message_t *message) +{ + return DESTROY_ME; +} + +METHOD(task_t, get_type, task_type_t, + private_ike_reauth_complete_t *this) +{ + return TASK_IKE_REAUTH_COMPLETE; +} + +METHOD(task_t, migrate, void, + private_ike_reauth_complete_t *this, ike_sa_t *ike_sa) +{ + this->ike_sa = ike_sa; +} + +METHOD(task_t, destroy, void, + private_ike_reauth_complete_t *this) +{ + this->id->destroy(this->id); + free(this); +} + +/* + * Described in header. + */ +ike_reauth_complete_t *ike_reauth_complete_create(ike_sa_t *ike_sa, + ike_sa_id_t *id) +{ + private_ike_reauth_complete_t *this; + + INIT(this, + .public = { + .task = { + .get_type = _get_type, + .migrate = _migrate, + .build = _build_i, + .process = _process_i, + .destroy = _destroy, + }, + }, + .ike_sa = ike_sa, + .id = id->clone(id), + ); + + return &this->public; +} diff --git a/src/libcharon/sa/ikev2/tasks/ike_reauth_complete.h b/src/libcharon/sa/ikev2/tasks/ike_reauth_complete.h new file mode 100644 index 000000000..cc3d3b713 --- /dev/null +++ b/src/libcharon/sa/ikev2/tasks/ike_reauth_complete.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup ike_reauth_complete ike_reauth_complete + * @{ @ingroup tasks_v2 + */ + +#ifndef IKE_REAUTH_COMPLETE_H_ +#define IKE_REAUTH_COMPLETE_H_ + +typedef struct ike_reauth_complete_t ike_reauth_complete_t; + +#include <library.h> +#include <sa/ike_sa.h> +#include <sa/task.h> + +/** + * Task of type IKE_REAUTH_COMPLETE, removes reauthenticated SA after reauth. + * + * This task completes make-before-break reauthentication by deleting the + * old, reauthenticated IKE_SA after the new one established. + */ +struct ike_reauth_complete_t { + + /** + * Implements the task_t interface + */ + task_t task; +}; + +/** + * Create a new ike_reauth_complete task. + * + * This task is initiator only. + * + * @param ike_sa IKE_SA this task works for + * @param id old, reauthenticated IKE_SA + * @return ike_reauth_complete task to handle by the task_manager + */ +ike_reauth_complete_t *ike_reauth_complete_create(ike_sa_t *ike_sa, + ike_sa_id_t *id); + +#endif /** IKE_REAUTH_COMPLETE_H_ @}*/ diff --git a/src/libcharon/sa/ikev2/tasks/ike_rekey.c b/src/libcharon/sa/ikev2/tasks/ike_rekey.c index 444ac6ade..1855517ce 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_rekey.c +++ b/src/libcharon/sa/ikev2/tasks/ike_rekey.c @@ -22,6 +22,7 @@ #include <sa/ikev2/tasks/ike_delete.h> #include <processing/jobs/delete_ike_sa_job.h> #include <processing/jobs/rekey_ike_sa_job.h> +#include <processing/jobs/initiate_tasks_job.h> typedef struct private_ike_rekey_t private_ike_rekey_t; @@ -68,12 +69,33 @@ struct private_ike_rekey_t { }; /** + * Check if an IKE_SA has any queued tasks, return initiation job + */ +static job_t* check_queued_tasks(ike_sa_t *ike_sa) +{ + enumerator_t *enumerator; + task_t *task; + job_t *job = NULL; + + enumerator = ike_sa->create_task_enumerator(ike_sa, TASK_QUEUE_QUEUED); + if (enumerator->enumerate(enumerator, &task)) + { + job = (job_t*)initiate_tasks_job_create(ike_sa->get_id(ike_sa)); + } + enumerator->destroy(enumerator); + + return job; +} + +/** * Establish the new replacement IKE_SA */ static void establish_new(private_ike_rekey_t *this) { if (this->new_sa) { + job_t *job; + this->new_sa->set_state(this->new_sa, IKE_ESTABLISHED); DBG0(DBG_IKE, "IKE_SA %s[%d] rekeyed between %H[%Y]...%H[%Y]", this->new_sa->get_name(this->new_sa), @@ -85,7 +107,14 @@ static void establish_new(private_ike_rekey_t *this) this->new_sa->inherit_post(this->new_sa, this->ike_sa); charon->bus->ike_rekey(charon->bus, this->ike_sa, this->new_sa); + job = check_queued_tasks(this->new_sa); + /* don't queue job before checkin(), as the IKE_SA is not yet + * registered at the manager */ charon->ike_sa_manager->checkin(charon->ike_sa_manager, this->new_sa); + if (job) + { + lib->processor->queue_job(lib->processor, job); + } this->new_sa = NULL; /* set threads active IKE_SA after checkin */ charon->bus->set_sa(charon->bus, this->ike_sa); @@ -163,6 +192,7 @@ METHOD(task_t, process_r, status_t, { case CHILD_CREATED: case CHILD_REKEYING: + case CHILD_RETRYING: case CHILD_DELETING: /* we do not allow rekeying while we have children in-progress */ DBG1(DBG_IKE, "peer initiated rekeying, but a child is half-open"); @@ -209,6 +239,12 @@ METHOD(task_t, build_r, status_t, this->public.task.build = _build_r_delete; this->public.task.process = _process_r_delete; + /* the peer does have to delete the IKE_SA. If it does not, we get a + * unusable IKE_SA in REKEYING state without a replacement. We consider + * this a timeout condition by the peer, and trigger a delete actively. */ + lib->scheduler->schedule_job(lib->scheduler, (job_t*) + delete_ike_sa_job_create(this->ike_sa->get_id(this->ike_sa), TRUE), 90); + return NEED_MORE; } diff --git a/src/libcharon/sa/task.c b/src/libcharon/sa/task.c index 4336b23ff..b35b58185 100644 --- a/src/libcharon/sa/task.c +++ b/src/libcharon/sa/task.c @@ -27,6 +27,7 @@ ENUM(task_type_names, TASK_IKE_INIT, TASK_ISAKMP_CERT_POST, "IKE_CONFIG", "IKE_REKEY", "IKE_REAUTH", + "IKE_REAUTH_COMPLETE", "IKE_DELETE", "IKE_DPD", "IKE_VENDOR", diff --git a/src/libcharon/sa/task.h b/src/libcharon/sa/task.h index f2c4299cc..7bd3da1fe 100644 --- a/src/libcharon/sa/task.h +++ b/src/libcharon/sa/task.h @@ -22,6 +22,8 @@ #ifndef TASK_H_ #define TASK_H_ +#include <utils/utils.h> + typedef enum task_type_t task_type_t; typedef struct task_t task_t; @@ -51,8 +53,10 @@ enum task_type_t { TASK_IKE_CONFIG, /** rekey an IKE_SA */ TASK_IKE_REKEY, - /** reestablish a complete IKE_SA */ + /** reestablish a complete IKE_SA, break-before-make */ TASK_IKE_REAUTH, + /** completion task for make-before-break IKE_SA re-authentication */ + TASK_IKE_REAUTH_COMPLETE, /** delete an IKE_SA */ TASK_IKE_DELETE, /** liveness check */ diff --git a/src/libcharon/sa/trap_manager.c b/src/libcharon/sa/trap_manager.c index 7e55d6b0f..d6ff3c8c5 100644 --- a/src/libcharon/sa/trap_manager.c +++ b/src/libcharon/sa/trap_manager.c @@ -65,6 +65,11 @@ struct private_trap_manager_t { * listener to track acquiring IKE_SAs */ trap_listener_t listener; + + /** + * Whether to ignore traffic selectors from acquires + */ + bool ignore_acquire_ts; }; /** @@ -171,7 +176,7 @@ METHOD(trap_manager_t, install, u_int32_t, this->lock->unlock(this->lock); /* create and route CHILD_SA */ - child_sa = child_sa_create(me, other, child, reqid, FALSE); + child_sa = child_sa_create(me, other, child, reqid, FALSE, 0, 0); list = linked_list_create_with_items(me, NULL); my_ts = child->get_traffic_selectors(child, TRUE, NULL, list); @@ -353,7 +358,7 @@ METHOD(trap_manager_t, acquire, void, { ike_sa->set_peer_cfg(ike_sa, peer); } - if (ike_sa->get_version(ike_sa) == IKEV1) + if (this->ignore_acquire_ts || ike_sa->get_version(ike_sa) == IKEV1) { /* in IKEv1, don't prepend the acquiring packet TS, as we only * have a single TS that we can establish in a Quick Mode. */ src = dst = NULL; @@ -484,6 +489,8 @@ trap_manager_t *trap_manager_create(void) }, .traps = linked_list_create(), .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), + .ignore_acquire_ts = lib->settings->get_bool(lib->settings, + "%s.ignore_acquire_ts", FALSE, lib->ns), ); charon->bus->add_listener(charon->bus, &this->listener.listener); diff --git a/src/libcharon/tests/Makefile.am b/src/libcharon/tests/Makefile.am new file mode 100644 index 000000000..c8be28594 --- /dev/null +++ b/src/libcharon/tests/Makefile.am @@ -0,0 +1,21 @@ +TESTS = libcharon_tests + +check_PROGRAMS = $(TESTS) + +libcharon_tests_SOURCES = \ + suites/test_mem_pool.c \ + libcharon_tests.h libcharon_tests.c + +libcharon_tests_CFLAGS = \ + -I$(top_srcdir)/src/libcharon \ + -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libstrongswan/tests \ + @COVERAGE_CFLAGS@ + +libcharon_tests_LDFLAGS = @COVERAGE_LDFLAGS@ +libcharon_tests_LDADD = \ + $(top_builddir)/src/libcharon/libcharon.la \ + $(top_builddir)/src/libhydra/libhydra.la \ + $(top_builddir)/src/libstrongswan/libstrongswan.la \ + $(top_builddir)/src/libstrongswan/tests/libtest.la diff --git a/src/libcharon/tests/Makefile.in b/src/libcharon/tests/Makefile.in new file mode 100644 index 000000000..7f4f4b24e --- /dev/null +++ b/src/libcharon/tests/Makefile.in @@ -0,0 +1,874 @@ +# Makefile.in generated by automake 1.14.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +TESTS = libcharon_tests$(EXEEXT) +check_PROGRAMS = $(am__EXEEXT_1) +subdir = src/libcharon/tests +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ + $(top_srcdir)/m4/config/ltoptions.m4 \ + $(top_srcdir)/m4/config/ltsugar.m4 \ + $(top_srcdir)/m4/config/ltversion.m4 \ + $(top_srcdir)/m4/config/lt~obsolete.m4 \ + $(top_srcdir)/m4/macros/split-package-version.m4 \ + $(top_srcdir)/m4/macros/with.m4 \ + $(top_srcdir)/m4/macros/enable-disable.m4 \ + $(top_srcdir)/m4/macros/add-plugin.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__EXEEXT_1 = libcharon_tests$(EXEEXT) +am__dirstamp = $(am__leading_dot)dirstamp +am_libcharon_tests_OBJECTS = \ + suites/libcharon_tests-test_mem_pool.$(OBJEXT) \ + libcharon_tests-libcharon_tests.$(OBJEXT) +libcharon_tests_OBJECTS = $(am_libcharon_tests_OBJECTS) +libcharon_tests_DEPENDENCIES = \ + $(top_builddir)/src/libcharon/libcharon.la \ + $(top_builddir)/src/libhydra/libhydra.la \ + $(top_builddir)/src/libstrongswan/libstrongswan.la \ + $(top_builddir)/src/libstrongswan/tests/libtest.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libcharon_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(libcharon_tests_CFLAGS) $(CFLAGS) $(libcharon_tests_LDFLAGS) \ + $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libcharon_tests_SOURCES) +DIST_SOURCES = $(libcharon_tests_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red='[0;31m'; \ + grn='[0;32m'; \ + lgn='[1;32m'; \ + blu='[1;34m'; \ + mgn='[0;35m'; \ + brg='[1m'; \ + std='[m'; \ + fi; \ +} +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BFDLIB = @BFDLIB@ +BTLIB = @BTLIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +COVERAGE_CFLAGS = @COVERAGE_CFLAGS@ +COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLIB = @DLLIB@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GEM = @GEM@ +GENHTML = @GENHTML@ +GPERF = @GPERF@ +GPRBUILD = @GPRBUILD@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQLCFLAG = @MYSQLCFLAG@ +MYSQLCONFIG = @MYSQLCONFIG@ +MYSQLLIB = @MYSQLLIB@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_LIB = @OPENSSL_LIB@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@ +PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@ +PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@ +PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ +PTHREADLIB = @PTHREADLIB@ +PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ +RANLIB = @RANLIB@ +RTLIB = @RTLIB@ +RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ +RUBYINCLUDE = @RUBYINCLUDE@ +RUBYLIB = @RUBYLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ +STRIP = @STRIP@ +UNWINDLIB = @UNWINDLIB@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +aikgen_plugins = @aikgen_plugins@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ +clearsilver_LIBS = @clearsilver_LIBS@ +cmd_plugins = @cmd_plugins@ +datadir = @datadir@ +datarootdir = @datarootdir@ +dbusservicedir = @dbusservicedir@ +dev_headers = @dev_headers@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +fips_mode = @fips_mode@ +gtk_CFLAGS = @gtk_CFLAGS@ +gtk_LIBS = @gtk_LIBS@ +h_plugins = @h_plugins@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +imcvdir = @imcvdir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ +ipsecdir = @ipsecdir@ +ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ +ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ +linux_headers = @linux_headers@ +localedir = @localedir@ +localstatedir = @localstatedir@ +maemo_CFLAGS = @maemo_CFLAGS@ +maemo_LIBS = @maemo_LIBS@ +manager_plugins = @manager_plugins@ +mandir = @mandir@ +medsrv_plugins = @medsrv_plugins@ +mkdir_p = @mkdir_p@ +nm_CFLAGS = @nm_CFLAGS@ +nm_LIBS = @nm_LIBS@ +nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ +oldincludedir = @oldincludedir@ +pcsclite_CFLAGS = @pcsclite_CFLAGS@ +pcsclite_LIBS = @pcsclite_LIBS@ +pdfdir = @pdfdir@ +piddir = @piddir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +pki_plugins = @pki_plugins@ +plugindir = @plugindir@ +pool_plugins = @pool_plugins@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +random_device = @random_device@ +resolv_conf = @resolv_conf@ +routing_table = @routing_table@ +routing_table_prio = @routing_table_prio@ +s_plugins = @s_plugins@ +sbindir = @sbindir@ +scepclient_plugins = @scepclient_plugins@ +scripts_plugins = @scripts_plugins@ +sharedstatedir = @sharedstatedir@ +soup_CFLAGS = @soup_CFLAGS@ +soup_LIBS = @soup_LIBS@ +srcdir = @srcdir@ +starter_plugins = @starter_plugins@ +strongswan_conf = @strongswan_conf@ +strongswan_options = @strongswan_options@ +swanctldir = @swanctldir@ +sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ +systemdsystemunitdir = @systemdsystemunitdir@ +t_plugins = @t_plugins@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +urandom_device = @urandom_device@ +xml_CFLAGS = @xml_CFLAGS@ +xml_LIBS = @xml_LIBS@ +libcharon_tests_SOURCES = \ + suites/test_mem_pool.c \ + libcharon_tests.h libcharon_tests.c + +libcharon_tests_CFLAGS = \ + -I$(top_srcdir)/src/libcharon \ + -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libstrongswan/tests \ + @COVERAGE_CFLAGS@ + +libcharon_tests_LDFLAGS = @COVERAGE_LDFLAGS@ +libcharon_tests_LDADD = \ + $(top_builddir)/src/libcharon/libcharon.la \ + $(top_builddir)/src/libhydra/libhydra.la \ + $(top_builddir)/src/libstrongswan/libstrongswan.la \ + $(top_builddir)/src/libstrongswan/tests/libtest.la + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libcharon/tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libcharon/tests/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +suites/$(am__dirstamp): + @$(MKDIR_P) suites + @: > suites/$(am__dirstamp) +suites/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) suites/$(DEPDIR) + @: > suites/$(DEPDIR)/$(am__dirstamp) +suites/libcharon_tests-test_mem_pool.$(OBJEXT): \ + suites/$(am__dirstamp) suites/$(DEPDIR)/$(am__dirstamp) + +libcharon_tests$(EXEEXT): $(libcharon_tests_OBJECTS) $(libcharon_tests_DEPENDENCIES) $(EXTRA_libcharon_tests_DEPENDENCIES) + @rm -f libcharon_tests$(EXEEXT) + $(AM_V_CCLD)$(libcharon_tests_LINK) $(libcharon_tests_OBJECTS) $(libcharon_tests_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f suites/*.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcharon_tests-libcharon_tests.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/libcharon_tests-test_mem_pool.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +suites/libcharon_tests-test_mem_pool.o: suites/test_mem_pool.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcharon_tests_CFLAGS) $(CFLAGS) -MT suites/libcharon_tests-test_mem_pool.o -MD -MP -MF suites/$(DEPDIR)/libcharon_tests-test_mem_pool.Tpo -c -o suites/libcharon_tests-test_mem_pool.o `test -f 'suites/test_mem_pool.c' || echo '$(srcdir)/'`suites/test_mem_pool.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/libcharon_tests-test_mem_pool.Tpo suites/$(DEPDIR)/libcharon_tests-test_mem_pool.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_mem_pool.c' object='suites/libcharon_tests-test_mem_pool.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcharon_tests_CFLAGS) $(CFLAGS) -c -o suites/libcharon_tests-test_mem_pool.o `test -f 'suites/test_mem_pool.c' || echo '$(srcdir)/'`suites/test_mem_pool.c + +suites/libcharon_tests-test_mem_pool.obj: suites/test_mem_pool.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcharon_tests_CFLAGS) $(CFLAGS) -MT suites/libcharon_tests-test_mem_pool.obj -MD -MP -MF suites/$(DEPDIR)/libcharon_tests-test_mem_pool.Tpo -c -o suites/libcharon_tests-test_mem_pool.obj `if test -f 'suites/test_mem_pool.c'; then $(CYGPATH_W) 'suites/test_mem_pool.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_mem_pool.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/libcharon_tests-test_mem_pool.Tpo suites/$(DEPDIR)/libcharon_tests-test_mem_pool.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_mem_pool.c' object='suites/libcharon_tests-test_mem_pool.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcharon_tests_CFLAGS) $(CFLAGS) -c -o suites/libcharon_tests-test_mem_pool.obj `if test -f 'suites/test_mem_pool.c'; then $(CYGPATH_W) 'suites/test_mem_pool.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_mem_pool.c'; fi` + +libcharon_tests-libcharon_tests.o: libcharon_tests.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcharon_tests_CFLAGS) $(CFLAGS) -MT libcharon_tests-libcharon_tests.o -MD -MP -MF $(DEPDIR)/libcharon_tests-libcharon_tests.Tpo -c -o libcharon_tests-libcharon_tests.o `test -f 'libcharon_tests.c' || echo '$(srcdir)/'`libcharon_tests.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcharon_tests-libcharon_tests.Tpo $(DEPDIR)/libcharon_tests-libcharon_tests.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libcharon_tests.c' object='libcharon_tests-libcharon_tests.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcharon_tests_CFLAGS) $(CFLAGS) -c -o libcharon_tests-libcharon_tests.o `test -f 'libcharon_tests.c' || echo '$(srcdir)/'`libcharon_tests.c + +libcharon_tests-libcharon_tests.obj: libcharon_tests.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcharon_tests_CFLAGS) $(CFLAGS) -MT libcharon_tests-libcharon_tests.obj -MD -MP -MF $(DEPDIR)/libcharon_tests-libcharon_tests.Tpo -c -o libcharon_tests-libcharon_tests.obj `if test -f 'libcharon_tests.c'; then $(CYGPATH_W) 'libcharon_tests.c'; else $(CYGPATH_W) '$(srcdir)/libcharon_tests.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcharon_tests-libcharon_tests.Tpo $(DEPDIR)/libcharon_tests-libcharon_tests.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libcharon_tests.c' object='libcharon_tests-libcharon_tests.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcharon_tests_CFLAGS) $(CFLAGS) -c -o libcharon_tests-libcharon_tests.obj `if test -f 'libcharon_tests.c'; then $(CYGPATH_W) 'libcharon_tests.c'; else $(CYGPATH_W) '$(srcdir)/libcharon_tests.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f suites/$(DEPDIR)/$(am__dirstamp) + -rm -f suites/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) suites/$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) suites/$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libcharon/tests/libcharon_tests.c b/src/libcharon/tests/libcharon_tests.c new file mode 100644 index 000000000..1ed0f0c95 --- /dev/null +++ b/src/libcharon/tests/libcharon_tests.c @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include <test_runner.h> +#include <hydra.h> +#include <daemon.h> + +/* declare test suite constructors */ +#define TEST_SUITE(x) test_suite_t* x(); +#define TEST_SUITE_DEPEND(x, ...) TEST_SUITE(x) +#include "libcharon_tests.h" +#undef TEST_SUITE +#undef TEST_SUITE_DEPEND + +static test_configuration_t tests[] = { +#define TEST_SUITE(x) \ + { .suite = x, }, +#define TEST_SUITE_DEPEND(x, type, args) \ + { .suite = x, .feature = PLUGIN_DEPENDS(type, args) }, +#include "libcharon_tests.h" + { .suite = NULL, } +}; + +static bool test_runner_init(bool init) +{ + if (init) + { + libhydra_init(); + libcharon_init(); + } + else + { + lib->processor->set_threads(lib->processor, 0); + lib->processor->cancel(lib->processor); + libcharon_deinit(); + libhydra_deinit(); + } + return TRUE; +} + +int main(int argc, char *argv[]) +{ + return test_runner_run("libcharon", tests, test_runner_init); +} diff --git a/src/libcharon/tests/libcharon_tests.h b/src/libcharon/tests/libcharon_tests.h new file mode 100644 index 000000000..dc9681aeb --- /dev/null +++ b/src/libcharon/tests/libcharon_tests.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +TEST_SUITE(mem_pool_suite_create) diff --git a/src/libcharon/tests/suites/test_mem_pool.c b/src/libcharon/tests/suites/test_mem_pool.c new file mode 100644 index 000000000..4204d4bab --- /dev/null +++ b/src/libcharon/tests/suites/test_mem_pool.c @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2014 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "test_suite.h" + +#include <attributes/mem_pool.h> + +static void assert_host(char *expected, host_t *host) +{ + if (!expected) + { + ck_assert_msg(!host, "not epxecting IP != %+H", host); + } + else + { + host_t *verifier; + verifier = host_create_from_string(expected, 0); + ck_assert_msg(host, "expected IP %+H != NULL", verifier); + ck_assert_msg(verifier->ip_equals(verifier, host), "expected IP %+H != " + "%+H", verifier, host);; + verifier->destroy(verifier); + } +} + +static void assert_acquire(mem_pool_t *pool, char *requested, char *expected, + mem_pool_op_t operation) +{ + identification_t *id; + host_t *req, *acquired; + + id = identification_create_from_string("tester"); + req = host_create_from_string(requested, 0); + + acquired = pool->acquire_address(pool, id, req, operation, NULL); + assert_host(expected, acquired); + DESTROY_IF(acquired); + + req->destroy(req); + id->destroy(id); +} + +static void assert_acquires_new(mem_pool_t *pool, char *pattern, int first) +{ + char expected[16]; + int i; + + for (i = 0; i < pool->get_size(pool); i++) + { + snprintf(expected, sizeof(expected), pattern, first + i); + assert_acquire(pool, "0.0.0.0", expected, MEM_POOL_NEW); + ck_assert_int_eq(i + 1, pool->get_online(pool)); + } + assert_acquire(pool, "0.0.0.0", NULL, MEM_POOL_NEW); +} + +START_TEST(test_config) +{ + mem_pool_t *pool; + + pool = mem_pool_create("test", NULL, 0); + ck_assert_int_eq(0, pool->get_size(pool)); + assert_acquire(pool, "192.168.0.1", "192.168.0.1", MEM_POOL_NEW); + assert_acquire(pool, "10.0.1.1", "10.0.1.1", MEM_POOL_NEW); + assert_acquire(pool, "0.0.0.0", "0.0.0.0", MEM_POOL_NEW); + assert_acquire(pool, "255.255.255.255", "255.255.255.255", MEM_POOL_NEW); + ck_assert_int_eq(0, pool->get_online(pool)); + pool->destroy(pool); +} +END_TEST + +START_TEST(test_cidr) +{ + mem_pool_t *pool; + host_t *base; + + base = host_create_from_string("192.168.0.0", 0); + + pool = mem_pool_create("test", base, 32); + ck_assert_int_eq(1, pool->get_size(pool)); + assert_acquires_new(pool, "192.168.0.%d", 0); + pool->destroy(pool); + + pool = mem_pool_create("test", base, 31); + ck_assert_int_eq(2, pool->get_size(pool)); + assert_acquires_new(pool, "192.168.0.%d", 0); + pool->destroy(pool); + + pool = mem_pool_create("test", base, 30); + ck_assert_int_eq(2, pool->get_size(pool)); + assert_acquires_new(pool, "192.168.0.%d", 1); + pool->destroy(pool); + + pool = mem_pool_create("test", base, 29); + ck_assert_int_eq(6, pool->get_size(pool)); + assert_acquires_new(pool, "192.168.0.%d", 1); + pool->destroy(pool); + + pool = mem_pool_create("test", base, 24); + ck_assert_int_eq(254, pool->get_size(pool)); + assert_acquires_new(pool, "192.168.0.%d", 1); + pool->destroy(pool); + + base->destroy(base); +} +END_TEST + +START_TEST(test_cidr_offset) +{ + mem_pool_t *pool; + host_t *base; + + base = host_create_from_string("192.168.0.1", 0); + pool = mem_pool_create("test", base, 31); + ck_assert_int_eq(1, pool->get_size(pool)); + assert_acquires_new(pool, "192.168.0.%d", 1); + pool->destroy(pool); + + pool = mem_pool_create("test", base, 30); + ck_assert_int_eq(2, pool->get_size(pool)); + assert_acquires_new(pool, "192.168.0.%d", 1); + pool->destroy(pool); + base->destroy(base); + + base = host_create_from_string("192.168.0.2", 0); + pool = mem_pool_create("test", base, 30); + ck_assert_int_eq(1, pool->get_size(pool)); + assert_acquires_new(pool, "192.168.0.%d", 2); + pool->destroy(pool); + + pool = mem_pool_create("test", base, 24); + ck_assert_int_eq(253, pool->get_size(pool)); + assert_acquires_new(pool, "192.168.0.%d", 2); + pool->destroy(pool); + base->destroy(base); + + base = host_create_from_string("192.168.0.254", 0); + pool = mem_pool_create("test", base, 24); + ck_assert_int_eq(1, pool->get_size(pool)); + assert_acquires_new(pool, "192.168.0.%d", 254); + pool->destroy(pool); + base->destroy(base); + + /* due to size == 0 we get the requested IP back */ + base = host_create_from_string("192.168.0.255", 0); + pool = mem_pool_create("test", base, 24); + ck_assert_int_eq(0, pool->get_size(pool)); + assert_acquire(pool, "192.168.0.1", "192.168.0.1", MEM_POOL_NEW); + pool->destroy(pool); + + base->destroy(base); +} +END_TEST + +START_TEST(test_range) +{ + mem_pool_t *pool; + host_t *from, *to; + + from = host_create_from_string("192.168.0.0", 0); + to = host_create_from_string("192.168.0.0", 0); + pool = mem_pool_create_range("test", from, to); + ck_assert_int_eq(1, pool->get_size(pool)); + assert_acquires_new(pool, "192.168.0.%d", 0); + pool->destroy(pool); + + to->destroy(to); + to = host_create_from_string("192.168.0.1", 0); + pool = mem_pool_create_range("test", from, to); + ck_assert_int_eq(2, pool->get_size(pool)); + assert_acquires_new(pool, "192.168.0.%d", 0); + pool->destroy(pool); + + from->destroy(from); + from = host_create_from_string("192.168.0.10", 0); + pool = mem_pool_create_range("test", from, to); + ck_assert(!pool); + + to->destroy(to); + to = host_create_from_string("192.168.0.20", 0); + pool = mem_pool_create_range("test", from, to); + ck_assert_int_eq(11, pool->get_size(pool)); + assert_acquires_new(pool, "192.168.0.%d", 10); + pool->destroy(pool); + + from->destroy(from); + from = host_create_from_string("fec::1", 0); + to->destroy(to); + to = host_create_from_string("fed::1", 0); + pool = mem_pool_create_range("test", from, to); + ck_assert(!pool); + + from->destroy(from); + to->destroy(to); +} +END_TEST + +Suite *mem_pool_suite_create() +{ + Suite *s; + TCase *tc; + + s = suite_create("mem_pool"); + + tc = tcase_create("%config-like pool"); + tcase_add_test(tc, test_config); + suite_add_tcase(s, tc); + + tc = tcase_create("cidr constructor"); + tcase_add_test(tc, test_cidr); + tcase_add_test(tc, test_cidr_offset); + suite_add_tcase(s, tc); + + tc = tcase_create("range constructor"); + tcase_add_test(tc, test_range); + suite_add_tcase(s, tc); + + return s; +} diff --git a/src/libfast/Makefile.in b/src/libfast/Makefile.in index f0e9cbe35..6a3a4ebd5 100644 --- a/src/libfast/Makefile.in +++ b/src/libfast/Makefile.in @@ -230,6 +230,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -290,10 +291,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -367,6 +370,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libhydra/Android.mk b/src/libhydra/Android.mk index ff134da7b..af39f04ec 100644 --- a/src/libhydra/Android.mk +++ b/src/libhydra/Android.mk @@ -4,10 +4,6 @@ include $(CLEAR_VARS) # copy-n-paste from Makefile.am libhydra_la_SOURCES := \ hydra.c hydra.h \ -attributes/attributes.c attributes/attributes.h \ -attributes/attribute_provider.h attributes/attribute_handler.h \ -attributes/attribute_manager.c attributes/attribute_manager.h \ -attributes/mem_pool.c attributes/mem_pool.h \ kernel/kernel_interface.c kernel/kernel_interface.h \ kernel/kernel_ipsec.c kernel/kernel_ipsec.h \ kernel/kernel_net.c kernel/kernel_net.h \ @@ -17,8 +13,6 @@ LOCAL_SRC_FILES := $(filter %.c,$(libhydra_la_SOURCES)) # adding the plugin source files -LOCAL_SRC_FILES += $(call add_plugin, attr) - LOCAL_SRC_FILES += $(call add_plugin, kernel-pfkey) LOCAL_SRC_FILES += $(call add_plugin, kernel-netlink) @@ -42,4 +36,3 @@ LOCAL_PRELINK_MODULE := false LOCAL_SHARED_LIBRARIES += libstrongswan include $(BUILD_SHARED_LIBRARY) - diff --git a/src/libhydra/Makefile.am b/src/libhydra/Makefile.am index 510f2a124..9cdbc0147 100644 --- a/src/libhydra/Makefile.am +++ b/src/libhydra/Makefile.am @@ -2,10 +2,6 @@ ipseclib_LTLIBRARIES = libhydra.la libhydra_la_SOURCES = \ hydra.c hydra.h \ -attributes/attributes.c attributes/attributes.h \ -attributes/attribute_provider.h attributes/attribute_handler.h \ -attributes/attribute_manager.c attributes/attribute_manager.h \ -attributes/mem_pool.c attributes/mem_pool.h \ kernel/kernel_interface.c kernel/kernel_interface.h \ kernel/kernel_ipsec.c kernel/kernel_ipsec.h \ kernel/kernel_net.c kernel/kernel_net.h \ @@ -37,20 +33,6 @@ else SUBDIRS = . endif -if USE_ATTR - SUBDIRS += plugins/attr -if MONOLITHIC - libhydra_la_LIBADD += plugins/attr/libstrongswan-attr.la -endif -endif - -if USE_ATTR_SQL - SUBDIRS += plugins/attr_sql -if MONOLITHIC - libhydra_la_LIBADD += plugins/attr_sql/libstrongswan-attr-sql.la -endif -endif - if USE_KERNEL_PFKEY SUBDIRS += plugins/kernel_pfkey if MONOLITHIC @@ -72,9 +54,7 @@ if MONOLITHIC endif endif -if USE_RESOLVE - SUBDIRS += plugins/resolve if MONOLITHIC - libhydra_la_LIBADD += plugins/resolve/libstrongswan-resolve.la -endif + SUBDIRS += . endif +SUBDIRS += tests diff --git a/src/libhydra/Makefile.in b/src/libhydra/Makefile.in index e3ff1981c..9bb2e839a 100644 --- a/src/libhydra/Makefile.in +++ b/src/libhydra/Makefile.in @@ -79,18 +79,12 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @USE_WINDOWS_TRUE@am__append_1 = -lws2_32 -@USE_ATTR_TRUE@am__append_2 = plugins/attr -@MONOLITHIC_TRUE@@USE_ATTR_TRUE@am__append_3 = plugins/attr/libstrongswan-attr.la -@USE_ATTR_SQL_TRUE@am__append_4 = plugins/attr_sql -@MONOLITHIC_TRUE@@USE_ATTR_SQL_TRUE@am__append_5 = plugins/attr_sql/libstrongswan-attr-sql.la -@USE_KERNEL_PFKEY_TRUE@am__append_6 = plugins/kernel_pfkey -@MONOLITHIC_TRUE@@USE_KERNEL_PFKEY_TRUE@am__append_7 = plugins/kernel_pfkey/libstrongswan-kernel-pfkey.la -@USE_KERNEL_PFROUTE_TRUE@am__append_8 = plugins/kernel_pfroute -@MONOLITHIC_TRUE@@USE_KERNEL_PFROUTE_TRUE@am__append_9 = plugins/kernel_pfroute/libstrongswan-kernel-pfroute.la -@USE_KERNEL_NETLINK_TRUE@am__append_10 = plugins/kernel_netlink -@MONOLITHIC_TRUE@@USE_KERNEL_NETLINK_TRUE@am__append_11 = plugins/kernel_netlink/libstrongswan-kernel-netlink.la -@USE_RESOLVE_TRUE@am__append_12 = plugins/resolve -@MONOLITHIC_TRUE@@USE_RESOLVE_TRUE@am__append_13 = plugins/resolve/libstrongswan-resolve.la +@USE_KERNEL_PFKEY_TRUE@am__append_2 = plugins/kernel_pfkey +@MONOLITHIC_TRUE@@USE_KERNEL_PFKEY_TRUE@am__append_3 = plugins/kernel_pfkey/libstrongswan-kernel-pfkey.la +@USE_KERNEL_PFROUTE_TRUE@am__append_4 = plugins/kernel_pfroute +@MONOLITHIC_TRUE@@USE_KERNEL_PFROUTE_TRUE@am__append_5 = plugins/kernel_pfroute/libstrongswan-kernel-pfroute.la +@USE_KERNEL_NETLINK_TRUE@am__append_6 = plugins/kernel_netlink +@MONOLITHIC_TRUE@@USE_KERNEL_NETLINK_TRUE@am__append_7 = plugins/kernel_netlink/libstrongswan-kernel-netlink.la subdir = src/libhydra DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp @@ -144,13 +138,10 @@ am__DEPENDENCIES_1 = libhydra_la_DEPENDENCIES = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ $(am__DEPENDENCIES_1) $(am__append_3) $(am__append_5) \ - $(am__append_7) $(am__append_9) $(am__append_11) \ - $(am__append_13) + $(am__append_7) am__dirstamp = $(am__leading_dot)dirstamp -am_libhydra_la_OBJECTS = hydra.lo attributes/attributes.lo \ - attributes/attribute_manager.lo attributes/mem_pool.lo \ - kernel/kernel_interface.lo kernel/kernel_ipsec.lo \ - kernel/kernel_net.lo +am_libhydra_la_OBJECTS = hydra.lo kernel/kernel_interface.lo \ + kernel/kernel_ipsec.lo kernel/kernel_net.lo libhydra_la_OBJECTS = $(am_libhydra_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -232,8 +223,8 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags -DIST_SUBDIRS = . plugins/attr plugins/attr_sql plugins/kernel_pfkey \ - plugins/kernel_pfroute plugins/kernel_netlink plugins/resolve +DIST_SUBDIRS = . plugins/kernel_pfkey plugins/kernel_pfroute \ + plugins/kernel_netlink tests DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -285,6 +276,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -345,10 +337,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -422,6 +416,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ @@ -483,10 +479,6 @@ xml_LIBS = @xml_LIBS@ ipseclib_LTLIBRARIES = libhydra.la libhydra_la_SOURCES = \ hydra.c hydra.h \ -attributes/attributes.c attributes/attributes.h \ -attributes/attribute_provider.h attributes/attribute_handler.h \ -attributes/attribute_manager.c attributes/attribute_manager.h \ -attributes/mem_pool.c attributes/mem_pool.h \ kernel/kernel_interface.c kernel/kernel_interface.h \ kernel/kernel_ipsec.c kernel/kernel_ipsec.h \ kernel/kernel_net.c kernel/kernel_net.h \ @@ -495,8 +487,7 @@ kernel/kernel_listener.h libhydra_la_LIBADD = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ $(am__append_1) $(am__append_3) $(am__append_5) \ - $(am__append_7) $(am__append_9) $(am__append_11) \ - $(am__append_13) + $(am__append_7) AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ -DIPSEC_DIR=\"${ipsecdir}\" \ @@ -507,14 +498,12 @@ AM_LDFLAGS = \ EXTRA_DIST = Android.mk @MONOLITHIC_FALSE@SUBDIRS = . $(am__append_2) $(am__append_4) \ -@MONOLITHIC_FALSE@ $(am__append_6) $(am__append_8) \ -@MONOLITHIC_FALSE@ $(am__append_10) $(am__append_12) +@MONOLITHIC_FALSE@ $(am__append_6) tests # build optional plugins ######################## @MONOLITHIC_TRUE@SUBDIRS = $(am__append_2) $(am__append_4) \ -@MONOLITHIC_TRUE@ $(am__append_6) $(am__append_8) \ -@MONOLITHIC_TRUE@ $(am__append_10) $(am__append_12) +@MONOLITHIC_TRUE@ $(am__append_6) . tests all: all-recursive .SUFFIXES: @@ -584,18 +573,6 @@ clean-ipseclibLTLIBRARIES: echo rm -f $${locs}; \ rm -f $${locs}; \ } -attributes/$(am__dirstamp): - @$(MKDIR_P) attributes - @: > attributes/$(am__dirstamp) -attributes/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) attributes/$(DEPDIR) - @: > attributes/$(DEPDIR)/$(am__dirstamp) -attributes/attributes.lo: attributes/$(am__dirstamp) \ - attributes/$(DEPDIR)/$(am__dirstamp) -attributes/attribute_manager.lo: attributes/$(am__dirstamp) \ - attributes/$(DEPDIR)/$(am__dirstamp) -attributes/mem_pool.lo: attributes/$(am__dirstamp) \ - attributes/$(DEPDIR)/$(am__dirstamp) kernel/$(am__dirstamp): @$(MKDIR_P) kernel @: > kernel/$(am__dirstamp) @@ -614,8 +591,6 @@ libhydra.la: $(libhydra_la_OBJECTS) $(libhydra_la_DEPENDENCIES) $(EXTRA_libhydra mostlyclean-compile: -rm -f *.$(OBJEXT) - -rm -f attributes/*.$(OBJEXT) - -rm -f attributes/*.lo -rm -f kernel/*.$(OBJEXT) -rm -f kernel/*.lo @@ -623,9 +598,6 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hydra.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@attributes/$(DEPDIR)/attribute_manager.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@attributes/$(DEPDIR)/attributes.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@attributes/$(DEPDIR)/mem_pool.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@kernel/$(DEPDIR)/kernel_interface.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@kernel/$(DEPDIR)/kernel_ipsec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@kernel/$(DEPDIR)/kernel_net.Plo@am__quote@ @@ -659,7 +631,6 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs - -rm -rf attributes/.libs attributes/_libs -rm -rf kernel/.libs kernel/_libs # This directory's subdirectories are mostly independent; you can cd @@ -850,8 +821,6 @@ clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f attributes/$(DEPDIR)/$(am__dirstamp) - -rm -f attributes/$(am__dirstamp) -rm -f kernel/$(DEPDIR)/$(am__dirstamp) -rm -f kernel/$(am__dirstamp) @@ -864,7 +833,7 @@ clean-am: clean-generic clean-ipseclibLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-recursive - -rm -rf ./$(DEPDIR) attributes/$(DEPDIR) kernel/$(DEPDIR) + -rm -rf ./$(DEPDIR) kernel/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -910,7 +879,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive - -rm -rf ./$(DEPDIR) attributes/$(DEPDIR) kernel/$(DEPDIR) + -rm -rf ./$(DEPDIR) kernel/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic diff --git a/src/libhydra/hydra.c b/src/libhydra/hydra.c index 1b5065081..47ffb59c6 100644 --- a/src/libhydra/hydra.c +++ b/src/libhydra/hydra.c @@ -57,7 +57,6 @@ void libhydra_deinit() return; } - this->public.attributes->destroy(this->public.attributes); this->public.kernel_interface->destroy(this->public.kernel_interface); free(this); hydra = NULL; @@ -78,9 +77,6 @@ bool libhydra_init() } INIT(this, - .public = { - .attributes = attribute_manager_create(), - }, .ref = 1, ); hydra = &this->public; diff --git a/src/libhydra/hydra.h b/src/libhydra/hydra.h index 94209ff59..b23a30584 100644 --- a/src/libhydra/hydra.h +++ b/src/libhydra/hydra.h @@ -16,9 +16,6 @@ /** * @defgroup libhydra libhydra * - * @defgroup attributes attributes - * @ingroup libhydra - * * @defgroup hkernel kernel * @ingroup libhydra * @@ -34,7 +31,6 @@ typedef struct hydra_t hydra_t; -#include <attributes/attribute_manager.h> #include <kernel/kernel_interface.h> #include <library.h> @@ -45,11 +41,6 @@ typedef struct hydra_t hydra_t; struct hydra_t { /** - * manager for payload attributes - */ - attribute_manager_t *attributes; - - /** * kernel interface to communicate with kernel */ kernel_interface_t *kernel_interface; diff --git a/src/libhydra/kernel/kernel_interface.c b/src/libhydra/kernel/kernel_interface.c index 3fa28e054..ce31bd410 100644 --- a/src/libhydra/kernel/kernel_interface.c +++ b/src/libhydra/kernel/kernel_interface.c @@ -43,6 +43,8 @@ #include <utils/debug.h> #include <threading/mutex.h> #include <collections/linked_list.h> +#include <collections/hashtable.h> +#include <collections/array.h> typedef struct private_kernel_interface_t private_kernel_interface_t; @@ -115,6 +117,16 @@ struct private_kernel_interface_t { linked_list_t *listeners; /** + * Reqid entries indexed by reqids + */ + hashtable_t *reqids; + + /** + * Reqid entries indexed by traffic selectors + */ + hashtable_t *reqids_by_ts; + + /** * mutex for algorithm mappings */ mutex_t *mutex_algs; @@ -155,24 +167,252 @@ METHOD(kernel_interface_t, get_features, kernel_feature_t, METHOD(kernel_interface_t, get_spi, status_t, private_kernel_interface_t *this, host_t *src, host_t *dst, - u_int8_t protocol, u_int32_t reqid, u_int32_t *spi) + u_int8_t protocol, u_int32_t *spi) { if (!this->ipsec) { return NOT_SUPPORTED; } - return this->ipsec->get_spi(this->ipsec, src, dst, protocol, reqid, spi); + return this->ipsec->get_spi(this->ipsec, src, dst, protocol, spi); } METHOD(kernel_interface_t, get_cpi, status_t, private_kernel_interface_t *this, host_t *src, host_t *dst, - u_int32_t reqid, u_int16_t *cpi) + u_int16_t *cpi) { if (!this->ipsec) { return NOT_SUPPORTED; } - return this->ipsec->get_cpi(this->ipsec, src, dst, reqid, cpi); + return this->ipsec->get_cpi(this->ipsec, src, dst, cpi); +} + +/** + * Reqid mapping entry + */ +typedef struct { + /** allocated reqid */ + u_int32_t reqid; + /** references to this entry */ + u_int refs; + /** inbound mark used for SA */ + mark_t mark_in; + /** outbound mark used for SA */ + mark_t mark_out; + /** local traffic selectors */ + array_t *local; + /** remote traffic selectors */ + array_t *remote; +} reqid_entry_t; + +/** + * Destroy a reqid mapping entry + */ +static void reqid_entry_destroy(reqid_entry_t *entry) +{ + array_destroy_offset(entry->local, offsetof(traffic_selector_t, destroy)); + array_destroy_offset(entry->remote, offsetof(traffic_selector_t, destroy)); + free(entry); +} + +/** + * Hashtable hash function for reqid entries using reqid as key + */ +static u_int hash_reqid(reqid_entry_t *entry) +{ + return chunk_hash_inc(chunk_from_thing(entry->reqid), + chunk_hash_inc(chunk_from_thing(entry->mark_in), + chunk_hash(chunk_from_thing(entry->mark_out)))); +} + +/** + * Hashtable equals function for reqid entries using reqid as key + */ +static bool equals_reqid(reqid_entry_t *a, reqid_entry_t *b) +{ + return a->reqid == b->reqid && + a->mark_in.value == b->mark_in.value && + a->mark_in.mask == b->mark_in.mask && + a->mark_out.value == b->mark_out.value && + a->mark_out.mask == b->mark_out.mask; +} + +/** + * Hash an array of traffic selectors + */ +static u_int hash_ts_array(array_t *array, u_int hash) +{ + enumerator_t *enumerator; + traffic_selector_t *ts; + + enumerator = array_create_enumerator(array); + while (enumerator->enumerate(enumerator, &ts)) + { + hash = ts->hash(ts, hash); + } + enumerator->destroy(enumerator); + + return hash; +} + +/** + * Hashtable hash function for reqid entries using traffic selectors as key + */ +static u_int hash_reqid_by_ts(reqid_entry_t *entry) +{ + return hash_ts_array(entry->local, hash_ts_array(entry->remote, + chunk_hash_inc(chunk_from_thing(entry->mark_in), + chunk_hash(chunk_from_thing(entry->mark_out))))); +} + +/** + * Compare two array with traffic selectors for equality + */ +static bool ts_array_equals(array_t *a, array_t *b) +{ + traffic_selector_t *tsa, *tsb; + enumerator_t *ae, *be; + bool equal = TRUE; + + if (array_count(a) != array_count(b)) + { + return FALSE; + } + + ae = array_create_enumerator(a); + be = array_create_enumerator(b); + while (equal && ae->enumerate(ae, &tsa) && be->enumerate(be, &tsb)) + { + equal = tsa->equals(tsa, tsb); + } + ae->destroy(ae); + be->destroy(be); + + return equal; +} + +/** + * Hashtable equals function for reqid entries using traffic selectors as key + */ +static bool equals_reqid_by_ts(reqid_entry_t *a, reqid_entry_t *b) +{ + return ts_array_equals(a->local, b->local) && + ts_array_equals(a->remote, b->remote) && + a->mark_in.value == b->mark_in.value && + a->mark_in.mask == b->mark_in.mask && + a->mark_out.value == b->mark_out.value && + a->mark_out.mask == b->mark_out.mask; +} + +/** + * Create an array from copied traffic selector list items + */ +static array_t *array_from_ts_list(linked_list_t *list) +{ + enumerator_t *enumerator; + traffic_selector_t *ts; + array_t *array; + + array = array_create(0, 0); + + enumerator = list->create_enumerator(list); + while (enumerator->enumerate(enumerator, &ts)) + { + array_insert(array, ARRAY_TAIL, ts->clone(ts)); + } + enumerator->destroy(enumerator); + + return array; +} + +METHOD(kernel_interface_t, alloc_reqid, status_t, + private_kernel_interface_t *this, + linked_list_t *local_ts, linked_list_t *remote_ts, + mark_t mark_in, mark_t mark_out, u_int32_t *reqid) +{ + static u_int32_t counter = 0; + reqid_entry_t *entry = NULL, *tmpl; + status_t status = SUCCESS; + + INIT(tmpl, + .local = array_from_ts_list(local_ts), + .remote = array_from_ts_list(remote_ts), + .mark_in = mark_in, + .mark_out = mark_out, + .reqid = *reqid, + ); + + this->mutex->lock(this->mutex); + if (tmpl->reqid) + { + /* search by reqid if given */ + entry = this->reqids->get(this->reqids, tmpl); + } + if (entry) + { + /* we don't require a traffic selector match for explicit reqids, + * as we wan't to reuse a reqid for trap-triggered policies that + * got narrowed during negotiation. */ + reqid_entry_destroy(tmpl); + } + else + { + /* search by traffic selectors */ + entry = this->reqids_by_ts->get(this->reqids_by_ts, tmpl); + if (entry) + { + reqid_entry_destroy(tmpl); + } + else + { + /* none found, create a new entry, allocating a reqid */ + entry = tmpl; + entry->reqid = ++counter; + this->reqids_by_ts->put(this->reqids_by_ts, entry, entry); + this->reqids->put(this->reqids, entry, entry); + } + *reqid = entry->reqid; + } + entry->refs++; + this->mutex->unlock(this->mutex); + + return status; +} + +METHOD(kernel_interface_t, release_reqid, status_t, + private_kernel_interface_t *this, u_int32_t reqid, + mark_t mark_in, mark_t mark_out) +{ + reqid_entry_t *entry, tmpl = { + .reqid = reqid, + .mark_in = mark_in, + .mark_out = mark_out, + }; + + this->mutex->lock(this->mutex); + entry = this->reqids->remove(this->reqids, &tmpl); + if (entry) + { + if (--entry->refs == 0) + { + entry = this->reqids_by_ts->remove(this->reqids_by_ts, entry); + if (entry) + { + reqid_entry_destroy(entry); + } + } + else + { + this->reqids->put(this->reqids, entry, entry); + } + } + this->mutex->unlock(this->mutex); + + if (entry) + { + return SUCCESS; + } + return NOT_FOUND; } METHOD(kernel_interface_t, add_sa, status_t, @@ -181,8 +421,8 @@ METHOD(kernel_interface_t, add_sa, status_t, u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key, u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window, - bool initiator, bool encap, bool esn, bool inbound, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts) + bool initiator, bool encap, bool esn, bool inbound, bool update, + linked_list_t *src_ts, linked_list_t *dst_ts) { if (!this->ipsec) { @@ -191,7 +431,7 @@ METHOD(kernel_interface_t, add_sa, status_t, return this->ipsec->add_sa(this->ipsec, src, dst, spi, protocol, reqid, mark, tfc, lifetime, enc_alg, enc_key, int_alg, int_key, mode, ipcomp, cpi, replay_window, initiator, encap, esn, inbound, - src_ts, dst_ts); + update, src_ts, dst_ts); } METHOD(kernel_interface_t, update_sa, status_t, @@ -575,17 +815,18 @@ METHOD(kernel_interface_t, acquire, void, } METHOD(kernel_interface_t, expire, void, - private_kernel_interface_t *this, u_int32_t reqid, u_int8_t protocol, - u_int32_t spi, bool hard) + private_kernel_interface_t *this, u_int8_t protocol, u_int32_t spi, + host_t *dst, bool hard) { kernel_listener_t *listener; enumerator_t *enumerator; + this->mutex->lock(this->mutex); enumerator = this->listeners->create_enumerator(this->listeners); while (enumerator->enumerate(enumerator, &listener)) { if (listener->expire && - !listener->expire(listener, reqid, protocol, spi, hard)) + !listener->expire(listener, protocol, spi, dst, hard)) { this->listeners->remove_at(this->listeners, enumerator); } @@ -595,17 +836,18 @@ METHOD(kernel_interface_t, expire, void, } METHOD(kernel_interface_t, mapping, void, - private_kernel_interface_t *this, u_int32_t reqid, u_int32_t spi, - host_t *remote) + private_kernel_interface_t *this, u_int8_t protocol, u_int32_t spi, + host_t *dst, host_t *remote) { kernel_listener_t *listener; enumerator_t *enumerator; + this->mutex->lock(this->mutex); enumerator = this->listeners->create_enumerator(this->listeners); while (enumerator->enumerate(enumerator, &listener)) { if (listener->mapping && - !listener->mapping(listener, reqid, spi, remote)) + !listener->mapping(listener, protocol, spi, dst, remote)) { this->listeners->remove_at(this->listeners, enumerator); } @@ -733,6 +975,8 @@ METHOD(kernel_interface_t, destroy, void, DESTROY_IF(this->ipsec); DESTROY_IF(this->net); DESTROY_FUNCTION_IF(this->ifaces_filter, (void*)free); + this->reqids->destroy(this->reqids); + this->reqids_by_ts->destroy(this->reqids_by_ts); this->listeners->destroy(this->listeners); this->mutex->destroy(this->mutex); free(this); @@ -751,6 +995,8 @@ kernel_interface_t *kernel_interface_create() .get_features = _get_features, .get_spi = _get_spi, .get_cpi = _get_cpi, + .alloc_reqid = _alloc_reqid, + .release_reqid = _release_reqid, .add_sa = _add_sa, .update_sa = _update_sa, .query_sa = _query_sa, @@ -795,6 +1041,10 @@ kernel_interface_t *kernel_interface_create() .listeners = linked_list_create(), .mutex_algs = mutex_create(MUTEX_TYPE_DEFAULT), .algorithms = linked_list_create(), + .reqids = hashtable_create((hashtable_hash_t)hash_reqid, + (hashtable_equals_t)equals_reqid, 8), + .reqids_by_ts = hashtable_create((hashtable_hash_t)hash_reqid_by_ts, + (hashtable_equals_t)equals_reqid_by_ts, 8), ); ifaces = lib->settings->get_str(lib->settings, diff --git a/src/libhydra/kernel/kernel_interface.h b/src/libhydra/kernel/kernel_interface.h index cd550383c..96ce9e26d 100644 --- a/src/libhydra/kernel/kernel_interface.h +++ b/src/libhydra/kernel/kernel_interface.h @@ -104,39 +104,67 @@ struct kernel_interface_t { * @param src source address of SA * @param dst destination address of SA * @param protocol protocol for SA (ESP/AH) - * @param reqid unique ID for this SA * @param spi allocated spi - * @return SUCCESS if operation completed + * @return SUCCESS if operation completed */ status_t (*get_spi)(kernel_interface_t *this, host_t *src, host_t *dst, - u_int8_t protocol, u_int32_t reqid, u_int32_t *spi); + u_int8_t protocol, u_int32_t *spi); /** * Get a Compression Parameter Index (CPI) from the kernel. * * @param src source address of SA * @param dst destination address of SA - * @param reqid unique ID for the corresponding SA * @param cpi allocated cpi - * @return SUCCESS if operation completed + * @return SUCCESS if operation completed */ status_t (*get_cpi)(kernel_interface_t *this, host_t *src, host_t *dst, - u_int32_t reqid, u_int16_t *cpi); + u_int16_t *cpi); + + /** + * Allocate or confirm a reqid to use for a given SA pair. + * + * Each returned reqid by a successful call to alloc_reqid() must be + * released using release_reqid(). + * + * The reqid parameter is an in/out parameter. If it points to non-zero, + * the reqid is confirmed and registered for use. If it points to zero, + * a reqid is allocated for the given selectors, and returned to reqid. + * + * @param local_ts traffic selectors of local side for SA + * @param remote_ts traffic selectors of remote side for SA + * @param mark_in inbound mark on SA + * @param mark_out outbound mark on SA + * @param reqid allocated reqid + * @return SUCCESS if reqid allocated + */ + status_t (*alloc_reqid)(kernel_interface_t *this, + linked_list_t *local_ts, linked_list_t *remote_ts, + mark_t mark_in, mark_t mark_out, + u_int32_t *reqid); + + /** + * Release a previously allocated reqid. + * + * @param reqid reqid to release + * @param mark_in inbound mark on SA + * @param mark_out outbound mark on SA + * @return SUCCESS if reqid released + */ + status_t (*release_reqid)(kernel_interface_t *this, u_int32_t reqid, + mark_t mark_in, mark_t mark_out); /** * Add an SA to the SAD. * - * add_sa() may update an already allocated - * SPI (via get_spi). In this case, the replace - * flag must be set. - * This function does install a single SA for a - * single protocol in one direction. + * This function does install a single SA for a single protocol in one + * direction. * * @param src source address for this SA * @param dst destination address for this SA * @param spi SPI allocated by us or remote peer * @param protocol protocol for this SA (ESP/AH) - * @param reqid unique ID for this SA + * @param reqid reqid for this SA * @param mark optional mark for this SA * @param tfc Traffic Flow Confidentiality padding for this SA * @param lifetime lifetime_cfg_t for this SA @@ -152,8 +180,9 @@ struct kernel_interface_t { * @param encap enable UDP encapsulation for NAT traversal * @param esn TRUE to use Extended Sequence Numbers * @param inbound TRUE if this is an inbound SA - * @param src_ts traffic selector with BEET source address - * @param dst_ts traffic selector with BEET destination address + * @param update TRUE if an SPI has already been allocated for SA + * @param src_ts list of source traffic selectors + * @param dst_ts list of destination traffic selectors * @return SUCCESS if operation completed */ status_t (*add_sa) (kernel_interface_t *this, @@ -163,9 +192,9 @@ struct kernel_interface_t { u_int16_t enc_alg, chunk_t enc_key, u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi, - u_int32_t replay_window, - bool initiator, bool encap, bool esn, bool inbound, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts); + u_int32_t replay_window, bool initiator, bool encap, + bool esn, bool inbound, bool update, + linked_list_t *src_ts, linked_list_t *dst_ts); /** * Update the hosts on an installed SA. @@ -531,23 +560,24 @@ struct kernel_interface_t { /** * Raise an expire event. * - * @param reqid reqid of the expired SA * @param protocol protocol of the expired SA * @param spi spi of the expired SA + * @param dst destination address of expired SA * @param hard TRUE if it is a hard expire, FALSE otherwise */ - void (*expire)(kernel_interface_t *this, u_int32_t reqid, - u_int8_t protocol, u_int32_t spi, bool hard); + void (*expire)(kernel_interface_t *this, u_int8_t protocol, u_int32_t spi, + host_t *dst, bool hard); /** * Raise a mapping event. * - * @param reqid reqid of the SA + * @param protocol protocol of affected SA * @param spi spi of the SA + * @param dst original destination address of SA * @param remote new remote host */ - void (*mapping)(kernel_interface_t *this, u_int32_t reqid, u_int32_t spi, - host_t *remote); + void (*mapping)(kernel_interface_t *this, u_int8_t protocol, u_int32_t spi, + host_t *dst, host_t *remote); /** * Raise a migrate event. diff --git a/src/libhydra/kernel/kernel_ipsec.h b/src/libhydra/kernel/kernel_ipsec.h index eec7401e9..19caaa400 100644 --- a/src/libhydra/kernel/kernel_ipsec.h +++ b/src/libhydra/kernel/kernel_ipsec.h @@ -58,33 +58,28 @@ struct kernel_ipsec_t { * @param src source address of SA * @param dst destination address of SA * @param protocol protocol for SA (ESP/AH) - * @param reqid unique ID for this SA * @param spi allocated spi - * @return SUCCESS if operation completed + * @return SUCCESS if operation completed */ status_t (*get_spi)(kernel_ipsec_t *this, host_t *src, host_t *dst, - u_int8_t protocol, u_int32_t reqid, u_int32_t *spi); + u_int8_t protocol, u_int32_t *spi); /** * Get a Compression Parameter Index (CPI) from the kernel. * * @param src source address of SA * @param dst destination address of SA - * @param reqid unique ID for the corresponding SA * @param cpi allocated cpi - * @return SUCCESS if operation completed + * @return SUCCESS if operation completed */ status_t (*get_cpi)(kernel_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t reqid, u_int16_t *cpi); + u_int16_t *cpi); /** * Add an SA to the SAD. * - * add_sa() may update an already allocated - * SPI (via get_spi). In this case, the replace - * flag must be set. - * This function does install a single SA for a - * single protocol in one direction. + * This function does install a single SA for a single protocol in one + * direction. * * @param src source address for this SA * @param dst destination address for this SA @@ -106,8 +101,9 @@ struct kernel_ipsec_t { * @param encap enable UDP encapsulation for NAT traversal * @param esn TRUE to use Extended Sequence Numbers * @param inbound TRUE if this is an inbound SA - * @param src_ts traffic selector with BEET source address - * @param dst_ts traffic selector with BEET destination address + * @param update TRUE if an SPI has already been allocated for SA + * @param src_ts list of source traffic selectors + * @param dst_ts list of destination traffic selectors * @return SUCCESS if operation completed */ status_t (*add_sa) (kernel_ipsec_t *this, @@ -117,9 +113,9 @@ struct kernel_ipsec_t { u_int16_t enc_alg, chunk_t enc_key, u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi, - u_int32_t replay_window, - bool initiator, bool encap, bool esn, bool inbound, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts); + u_int32_t replay_window, bool initiator, bool encap, + bool esn, bool inbound, bool update, + linked_list_t *src_ts, linked_list_t *dst_ts); /** * Update the hosts on an installed SA. diff --git a/src/libhydra/kernel/kernel_listener.h b/src/libhydra/kernel/kernel_listener.h index 4382a43fd..8074356a4 100644 --- a/src/libhydra/kernel/kernel_listener.h +++ b/src/libhydra/kernel/kernel_listener.h @@ -49,25 +49,26 @@ struct kernel_listener_t { /** * Hook called if an exire event for an IPsec SA is received. * - * @param reqid reqid of the expired SA * @param protocol protocol of the expired SA * @param spi spi of the expired SA + * @param dst destination address of expired SA * @param hard TRUE if it is a hard expire, FALSE otherwise * @return TRUE to remain registered, FALSE to unregister */ - bool (*expire)(kernel_listener_t *this, u_int32_t reqid, - u_int8_t protocol, u_int32_t spi, bool hard); + bool (*expire)(kernel_listener_t *this, u_int8_t protocol, u_int32_t spi, + host_t *dst, bool hard); /** * Hook called if the NAT mappings of an IPsec SA changed. * - * @param reqid reqid of the SA + * @param protocol IPsec protocol of affected SA * @param spi spi of the SA + * @param dst old destinatino address of SA * @param remote new remote host * @return TRUE to remain registered, FALSE to unregister */ - bool (*mapping)(kernel_listener_t *this, u_int32_t reqid, u_int32_t spi, - host_t *remote); + bool (*mapping)(kernel_listener_t *this, u_int8_t protocol, u_int32_t spi, + host_t *dst, host_t *remote); /** * Hook called if a migrate event for a policy is received. diff --git a/src/libhydra/plugins/kernel_netlink/Makefile.am b/src/libhydra/plugins/kernel_netlink/Makefile.am index c91f9a9e4..cc8855406 100644 --- a/src/libhydra/plugins/kernel_netlink/Makefile.am +++ b/src/libhydra/plugins/kernel_netlink/Makefile.am @@ -21,3 +21,24 @@ libstrongswan_kernel_netlink_la_SOURCES = \ kernel_netlink_shared.h kernel_netlink_shared.c libstrongswan_kernel_netlink_la_LDFLAGS = -module -avoid-version + + +TESTS = tests + +check_PROGRAMS = $(TESTS) + +tests_SOURCES = \ + tests.h tests.c \ + suites/test_socket.c \ + kernel_netlink_shared.c + +tests_CFLAGS = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libstrongswan/tests \ + -DNETLINK_MSG_LOSS_HOOK=netlink_msg_loss \ + @COVERAGE_CFLAGS@ + +tests_LDFLAGS = @COVERAGE_LDFLAGS@ +tests_LDADD = \ + $(top_builddir)/src/libstrongswan/libstrongswan.la \ + $(top_builddir)/src/libstrongswan/tests/libtest.la diff --git a/src/libhydra/plugins/kernel_netlink/Makefile.in b/src/libhydra/plugins/kernel_netlink/Makefile.in index a9b523eb8..962fe1ba1 100644 --- a/src/libhydra/plugins/kernel_netlink/Makefile.in +++ b/src/libhydra/plugins/kernel_netlink/Makefile.in @@ -78,6 +78,8 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ +TESTS = tests$(EXEEXT) +check_PROGRAMS = $(am__EXEEXT_1) subdir = src/libhydra/plugins/kernel_netlink DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp @@ -144,6 +146,18 @@ libstrongswan_kernel_netlink_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ @MONOLITHIC_FALSE@am_libstrongswan_kernel_netlink_la_rpath = -rpath \ @MONOLITHIC_FALSE@ $(plugindir) @MONOLITHIC_TRUE@am_libstrongswan_kernel_netlink_la_rpath = +am__EXEEXT_1 = tests$(EXEEXT) +am__dirstamp = $(am__leading_dot)dirstamp +am_tests_OBJECTS = tests-tests.$(OBJEXT) \ + suites/tests-test_socket.$(OBJEXT) \ + tests-kernel_netlink_shared.$(OBJEXT) +tests_OBJECTS = $(am_tests_OBJECTS) +tests_DEPENDENCIES = \ + $(top_builddir)/src/libstrongswan/libstrongswan.la \ + $(top_builddir)/src/libstrongswan/tests/libtest.la +tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(tests_CFLAGS) $(CFLAGS) \ + $(tests_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -178,8 +192,9 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = $(libstrongswan_kernel_netlink_la_SOURCES) -DIST_SOURCES = $(libstrongswan_kernel_netlink_la_SOURCES) +SOURCES = $(libstrongswan_kernel_netlink_la_SOURCES) $(tests_SOURCES) +DIST_SOURCES = $(libstrongswan_kernel_netlink_la_SOURCES) \ + $(tests_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -204,6 +219,28 @@ am__define_uniq_tagged_files = \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red='[0;31m'; \ + grn='[0;32m'; \ + lgn='[1;32m'; \ + blu='[1;34m'; \ + mgn='[0;35m'; \ + brg='[1m'; \ + std='[m'; \ + fi; \ +} DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ ALLOCA = @ALLOCA@ @@ -230,6 +267,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -290,10 +328,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -367,6 +407,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ @@ -444,6 +486,22 @@ libstrongswan_kernel_netlink_la_SOURCES = \ kernel_netlink_shared.h kernel_netlink_shared.c libstrongswan_kernel_netlink_la_LDFLAGS = -module -avoid-version +tests_SOURCES = \ + tests.h tests.c \ + suites/test_socket.c \ + kernel_netlink_shared.c + +tests_CFLAGS = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libstrongswan/tests \ + -DNETLINK_MSG_LOSS_HOOK=netlink_msg_loss \ + @COVERAGE_CFLAGS@ + +tests_LDFLAGS = @COVERAGE_LDFLAGS@ +tests_LDADD = \ + $(top_builddir)/src/libstrongswan/libstrongswan.la \ + $(top_builddir)/src/libstrongswan/tests/libtest.la + all: all-am .SUFFIXES: @@ -528,8 +586,30 @@ clean-pluginLTLIBRARIES: libstrongswan-kernel-netlink.la: $(libstrongswan_kernel_netlink_la_OBJECTS) $(libstrongswan_kernel_netlink_la_DEPENDENCIES) $(EXTRA_libstrongswan_kernel_netlink_la_DEPENDENCIES) $(AM_V_CCLD)$(libstrongswan_kernel_netlink_la_LINK) $(am_libstrongswan_kernel_netlink_la_rpath) $(libstrongswan_kernel_netlink_la_OBJECTS) $(libstrongswan_kernel_netlink_la_LIBADD) $(LIBS) +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +suites/$(am__dirstamp): + @$(MKDIR_P) suites + @: > suites/$(am__dirstamp) +suites/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) suites/$(DEPDIR) + @: > suites/$(DEPDIR)/$(am__dirstamp) +suites/tests-test_socket.$(OBJEXT): suites/$(am__dirstamp) \ + suites/$(DEPDIR)/$(am__dirstamp) + +tests$(EXEEXT): $(tests_OBJECTS) $(tests_DEPENDENCIES) $(EXTRA_tests_DEPENDENCIES) + @rm -f tests$(EXEEXT) + $(AM_V_CCLD)$(tests_LINK) $(tests_OBJECTS) $(tests_LDADD) $(LIBS) + mostlyclean-compile: -rm -f *.$(OBJEXT) + -rm -f suites/*.$(OBJEXT) distclean-compile: -rm -f *.tab.c @@ -538,6 +618,9 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_netlink_net.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_netlink_plugin.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel_netlink_shared.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tests-kernel_netlink_shared.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tests-tests.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_socket.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @@ -563,6 +646,48 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< +tests-tests.o: tests.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT tests-tests.o -MD -MP -MF $(DEPDIR)/tests-tests.Tpo -c -o tests-tests.o `test -f 'tests.c' || echo '$(srcdir)/'`tests.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests-tests.Tpo $(DEPDIR)/tests-tests.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests.c' object='tests-tests.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o tests-tests.o `test -f 'tests.c' || echo '$(srcdir)/'`tests.c + +tests-tests.obj: tests.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT tests-tests.obj -MD -MP -MF $(DEPDIR)/tests-tests.Tpo -c -o tests-tests.obj `if test -f 'tests.c'; then $(CYGPATH_W) 'tests.c'; else $(CYGPATH_W) '$(srcdir)/tests.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests-tests.Tpo $(DEPDIR)/tests-tests.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='tests.c' object='tests-tests.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o tests-tests.obj `if test -f 'tests.c'; then $(CYGPATH_W) 'tests.c'; else $(CYGPATH_W) '$(srcdir)/tests.c'; fi` + +suites/tests-test_socket.o: suites/test_socket.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_socket.o -MD -MP -MF suites/$(DEPDIR)/tests-test_socket.Tpo -c -o suites/tests-test_socket.o `test -f 'suites/test_socket.c' || echo '$(srcdir)/'`suites/test_socket.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_socket.Tpo suites/$(DEPDIR)/tests-test_socket.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_socket.c' object='suites/tests-test_socket.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_socket.o `test -f 'suites/test_socket.c' || echo '$(srcdir)/'`suites/test_socket.c + +suites/tests-test_socket.obj: suites/test_socket.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_socket.obj -MD -MP -MF suites/$(DEPDIR)/tests-test_socket.Tpo -c -o suites/tests-test_socket.obj `if test -f 'suites/test_socket.c'; then $(CYGPATH_W) 'suites/test_socket.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_socket.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_socket.Tpo suites/$(DEPDIR)/tests-test_socket.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_socket.c' object='suites/tests-test_socket.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_socket.obj `if test -f 'suites/test_socket.c'; then $(CYGPATH_W) 'suites/test_socket.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_socket.c'; fi` + +tests-kernel_netlink_shared.o: kernel_netlink_shared.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT tests-kernel_netlink_shared.o -MD -MP -MF $(DEPDIR)/tests-kernel_netlink_shared.Tpo -c -o tests-kernel_netlink_shared.o `test -f 'kernel_netlink_shared.c' || echo '$(srcdir)/'`kernel_netlink_shared.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests-kernel_netlink_shared.Tpo $(DEPDIR)/tests-kernel_netlink_shared.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='kernel_netlink_shared.c' object='tests-kernel_netlink_shared.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o tests-kernel_netlink_shared.o `test -f 'kernel_netlink_shared.c' || echo '$(srcdir)/'`kernel_netlink_shared.c + +tests-kernel_netlink_shared.obj: kernel_netlink_shared.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT tests-kernel_netlink_shared.obj -MD -MP -MF $(DEPDIR)/tests-kernel_netlink_shared.Tpo -c -o tests-kernel_netlink_shared.obj `if test -f 'kernel_netlink_shared.c'; then $(CYGPATH_W) 'kernel_netlink_shared.c'; else $(CYGPATH_W) '$(srcdir)/kernel_netlink_shared.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/tests-kernel_netlink_shared.Tpo $(DEPDIR)/tests-kernel_netlink_shared.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='kernel_netlink_shared.c' object='tests-kernel_netlink_shared.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o tests-kernel_netlink_shared.obj `if test -f 'kernel_netlink_shared.c'; then $(CYGPATH_W) 'kernel_netlink_shared.c'; else $(CYGPATH_W) '$(srcdir)/kernel_netlink_shared.c'; fi` + mostlyclean-libtool: -rm -f *.lo @@ -621,6 +746,99 @@ cscopelist-am: $(am__tagged_files) distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ + test "$$failed" -eq 0; \ + else :; fi + distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -652,6 +870,8 @@ distdir: $(DISTFILES) fi; \ done check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am all-am: Makefile $(LTLIBRARIES) installdirs: @@ -684,17 +904,19 @@ clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f suites/$(DEPDIR)/$(am__dirstamp) + -rm -f suites/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - clean-pluginLTLIBRARIES mostlyclean-am +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) + -rm -rf ./$(DEPDIR) suites/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -740,7 +962,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) + -rm -rf ./$(DEPDIR) suites/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -759,22 +981,23 @@ ps-am: uninstall-am: uninstall-pluginLTLIBRARIES -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \ - cscopelist-am ctags ctags-am distclean distclean-compile \ - distclean-generic distclean-libtool distclean-tags distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-pdf \ - install-pdf-am install-pluginLTLIBRARIES install-ps \ - install-ps-am install-strip installcheck installcheck-am \ - installdirs maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am uninstall-pluginLTLIBRARIES +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool \ + clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-pluginLTLIBRARIES install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-pluginLTLIBRARIES # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c index dfd71f3bd..03e44e510 100644 --- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c +++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_ipsec.c @@ -38,6 +38,7 @@ #include <hydra.h> #include <utils/debug.h> #include <threading/mutex.h> +#include <collections/array.h> #include <collections/hashtable.h> #include <collections/linked_list.h> @@ -319,6 +320,16 @@ struct private_kernel_netlink_ipsec_t { * Whether to track the history of a policy */ bool policy_history; + + /** + * Whether to always use UPDATE to install policies + */ + bool policy_update; + + /** + * Installed port based IKE bypass policies, as bypass_t + */ + array_t *bypass; }; typedef struct route_entry_t route_entry_t; @@ -859,25 +870,26 @@ static void process_expire(private_kernel_netlink_ipsec_t *this, struct nlmsghdr *hdr) { struct xfrm_user_expire *expire; - u_int32_t spi, reqid; + u_int32_t spi; u_int8_t protocol; + host_t *dst; expire = NLMSG_DATA(hdr); protocol = expire->state.id.proto; spi = expire->state.id.spi; - reqid = expire->state.reqid; DBG2(DBG_KNL, "received a XFRM_MSG_EXPIRE"); - if (protocol != IPPROTO_ESP && protocol != IPPROTO_AH) + if (protocol == IPPROTO_ESP || protocol == IPPROTO_AH) { - DBG2(DBG_KNL, "ignoring XFRM_MSG_EXPIRE for SA with SPI %.8x and " - "reqid {%u} which is not a CHILD_SA", ntohl(spi), reqid); - return; + dst = xfrm2host(expire->state.family, &expire->state.id.daddr, 0); + if (dst) + { + hydra->kernel_interface->expire(hydra->kernel_interface, protocol, + spi, dst, expire->hard != 0); + dst->destroy(dst); + } } - - hydra->kernel_interface->expire(hydra->kernel_interface, reqid, protocol, - spi, expire->hard != 0); } /** @@ -961,23 +973,29 @@ static void process_mapping(private_kernel_netlink_ipsec_t *this, struct nlmsghdr *hdr) { struct xfrm_user_mapping *mapping; - u_int32_t spi, reqid; + u_int32_t spi; mapping = NLMSG_DATA(hdr); spi = mapping->id.spi; - reqid = mapping->reqid; DBG2(DBG_KNL, "received a XFRM_MSG_MAPPING"); if (mapping->id.proto == IPPROTO_ESP) { - host_t *host; - host = xfrm2host(mapping->id.family, &mapping->new_saddr, - mapping->new_sport); - if (host) + host_t *dst, *new; + + dst = xfrm2host(mapping->id.family, &mapping->id.daddr, 0); + if (dst) { - hydra->kernel_interface->mapping(hydra->kernel_interface, reqid, - spi, host); + new = xfrm2host(mapping->id.family, &mapping->new_saddr, + mapping->new_sport); + if (new) + { + hydra->kernel_interface->mapping(hydra->kernel_interface, + IPPROTO_ESP, spi, dst, new); + new->destroy(new); + } + dst->destroy(dst); } } } @@ -1055,7 +1073,7 @@ METHOD(kernel_ipsec_t, get_features, kernel_feature_t, */ static status_t get_spi_internal(private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst, u_int8_t proto, u_int32_t min, u_int32_t max, - u_int32_t reqid, u_int32_t *spi) + u_int32_t *spi) { netlink_buf_t request; struct nlmsghdr *hdr, *out; @@ -1075,7 +1093,6 @@ static status_t get_spi_internal(private_kernel_netlink_ipsec_t *this, host2xfrm(dst, &userspi->info.id.daddr); userspi->info.id.proto = proto; userspi->info.mode = XFRM_MODE_TUNNEL; - userspi->info.reqid = reqid; userspi->info.family = src->get_family(src); userspi->min = min; userspi->max = max; @@ -1122,39 +1139,35 @@ static status_t get_spi_internal(private_kernel_netlink_ipsec_t *this, METHOD(kernel_ipsec_t, get_spi, status_t, private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst, - u_int8_t protocol, u_int32_t reqid, u_int32_t *spi) + u_int8_t protocol, u_int32_t *spi) { - DBG2(DBG_KNL, "getting SPI for reqid {%u}", reqid); - if (get_spi_internal(this, src, dst, protocol, - 0xc0000000, 0xcFFFFFFF, reqid, spi) != SUCCESS) + 0xc0000000, 0xcFFFFFFF, spi) != SUCCESS) { - DBG1(DBG_KNL, "unable to get SPI for reqid {%u}", reqid); + DBG1(DBG_KNL, "unable to get SPI"); return FAILED; } - DBG2(DBG_KNL, "got SPI %.8x for reqid {%u}", ntohl(*spi), reqid); + DBG2(DBG_KNL, "got SPI %.8x", ntohl(*spi)); return SUCCESS; } METHOD(kernel_ipsec_t, get_cpi, status_t, private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t reqid, u_int16_t *cpi) + u_int16_t *cpi) { u_int32_t received_spi = 0; - DBG2(DBG_KNL, "getting CPI for reqid {%u}", reqid); - if (get_spi_internal(this, src, dst, IPPROTO_COMP, - 0x100, 0xEFFF, reqid, &received_spi) != SUCCESS) + 0x100, 0xEFFF, &received_spi) != SUCCESS) { - DBG1(DBG_KNL, "unable to get CPI for reqid {%u}", reqid); + DBG1(DBG_KNL, "unable to get CPI"); return FAILED; } *cpi = htons((u_int16_t)ntohl(received_spi)); - DBG2(DBG_KNL, "got CPI %.4x for reqid {%u}", ntohs(*cpi), reqid); + DBG2(DBG_KNL, "got CPI %.4x", ntohs(*cpi)); return SUCCESS; } @@ -1184,8 +1197,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t, u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key, u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window, - bool initiator, bool encap, bool esn, bool inbound, - traffic_selector_t* src_ts, traffic_selector_t* dst_ts) + bool initiator, bool encap, bool esn, bool inbound, bool update, + linked_list_t* src_ts, linked_list_t* dst_ts) { netlink_buf_t request; char *alg_name; @@ -1193,6 +1206,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t, struct xfrm_usersa_info *sa; u_int16_t icv_size = 64; ipsec_mode_t original_mode = mode; + traffic_selector_t *first_src_ts, *first_dst_ts; status_t status = FAILED; /* if IPComp is used, we install an additional IPComp SA. if the cpi is 0 @@ -1203,7 +1217,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t, add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, mark, tfc, &lft, ENCR_UNDEFINED, chunk_empty, AUTH_UNDEFINED, chunk_empty, mode, ipcomp, 0, 0, initiator, FALSE, FALSE, - inbound, src_ts, dst_ts); + inbound, update, src_ts, dst_ts); ipcomp = IPCOMP_NONE; /* use transport mode ESP SA, IPComp uses tunnel mode */ mode = MODE_TRANSPORT; @@ -1216,7 +1230,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t, hdr = &request.hdr; hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - hdr->nlmsg_type = inbound ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA; + hdr->nlmsg_type = update ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA; hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)); sa = NLMSG_DATA(hdr); @@ -1238,9 +1252,10 @@ METHOD(kernel_ipsec_t, add_sa, status_t, * selector can be installed other traffic would get dropped */ break; } - if (src_ts && dst_ts) + if (src_ts->get_first(src_ts, (void**)&first_src_ts) == SUCCESS && + dst_ts->get_first(dst_ts, (void**)&first_dst_ts) == SUCCESS) { - sa->sel = ts2selector(src_ts, dst_ts); + sa->sel = ts2selector(first_src_ts, first_dst_ts); if (!this->proto_port_transport) { /* don't install proto/port on SA. This would break @@ -1535,7 +1550,8 @@ static void get_replay_state(private_kernel_netlink_ipsec_t *this, host_t *dst, mark_t mark, struct xfrm_replay_state_esn **replay_esn, u_int32_t *replay_esn_len, - struct xfrm_replay_state **replay) + struct xfrm_replay_state **replay, + struct xfrm_lifetime_cur **lifetime) { netlink_buf_t request; struct nlmsghdr *hdr, *out = NULL; @@ -1603,20 +1619,27 @@ static void get_replay_state(private_kernel_netlink_ipsec_t *this, rtasize = XFRM_PAYLOAD(out, struct xfrm_aevent_id); while (RTA_OK(rta, rtasize)) { + if (rta->rta_type == XFRMA_LTIME_VAL && + RTA_PAYLOAD(rta) == sizeof(**lifetime)) + { + free(*lifetime); + *lifetime = malloc(RTA_PAYLOAD(rta)); + memcpy(*lifetime, RTA_DATA(rta), RTA_PAYLOAD(rta)); + } if (rta->rta_type == XFRMA_REPLAY_VAL && RTA_PAYLOAD(rta) == sizeof(**replay)) { + free(*replay); *replay = malloc(RTA_PAYLOAD(rta)); memcpy(*replay, RTA_DATA(rta), RTA_PAYLOAD(rta)); - break; } if (rta->rta_type == XFRMA_REPLAY_ESN_VAL && RTA_PAYLOAD(rta) >= sizeof(**replay_esn)) { + free(*replay_esn); *replay_esn = malloc(RTA_PAYLOAD(rta)); *replay_esn_len = RTA_PAYLOAD(rta); memcpy(*replay_esn, RTA_DATA(rta), RTA_PAYLOAD(rta)); - break; } rta = RTA_NEXT(rta, rtasize); } @@ -1798,6 +1821,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t, struct xfrm_encap_tmpl* tmpl = NULL; struct xfrm_replay_state *replay = NULL; struct xfrm_replay_state_esn *replay_esn = NULL; + struct xfrm_lifetime_cur *lifetime = NULL; u_int32_t replay_esn_len; status_t status = FAILED; @@ -1863,7 +1887,8 @@ METHOD(kernel_ipsec_t, update_sa, status_t, goto failed; } - get_replay_state(this, spi, protocol, dst, mark, &replay_esn, &replay_esn_len, &replay); + get_replay_state(this, spi, protocol, dst, mark, &replay_esn, + &replay_esn_len, &replay, &lifetime); /* delete the old SA (without affecting the IPComp SA) */ if (del_sa(this, src, dst, spi, protocol, 0, mark) != SUCCESS) @@ -1952,8 +1977,25 @@ METHOD(kernel_ipsec_t, update_sa, status_t, } else { - DBG1(DBG_KNL, "unable to copy replay state from old SAD entry " - "with SPI %.8x", ntohl(spi)); + DBG1(DBG_KNL, "unable to copy replay state from old SAD entry with " + "SPI %.8x", ntohl(spi)); + } + if (lifetime) + { + struct xfrm_lifetime_cur *state; + + state = netlink_reserve(hdr, sizeof(request), XFRMA_LTIME_VAL, + sizeof(*state)); + if (!state) + { + goto failed; + } + memcpy(state, lifetime, sizeof(*state)); + } + else + { + DBG1(DBG_KNL, "unable to copy usage stats from old SAD entry with " + "SPI %.8x", ntohl(spi)); } if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS) @@ -1966,6 +2008,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t, failed: free(replay); free(replay_esn); + free(lifetime); memwipe(out, len); memwipe(&request, sizeof(request)); free(out); @@ -2313,6 +2356,11 @@ METHOD(kernel_ipsec_t, add_policy, status_t, return SUCCESS; } + if (this->policy_update) + { + found = TRUE; + } + DBG2(DBG_KNL, "%s policy %R === %R %N (mark %u/0x%08x)", found ? "updating" : "adding", src_ts, dst_ts, policy_dir_names, direction, mark.value, mark.mask); @@ -2576,9 +2624,11 @@ METHOD(kernel_ipsec_t, flush_policies, status_t, return SUCCESS; } - -METHOD(kernel_ipsec_t, bypass_socket, bool, - private_kernel_netlink_ipsec_t *this, int fd, int family) +/** + * Bypass socket using a per-socket policy + */ +static bool add_socket_bypass(private_kernel_netlink_ipsec_t *this, + int fd, int family) { struct xfrm_userpolicy_info policy; u_int sol, ipsec_policy; @@ -2618,6 +2668,154 @@ METHOD(kernel_ipsec_t, bypass_socket, bool, return TRUE; } +/** + * Port based IKE bypass policy + */ +typedef struct { + /** address family */ + int family; + /** layer 4 protocol */ + int proto; + /** port number, network order */ + u_int16_t port; +} bypass_t; + +/** + * Add or remove a bypass policy from/to kernel + */ +static bool manage_bypass(private_kernel_netlink_ipsec_t *this, + int type, policy_dir_t dir, bypass_t *bypass) +{ + netlink_buf_t request; + struct xfrm_selector *sel; + struct nlmsghdr *hdr; + + memset(&request, 0, sizeof(request)); + hdr = &request.hdr; + hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; + hdr->nlmsg_type = type; + + if (type == XFRM_MSG_NEWPOLICY) + { + struct xfrm_userpolicy_info *policy; + + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info)); + + policy = NLMSG_DATA(hdr); + policy->dir = dir; + policy->priority = 32; + policy->action = XFRM_POLICY_ALLOW; + policy->share = XFRM_SHARE_ANY; + + policy->lft.soft_byte_limit = XFRM_INF; + policy->lft.soft_packet_limit = XFRM_INF; + policy->lft.hard_byte_limit = XFRM_INF; + policy->lft.hard_packet_limit = XFRM_INF; + + sel = &policy->sel; + } + else /* XFRM_MSG_DELPOLICY */ + { + struct xfrm_userpolicy_id *policy; + + hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_id)); + + policy = NLMSG_DATA(hdr); + policy->dir = dir; + + sel = &policy->sel; + } + + sel->family = bypass->family; + sel->proto = bypass->proto; + if (dir == POLICY_IN) + { + sel->dport = bypass->port; + sel->dport_mask = 0xffff; + } + else + { + sel->sport = bypass->port; + sel->sport_mask = 0xffff; + } + return this->socket_xfrm->send_ack(this->socket_xfrm, hdr) == SUCCESS; +} + +/** + * Bypass socket using a port-based bypass policy + */ +static bool add_port_bypass(private_kernel_netlink_ipsec_t *this, + int fd, int family) +{ + union { + struct sockaddr sa; + struct sockaddr_in in; + struct sockaddr_in6 in6; + } saddr; + socklen_t len; + bypass_t bypass = { + .family = family, + }; + + len = sizeof(saddr); + if (getsockname(fd, &saddr.sa, &len) != 0) + { + return FALSE; + } +#ifdef SO_PROTOCOL /* since 2.6.32 */ + len = sizeof(bypass.proto); + if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &bypass.proto, &len) != 0) +#endif + { /* assume UDP if SO_PROTOCOL not supported */ + bypass.proto = IPPROTO_UDP; + } + switch (family) + { + case AF_INET: + bypass.port = saddr.in.sin_port; + break; + case AF_INET6: + bypass.port = saddr.in6.sin6_port; + break; + default: + return FALSE; + } + + if (!manage_bypass(this, XFRM_MSG_NEWPOLICY, POLICY_IN, &bypass)) + { + return FALSE; + } + if (!manage_bypass(this, XFRM_MSG_NEWPOLICY, POLICY_OUT, &bypass)) + { + manage_bypass(this, XFRM_MSG_DELPOLICY, POLICY_IN, &bypass); + return FALSE; + } + array_insert(this->bypass, ARRAY_TAIL, &bypass); + + return TRUE; +} + +/** + * Remove installed port based bypass policy + */ +static void remove_port_bypass(bypass_t *bypass, int idx, + private_kernel_netlink_ipsec_t *this) +{ + manage_bypass(this, XFRM_MSG_DELPOLICY, POLICY_OUT, bypass); + manage_bypass(this, XFRM_MSG_DELPOLICY, POLICY_IN, bypass); +} + +METHOD(kernel_ipsec_t, bypass_socket, bool, + private_kernel_netlink_ipsec_t *this, int fd, int family) +{ + if (lib->settings->get_bool(lib->settings, + "%s.plugins.kernel-netlink.port_bypass", FALSE, lib->ns)) + { + return add_port_bypass(this, fd, family); + } + return add_socket_bypass(this, fd, family); +} + METHOD(kernel_ipsec_t, enable_udp_decap, bool, private_kernel_netlink_ipsec_t *this, int fd, int family, u_int16_t port) { @@ -2637,6 +2835,8 @@ METHOD(kernel_ipsec_t, destroy, void, enumerator_t *enumerator; policy_entry_t *policy; + array_destroy_function(this->bypass, + (array_callback_t)remove_port_bypass, this); if (this->socket_xfrm_events > 0) { lib->watcher->remove(lib->watcher, this->socket_xfrm_events); @@ -2688,8 +2888,11 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create() (hashtable_equals_t)policy_equals, 32), .sas = hashtable_create((hashtable_hash_t)ipsec_sa_hash, (hashtable_equals_t)ipsec_sa_equals, 32), + .bypass = array_create(sizeof(bypass_t), 0), .mutex = mutex_create(MUTEX_TYPE_DEFAULT), .policy_history = TRUE, + .policy_update = lib->settings->get_bool(lib->settings, + "%s.plugins.kernel-netlink.policy_update", FALSE, lib->ns), .install_routes = lib->settings->get_bool(lib->settings, "%s.install_routes", TRUE, lib->ns), .proto_port_transport = lib->settings->get_bool(lib->settings, @@ -2711,7 +2914,9 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create() fclose(f); } - this->socket_xfrm = netlink_socket_create(NETLINK_XFRM, xfrm_msg_names); + this->socket_xfrm = netlink_socket_create(NETLINK_XFRM, xfrm_msg_names, + lib->settings->get_bool(lib->settings, + "%s.plugins.kernel-netlink.parallel_xfrm", FALSE, lib->ns)); if (!this->socket_xfrm) { destroy(this); diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c index 9d9f15974..a431e49b7 100644 --- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c +++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_net.c @@ -1538,6 +1538,7 @@ typedef struct { u_int8_t dst_len; u_int32_t table; u_int32_t oif; + u_int32_t priority; } rt_entry_t; /** @@ -1573,6 +1574,7 @@ static rt_entry_t *parse_route(struct nlmsghdr *hdr, rt_entry_t *route) route->dst_len = msg->rtm_dst_len; route->table = msg->rtm_table; route->oif = 0; + route->priority = 0; } else { @@ -1601,6 +1603,12 @@ static rt_entry_t *parse_route(struct nlmsghdr *hdr, rt_entry_t *route) route->oif = *(u_int32_t*)RTA_DATA(rta); } break; + case RTA_PRIORITY: + if (RTA_PAYLOAD(rta) == sizeof(route->priority)) + { + route->priority = *(u_int32_t*)RTA_DATA(rta); + } + break; #ifdef HAVE_RTA_TABLE case RTA_TABLE: if (RTA_PAYLOAD(rta) == sizeof(route->table)) @@ -1724,11 +1732,16 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest, } route->src_host = src; } - /* insert route, sorted by decreasing network prefix */ + /* insert route, sorted by priority and network prefix */ enumerator = routes->create_enumerator(routes); while (enumerator->enumerate(enumerator, &other)) { - if (route->dst_len > other->dst_len) + if (route->priority < other->priority) + { + break; + } + if (route->priority == other->priority && + route->dst_len > other->dst_len) { break; } @@ -1975,6 +1988,8 @@ METHOD(kernel_net_t, add_ip, status_t, if (iface) { addr_entry_t *addr; + char *ifname; + int ifi; INIT(addr, .ip = virtual_ip->clone(virtual_ip), @@ -1983,26 +1998,30 @@ METHOD(kernel_net_t, add_ip, status_t, ); iface->addrs->insert_last(iface->addrs, addr); addr_map_entry_add(this->vips, addr, iface); + ifi = iface->ifindex; + this->lock->unlock(this->lock); if (manage_ipaddr(this, RTM_NEWADDR, NLM_F_CREATE | NLM_F_EXCL, - iface->ifindex, virtual_ip, prefix) == SUCCESS) + ifi, virtual_ip, prefix) == SUCCESS) { + this->lock->write_lock(this->lock); while (!is_vip_installed_or_gone(this, virtual_ip, &entry)) { /* wait until address appears */ this->condvar->wait(this->condvar, this->lock); } if (entry) { /* we fail if the interface got deleted in the meantime */ - DBG2(DBG_KNL, "virtual IP %H installed on %s", virtual_ip, - entry->iface->ifname); + ifname = strdup(entry->iface->ifname); this->lock->unlock(this->lock); + DBG2(DBG_KNL, "virtual IP %H installed on %s", + virtual_ip, ifname); /* during IKEv1 reauthentication, children get moved from * old the new SA before the virtual IP is available. This * kills the route for our virtual IP, reinstall. */ - queue_route_reinstall(this, strdup(entry->iface->ifname)); + queue_route_reinstall(this, ifname); return SUCCESS; } + this->lock->unlock(this->lock); } - this->lock->unlock(this->lock); DBG1(DBG_KNL, "adding virtual IP %H failed", virtual_ip); return FAILED; } @@ -2048,20 +2067,23 @@ METHOD(kernel_net_t, del_ip, status_t, if (entry->addr->refcount == 1) { status_t status; + int ifi; /* we set this flag so that threads calling add_ip will block and wait * until the entry is gone, also so we can wait below */ entry->addr->installed = FALSE; - status = manage_ipaddr(this, RTM_DELADDR, 0, entry->iface->ifindex, - virtual_ip, prefix); + ifi = entry->iface->ifindex; + this->lock->unlock(this->lock); + status = manage_ipaddr(this, RTM_DELADDR, 0, ifi, virtual_ip, prefix); if (status == SUCCESS && wait) { /* wait until the address is really gone */ + this->lock->write_lock(this->lock); while (is_known_vip(this, virtual_ip)) { this->condvar->wait(this->condvar, this->lock); } + this->lock->unlock(this->lock); } - this->lock->unlock(this->lock); return status; } else @@ -2490,7 +2512,9 @@ kernel_netlink_net_t *kernel_netlink_net_create() .destroy = _destroy, }, }, - .socket = netlink_socket_create(NETLINK_ROUTE, rt_msg_names), + .socket = netlink_socket_create(NETLINK_ROUTE, rt_msg_names, + lib->settings->get_bool(lib->settings, + "%s.plugins.kernel-netlink.parallel_route", FALSE, lib->ns)), .rt_exclude = linked_list_create(), .routes = hashtable_create((hashtable_hash_t)route_entry_hash, (hashtable_equals_t)route_entry_equals, 16), diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c b/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c index b4cece720..a9adfe091 100644 --- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c +++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.c @@ -1,4 +1,6 @@ /* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG * Copyright (C) 2008 Tobias Brunner * Hochschule fuer Technik Rapperswil * @@ -16,6 +18,7 @@ #include <sys/socket.h> #include <linux/netlink.h> #include <linux/rtnetlink.h> +#include <linux/xfrm.h> #include <errno.h> #include <unistd.h> @@ -23,6 +26,9 @@ #include <utils/debug.h> #include <threading/mutex.h> +#include <threading/condvar.h> +#include <collections/array.h> +#include <collections/hashtable.h> typedef struct private_netlink_socket_t private_netlink_socket_t; @@ -30,20 +36,26 @@ typedef struct private_netlink_socket_t private_netlink_socket_t; * Private variables and functions of netlink_socket_t class. */ struct private_netlink_socket_t { + /** * public part of the netlink_socket_t object. */ netlink_socket_t public; /** - * mutex to lock access to netlink socket + * mutex to lock access entries */ mutex_t *mutex; /** - * current sequence number for netlink request + * Netlink request entries currently active, uintptr_t seq => entry_t + */ + hashtable_t *entries; + + /** + * Current sequence number for Netlink requests */ - int seq; + refcount_t seq; /** * netlink socket @@ -51,119 +63,420 @@ struct private_netlink_socket_t { int socket; /** + * Netlink protocol + */ + int protocol; + + /** * Enum names for Netlink messages */ enum_name_t *names; + + /** + * Timeout for Netlink replies, in ms + */ + u_int timeout; + + /** + * Number of times to repeat timed out queries + */ + u_int retries; + + /** + * Use parallel netlink queries + */ + bool parallel; + + /** + * Ignore errors potentially resulting from a retransmission + */ + bool ignore_retransmit_errors; }; /** - * Imported from kernel_netlink_ipsec.c + * #definable hook to simulate request message loss */ -extern enum_name_t *xfrm_msg_names; - -METHOD(netlink_socket_t, netlink_send, status_t, - private_netlink_socket_t *this, struct nlmsghdr *in, struct nlmsghdr **out, - size_t *out_len) -{ - union { - struct nlmsghdr hdr; - u_char bytes[4096]; - } response; - struct sockaddr_nl addr; - chunk_t result = chunk_empty; - int len; +#ifdef NETLINK_MSG_LOSS_HOOK +bool NETLINK_MSG_LOSS_HOOK(struct nlmsghdr *msg); +#define msg_loss_hook(msg) NETLINK_MSG_LOSS_HOOK(msg) +#else +#define msg_loss_hook(msg) FALSE +#endif - this->mutex->lock(this->mutex); +/** + * Request entry the answer for a waiting thread is collected in + */ +typedef struct { + /** Condition variable thread is waiting */ + condvar_t *condvar; + /** Array of hdrs in a multi-message response, as struct nlmsghdr* */ + array_t *hdrs; + /** All response messages received? */ + bool complete; +} entry_t; - in->nlmsg_seq = ++this->seq; - in->nlmsg_pid = getpid(); +/** + * Clean up a thread waiting entry + */ +static void destroy_entry(entry_t *entry) +{ + entry->condvar->destroy(entry->condvar); + array_destroy_function(entry->hdrs, (void*)free, NULL); + free(entry); +} - memset(&addr, 0, sizeof(addr)); - addr.nl_family = AF_NETLINK; - addr.nl_pid = 0; - addr.nl_groups = 0; +/** + * Write a Netlink message to socket + */ +static bool write_msg(private_netlink_socket_t *this, struct nlmsghdr *msg) +{ + struct sockaddr_nl addr = { + .nl_family = AF_NETLINK, + }; + int len; - if (this->names) + if (msg_loss_hook(msg)) { - DBG3(DBG_KNL, "sending %N: %b", - this->names, in->nlmsg_type, in, in->nlmsg_len); + return TRUE; } + while (TRUE) { - len = sendto(this->socket, in, in->nlmsg_len, 0, + len = sendto(this->socket, msg, msg->nlmsg_len, 0, (struct sockaddr*)&addr, sizeof(addr)); - - if (len != in->nlmsg_len) + if (len != msg->nlmsg_len) { if (errno == EINTR) { - /* interrupted, try again */ continue; } - this->mutex->unlock(this->mutex); - DBG1(DBG_KNL, "error sending to netlink socket: %s", strerror(errno)); - return FAILED; + DBG1(DBG_KNL, "netlink write error: %s", strerror(errno)); + return FALSE; } - break; + return TRUE; } +} - while (TRUE) +/** + * Read a single Netlink message from socket, return 0 on error, -1 on timeout + */ +static ssize_t read_msg(private_netlink_socket_t *this, + char buf[4096], size_t buflen, bool block) +{ + ssize_t len; + + if (block) { - len = recv(this->socket, &response, sizeof(response), 0); - if (len < 0) + fd_set set; + timeval_t tv = {}; + + FD_ZERO(&set); + FD_SET(this->socket, &set); + timeval_add_ms(&tv, this->timeout); + + if (select(this->socket + 1, &set, NULL, NULL, + this->timeout ? &tv : NULL) <= 0) { - if (errno == EINTR) + return -1; + } + } + len = recv(this->socket, buf, buflen, block ? 0 : MSG_DONTWAIT); + if (len == buflen) + { + DBG1(DBG_KNL, "netlink response exceeds buffer size"); + return 0; + } + if (len < 0) + { + if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) + { + DBG1(DBG_KNL, "netlink read error: %s", strerror(errno)); + } + return 0; + } + return len; +} + +/** + * Queue received response message + */ +static bool queue(private_netlink_socket_t *this, struct nlmsghdr *buf) +{ + struct nlmsghdr *hdr; + entry_t *entry; + uintptr_t seq; + + seq = (uintptr_t)buf->nlmsg_seq; + + this->mutex->lock(this->mutex); + entry = this->entries->get(this->entries, (void*)seq); + if (entry) + { + hdr = malloc(buf->nlmsg_len); + memcpy(hdr, buf, buf->nlmsg_len); + array_insert(entry->hdrs, ARRAY_TAIL, hdr); + if (hdr->nlmsg_type == NLMSG_DONE || !(hdr->nlmsg_flags & NLM_F_MULTI)) + { + entry->complete = TRUE; + entry->condvar->signal(entry->condvar); + } + } + else + { + DBG1(DBG_KNL, "received unknown netlink seq %u, ignored", seq); + } + this->mutex->unlock(this->mutex); + + return entry != NULL; +} + +/** + * Read and queue response message, optionally blocking, returns TRUE on timeout + */ +static bool read_and_queue(private_netlink_socket_t *this, bool block) +{ + struct nlmsghdr *hdr; + union { + struct nlmsghdr hdr; + char bytes[4096]; + } buf; + ssize_t len; + + len = read_msg(this, buf.bytes, sizeof(buf.bytes), block); + if (len == -1) + { + return TRUE; + } + if (len) + { + hdr = &buf.hdr; + while (NLMSG_OK(hdr, len)) + { + if (!queue(this, hdr)) { - DBG1(DBG_KNL, "got interrupted"); - /* interrupted, try again */ - continue; + break; } - DBG1(DBG_KNL, "error reading from netlink socket: %s", strerror(errno)); - this->mutex->unlock(this->mutex); - free(result.ptr); - return FAILED; + hdr = NLMSG_NEXT(hdr, len); } - if (!NLMSG_OK(&response.hdr, len)) + } + return FALSE; +} + +CALLBACK(watch, bool, + private_netlink_socket_t *this, int fd, watcher_event_t event) +{ + if (event == WATCHER_READ) + { + read_and_queue(this, FALSE); + } + return TRUE; +} + +/** + * Send a netlink request, try once + */ +static status_t send_once(private_netlink_socket_t *this, struct nlmsghdr *in, + uintptr_t seq, struct nlmsghdr **out, size_t *out_len) +{ + struct nlmsghdr *hdr; + chunk_t result = {}; + entry_t *entry; + + in->nlmsg_seq = seq; + in->nlmsg_pid = getpid(); + + if (this->names) + { + DBG3(DBG_KNL, "sending %N %u: %b", this->names, in->nlmsg_type, + (u_int)seq, in, in->nlmsg_len); + } + + this->mutex->lock(this->mutex); + if (!write_msg(this, in)) + { + this->mutex->unlock(this->mutex); + return FAILED; + } + + INIT(entry, + .condvar = condvar_create(CONDVAR_TYPE_DEFAULT), + .hdrs = array_create(0, 0), + ); + this->entries->put(this->entries, (void*)seq, entry); + + while (!entry->complete) + { + if (this->parallel && + lib->watcher->get_state(lib->watcher) == WATCHER_RUNNING) { - DBG1(DBG_KNL, "received corrupted netlink message"); - this->mutex->unlock(this->mutex); - free(result.ptr); - return FAILED; + if (this->timeout) + { + if (entry->condvar->timed_wait(entry->condvar, this->mutex, + this->timeout)) + { + break; + } + } + else + { + entry->condvar->wait(entry->condvar, this->mutex); + } } - if (response.hdr.nlmsg_seq != this->seq) - { - DBG1(DBG_KNL, "received invalid netlink sequence number"); - if (response.hdr.nlmsg_seq < this->seq) + else + { /* During (de-)initialization, no watcher thread is active. + * collect responses ourselves. */ + if (read_and_queue(this, TRUE)) { - continue; + break; } - this->mutex->unlock(this->mutex); - free(result.ptr); - return FAILED; } + } + this->entries->remove(this->entries, (void*)seq); - result = chunk_cat("mc", result, chunk_create(response.bytes, len)); + this->mutex->unlock(this->mutex); - /* NLM_F_MULTI flag does not seem to be set correctly, we use sequence - * numbers to detect multi header messages */ - len = recv(this->socket, &response.hdr, sizeof(response.hdr), - MSG_PEEK | MSG_DONTWAIT); - if (len == sizeof(response.hdr) && response.hdr.nlmsg_seq == this->seq) + if (!entry->complete) + { /* timeout */ + destroy_entry(entry); + return OUT_OF_RES; + } + + while (array_remove(entry->hdrs, ARRAY_HEAD, &hdr)) + { + if (this->names) { - /* seems to be multipart */ - continue; + DBG3(DBG_KNL, "received %N %u: %b", this->names, hdr->nlmsg_type, + hdr->nlmsg_seq, hdr, hdr->nlmsg_len); } - break; + result = chunk_cat("mm", result, + chunk_create((char*)hdr, hdr->nlmsg_len)); } + destroy_entry(entry); *out_len = result.len; *out = (struct nlmsghdr*)result.ptr; - this->mutex->unlock(this->mutex); - return SUCCESS; } +/** + * Ignore errors for message types that might have completed previously + */ +static void ignore_retransmit_error(private_netlink_socket_t *this, + struct nlmsgerr *err, int type) +{ + switch (err->error) + { + case -EEXIST: + switch (this->protocol) + { + case NETLINK_XFRM: + switch (type) + { + case XFRM_MSG_NEWPOLICY: + case XFRM_MSG_NEWSA: + err->error = 0; + break; + } + break; + case NETLINK_ROUTE: + switch (type) + { + case RTM_NEWADDR: + case RTM_NEWLINK: + case RTM_NEWNEIGH: + case RTM_NEWROUTE: + case RTM_NEWRULE: + err->error = 0; + break; + } + break; + } + break; + case -ENOENT: + switch (this->protocol) + { + case NETLINK_XFRM: + switch (type) + { + case XFRM_MSG_DELPOLICY: + case XFRM_MSG_DELSA: + err->error = 0; + break; + } + break; + case NETLINK_ROUTE: + switch (type) + { + case RTM_DELADDR: + case RTM_DELLINK: + case RTM_DELNEIGH: + case RTM_DELROUTE: + case RTM_DELRULE: + err->error = 0; + break; + } + break; + } + break; + } +} + +METHOD(netlink_socket_t, netlink_send, status_t, + private_netlink_socket_t *this, struct nlmsghdr *in, struct nlmsghdr **out, + size_t *out_len) +{ + uintptr_t seq; + u_int try; + + seq = ref_get(&this->seq); + + for (try = 0; try <= this->retries; ++try) + { + struct nlmsghdr *hdr; + status_t status; + size_t len; + + if (try > 0) + { + DBG1(DBG_KNL, "retransmitting Netlink request (%u/%u)", + try, this->retries); + } + status = send_once(this, in, seq, &hdr, &len); + switch (status) + { + case SUCCESS: + break; + case OUT_OF_RES: + continue; + default: + return status; + } + if (hdr->nlmsg_type == NLMSG_ERROR) + { + struct nlmsgerr* err; + + err = NLMSG_DATA(hdr); + if (err->error == -EBUSY) + { + free(hdr); + try--; + continue; + } + if (this->ignore_retransmit_errors && try > 0) + { + ignore_retransmit_error(this, err, in->nlmsg_type); + } + } + *out = hdr; + *out_len = len; + return SUCCESS; + } + DBG1(DBG_KNL, "Netlink request timed out after %u retransmits", + this->retries); + return OUT_OF_RES; +} + METHOD(netlink_socket_t, netlink_send_ack, status_t, private_netlink_socket_t *this, struct nlmsghdr *in) { @@ -221,8 +534,13 @@ METHOD(netlink_socket_t, destroy, void, { if (this->socket != -1) { + if (this->parallel) + { + lib->watcher->remove(lib->watcher, this->socket); + } close(this->socket); } + this->entries->destroy(this->entries); this->mutex->destroy(this->mutex); free(this); } @@ -230,7 +548,8 @@ METHOD(netlink_socket_t, destroy, void, /** * Described in header. */ -netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names) +netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names, + bool parallel) { private_netlink_socket_t *this; struct sockaddr_nl addr = { @@ -244,9 +563,19 @@ netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names) .destroy = _destroy, }, .seq = 200, - .mutex = mutex_create(MUTEX_TYPE_DEFAULT), + .mutex = mutex_create(MUTEX_TYPE_RECURSIVE), .socket = socket(AF_NETLINK, SOCK_RAW, protocol), + .entries = hashtable_create(hashtable_hash_ptr, hashtable_equals_ptr, 4), + .protocol = protocol, .names = names, + .timeout = lib->settings->get_int(lib->settings, + "%s.plugins.kernel-netlink.timeout", 0, lib->ns), + .retries = lib->settings->get_int(lib->settings, + "%s.plugins.kernel-netlink.retries", 0, lib->ns), + .ignore_retransmit_errors = lib->settings->get_bool(lib->settings, + "%s.plugins.kernel-netlink.ignore_retransmit_errors", + FALSE, lib->ns), + .parallel = parallel, ); if (this->socket == -1) @@ -261,6 +590,10 @@ netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names) destroy(this); return NULL; } + if (this->parallel) + { + lib->watcher->add(lib->watcher, this->socket, WATCHER_READ, watch, this); + } return &this->public; } diff --git a/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.h b/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.h index 069f746d1..66682907d 100644 --- a/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.h +++ b/src/libhydra/plugins/kernel_netlink/kernel_netlink_shared.h @@ -66,8 +66,10 @@ struct netlink_socket_t { * * @param protocol protocol type (e.g. NETLINK_XFRM or NETLINK_ROUTE) * @param names optional enum names for Netlink messages + * @param parallel support parallel queries on this Netlink socket */ -netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names); +netlink_socket_t *netlink_socket_create(int protocol, enum_name_t *names, + bool parallel); /** * Creates an rtattr and adds it to the given netlink message. diff --git a/src/libhydra/plugins/kernel_netlink/suites/test_socket.c b/src/libhydra/plugins/kernel_netlink/suites/test_socket.c new file mode 100644 index 000000000..3e8facd0a --- /dev/null +++ b/src/libhydra/plugins/kernel_netlink/suites/test_socket.c @@ -0,0 +1,302 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include <test_suite.h> + +#include <threading/thread.h> + +#include "../kernel_netlink_shared.h" + +/** + * Netlink message drop configuration + */ +static int drop_interval = 0; + +/** + * Netlink message drop hook + */ +bool netlink_msg_loss(struct nlmsghdr *hdr) +{ + static refcount_t i; + + if (drop_interval) + { + return ref_get(&i) % drop_interval == drop_interval - 1; + } + return FALSE; +} + +START_TEST(test_echo) +{ + netlink_socket_t *s; + struct nlmsghdr *out; + struct rtmsg *msg; + char dst[] = { + 127,0,0,1 + }; + size_t len; + netlink_buf_t request = { + .hdr = { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)), + .nlmsg_flags = NLM_F_REQUEST, + .nlmsg_type = RTM_GETROUTE, + }, + }; + + msg = NLMSG_DATA(&request.hdr); + msg->rtm_family = AF_INET; + netlink_add_attribute(&request.hdr, RTA_DST, + chunk_from_thing(dst), sizeof(request)); + + s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0); + + ck_assert(s->send(s, &request.hdr, &out, &len) == SUCCESS); + ck_assert_int_eq(out->nlmsg_type, RTM_NEWROUTE); + free(out); + s->destroy(s); +} +END_TEST + +START_TEST(test_echo_dump) +{ + netlink_socket_t *s; + struct nlmsghdr *out, *current; + struct rtgenmsg *msg; + size_t len; + netlink_buf_t request = { + .hdr = { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)), + .nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH | NLM_F_ROOT, + .nlmsg_type = RTM_GETLINK, + }, + }; + + s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0); + msg = NLMSG_DATA(&request.hdr); + msg->rtgen_family = AF_UNSPEC; + + ck_assert(s->send(s, &request.hdr, &out, &len) == SUCCESS); + current = out; + while (TRUE) + { + ck_assert(NLMSG_OK(current, len)); + if (current->nlmsg_type == NLMSG_DONE) + { + break; + } + ck_assert_int_eq(current->nlmsg_type, RTM_NEWLINK); + current = NLMSG_NEXT(current, len); + } + free(out); + s->destroy(s); +} +END_TEST + +CALLBACK(stress, void*, + netlink_socket_t *s) +{ + struct nlmsghdr *out; + struct rtmsg *msg; + char dst[] = { + 127,0,0,1 + }; + size_t len; + int i; + netlink_buf_t request = { + .hdr = { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)), + .nlmsg_flags = NLM_F_REQUEST, + .nlmsg_type = RTM_GETROUTE, + }, + }; + + for (i = 0; i < 10; i++) + { + msg = NLMSG_DATA(&request.hdr); + msg->rtm_family = AF_INET; + netlink_add_attribute(&request.hdr, RTA_DST, + chunk_from_thing(dst), sizeof(request)); + + ck_assert(s->send(s, &request.hdr, &out, &len) == SUCCESS); + ck_assert_int_eq(out->nlmsg_type, RTM_NEWROUTE); + free(out); + } + return NULL; +} + +CALLBACK(stress_dump, void*, + netlink_socket_t *s) +{ + struct nlmsghdr *out, *current; + struct rtgenmsg *msg; + size_t len; + int i; + netlink_buf_t request = { + .hdr = { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)), + .nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH | NLM_F_ROOT, + .nlmsg_type = RTM_GETLINK, + }, + }; + + msg = NLMSG_DATA(&request.hdr); + msg->rtgen_family = AF_UNSPEC; + + for (i = 0; i < 10; i++) + { + ck_assert(s->send(s, &request.hdr, &out, &len) == SUCCESS); + current = out; + while (TRUE) + { + ck_assert(NLMSG_OK(current, len)); + if (current->nlmsg_type == NLMSG_DONE) + { + break; + } + ck_assert_int_eq(current->nlmsg_type, RTM_NEWLINK); + current = NLMSG_NEXT(current, len); + } + free(out); + } + return NULL; +} + +START_TEST(test_stress) +{ + thread_t *threads[10]; + netlink_socket_t *s; + int i; + + s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0); + for (i = 0; i < countof(threads); i++) + { + threads[i] = thread_create(stress, s); + } + for (i = 0; i < countof(threads); i++) + { + threads[i]->join(threads[i]); + } + s->destroy(s); +} +END_TEST + +START_TEST(test_stress_dump) +{ + thread_t *threads[10]; + netlink_socket_t *s; + int i; + + s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0); + for (i = 0; i < countof(threads); i++) + { + threads[i] = thread_create(stress_dump, s); + } + for (i = 0; i < countof(threads); i++) + { + threads[i]->join(threads[i]); + } + s->destroy(s); +} +END_TEST + +START_TEST(test_retransmit_success) +{ + netlink_socket_t *s; + struct nlmsghdr *out; + struct rtgenmsg *msg; + size_t len; + netlink_buf_t request = { + .hdr = { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)), + .nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH | NLM_F_ROOT, + .nlmsg_type = RTM_GETLINK, + }, + }; + + drop_interval = 2; + + lib->settings->set_int(lib->settings, + "%s.plugins.kernel-netlink.timeout", 100, lib->ns); + lib->settings->set_int(lib->settings, + "%s.plugins.kernel-netlink.retries", 1, lib->ns); + + s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0); + msg = NLMSG_DATA(&request.hdr); + msg->rtgen_family = AF_UNSPEC; + + ck_assert(s->send(s, &request.hdr, &out, &len) == SUCCESS); + free(out); + s->destroy(s); + + drop_interval = 0; +} +END_TEST + +START_TEST(test_retransmit_fail) +{ + netlink_socket_t *s; + struct nlmsghdr *out; + struct rtgenmsg *msg; + size_t len; + netlink_buf_t request = { + .hdr = { + .nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)), + .nlmsg_flags = NLM_F_REQUEST | NLM_F_MATCH | NLM_F_ROOT, + .nlmsg_type = RTM_GETLINK, + }, + }; + + drop_interval = 1; + + lib->settings->set_int(lib->settings, + "%s.plugins.kernel-netlink.timeout", 50, lib->ns); + lib->settings->set_int(lib->settings, + "%s.plugins.kernel-netlink.retries", 3, lib->ns); + + s = netlink_socket_create(NETLINK_ROUTE, NULL, _i != 0); + msg = NLMSG_DATA(&request.hdr); + msg->rtgen_family = AF_UNSPEC; + + ck_assert(s->send(s, &request.hdr, &out, &len) == OUT_OF_RES); + s->destroy(s); + + drop_interval = 0; +} +END_TEST + +Suite *socket_suite_create() +{ + Suite *s; + TCase *tc; + + s = suite_create("netlink socket"); + + tc = tcase_create("echo"); + tcase_add_loop_test(tc, test_echo, 0, 2); + tcase_add_loop_test(tc, test_echo_dump, 0, 2); + suite_add_tcase(s, tc); + + tc = tcase_create("stress"); + tcase_add_loop_test(tc, test_stress, 0, 2); + tcase_add_loop_test(tc, test_stress_dump, 0, 2); + suite_add_tcase(s, tc); + + tc = tcase_create("retransmit"); + tcase_add_loop_test(tc, test_retransmit_success, 0, 2); + tcase_add_loop_test(tc, test_retransmit_fail, 0, 2); + suite_add_tcase(s, tc); + + return s; +} diff --git a/src/libhydra/plugins/kernel_netlink/tests.c b/src/libhydra/plugins/kernel_netlink/tests.c new file mode 100644 index 000000000..136b34d29 --- /dev/null +++ b/src/libhydra/plugins/kernel_netlink/tests.c @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include <test_runner.h> + +#include <hydra.h> + +/* declare test suite constructors */ +#define TEST_SUITE(x) test_suite_t* x(); +#include "tests.h" +#undef TEST_SUITE + +static test_configuration_t tests[] = { +#define TEST_SUITE(x) \ + { .suite = x, }, +#include "tests.h" + { .suite = NULL, } +}; + +static bool test_runner_init(bool init) +{ + if (init) + { + dbg_default_set_level(0); + lib->processor->set_threads(lib->processor, 8); + dbg_default_set_level(1); + } + else + { + lib->processor->set_threads(lib->processor, 0); + lib->processor->cancel(lib->processor); + } + return TRUE; +} + +int main(int argc, char *argv[]) +{ + return test_runner_run("kernel-netlink", tests, test_runner_init); +} diff --git a/src/libhydra/plugins/kernel_netlink/tests.h b/src/libhydra/plugins/kernel_netlink/tests.h new file mode 100644 index 000000000..2b6715a78 --- /dev/null +++ b/src/libhydra/plugins/kernel_netlink/tests.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +TEST_SUITE(socket_suite_create) diff --git a/src/libhydra/plugins/kernel_pfkey/Makefile.in b/src/libhydra/plugins/kernel_pfkey/Makefile.in index 821ad7710..177d2f23f 100644 --- a/src/libhydra/plugins/kernel_pfkey/Makefile.in +++ b/src/libhydra/plugins/kernel_pfkey/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c index 00ab5ab5a..3b32ba553 100644 --- a/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c +++ b/src/libhydra/plugins/kernel_pfkey/kernel_pfkey_ipsec.c @@ -1296,7 +1296,8 @@ static void process_expire(private_kernel_pfkey_ipsec_t *this, { pfkey_msg_t response; u_int8_t protocol; - u_int32_t spi, reqid; + u_int32_t spi; + host_t *dst; bool hard; DBG2(DBG_KNL, "received an SADB_EXPIRE"); @@ -1309,18 +1310,18 @@ static void process_expire(private_kernel_pfkey_ipsec_t *this, protocol = satype2proto(msg->sadb_msg_satype); spi = response.sa->sadb_sa_spi; - reqid = response.x_sa2->sadb_x_sa2_reqid; hard = response.lft_hard != NULL; - if (protocol != IPPROTO_ESP && protocol != IPPROTO_AH) + if (protocol == IPPROTO_ESP || protocol == IPPROTO_AH) { - DBG2(DBG_KNL, "ignoring SADB_EXPIRE for SA with SPI %.8x and " - "reqid {%u} which is not a CHILD_SA", ntohl(spi), reqid); - return; + dst = host_create_from_sockaddr((sockaddr_t*)(response.dst + 1)); + if (dst) + { + hydra->kernel_interface->expire(hydra->kernel_interface, protocol, + spi, dst, hard); + dst->destroy(dst); + } } - - hydra->kernel_interface->expire(hydra->kernel_interface, reqid, protocol, - spi, hard); } #ifdef SADB_X_MIGRATE @@ -1387,9 +1388,9 @@ static void process_mapping(private_kernel_pfkey_ipsec_t *this, struct sadb_msg* msg) { pfkey_msg_t response; - u_int32_t spi, reqid; + u_int32_t spi; sockaddr_t *sa; - host_t *host; + host_t *dst, *new; DBG2(DBG_KNL, "received an SADB_X_NAT_T_NEW_MAPPING"); @@ -1407,7 +1408,6 @@ static void process_mapping(private_kernel_pfkey_ipsec_t *this, } spi = response.sa->sadb_sa_spi; - reqid = response.x_sa2->sadb_x_sa2_reqid; if (satype2proto(msg->sadb_msg_satype) != IPPROTO_ESP) { @@ -1415,6 +1415,7 @@ static void process_mapping(private_kernel_pfkey_ipsec_t *this, } sa = (sockaddr_t*)(response.dst + 1); + dst = host_create_from_sockaddr(sa); switch (sa->sa_family) { case AF_INET: @@ -1432,12 +1433,16 @@ static void process_mapping(private_kernel_pfkey_ipsec_t *this, default: break; } - - host = host_create_from_sockaddr(sa); - if (host) + if (dst) { - hydra->kernel_interface->mapping(hydra->kernel_interface, reqid, - spi, host); + new = host_create_from_sockaddr(sa); + if (new) + { + hydra->kernel_interface->mapping(hydra->kernel_interface, + IPPROTO_ESP, spi, dst, new); + new->destroy(new); + } + dst->destroy(dst); } } #endif /*SADB_X_NAT_T_NEW_MAPPING*/ @@ -1518,11 +1523,10 @@ static bool receive_events(private_kernel_pfkey_ipsec_t *this, int fd, static status_t get_spi_internal(private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst, u_int8_t proto, u_int32_t min, u_int32_t max, - u_int32_t reqid, u_int32_t *spi) + u_int32_t *spi) { unsigned char request[PFKEY_BUFFER_SIZE]; struct sadb_msg *msg, *out; - struct sadb_x_sa2 *sa2; struct sadb_spirange *range; pfkey_msg_t response; u_int32_t received_spi = 0; @@ -1536,12 +1540,6 @@ static status_t get_spi_internal(private_kernel_pfkey_ipsec_t *this, msg->sadb_msg_satype = proto2satype(proto); msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); - sa2 = (struct sadb_x_sa2*)PFKEY_EXT_ADD_NEXT(msg); - sa2->sadb_x_sa2_exttype = SADB_X_EXT_SA2; - sa2->sadb_x_sa2_len = PFKEY_LEN(sizeof(struct sadb_spirange)); - sa2->sadb_x_sa2_reqid = reqid; - PFKEY_EXT_ADD(msg, sa2); - add_addr_ext(msg, src, SADB_EXT_ADDRESS_SRC, 0, 0, FALSE); add_addr_ext(msg, dst, SADB_EXT_ADDRESS_DST, 0, 0, FALSE); @@ -1577,39 +1575,37 @@ static status_t get_spi_internal(private_kernel_pfkey_ipsec_t *this, METHOD(kernel_ipsec_t, get_spi, status_t, private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst, - u_int8_t protocol, u_int32_t reqid, u_int32_t *spi) + u_int8_t protocol, u_int32_t *spi) { - DBG2(DBG_KNL, "getting SPI for reqid {%u}", reqid); - if (get_spi_internal(this, src, dst, protocol, - 0xc0000000, 0xcFFFFFFF, reqid, spi) != SUCCESS) + 0xc0000000, 0xcFFFFFFF, spi) != SUCCESS) { - DBG1(DBG_KNL, "unable to get SPI for reqid {%u}", reqid); + DBG1(DBG_KNL, "unable to get SPI"); return FAILED; } - DBG2(DBG_KNL, "got SPI %.8x for reqid {%u}", ntohl(*spi), reqid); + DBG2(DBG_KNL, "got SPI %.8x", ntohl(*spi)); return SUCCESS; } METHOD(kernel_ipsec_t, get_cpi, status_t, private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst, - u_int32_t reqid, u_int16_t *cpi) + u_int16_t *cpi) { u_int32_t received_spi = 0; - DBG2(DBG_KNL, "getting CPI for reqid {%u}", reqid); + DBG2(DBG_KNL, "getting CPI"); if (get_spi_internal(this, src, dst, IPPROTO_COMP, - 0x100, 0xEFFF, reqid, &received_spi) != SUCCESS) + 0x100, 0xEFFF, &received_spi) != SUCCESS) { - DBG1(DBG_KNL, "unable to get CPI for reqid {%u}", reqid); + DBG1(DBG_KNL, "unable to get CPI"); return FAILED; } *cpi = htons((u_int16_t)ntohl(received_spi)); - DBG2(DBG_KNL, "got CPI %.4x for reqid {%u}", ntohs(*cpi), reqid); + DBG2(DBG_KNL, "got CPI %.4x", ntohs(*cpi)); return SUCCESS; } @@ -1619,8 +1615,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key, u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi, u_int32_t replay_window, - bool initiator, bool encap, bool esn, bool inbound, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts) + bool initiator, bool encap, bool esn, bool inbound, bool update, + linked_list_t *src_ts, linked_list_t *dst_ts) { unsigned char request[PFKEY_BUFFER_SIZE]; struct sadb_msg *msg, *out; @@ -1638,12 +1634,29 @@ METHOD(kernel_ipsec_t, add_sa, status_t, add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, mark, tfc, &lft, ENCR_UNDEFINED, chunk_empty, AUTH_UNDEFINED, chunk_empty, mode, ipcomp, 0, 0, FALSE, FALSE, FALSE, inbound, - NULL, NULL); + update, NULL, NULL); ipcomp = IPCOMP_NONE; /* use transport mode ESP SA, IPComp uses tunnel mode */ mode = MODE_TRANSPORT; } + if (update) + { + /* As we didn't know the reqid during SPI allocation, we used reqid + * zero. Unfortunately we can't SADB_UPDATE to the new reqid, hence we + * have to delete the SPI allocation state manually. The reqid + * selector does not count for that, therefore we have to delete + * that state before installing the new SA to avoid deleting the + * the new state after installing it. */ + mark_t zeromark = {0, 0}; + + if (this->public.interface.del_sa(&this->public.interface, + src, dst, spi, protocol, 0, zeromark) != SUCCESS) + { + DBG1(DBG_KNL, "deleting SPI allocation SA failed"); + } + } + memset(&request, 0, sizeof(request)); DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u}", @@ -1651,7 +1664,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t, msg = (struct sadb_msg*)request; msg->sadb_msg_version = PF_KEY_V2; - msg->sadb_msg_type = inbound ? SADB_UPDATE : SADB_ADD; + msg->sadb_msg_type = SADB_ADD; msg->sadb_msg_satype = proto2satype(protocol); msg->sadb_msg_len = PFKEY_LEN(sizeof(struct sadb_msg)); @@ -1680,7 +1693,13 @@ METHOD(kernel_ipsec_t, add_sa, status_t, } else { + /* Linux interprets sadb_sa_replay as number of packets/bits in the + * replay window, whereas on BSD it's the size of the window in bytes */ +#ifdef __linux__ sa->sadb_sa_replay = min(replay_window, 32); +#else + sa->sadb_sa_replay = (replay_window + 7) / 8; +#endif sa->sadb_sa_auth = lookup_algorithm(INTEGRITY_ALGORITHM, int_alg); sa->sadb_sa_encrypt = lookup_algorithm(ENCRYPTION_ALGORITHM, enc_alg); } @@ -2969,6 +2988,7 @@ kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create() { private_kernel_pfkey_ipsec_t *this; bool register_for_events = TRUE; + int rcv_buffer; INIT(this, .public = { @@ -3025,6 +3045,18 @@ kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create() return NULL; } + rcv_buffer = lib->settings->get_int(lib->settings, + "%s.plugins.kernel-pfkey.events_buffer_size", 0, lib->ns); + if (rcv_buffer > 0) + { + if (setsockopt(this->socket_events, SOL_SOCKET, SO_RCVBUF, + &rcv_buffer, sizeof(rcv_buffer)) == -1) + { + DBG1(DBG_KNL, "unable to set receive buffer size on PF_KEY " + "event socket: %s", strerror(errno)); + } + } + /* register the event socket */ if (register_pfkey_socket(this, SADB_SATYPE_ESP) != SUCCESS || register_pfkey_socket(this, SADB_SATYPE_AH) != SUCCESS) diff --git a/src/libhydra/plugins/kernel_pfroute/Makefile.in b/src/libhydra/plugins/kernel_pfroute/Makefile.in index 662f2fd7d..9f676d21d 100644 --- a/src/libhydra/plugins/kernel_pfroute/Makefile.in +++ b/src/libhydra/plugins/kernel_pfroute/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c b/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c index 26fae0d6b..0f7802270 100644 --- a/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c +++ b/src/libhydra/plugins/kernel_pfroute/kernel_pfroute_net.c @@ -830,6 +830,15 @@ static void process_link(private_kernel_pfroute_net_t *this, DBG1(DBG_KNL, "interface %s deactivated", iface->ifname); } } +#ifdef __APPLE__ + /* There seems to be a race condition on 10.10, where we get + * the RTM_IFINFO, but getifaddrs() does not return the virtual + * IP installed on a tun device, but we also don't get a + * RTM_NEWADDR. We therefore could miss the new address, letting + * virtual IP installation fail. Delaying getifaddrs() helps, + * but is obviously not a clean fix. */ + usleep(50000); +#endif iface->flags = msg->ifm_flags; repopulate_iface(this, iface); found = TRUE; diff --git a/src/libhydra/tests/Makefile.am b/src/libhydra/tests/Makefile.am new file mode 100644 index 000000000..5acd5c28c --- /dev/null +++ b/src/libhydra/tests/Makefile.am @@ -0,0 +1,18 @@ +TESTS = hydra_tests + +check_PROGRAMS = $(TESTS) + +hydra_tests_SOURCES = \ + hydra_tests.h hydra_tests.c + +hydra_tests_CFLAGS = \ + -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libstrongswan/tests \ + @COVERAGE_CFLAGS@ + +hydra_tests_LDFLAGS = @COVERAGE_LDFLAGS@ +hydra_tests_LDADD = \ + $(top_builddir)/src/libhydra/libhydra.la \ + $(top_builddir)/src/libstrongswan/libstrongswan.la \ + $(top_builddir)/src/libstrongswan/tests/libtest.la diff --git a/src/libhydra/tests/Makefile.in b/src/libhydra/tests/Makefile.in new file mode 100644 index 000000000..1fa889d67 --- /dev/null +++ b/src/libhydra/tests/Makefile.in @@ -0,0 +1,839 @@ +# Makefile.in generated by automake 1.14.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +TESTS = hydra_tests$(EXEEXT) +check_PROGRAMS = $(am__EXEEXT_1) +subdir = src/libhydra/tests +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ + $(top_srcdir)/m4/config/ltoptions.m4 \ + $(top_srcdir)/m4/config/ltsugar.m4 \ + $(top_srcdir)/m4/config/ltversion.m4 \ + $(top_srcdir)/m4/config/lt~obsolete.m4 \ + $(top_srcdir)/m4/macros/split-package-version.m4 \ + $(top_srcdir)/m4/macros/with.m4 \ + $(top_srcdir)/m4/macros/enable-disable.m4 \ + $(top_srcdir)/m4/macros/add-plugin.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__EXEEXT_1 = hydra_tests$(EXEEXT) +am_hydra_tests_OBJECTS = hydra_tests-hydra_tests.$(OBJEXT) +hydra_tests_OBJECTS = $(am_hydra_tests_OBJECTS) +hydra_tests_DEPENDENCIES = $(top_builddir)/src/libhydra/libhydra.la \ + $(top_builddir)/src/libstrongswan/libstrongswan.la \ + $(top_builddir)/src/libstrongswan/tests/libtest.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +hydra_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(hydra_tests_CFLAGS) \ + $(CFLAGS) $(hydra_tests_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(hydra_tests_SOURCES) +DIST_SOURCES = $(hydra_tests_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red='[0;31m'; \ + grn='[0;32m'; \ + lgn='[1;32m'; \ + blu='[1;34m'; \ + mgn='[0;35m'; \ + brg='[1m'; \ + std='[m'; \ + fi; \ +} +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BFDLIB = @BFDLIB@ +BTLIB = @BTLIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +COVERAGE_CFLAGS = @COVERAGE_CFLAGS@ +COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLIB = @DLLIB@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GEM = @GEM@ +GENHTML = @GENHTML@ +GPERF = @GPERF@ +GPRBUILD = @GPRBUILD@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQLCFLAG = @MYSQLCFLAG@ +MYSQLCONFIG = @MYSQLCONFIG@ +MYSQLLIB = @MYSQLLIB@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_LIB = @OPENSSL_LIB@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@ +PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@ +PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@ +PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ +PTHREADLIB = @PTHREADLIB@ +PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ +RANLIB = @RANLIB@ +RTLIB = @RTLIB@ +RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ +RUBYINCLUDE = @RUBYINCLUDE@ +RUBYLIB = @RUBYLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ +STRIP = @STRIP@ +UNWINDLIB = @UNWINDLIB@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +aikgen_plugins = @aikgen_plugins@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ +clearsilver_LIBS = @clearsilver_LIBS@ +cmd_plugins = @cmd_plugins@ +datadir = @datadir@ +datarootdir = @datarootdir@ +dbusservicedir = @dbusservicedir@ +dev_headers = @dev_headers@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +fips_mode = @fips_mode@ +gtk_CFLAGS = @gtk_CFLAGS@ +gtk_LIBS = @gtk_LIBS@ +h_plugins = @h_plugins@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +imcvdir = @imcvdir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ +ipsecdir = @ipsecdir@ +ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ +ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ +linux_headers = @linux_headers@ +localedir = @localedir@ +localstatedir = @localstatedir@ +maemo_CFLAGS = @maemo_CFLAGS@ +maemo_LIBS = @maemo_LIBS@ +manager_plugins = @manager_plugins@ +mandir = @mandir@ +medsrv_plugins = @medsrv_plugins@ +mkdir_p = @mkdir_p@ +nm_CFLAGS = @nm_CFLAGS@ +nm_LIBS = @nm_LIBS@ +nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ +oldincludedir = @oldincludedir@ +pcsclite_CFLAGS = @pcsclite_CFLAGS@ +pcsclite_LIBS = @pcsclite_LIBS@ +pdfdir = @pdfdir@ +piddir = @piddir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +pki_plugins = @pki_plugins@ +plugindir = @plugindir@ +pool_plugins = @pool_plugins@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +random_device = @random_device@ +resolv_conf = @resolv_conf@ +routing_table = @routing_table@ +routing_table_prio = @routing_table_prio@ +s_plugins = @s_plugins@ +sbindir = @sbindir@ +scepclient_plugins = @scepclient_plugins@ +scripts_plugins = @scripts_plugins@ +sharedstatedir = @sharedstatedir@ +soup_CFLAGS = @soup_CFLAGS@ +soup_LIBS = @soup_LIBS@ +srcdir = @srcdir@ +starter_plugins = @starter_plugins@ +strongswan_conf = @strongswan_conf@ +strongswan_options = @strongswan_options@ +swanctldir = @swanctldir@ +sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ +systemdsystemunitdir = @systemdsystemunitdir@ +t_plugins = @t_plugins@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +urandom_device = @urandom_device@ +xml_CFLAGS = @xml_CFLAGS@ +xml_LIBS = @xml_LIBS@ +hydra_tests_SOURCES = \ + hydra_tests.h hydra_tests.c + +hydra_tests_CFLAGS = \ + -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libstrongswan/tests \ + @COVERAGE_CFLAGS@ + +hydra_tests_LDFLAGS = @COVERAGE_LDFLAGS@ +hydra_tests_LDADD = \ + $(top_builddir)/src/libhydra/libhydra.la \ + $(top_builddir)/src/libstrongswan/libstrongswan.la \ + $(top_builddir)/src/libstrongswan/tests/libtest.la + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libhydra/tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libhydra/tests/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +hydra_tests$(EXEEXT): $(hydra_tests_OBJECTS) $(hydra_tests_DEPENDENCIES) $(EXTRA_hydra_tests_DEPENDENCIES) + @rm -f hydra_tests$(EXEEXT) + $(AM_V_CCLD)$(hydra_tests_LINK) $(hydra_tests_OBJECTS) $(hydra_tests_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hydra_tests-hydra_tests.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +hydra_tests-hydra_tests.o: hydra_tests.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hydra_tests_CFLAGS) $(CFLAGS) -MT hydra_tests-hydra_tests.o -MD -MP -MF $(DEPDIR)/hydra_tests-hydra_tests.Tpo -c -o hydra_tests-hydra_tests.o `test -f 'hydra_tests.c' || echo '$(srcdir)/'`hydra_tests.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/hydra_tests-hydra_tests.Tpo $(DEPDIR)/hydra_tests-hydra_tests.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hydra_tests.c' object='hydra_tests-hydra_tests.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hydra_tests_CFLAGS) $(CFLAGS) -c -o hydra_tests-hydra_tests.o `test -f 'hydra_tests.c' || echo '$(srcdir)/'`hydra_tests.c + +hydra_tests-hydra_tests.obj: hydra_tests.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hydra_tests_CFLAGS) $(CFLAGS) -MT hydra_tests-hydra_tests.obj -MD -MP -MF $(DEPDIR)/hydra_tests-hydra_tests.Tpo -c -o hydra_tests-hydra_tests.obj `if test -f 'hydra_tests.c'; then $(CYGPATH_W) 'hydra_tests.c'; else $(CYGPATH_W) '$(srcdir)/hydra_tests.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/hydra_tests-hydra_tests.Tpo $(DEPDIR)/hydra_tests-hydra_tests.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hydra_tests.c' object='hydra_tests-hydra_tests.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hydra_tests_CFLAGS) $(CFLAGS) -c -o hydra_tests-hydra_tests.obj `if test -f 'hydra_tests.c'; then $(CYGPATH_W) 'hydra_tests.c'; else $(CYGPATH_W) '$(srcdir)/hydra_tests.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libhydra/tests/hydra_tests.c b/src/libhydra/tests/hydra_tests.c new file mode 100644 index 000000000..90abd8369 --- /dev/null +++ b/src/libhydra/tests/hydra_tests.c @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2014 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include <test_runner.h> +#include <hydra.h> + +/* declare test suite constructors */ +#define TEST_SUITE(x) test_suite_t* x(); +#define TEST_SUITE_DEPEND(x, ...) TEST_SUITE(x) +#include "hydra_tests.h" +#undef TEST_SUITE +#undef TEST_SUITE_DEPEND + +static test_configuration_t tests[] = { +#define TEST_SUITE(x) \ + { .suite = x, }, +#define TEST_SUITE_DEPEND(x, type, args) \ + { .suite = x, .feature = PLUGIN_DEPENDS(type, args) }, +#include "hydra_tests.h" + { .suite = NULL, } +}; + +static bool test_runner_init(bool init) +{ + if (init) + { + libhydra_init(); + } + else + { + lib->processor->set_threads(lib->processor, 0); + lib->processor->cancel(lib->processor); + libhydra_deinit(); + } + return TRUE; +} + +int main(int argc, char *argv[]) +{ + return test_runner_run("libhydra", tests, test_runner_init); +} diff --git a/src/libhydra/tests/hydra_tests.h b/src/libhydra/tests/hydra_tests.h new file mode 100644 index 000000000..6b213d026 --- /dev/null +++ b/src/libhydra/tests/hydra_tests.h @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2014 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ diff --git a/src/libimcv/Makefile.am b/src/libimcv/Makefile.am index d9a5cd50d..a61382723 100644 --- a/src/libimcv/Makefile.am +++ b/src/libimcv/Makefile.am @@ -127,7 +127,8 @@ imv_policy_manager_SOURCES = \ imv/imv_policy_manager.c \ imv/imv_policy_manager_usage.h imv/imv_policy_manager_usage.c imv_policy_manager_LDADD = \ - $(top_builddir)/src/libstrongswan/libstrongswan.la + $(top_builddir)/src/libstrongswan/libstrongswan.la \ + $(top_builddir)/src/libtncif/libtncif.la #imv/imv_policy_manager.o : $(top_builddir)/config.status SUBDIRS = . diff --git a/src/libimcv/Makefile.in b/src/libimcv/Makefile.in index 239e62a17..03778a22c 100644 --- a/src/libimcv/Makefile.in +++ b/src/libimcv/Makefile.in @@ -237,7 +237,8 @@ am_imv_policy_manager_OBJECTS = imv/imv_policy_manager.$(OBJEXT) \ imv/imv_policy_manager_usage.$(OBJEXT) imv_policy_manager_OBJECTS = $(am_imv_policy_manager_OBJECTS) imv_policy_manager_DEPENDENCIES = \ - $(top_builddir)/src/libstrongswan/libstrongswan.la + $(top_builddir)/src/libstrongswan/libstrongswan.la \ + $(top_builddir)/src/libtncif/libtncif.la SCRIPTS = $(ipsec_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) @@ -395,6 +396,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -455,10 +457,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -532,6 +536,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ @@ -708,7 +714,8 @@ imv_policy_manager_SOURCES = \ imv/imv_policy_manager_usage.h imv/imv_policy_manager_usage.c imv_policy_manager_LDADD = \ - $(top_builddir)/src/libstrongswan/libstrongswan.la + $(top_builddir)/src/libstrongswan/libstrongswan.la \ + $(top_builddir)/src/libtncif/libtncif.la #imv/imv_policy_manager.o : $(top_builddir)/config.status SUBDIRS = . $(am__append_3) $(am__append_4) $(am__append_5) \ diff --git a/src/libimcv/imv/data.sql b/src/libimcv/imv/data.sql index 425748f59..ff6191117 100644 --- a/src/libimcv/imv/data.sql +++ b/src/libimcv/imv/data.sql @@ -323,6 +323,71 @@ INSERT INTO products ( /* 54 */ 'Debian 7.6 armv6l' ); +INSERT INTO products ( /* 55 */ + name +) VALUES ( + 'Debian 7.7 i686' +); + +INSERT INTO products ( /* 56 */ + name +) VALUES ( + 'Debian 7.7 x86_64' +); +INSERT INTO products ( /* 57 */ + name +) VALUES ( + 'Debian 7.7 armv6l' +); + +INSERT INTO products ( /* 58 */ + name +) VALUES ( + 'Debian 7.8 i686' +); + +INSERT INTO products ( /* 59 */ + name +) VALUES ( + 'Debian 7.8 x86_64' +); + +INSERT INTO products ( /* 60 */ + name +) VALUES ( + 'Debian 7.8 armv6l' +); + +INSERT INTO products ( /* 61 */ + name +) VALUES ( + 'Ubuntu 14.10 i686' +); + +INSERT INTO products ( /* 62 */ + name +) VALUES ( + 'Ubuntu 14.10 x86_64' +); + +INSERT INTO products ( /* 63 */ + name +) VALUES ( + 'Android 5.0' +); + +INSERT INTO products ( /* 64 */ + name +) VALUES ( + 'Android 5.0.1' +); + +INSERT INTO products ( /* 65 */ + name +) VALUES ( + 'Debian 7.8 armv7l' +); + /* Directories */ INSERT INTO directories ( /* 1 */ @@ -741,6 +806,18 @@ INSERT INTO groups ( /* 14 */ 'Debian armv6l', 2 ); +INSERT INTO groups ( /* 15 */ + name, parent +) VALUES ( + 'Debian armv7l', 2 +); + +INSERT INTO groups ( /* 16 */ + name +) VALUES ( + 'TPM TBOOT' +); + /* Default Product Groups */ INSERT INTO groups_product_defaults ( @@ -800,6 +877,18 @@ INSERT INTO groups_product_defaults ( INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( + 4, 55 +); + +INSERT INTO groups_product_defaults ( + group_id, product_id +) VALUES ( + 4, 58 +); + +INSERT INTO groups_product_defaults ( + group_id, product_id +) VALUES ( 5, 2 ); @@ -854,6 +943,18 @@ INSERT INTO groups_product_defaults ( INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( + 5, 56 +); + +INSERT INTO groups_product_defaults ( + group_id, product_id +) VALUES ( + 5, 59 +); + +INSERT INTO groups_product_defaults ( + group_id, product_id +) VALUES ( 6, 9 ); @@ -902,6 +1003,12 @@ INSERT INTO groups_product_defaults ( INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( + 6, 61 +); + +INSERT INTO groups_product_defaults ( + group_id, product_id +) VALUES ( 7, 8 ); @@ -956,6 +1063,12 @@ INSERT INTO groups_product_defaults ( INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( + 7, 62 +); + +INSERT INTO groups_product_defaults ( + group_id, product_id +) VALUES ( 3, 21 ); @@ -1016,6 +1129,18 @@ INSERT INTO groups_product_defaults ( INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( + 3, 63 +); + +INSERT INTO groups_product_defaults ( + group_id, product_id +) VALUES ( + 3, 64 +); + +INSERT INTO groups_product_defaults ( + group_id, product_id +) VALUES ( 3, 51 ); @@ -1061,6 +1186,24 @@ INSERT INTO groups_product_defaults ( 14, 54 ); +INSERT INTO groups_product_defaults ( + group_id, product_id +) VALUES ( + 14, 57 +); + +INSERT INTO groups_product_defaults ( + group_id, product_id +) VALUES ( + 14, 60 +); + +INSERT INTO groups_product_defaults ( + group_id, product_id +) VALUES ( + 15, 65 +); + /* Policies */ INSERT INTO policies ( /* 1 */ @@ -1189,6 +1332,12 @@ INSERT INTO policies ( /* 21 */ 16, 'TPM BIOS/IMA Measurements', 'BI', 2, 2 ); +INSERT INTO policies ( /* 22 */ + type, name, argument, rec_fail, rec_noresult +) VALUES ( + 16, 'TPM TBOOT Measurements', 'T', 2, 2 +); + /* Enforcements */ INSERT INTO enforcements ( /* 1 */ @@ -1293,6 +1442,12 @@ INSERT INTO enforcements ( /* 17 */ 21, 13, 60 ); +INSERT INTO enforcements ( /* 18 */ + policy, group_id, max_age +) VALUES ( + 22, 16, 60 +); + /* swid_entities */ INSERT INTO "swid_entities" ( /* 1 */ diff --git a/src/libimcv/imv/imv_agent.c b/src/libimcv/imv/imv_agent.c index 6b24f4b28..d0508624d 100644 --- a/src/libimcv/imv/imv_agent.c +++ b/src/libimcv/imv/imv_agent.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2014 Andreas Steffen + * Copyright (C) 2011-2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -412,14 +412,10 @@ METHOD(imv_agent_t, create_state, TNC_Result, { TNC_ConnectionID conn_id; char *tnccs_p = NULL, *tnccs_v = NULL, *t_p = NULL, *t_v = NULL; - bool has_long = FALSE, has_excl = FALSE, has_soh = FALSE, first = TRUE; + bool has_long = FALSE, has_excl = FALSE, has_soh = FALSE; linked_list_t *ar_identities; - enumerator_t *enumerator; - tncif_identity_t *tnc_id; imv_session_t *session; uint32_t max_msg_len; - uint32_t ar_id_type = TNC_ID_UNKNOWN; - chunk_t ar_id_value = chunk_empty; conn_id = state->get_connection_id(state); if (find_connection(this, conn_id)) @@ -431,15 +427,24 @@ METHOD(imv_agent_t, create_state, TNC_Result, } /* Get and display attributes from TNCS via IF-IMV */ - has_long = get_bool_attribute(this, conn_id, TNC_ATTRIBUTEID_HAS_LONG_TYPES); - has_excl = get_bool_attribute(this, conn_id, TNC_ATTRIBUTEID_HAS_EXCLUSIVE); - has_soh = get_bool_attribute(this, conn_id, TNC_ATTRIBUTEID_HAS_SOH); - tnccs_p = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFTNCCS_PROTOCOL); - tnccs_v = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFTNCCS_VERSION); - t_p = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFT_PROTOCOL); - t_v = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFT_VERSION); - max_msg_len = get_uint_attribute(this, conn_id, TNC_ATTRIBUTEID_MAX_MESSAGE_SIZE); - ar_identities = get_identity_attribute(this, conn_id, TNC_ATTRIBUTEID_AR_IDENTITIES); + has_long = get_bool_attribute(this, conn_id, + TNC_ATTRIBUTEID_HAS_LONG_TYPES); + has_excl = get_bool_attribute(this, conn_id, + TNC_ATTRIBUTEID_HAS_EXCLUSIVE); + has_soh = get_bool_attribute(this, conn_id, + TNC_ATTRIBUTEID_HAS_SOH); + tnccs_p = get_str_attribute(this, conn_id, + TNC_ATTRIBUTEID_IFTNCCS_PROTOCOL); + tnccs_v = get_str_attribute(this, conn_id, + TNC_ATTRIBUTEID_IFTNCCS_VERSION); + t_p = get_str_attribute(this, conn_id, + TNC_ATTRIBUTEID_IFT_PROTOCOL); + t_v = get_str_attribute(this, conn_id, + TNC_ATTRIBUTEID_IFT_VERSION); + max_msg_len = get_uint_attribute(this, conn_id, + TNC_ATTRIBUTEID_MAX_MESSAGE_SIZE); + ar_identities = get_identity_attribute(this, conn_id, + TNC_ATTRIBUTEID_AR_IDENTITIES); state->set_flags(state, has_long, has_excl); state->set_max_msg_len(state, max_msg_len); @@ -451,48 +456,9 @@ METHOD(imv_agent_t, create_state, TNC_Result, DBG2(DBG_IMV, " over %s %s with maximum PA-TNC message size of %u bytes", t_p ? t_p:"?", t_v ? t_v :"?", max_msg_len); - enumerator = ar_identities->create_enumerator(ar_identities); - while (enumerator->enumerate(enumerator, &tnc_id)) - { - pen_type_t id_type, subject_type, auth_type; - uint32_t tcg_id_type, tcg_subject_type, tcg_auth_type; - chunk_t id_value; - - id_type = tnc_id->get_identity_type(tnc_id); - id_value = tnc_id->get_identity_value(tnc_id); - subject_type = tnc_id->get_subject_type(tnc_id); - auth_type = tnc_id->get_auth_type(tnc_id); - - tcg_id_type = (id_type.vendor_id == PEN_TCG) ? - id_type.type : TNC_ID_UNKNOWN; - tcg_subject_type = (subject_type.vendor_id == PEN_TCG) ? - subject_type.type : TNC_SUBJECT_UNKNOWN; - tcg_auth_type = (auth_type.vendor_id == PEN_TCG) ? - auth_type.type : TNC_AUTH_UNKNOWN; - - - DBG2(DBG_IMV, " %N AR identity '%.*s' authenticated by %N", - TNC_Subject_names, tcg_subject_type, - id_value.len, id_value.ptr, - TNC_Authentication_names, tcg_auth_type); - - /* keep the first access requestor ID */ - if (first) - { - ar_id_type = tcg_id_type; - ar_id_value = id_value; - first = FALSE; - } - } - enumerator->destroy(enumerator); - - session = imcv_sessions->add_session(imcv_sessions, conn_id, - ar_id_type, ar_id_value); + session = imcv_sessions->add_session(imcv_sessions, conn_id, ar_identities); state->set_session(state, session); - /* clean up temporary variables */ - ar_identities->destroy_offset(ar_identities, - offsetof(tncif_identity_t, destroy)); free(tnccs_p); free(tnccs_v); free(t_p); diff --git a/src/libimcv/imv/imv_database.c b/src/libimcv/imv/imv_database.c index 0c4bb7514..0a18cd71b 100644 --- a/src/libimcv/imv/imv_database.c +++ b/src/libimcv/imv/imv_database.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2014 Andreas Steffen + * Copyright (C) 2013-2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -22,6 +22,8 @@ #include "imv_database.h" +#include <tncif_identity.h> + #include <utils/debug.h> #include <threading/mutex.h> @@ -60,41 +62,14 @@ METHOD(imv_database_t, get_database, database_t*, */ static bool create_session(private_imv_database_t *this, imv_session_t *session) { - enumerator_t *e; + enumerator_t *enumerator, *e; imv_os_info_t *os_info; - chunk_t device_id, ar_id_value; + chunk_t device_id; + tncif_identity_t *tnc_id; TNC_ConnectionID conn_id; - uint32_t ar_id_type; char *product, *device; - int session_id = 0, ar_id = 0, pid = 0, did = 0, trusted = 0, created; - - ar_id_value = session->get_ar_id(session, &ar_id_type); - if (ar_id_value.len) - { - /* get primary key of AR identity if it exists */ - e = this->db->query(this->db, - "SELECT id FROM identities WHERE type = ? AND value = ?", - DB_INT, ar_id_type, DB_BLOB, ar_id_value, DB_INT); - if (e) - { - e->enumerate(e, &ar_id); - e->destroy(e); - } - - /* if AR identity has not been found - register it */ - if (!ar_id) - { - this->db->execute(this->db, &ar_id, - "INSERT INTO identities (type, value) VALUES (?, ?)", - DB_INT, ar_id_type, DB_BLOB, ar_id_value); - } - - if (!ar_id) - { - DBG1(DBG_IMV, "imv_db: registering access requestor failed"); - return FALSE; - } - } + int session_id = 0, pid = 0, did = 0, trusted = 0, created; + bool first = TRUE, success = TRUE; /* get product info string */ os_info = session->get_os_info(session); @@ -170,10 +145,9 @@ static bool create_session(private_imv_database_t *this, imv_session_t *session) created = session->get_creation_time(session); conn_id = session->get_connection_id(session); this->db->execute(this->db, &session_id, - "INSERT INTO sessions (time, connection, identity, product, device) " - "VALUES (?, ?, ?, ?, ?)", - DB_INT, created, DB_INT, conn_id, DB_INT, ar_id, - DB_INT, pid, DB_INT, did); + "INSERT INTO sessions (time, connection, product, device) " + "VALUES (?, ?, ?, ?)", + DB_INT, created, DB_INT, conn_id, DB_INT, pid, DB_INT, did); if (session_id) { @@ -187,7 +161,68 @@ static bool create_session(private_imv_database_t *this, imv_session_t *session) } session->set_session_id(session, session_id, pid, did); - return TRUE; + enumerator = session->create_ar_identities_enumerator(session); + while (enumerator->enumerate(enumerator, &tnc_id)) + { + pen_type_t ar_id_type; + chunk_t ar_id_value; + int ar_id = 0, si_id = 0; + + ar_id_type = tnc_id->get_identity_type(tnc_id); + ar_id_value = tnc_id->get_identity_value(tnc_id); + + if (ar_id_type.vendor_id != PEN_TCG || ar_id_value.len == 0) + { + continue; + } + + /* get primary key of AR identity if it exists */ + e = this->db->query(this->db, + "SELECT id FROM identities WHERE type = ? AND value = ?", + DB_INT, ar_id_type.type, DB_BLOB, ar_id_value, DB_INT); + if (e) + { + e->enumerate(e, &ar_id); + e->destroy(e); + } + + /* if AR identity has not been found - register it */ + if (!ar_id) + { + this->db->execute(this->db, &ar_id, + "INSERT INTO identities (type, value) VALUES (?, ?)", + DB_INT, ar_id_type.type, DB_BLOB, ar_id_value); + } + if (!ar_id) + { + DBG1(DBG_IMV, "imv_db: registering access requestor failed"); + success = FALSE; + break; + } + + this->db->execute(this->db, &si_id, + "INSERT INTO sessions_identities (session_id, identity_id) " + "VALUES (?, ?)", + DB_INT, session_id, DB_INT, ar_id); + + if (!si_id) + { + DBG1(DBG_IMV, "imv_db: assigning identity to session failed"); + success = FALSE; + break; + } + + if (first) + { + this->db->execute(this->db, NULL, + "UPDATE sessions SET identity = ? WHERE id = ?", + DB_INT, ar_id, DB_INT, session_id); + first = FALSE; + } + } + enumerator->destroy(enumerator); + + return success; } static bool add_workitems(private_imv_database_t *this, imv_session_t *session) diff --git a/src/libimcv/imv/imv_policy_manager.c b/src/libimcv/imv/imv_policy_manager.c index 50f7f2e39..9f7e4e8f4 100644 --- a/src/libimcv/imv/imv_policy_manager.c +++ b/src/libimcv/imv/imv_policy_manager.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Andreas Steffen + * Copyright (C) 2013-2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -19,6 +19,8 @@ #include <library.h> #include <utils/debug.h> +#include <tncif_names.h> + #include <stdlib.h> #include <stdio.h> #include <time.h> @@ -251,9 +253,12 @@ static bool policy_start(database_t *db, int session_id) static bool policy_stop(database_t *db, int session_id) { enumerator_t *e; - int rec, policy; - char *result; + int rec, policy, final_rec, id_type; + chunk_t id_value; + char *result, *ip_address = NULL; + bool success = TRUE; + /* store all workitem results for this session in the results table */ e = db->query(db, "SELECT w.rec_final, w.result, e.policy FROM workitems AS w " "JOIN enforcements AS e ON w.enforcement = e.id " @@ -270,9 +275,68 @@ static bool policy_stop(database_t *db, int session_id) } e->destroy(e); } - return db->execute(db, NULL, - "DELETE FROM workitems WHERE session = ?", - DB_UINT, session_id) >= 0; + else + { + success = FALSE; + } + + /* delete all workitems for this session from the database */ + if (db->execute(db, NULL, + "DELETE FROM workitems WHERE session = ?", + DB_UINT, session_id) < 0) + { + success = FALSE; + } + + final_rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION; + + /* retrieve the final recommendation for this session */ + e = db->query(db, + "SELECT rec FROM sessions WHERE id = ?", + DB_INT, session_id, DB_INT); + if (e) + { + if (!e->enumerate(e, &final_rec)) + { + success = FALSE; + } + e->destroy(e); + } + else + { + success = FALSE; + } + + /* retrieve client IP address for this session */ + e = db->query(db, + "SELECT i.type, i.value FROM identities AS i " + "JOIN sessions_identities AS si ON si.identity_id = i.id " + "WHERE si.session_id = ? AND (i.type = ? OR i.type = ?)", + DB_INT, session_id, DB_INT, TNC_ID_IPV4_ADDR, DB_INT, + TNC_ID_IPV6_ADDR, DB_INT, DB_BLOB); + if (e) + { + if (e->enumerate(e, &id_type, &id_value)) + { + ip_address = strndup(id_value.ptr, id_value.len); + } + else + { + success = FALSE; + } + e->destroy(e); + } + else + { + success = FALSE; + } + + fprintf(stderr, "recommendation for access requestor %s is %N\n", + ip_address ? ip_address : "0.0.0.0", + TNC_IMV_Action_Recommendation_names, final_rec); + free(ip_address); + + return success; } int main(int argc, char *argv[]) diff --git a/src/libimcv/imv/imv_session.c b/src/libimcv/imv/imv_session.c index 1f0d8cf14..bc6b5a8d1 100644 --- a/src/libimcv/imv/imv_session.c +++ b/src/libimcv/imv/imv_session.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Andreas Steffen + * Copyright (C) 2013-2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -15,6 +15,8 @@ #include "imv_session.h" +#include <tncif_identity.h> + #include <utils/debug.h> typedef struct private_imv_session_t private_imv_session_t; @@ -55,14 +57,9 @@ struct private_imv_session_t { time_t created; /** - * Access Requestor ID type - */ - uint32_t ar_id_type; - - /** - * Access Requestor ID value + * List of Access Requestor identities */ - chunk_t ar_id_value; + linked_list_t *ar_identities; /** * OS information @@ -130,14 +127,10 @@ METHOD(imv_session_t, get_creation_time, time_t, return this->created; } -METHOD(imv_session_t, get_ar_id, chunk_t, - private_imv_session_t *this, uint32_t *ar_id_type) +METHOD(imv_session_t, create_ar_identities_enumerator, enumerator_t*, + private_imv_session_t *this) { - if (ar_id_type) - { - *ar_id_type = this->ar_id_type; - } - return this->ar_id_value; + return this->ar_identities->create_enumerator(this->ar_identities); } METHOD(imv_session_t, get_os_info, imv_os_info_t*, @@ -256,7 +249,8 @@ METHOD(imv_session_t, destroy, void, this->workitems->destroy_offset(this->workitems, offsetof(imv_workitem_t, destroy)); this->os_info->destroy(this->os_info); - free(this->ar_id_value.ptr); + this->ar_identities->destroy_offset(this->ar_identities, + offsetof(tncif_identity_t, destroy)); free(this->device_id.ptr); free(this); } @@ -266,7 +260,7 @@ METHOD(imv_session_t, destroy, void, * See header */ imv_session_t *imv_session_create(TNC_ConnectionID conn_id, time_t created, - uint32_t ar_id_type, chunk_t ar_id_value) + linked_list_t *ar_identities) { private_imv_session_t *this; @@ -276,7 +270,7 @@ imv_session_t *imv_session_create(TNC_ConnectionID conn_id, time_t created, .get_session_id = _get_session_id, .get_connection_id = _get_connection_id, .get_creation_time = _get_creation_time, - .get_ar_id = _get_ar_id, + .create_ar_identities_enumerator = _create_ar_identities_enumerator, .get_os_info = _get_os_info, .set_device_id = _set_device_id, .get_device_id = _get_device_id, @@ -293,8 +287,7 @@ imv_session_t *imv_session_create(TNC_ConnectionID conn_id, time_t created, }, .conn_id = conn_id, .created = created, - .ar_id_type = ar_id_type, - .ar_id_value = chunk_clone(ar_id_value), + .ar_identities = ar_identities, .os_info = imv_os_info_create(), .workitems = linked_list_create(), .ref = 1, diff --git a/src/libimcv/imv/imv_session.h b/src/libimcv/imv/imv_session.h index 42b9118a6..107716f30 100644 --- a/src/libimcv/imv/imv_session.h +++ b/src/libimcv/imv/imv_session.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2014 Andreas Steffen + * Copyright (C) 2013-2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -70,12 +70,11 @@ struct imv_session_t { time_t (*get_creation_time)(imv_session_t *this); /** - * Get Access Requestor ID + * Get list of Access Requestor identities * - * @param id_type Access Requestor TCG Standard ID Type - * @return Access Requestor TCG Standard ID Value + * @return List of Access Requestor identities */ - chunk_t (*get_ar_id)(imv_session_t *this, uint32_t *id_type); + enumerator_t* (*create_ar_identities_enumerator)(imv_session_t *this); /** * Get OS Information @@ -172,10 +171,9 @@ struct imv_session_t { * * @param id Associated Connection ID * @param created Session creation time - * @param ar_id_type Access Requestor ID type - * @param ar_id_value Access Requestor ID value + * @param ar_identities List of Access Requestor identities */ imv_session_t* imv_session_create(TNC_ConnectionID id, time_t created, - uint32_t ar_id_type, chunk_t ar_id_value); + linked_list_t *ar_identities); #endif /** IMV_SESSION_H_ @}*/ diff --git a/src/libimcv/imv/imv_session_manager.c b/src/libimcv/imv/imv_session_manager.c index 0fb8de45e..c97602998 100644 --- a/src/libimcv/imv/imv_session_manager.c +++ b/src/libimcv/imv/imv_session_manager.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Andreas Steffen + * Copyright (C) 2014-2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -15,6 +15,9 @@ #include "imv_session_manager.h" +#include <tncif_names.h> +#include <tncif_identity.h> + #include <threading/mutex.h> typedef struct private_imv_session_manager_t private_imv_session_manager_t; @@ -43,9 +46,10 @@ struct private_imv_session_manager_t { METHOD(imv_session_manager_t, add_session, imv_session_t*, private_imv_session_manager_t *this, TNC_ConnectionID conn_id, - uint32_t ar_id_type, chunk_t ar_id_value) + linked_list_t *ar_identities) { enumerator_t *enumerator; + tncif_identity_t *tnc_id; imv_session_t *current, *session = NULL; time_t created; @@ -66,13 +70,43 @@ METHOD(imv_session_manager_t, add_session, imv_session_t*, /* session already exists */ if (session) { + ar_identities->destroy_offset(ar_identities, + offsetof(tncif_identity_t, destroy)); this->mutex->unlock(this->mutex); return session->get_ref(session); } + /* Output list of Access Requestor identities */ + enumerator = ar_identities->create_enumerator(ar_identities); + while (enumerator->enumerate(enumerator, &tnc_id)) + { + pen_type_t id_type, subject_type, auth_type; + uint32_t tcg_id_type, tcg_subject_type, tcg_auth_type; + chunk_t id_value; + + id_type = tnc_id->get_identity_type(tnc_id); + id_value = tnc_id->get_identity_value(tnc_id); + subject_type = tnc_id->get_subject_type(tnc_id); + auth_type = tnc_id->get_auth_type(tnc_id); + + tcg_id_type = (subject_type.vendor_id == PEN_TCG) ? + id_type.type : TNC_SUBJECT_UNKNOWN; + tcg_subject_type = (subject_type.vendor_id == PEN_TCG) ? + subject_type.type : TNC_SUBJECT_UNKNOWN; + tcg_auth_type = (auth_type.vendor_id == PEN_TCG) ? + auth_type.type : TNC_AUTH_UNKNOWN; + + DBG2(DBG_IMV, " %N AR identity '%.*s' of type %N authenticated by %N", + TNC_Subject_names, tcg_subject_type, + id_value.len, id_value.ptr, + TNC_Identity_names, tcg_id_type, + TNC_Authentication_names, tcg_auth_type); + } + enumerator->destroy(enumerator); + /* create a new session entry */ created = time(NULL); - session = imv_session_create(conn_id, created, ar_id_type, ar_id_value); + session = imv_session_create(conn_id, created, ar_identities); this->sessions->insert_last(this->sessions, session); this->mutex->unlock(this->mutex); diff --git a/src/libimcv/imv/imv_session_manager.h b/src/libimcv/imv/imv_session_manager.h index 8a733accb..cfae23bc9 100644 --- a/src/libimcv/imv/imv_session_manager.h +++ b/src/libimcv/imv/imv_session_manager.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Andreas Steffen + * Copyright (C) 2014-2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -39,13 +39,12 @@ struct imv_session_manager_t { * Create or get a session associated with a TNCCS connection * * @param conn_id TNCCS Connection ID - * @param ar_id_type Access Requestor identity type - * @param ar_id_value Access Requestor identity value + * @param ar_identities List of Access Requestor identities * @return Session associated with TNCCS Connection */ imv_session_t* (*add_session)(imv_session_manager_t *this, TNC_ConnectionID conn_id, - uint32_t ar_id_type, chunk_t ar_id_value); + linked_list_t *ar_identities); /** * Remove a session diff --git a/src/libimcv/imv/tables-mysql.sql b/src/libimcv/imv/tables-mysql.sql index 47ee41c86..cf50742c3 100644 --- a/src/libimcv/imv/tables-mysql.sql +++ b/src/libimcv/imv/tables-mysql.sql @@ -99,6 +99,14 @@ CREATE TABLE `sessions` ( `rec` INTEGER DEFAULT 3 ); +DROP TABLE IF EXISTS `sessions_identities`; +CREATE TABLE `sessions_identities` ( + `id` INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, + `session_id` INTEGER NOT NULL REFERENCES `sessions`(`id`), + `identity_id` INTEGER NOT NULL REFERENCES `identities`(`id`), + UNIQUE (`session_id`, `identity_id`) +); + DROP TABLE IF EXISTS `workitems`; CREATE TABLE `workitems` ( `id` INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT, diff --git a/src/libimcv/imv/tables.sql b/src/libimcv/imv/tables.sql index f7324896e..5c2a6563b 100644 --- a/src/libimcv/imv/tables.sql +++ b/src/libimcv/imv/tables.sql @@ -104,6 +104,14 @@ CREATE TABLE sessions ( rec INTEGER DEFAULT 3 ); +DROP TABLE IF EXISTS sessions_identities; +CREATE TABLE sessions_identities ( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + session_id INTEGER NOT NULL REFERENCES sessions(id), + identity_id INTEGER NOT NULL REFERENCES identities(id), + UNIQUE (session_id, identity_id) +); + DROP TABLE IF EXISTS workitems; CREATE TABLE workitems ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, diff --git a/src/libimcv/plugins/imc_attestation/Makefile.in b/src/libimcv/plugins/imc_attestation/Makefile.in index 3c5017f32..8ad56181e 100644 --- a/src/libimcv/plugins/imc_attestation/Makefile.in +++ b/src/libimcv/plugins/imc_attestation/Makefile.in @@ -227,6 +227,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libimcv/plugins/imc_attestation/imc_attestation_process.c b/src/libimcv/plugins/imc_attestation/imc_attestation_process.c index 2fc2998e1..f24aec881 100644 --- a/src/libimcv/plugins/imc_attestation/imc_attestation_process.c +++ b/src/libimcv/plugins/imc_attestation/imc_attestation_process.c @@ -137,7 +137,11 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, imc_msg_t *msg, { return FALSE; } - pts->get_my_public_value(pts, &responder_value, &responder_nonce); + if (!pts->get_my_public_value(pts, &responder_value, + &responder_nonce)) + { + return FALSE; + } /* Send DH Nonce Parameters Response attribute */ attr = tcg_pts_attr_dh_nonce_params_resp_create(selected_dh_group, @@ -174,8 +178,10 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, imc_msg_t *msg, return FALSE; } - pts->set_peer_public_value(pts, initiator_value, initiator_nonce); - if (!pts->calculate_secret(pts)) + + if (!pts->set_peer_public_value(pts, initiator_value, + initiator_nonce) || + !pts->calculate_secret(pts)) { return FALSE; } diff --git a/src/libimcv/plugins/imc_os/Makefile.in b/src/libimcv/plugins/imc_os/Makefile.in index 3f4cf41a9..3b7538688 100644 --- a/src/libimcv/plugins/imc_os/Makefile.in +++ b/src/libimcv/plugins/imc_os/Makefile.in @@ -224,6 +224,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -284,10 +285,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -361,6 +364,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libimcv/plugins/imc_scanner/Makefile.in b/src/libimcv/plugins/imc_scanner/Makefile.in index a192b0a41..7b696896f 100644 --- a/src/libimcv/plugins/imc_scanner/Makefile.in +++ b/src/libimcv/plugins/imc_scanner/Makefile.in @@ -225,6 +225,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -285,10 +286,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -362,6 +365,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libimcv/plugins/imc_swid/Makefile.in b/src/libimcv/plugins/imc_swid/Makefile.in index f1859a2cb..2847f09b4 100644 --- a/src/libimcv/plugins/imc_swid/Makefile.in +++ b/src/libimcv/plugins/imc_swid/Makefile.in @@ -227,6 +227,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libimcv/plugins/imc_test/Makefile.in b/src/libimcv/plugins/imc_test/Makefile.in index 3e1d0232f..2048caa4d 100644 --- a/src/libimcv/plugins/imc_test/Makefile.in +++ b/src/libimcv/plugins/imc_test/Makefile.in @@ -224,6 +224,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -284,10 +285,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -361,6 +364,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libimcv/plugins/imv_attestation/Makefile.in b/src/libimcv/plugins/imv_attestation/Makefile.in index 3ba7c8c88..09a0ab0ce 100644 --- a/src/libimcv/plugins/imv_attestation/Makefile.in +++ b/src/libimcv/plugins/imv_attestation/Makefile.in @@ -236,6 +236,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -296,10 +297,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -373,6 +376,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libimcv/plugins/imv_attestation/attest_db.c b/src/libimcv/plugins/imv_attestation/attest_db.c index f85a02b3d..f1a1f923e 100644 --- a/src/libimcv/plugins/imv_attestation/attest_db.c +++ b/src/libimcv/plugins/imv_attestation/attest_db.c @@ -849,29 +849,31 @@ METHOD(attest_db_t, list_devices, void, { enumerator_t *e, *e_ar; chunk_t ar_id_value = chunk_empty; - char *product, *device; + char *product, *device, *description; time_t timestamp; - int id, last_id = 0, ar_id = 0, last_ar_id = 0, device_count = 0; + int id, last_id = 0, ar_id = 0, last_ar_id = 0, device_count = 0, trusted; int session_id, rec; u_int32_t ar_id_type; u_int tstamp; e = this->db->query(this->db, - "SELECT d.id, d.value, s.id, s.time, s.identity, s.rec, p.name " + "SELECT d.id, d.value, d.trusted, d.description, " + "s.id, s.time, s.identity, s.rec, p.name " "FROM devices AS d " "JOIN sessions AS s ON d.id = s.device " "JOIN products AS p ON p.id = s.product " - "ORDER BY d.value, s.time DESC", DB_INT, DB_TEXT, DB_INT, DB_UINT, - DB_INT, DB_INT, DB_TEXT); + "ORDER BY d.value, s.time DESC", DB_INT, DB_TEXT, DB_INT, DB_TEXT, + DB_INT, DB_UINT, DB_INT, DB_INT, DB_TEXT); if (e) { - while (e->enumerate(e, &id, &device, &session_id, &tstamp, &ar_id, &rec, - &product)) + while (e->enumerate(e, &id, &device, &trusted, &description, + &session_id, &tstamp, &ar_id, &rec, &product)) { if (id != last_id) { - printf("%4d: %s - %s\n", id, device, product); + printf("%4d: %s %s - %s - %s\n", id, trusted ? "+" : "-", + device, product, description); device_count++; last_id = id; } diff --git a/src/libimcv/plugins/imv_attestation/build-database.sh b/src/libimcv/plugins/imv_attestation/build-database.sh index ca2939b49..0babb5366 100755 --- a/src/libimcv/plugins/imv_attestation/build-database.sh +++ b/src/libimcv/plugins/imv_attestation/build-database.sh @@ -2,7 +2,7 @@ p="Ubuntu 14.04 x86_64" a="x86_64-linux-gnu" -k="3.13.0-37-generic" +k="3.13.0-46-generic" for hash in sha1 sha256 do diff --git a/src/libimcv/plugins/imv_attestation/imv_attestation_build.c b/src/libimcv/plugins/imv_attestation/imv_attestation_build.c index c39fe8d47..db93ac45f 100644 --- a/src/libimcv/plugins/imv_attestation/imv_attestation_build.c +++ b/src/libimcv/plugins/imv_attestation/imv_attestation_build.c @@ -69,7 +69,11 @@ bool imv_attestation_build(imv_msg_t *out_msg, imv_state_t *state, /* Send DH nonce finish attribute */ selected_algorithm = pts->get_meas_algorithm(pts); - pts->get_my_public_value(pts, &initiator_value, &initiator_nonce); + if (!pts->get_my_public_value(pts, &initiator_value, + &initiator_nonce)) + { + return FALSE; + } attr = tcg_pts_attr_dh_nonce_finish_create(selected_algorithm, initiator_value, initiator_nonce); attr->set_noskip_flag(attr, TRUE); diff --git a/src/libimcv/plugins/imv_attestation/imv_attestation_process.c b/src/libimcv/plugins/imv_attestation/imv_attestation_process.c index 89a1f02cf..fbeb6618e 100644 --- a/src/libimcv/plugins/imv_attestation/imv_attestation_process.c +++ b/src/libimcv/plugins/imv_attestation/imv_attestation_process.c @@ -134,11 +134,11 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg, } responder_value = attr_cast->get_responder_value(attr_cast); - pts->set_peer_public_value(pts, responder_value, - responder_nonce); /* Calculate secret assessment value */ - if (!pts->calculate_secret(pts)) + if (!pts->set_peer_public_value(pts, responder_value, + responder_nonce) || + !pts->calculate_secret(pts)) { return FALSE; } @@ -198,7 +198,7 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg, e = pts_credmgr->create_trusted_enumerator(pts_credmgr, KEY_ANY, aik->get_issuer(aik), FALSE); - while (e->enumerate(e, &issuer)) + while (e->enumerate(e, &issuer, NULL)) { if (aik->issued_by(aik, issuer, NULL)) { diff --git a/src/libimcv/plugins/imv_os/Makefile.in b/src/libimcv/plugins/imv_os/Makefile.in index 36e708fc9..ec3488992 100644 --- a/src/libimcv/plugins/imv_os/Makefile.in +++ b/src/libimcv/plugins/imv_os/Makefile.in @@ -232,6 +232,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -292,10 +293,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -369,6 +372,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libimcv/plugins/imv_scanner/Makefile.in b/src/libimcv/plugins/imv_scanner/Makefile.in index 2677b339a..08abbf596 100644 --- a/src/libimcv/plugins/imv_scanner/Makefile.in +++ b/src/libimcv/plugins/imv_scanner/Makefile.in @@ -226,6 +226,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libimcv/plugins/imv_swid/Makefile.in b/src/libimcv/plugins/imv_swid/Makefile.in index 815722f9c..936bee86e 100644 --- a/src/libimcv/plugins/imv_swid/Makefile.in +++ b/src/libimcv/plugins/imv_swid/Makefile.in @@ -227,6 +227,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libimcv/plugins/imv_test/Makefile.in b/src/libimcv/plugins/imv_test/Makefile.in index 66da75a1e..8e0e22353 100644 --- a/src/libimcv/plugins/imv_test/Makefile.in +++ b/src/libimcv/plugins/imv_test/Makefile.in @@ -225,6 +225,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -285,10 +286,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -362,6 +365,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libimcv/pts/components/ita/ita_comp_tboot.c b/src/libimcv/pts/components/ita/ita_comp_tboot.c index 273c18f31..ce318ec84 100644 --- a/src/libimcv/pts/components/ita/ita_comp_tboot.c +++ b/src/libimcv/pts/components/ita/ita_comp_tboot.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2014 Andreas Steffen + * Copyright (C) 2011-2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -61,11 +61,6 @@ struct pts_ita_comp_tboot_t { int cid; /** - * Primary key for AIK database entry - */ - int kid; - - /** * Component is registering measurements */ bool is_registering; @@ -243,7 +238,7 @@ METHOD(pts_component_t, verify, status_t, else { status = this->pts_db->check_comp_measurement(this->pts_db, - measurement, this->cid, this->kid, + measurement, this->cid, this->aik_id, ++this->seq_no, extended_pcr, algo); if (status != SUCCESS) { diff --git a/src/libimcv/pts/pts.c b/src/libimcv/pts/pts.c index 2fff4c901..1ca72098e 100644 --- a/src/libimcv/pts/pts.c +++ b/src/libimcv/pts/pts.c @@ -224,17 +224,24 @@ METHOD(pts_t, create_dh_nonce, bool, return TRUE; } -METHOD(pts_t, get_my_public_value, void, +METHOD(pts_t, get_my_public_value, bool, private_pts_t *this, chunk_t *value, chunk_t *nonce) { - this->dh->get_my_public_value(this->dh, value); + if (!this->dh->get_my_public_value(this->dh, value)) + { + return FALSE; + } *nonce = this->is_imc ? this->responder_nonce : this->initiator_nonce; + return TRUE; } -METHOD(pts_t, set_peer_public_value, void, +METHOD(pts_t, set_peer_public_value, bool, private_pts_t *this, chunk_t value, chunk_t nonce) { - this->dh->set_other_public_value(this->dh, value); + if (!this->dh->set_other_public_value(this->dh, value)) + { + return FALSE; + } nonce = chunk_clone(nonce); if (this->is_imc) @@ -245,6 +252,7 @@ METHOD(pts_t, set_peer_public_value, void, { this->responder_nonce = nonce; } + return TRUE; } METHOD(pts_t, calculate_secret, bool, @@ -264,7 +272,7 @@ METHOD(pts_t, calculate_secret, bool, DBG3(DBG_PTS, "responder nonce: %B", &this->responder_nonce); /* Calculate the DH secret */ - if (this->dh->get_shared_secret(this->dh, &shared_secret) != SUCCESS) + if (!this->dh->get_shared_secret(this->dh, &shared_secret)) { DBG1(DBG_PTS, "shared DH secret computation failed"); return FALSE; diff --git a/src/libimcv/pts/pts.h b/src/libimcv/pts/pts.h index be32a3464..d525306dd 100644 --- a/src/libimcv/pts/pts.h +++ b/src/libimcv/pts/pts.h @@ -143,16 +143,18 @@ struct pts_t { * * @param value My public DH value * @param nonce My DH nonce + * @return TRUE if public value retrieved successfully */ - void (*get_my_public_value)(pts_t *this, chunk_t *value, chunk_t *nonce); + bool (*get_my_public_value)(pts_t *this, chunk_t *value, chunk_t *nonce); /** * Set peer Diffie.Hellman public value * * @param value Peer public DH value * @param nonce Peer DH nonce + * @return TRUE if public value set successfully */ - void (*set_peer_public_value) (pts_t *this, chunk_t value, chunk_t nonce); + bool (*set_peer_public_value) (pts_t *this, chunk_t value, chunk_t nonce); /** * Calculates assessment secret to be used for TPM Quote as ExternalData diff --git a/src/libimcv/seg/seg_env.c b/src/libimcv/seg/seg_env.c index c47ce2934..f38419248 100644 --- a/src/libimcv/seg/seg_env.c +++ b/src/libimcv/seg/seg_env.c @@ -219,6 +219,7 @@ seg_env_t *seg_env_create(uint32_t base_attr_id, pa_tnc_attr_t *base_attr, if (max_seg_size < PA_TNC_ATTR_HEADER_SIZE || max_seg_size >= PA_TNC_ATTR_HEADER_SIZE + value.len) { + base_attr->destroy(base_attr); return NULL; } @@ -233,7 +234,7 @@ seg_env_t *seg_env_create(uint32_t base_attr_id, pa_tnc_attr_t *base_attr, .destroy = _destroy, }, .base_attr_id = base_attr_id, - .base_attr = base_attr->get_ref(base_attr), + .base_attr = base_attr, .max_seg_size = max_seg_size, .data = base_attr->get_value(base_attr), ); diff --git a/src/libimcv/seg/seg_env.h b/src/libimcv/seg/seg_env.h index 08d33d752..611f9a98a 100644 --- a/src/libimcv/seg/seg_env.h +++ b/src/libimcv/seg/seg_env.h @@ -98,7 +98,7 @@ struct seg_env_t { * Create a PA-TNC attribute segment envelope object * * @param base_attr_id Base Attribute ID - * @param base_attr Base Attribute to be segmented + * @param base_attr Base Attribute to be segmented, owned by seg_env_t * @param max_seg_size Maximum segment size */ seg_env_t* seg_env_create(uint32_t base_attr_id, pa_tnc_attr_t *base_attr, diff --git a/src/libimcv/suites/test_imcv_seg.c b/src/libimcv/suites/test_imcv_seg.c index 469b1110d..8b51eda05 100644 --- a/src/libimcv/suites/test_imcv_seg.c +++ b/src/libimcv/suites/test_imcv_seg.c @@ -64,10 +64,11 @@ START_TEST(test_imcv_seg_env) libimcv_init(FALSE); max_seg_size = seg_env_tests[_i].max_seg_size; last_seg_size = seg_env_tests[_i].last_seg_size; + base_attr = ita_attr_command_create(command); base_attr->build(base_attr); - seg_env = seg_env_create(id, base_attr, max_seg_size); + if (seg_env_tests[_i].next_segs == 0) { ck_assert(seg_env == NULL); @@ -156,7 +157,6 @@ START_TEST(test_imcv_seg_env) seg_env1->destroy(seg_env1); base_attr1->destroy(base_attr1); } - base_attr->destroy(base_attr); libimcv_deinit(); } END_TEST @@ -226,7 +226,6 @@ START_TEST(test_imcv_seg_env_special) /* cleanup */ attr->destroy(attr); seg_env->destroy(seg_env); - base_attr->destroy(base_attr); } END_TEST @@ -306,7 +305,8 @@ START_TEST(test_imcv_seg_contract) TRUE, issuer_id, FALSE); contract_r = seg_contract_create(msg_type, max_attr_size, max_seg_size, FALSE, issuer_id, TRUE); - attr = contract_r->first_segment(contract_r, base_attr_r); + attr = contract_r->first_segment(contract_r, + base_attr_r->get_ref(base_attr_r)); if (seg_env_tests[_i].next_segs == 0) { @@ -422,8 +422,8 @@ START_TEST(test_imcv_seg_contract_special) ck_assert(!oversize); /* get first segment of each base attribute */ - attr1_f = contract_r->first_segment(contract_r, base_attr1_r); - attr2_f = contract_r->first_segment(contract_r, base_attr2_r); + attr1_f = contract_r->first_segment(contract_r, base_attr1_r->get_ref(base_attr1_r)); + attr2_f = contract_r->first_segment(contract_r, base_attr2_r->get_ref(base_attr2_r)); ck_assert(attr1_f); ck_assert(attr2_f); seg_env_attr1 = (tcg_seg_attr_seg_env_t*)attr1_f; diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_file_meas.c b/src/libimcv/tcg/pts/tcg_pts_attr_file_meas.c index 5b4cc273b..397882926 100644 --- a/src/libimcv/tcg/pts/tcg_pts_attr_file_meas.c +++ b/src/libimcv/tcg/pts/tcg_pts_attr_file_meas.c @@ -242,6 +242,8 @@ METHOD(pa_tnc_attr_t, process, status_t, this->count--; } + status = SUCCESS; + if (this->length != this->offset) { DBG1(DBG_TNC, "inconsistent length for %N/%N", pen_names, PEN_TCG, @@ -249,7 +251,6 @@ METHOD(pa_tnc_attr_t, process, status_t, *offset = this->offset; status = FAILED; } - status = SUCCESS; end: reader->destroy(reader); diff --git a/src/libipsec/Makefile.in b/src/libipsec/Makefile.in index 3663cf825..a80d28ac6 100644 --- a/src/libipsec/Makefile.in +++ b/src/libipsec/Makefile.in @@ -266,6 +266,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -326,10 +327,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -403,6 +406,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libipsec/ip_packet.c b/src/libipsec/ip_packet.c index 0998efa9d..21dbd5e89 100644 --- a/src/libipsec/ip_packet.c +++ b/src/libipsec/ip_packet.c @@ -443,7 +443,7 @@ ip_packet_t *ip_packet_create_from_data(host_t *src, host_t *dst, { struct ip6_hdr ip = { .ip6_flow = htonl(6), - .ip6_plen = htons(40 + data.len), + .ip6_plen = htons(data.len), .ip6_nxt = next_header, .ip6_hlim = 0x80, }; diff --git a/src/libipsec/ipsec_event_listener.h b/src/libipsec/ipsec_event_listener.h index c5c39b0f1..f15f6fe52 100644 --- a/src/libipsec/ipsec_event_listener.h +++ b/src/libipsec/ipsec_event_listener.h @@ -35,14 +35,12 @@ struct ipsec_event_listener_t { /** * Called when the lifetime of an IPsec SA expired * - * @param reqid reqid of the expired SA * @param protocol protocol of the expired SA * @param spi spi of the expired SA + * @param dst destination address of expired SA * @param hard TRUE if this is a hard expire, FALSE otherwise */ - void (*expire)(u_int32_t reqid, u_int8_t protocol, u_int32_t spi, - bool hard); - + void (*expire)(u_int8_t protocol, u_int32_t spi, host_t *dst, bool hard); }; #endif /** IPSEC_EVENT_LISTENER_H_ @}*/ diff --git a/src/libipsec/ipsec_event_relay.c b/src/libipsec/ipsec_event_relay.c index c6b2a550d..048063053 100644 --- a/src/libipsec/ipsec_event_relay.c +++ b/src/libipsec/ipsec_event_relay.c @@ -65,9 +65,9 @@ typedef struct { } type; /** - * Reqid of the SA, if any + * Protocol of the SA */ - u_int32_t reqid; + u_int8_t protocol; /** * SPI of the SA, if any @@ -75,13 +75,16 @@ typedef struct { u_int32_t spi; /** + * SA destination address + */ + host_t *dst; + + /** * Additional data for specific event types */ union { struct { - /** Protocol of the SA */ - u_int8_t protocol; /** TRUE in case of a hard expire */ bool hard; } expire; @@ -91,6 +94,15 @@ typedef struct { } ipsec_event_t; /** + * Destroy IPsec event data + */ +static void ipsec_event_destroy(ipsec_event_t *event) +{ + event->dst->destroy(event->dst); + free(event); +} + +/** * Dequeue events and relay them to listeners */ static job_requeue_t handle_events(private_ipsec_event_relay_t *this) @@ -110,31 +122,31 @@ static job_requeue_t handle_events(private_ipsec_event_relay_t *this) case IPSEC_EVENT_EXPIRE: if (current->expire) { - current->expire(event->reqid, event->data.expire.protocol, - event->spi, event->data.expire.hard); + current->expire(event->protocol, event->spi, event->dst, + event->data.expire.hard); } break; } } enumerator->destroy(enumerator); this->lock->unlock(this->lock); - free(event); + ipsec_event_destroy(event); return JOB_REQUEUE_DIRECT; } METHOD(ipsec_event_relay_t, expire, void, - private_ipsec_event_relay_t *this, u_int32_t reqid, u_int8_t protocol, - u_int32_t spi, bool hard) + private_ipsec_event_relay_t *this, u_int8_t protocol, u_int32_t spi, + host_t *dst, bool hard) { ipsec_event_t *event; INIT(event, .type = IPSEC_EVENT_EXPIRE, - .reqid = reqid, + .protocol = protocol, .spi = spi, + .dst = dst->clone(dst), .data = { .expire = { - .protocol = protocol, .hard = hard, }, }, diff --git a/src/libipsec/ipsec_event_relay.h b/src/libipsec/ipsec_event_relay.h index c6935d546..1dddf121b 100644 --- a/src/libipsec/ipsec_event_relay.h +++ b/src/libipsec/ipsec_event_relay.h @@ -38,13 +38,13 @@ struct ipsec_event_relay_t { /** * Raise an expire event. * - * @param reqid reqid of the expired IPsec SA * @param protocol protocol (e.g ESP) of the expired SA * @param spi SPI of the expired SA + * @param dst destination address of expired SA * @param hard TRUE for a hard expire, FALSE otherwise */ - void (*expire)(ipsec_event_relay_t *this, u_int32_t reqid, - u_int8_t protocol, u_int32_t spi, bool hard); + void (*expire)(ipsec_event_relay_t *this, u_int8_t protocol, u_int32_t spi, + host_t *dst, bool hard); /** * Register a listener to events raised by this manager diff --git a/src/libipsec/ipsec_sa.c b/src/libipsec/ipsec_sa.c index 6ec8bd25e..ccbbb1b3c 100644 --- a/src/libipsec/ipsec_sa.c +++ b/src/libipsec/ipsec_sa.c @@ -194,8 +194,8 @@ METHOD(ipsec_sa_t, expire, void, if (!this->hard_expired) { this->hard_expired = TRUE; - ipsec->events->expire(ipsec->events, this->reqid, this->protocol, - this->spi, TRUE); + ipsec->events->expire(ipsec->events, this->protocol, this->spi, + this->dst, TRUE); } } else @@ -203,8 +203,8 @@ METHOD(ipsec_sa_t, expire, void, if (!this->hard_expired && !this->soft_expired) { this->soft_expired = TRUE; - ipsec->events->expire(ipsec->events, this->reqid, this->protocol, - this->spi, FALSE); + ipsec->events->expire(ipsec->events, this->protocol, this->spi, + this->dst, FALSE); } } } @@ -275,8 +275,7 @@ ipsec_sa_t *ipsec_sa_create(u_int32_t spi, host_t *src, host_t *dst, u_int8_t protocol, u_int32_t reqid, mark_t mark, u_int32_t tfc, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key, u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, - u_int16_t ipcomp, u_int16_t cpi, bool encap, bool esn, bool inbound, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts) + u_int16_t ipcomp, u_int16_t cpi, bool encap, bool esn, bool inbound) { private_ipsec_sa_t *this; diff --git a/src/libipsec/ipsec_sa.h b/src/libipsec/ipsec_sa.h index 5e69f18cf..8dad29ac5 100644 --- a/src/libipsec/ipsec_sa.h +++ b/src/libipsec/ipsec_sa.h @@ -197,8 +197,6 @@ struct ipsec_sa_t { * @param encap enable UDP encapsulation (must be TRUE) * @param esn Extended Sequence Numbers (currently not supported) * @param inbound TRUE if this is an inbound SA, FALSE otherwise - * @param src_ts source traffic selector - * @param dst_ts destination traffic selector * @return the IPsec SA, or NULL if the creation failed */ ipsec_sa_t *ipsec_sa_create(u_int32_t spi, host_t *src, host_t *dst, @@ -207,8 +205,6 @@ ipsec_sa_t *ipsec_sa_create(u_int32_t spi, host_t *src, host_t *dst, u_int16_t enc_alg, chunk_t enc_key, u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi, - bool encap, bool esn, bool inbound, - traffic_selector_t *src_ts, - traffic_selector_t *dst_ts); + bool encap, bool esn, bool inbound); #endif /** IPSEC_SA_H_ @}*/ diff --git a/src/libipsec/ipsec_sa_mgr.c b/src/libipsec/ipsec_sa_mgr.c index 1db1776c0..07ffa9e4f 100644 --- a/src/libipsec/ipsec_sa_mgr.c +++ b/src/libipsec/ipsec_sa_mgr.c @@ -396,12 +396,10 @@ static bool allocate_spi(private_ipsec_sa_mgr_t *this, u_int32_t spi) METHOD(ipsec_sa_mgr_t, get_spi, status_t, private_ipsec_sa_mgr_t *this, host_t *src, host_t *dst, u_int8_t protocol, - u_int32_t reqid, u_int32_t *spi) + u_int32_t *spi) { u_int32_t spi_new; - DBG2(DBG_ESP, "allocating SPI for reqid {%u}", reqid); - this->mutex->lock(this->mutex); if (!this->rng) { @@ -420,7 +418,7 @@ METHOD(ipsec_sa_mgr_t, get_spi, status_t, (u_int8_t*)&spi_new)) { this->mutex->unlock(this->mutex); - DBG1(DBG_ESP, "failed to allocate SPI for reqid {%u}", reqid); + DBG1(DBG_ESP, "failed to allocate SPI"); return FAILED; } /* make sure the SPI is valid (not in range 0-255) */ @@ -432,7 +430,7 @@ METHOD(ipsec_sa_mgr_t, get_spi, status_t, *spi = spi_new; - DBG2(DBG_ESP, "allocated SPI %.8x for reqid {%u}", ntohl(*spi), reqid); + DBG2(DBG_ESP, "allocated SPI %.8x", ntohl(*spi)); return SUCCESS; } @@ -442,7 +440,7 @@ METHOD(ipsec_sa_mgr_t, add_sa, status_t, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key, u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi, bool initiator, bool encap, bool esn, bool inbound, - traffic_selector_t *src_ts, traffic_selector_t *dst_ts) + bool update) { ipsec_sa_entry_t *entry; ipsec_sa_t *sa_new; @@ -456,7 +454,7 @@ METHOD(ipsec_sa_mgr_t, add_sa, status_t, sa_new = ipsec_sa_create(spi, src, dst, protocol, reqid, mark, tfc, lifetime, enc_alg, enc_key, int_alg, int_key, mode, - ipcomp, cpi, encap, esn, inbound, src_ts, dst_ts); + ipcomp, cpi, encap, esn, inbound); if (!sa_new) { DBG1(DBG_ESP, "failed to create SAD entry"); @@ -465,7 +463,7 @@ METHOD(ipsec_sa_mgr_t, add_sa, status_t, this->mutex->lock(this->mutex); - if (inbound) + if (update) { /* remove any pre-allocated SPIs */ u_int32_t *spi_alloc; diff --git a/src/libipsec/ipsec_sa_mgr.h b/src/libipsec/ipsec_sa_mgr.h index 8c234cefa..a57eab4e7 100644 --- a/src/libipsec/ipsec_sa_mgr.h +++ b/src/libipsec/ipsec_sa_mgr.h @@ -45,12 +45,11 @@ struct ipsec_sa_mgr_t { * @param src source address of the SA * @param dst destination address of the SA * @param protocol protocol of the SA (only ESP supported) - * @param reqid reqid for the SA * @param spi the allocated SPI * @return SUCCESS of operation successful */ status_t (*get_spi)(ipsec_sa_mgr_t *this, host_t *src, host_t *dst, - u_int8_t protocol, u_int32_t reqid, u_int32_t *spi); + u_int8_t protocol, u_int32_t *spi); /** * Add a new SA @@ -74,8 +73,7 @@ struct ipsec_sa_mgr_t { * @param encap enable UDP encapsulation (must be TRUE) * @param esn Extended Sequence Numbers (currently not supported) * @param inbound TRUE if this is an inbound SA, FALSE otherwise - * @param src_ts source traffic selector - * @param dst_ts destination traffic selector + * @param update TRUE if an SPI has already been allocated for SA * @return SUCCESS if operation completed */ status_t (*add_sa)(ipsec_sa_mgr_t *this, host_t *src, host_t *dst, @@ -84,8 +82,7 @@ struct ipsec_sa_mgr_t { u_int16_t enc_alg, chunk_t enc_key, u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi, bool initiator, bool encap, bool esn, - bool inbound, traffic_selector_t *src_ts, - traffic_selector_t *dst_ts); + bool inbound, bool update); /** * Update the hosts on an installed SA. diff --git a/src/libpttls/Makefile.in b/src/libpttls/Makefile.in index 74cd8084a..96d1ae4aa 100644 --- a/src/libpttls/Makefile.in +++ b/src/libpttls/Makefile.in @@ -227,6 +227,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libradius/Makefile.in b/src/libradius/Makefile.in index faaae70fe..5dd8ac56b 100644 --- a/src/libradius/Makefile.in +++ b/src/libradius/Makefile.in @@ -222,6 +222,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -282,10 +283,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -359,6 +362,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libradius/radius_socket.c b/src/libradius/radius_socket.c index f432151c0..fe9cf3c01 100644 --- a/src/libradius/radius_socket.c +++ b/src/libradius/radius_socket.c @@ -129,7 +129,7 @@ METHOD(radius_socket_t, request, radius_message_t*, private_radius_socket_t *this, radius_message_t *request) { chunk_t data; - int i, *fd; + int i, *fd, retransmit = 0; u_int16_t port; rng_t *rng = NULL; @@ -166,64 +166,59 @@ METHOD(radius_socket_t, request, radius_message_t*, for (i = 2; i <= 5; i++) { radius_message_t *response; - bool retransmit = FALSE; - struct timeval tv; char buf[4096]; - fd_set fds; int res; + struct pollfd pfd = { + .fd = *fd, + .events = POLLIN, + }; + if (retransmit) + { + DBG1(DBG_CFG, "retransmitting RADIUS %N (attempt %d)", + radius_message_code_names, request->get_code(request), + retransmit); + } if (send(*fd, data.ptr, data.len, 0) != data.len) { DBG1(DBG_CFG, "sending RADIUS message failed: %s", strerror(errno)); return NULL; } - tv.tv_sec = i; - tv.tv_usec = 0; - - while (TRUE) + res = poll(&pfd, 1, i * 1000); + if (res < 0) { - FD_ZERO(&fds); - FD_SET(*fd, &fds); - res = select((*fd) + 1, &fds, NULL, NULL, &tv); - /* TODO: updated tv to time not waited. Linux does this for us. */ - if (res < 0) - { /* failed */ - DBG1(DBG_CFG, "waiting for RADIUS message failed: %s", - strerror(errno)); - break; - } - if (res == 0) - { /* timeout */ - DBG1(DBG_CFG, "retransmitting RADIUS message"); - retransmit = TRUE; - break; - } - res = recv(*fd, buf, sizeof(buf), MSG_DONTWAIT); - if (res <= 0) - { - DBG1(DBG_CFG, "receiving RADIUS message failed: %s", - strerror(errno)); - break; - } - response = radius_message_parse(chunk_create(buf, res)); - if (response) - { - if (response->verify(response, - request->get_authenticator(request), this->secret, - this->hasher, this->signer)) - { - return response; - } - response->destroy(response); - } - DBG1(DBG_CFG, "received invalid RADIUS message, ignored"); + DBG1(DBG_CFG, "waiting for RADIUS message failed: %s", + strerror(errno)); + return NULL; + } + if (res == 0) + { /* timeout */ + retransmit++; + continue; } - if (!retransmit) + res = recv(*fd, buf, sizeof(buf), MSG_DONTWAIT); + if (res <= 0) { - break; + DBG1(DBG_CFG, "receiving RADIUS message failed: %s", + strerror(errno)); + return NULL; } + response = radius_message_parse(chunk_create(buf, res)); + if (response) + { + if (response->verify(response, + request->get_authenticator(request), this->secret, + this->hasher, this->signer)) + { + return response; + } + response->destroy(response); + } + DBG1(DBG_CFG, "received invalid RADIUS message, ignored"); + return NULL; } - DBG1(DBG_CFG, "RADIUS server is not responding"); + DBG1(DBG_CFG, "RADIUS %N timed out after %d retransmits", + radius_message_code_names, request->get_code(request), retransmit - 1); return NULL; } diff --git a/src/libsimaka/Makefile.in b/src/libsimaka/Makefile.in index a16991927..79962d3bd 100644 --- a/src/libsimaka/Makefile.in +++ b/src/libsimaka/Makefile.in @@ -222,6 +222,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -282,10 +283,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -359,6 +362,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/Android.mk b/src/libstrongswan/Android.mk index 9b775f9b3..2a8894b0e 100644 --- a/src/libstrongswan/Android.mk +++ b/src/libstrongswan/Android.mk @@ -8,12 +8,14 @@ asn1/asn1.c asn1/asn1_parser.c asn1/oid.c bio/bio_reader.c bio/bio_writer.c \ collections/blocking_queue.c collections/enumerator.c collections/hashtable.c \ collections/array.c \ collections/linked_list.c crypto/crypters/crypter.c crypto/hashers/hasher.c \ +crypto/hashers/hash_algorithm_set.c \ crypto/proposal/proposal_keywords.c crypto/proposal/proposal_keywords_static.c \ crypto/prfs/prf.c crypto/prfs/mac_prf.c crypto/pkcs5.c \ crypto/rngs/rng.c crypto/prf_plus.c crypto/signers/signer.c \ crypto/signers/mac_signer.c crypto/crypto_factory.c crypto/crypto_tester.c \ crypto/diffie_hellman.c crypto/aead.c crypto/transform.c \ crypto/iv/iv_gen_rand.c crypto/iv/iv_gen_seq.c \ +crypto/mgf1/mgf1.c crypto/mgf1/mgf1_bitspender.c \ credentials/credential_factory.c credentials/builder.c \ credentials/cred_encoding.c credentials/keys/private_key.c \ credentials/keys/public_key.c credentials/keys/shared_key.c \ diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am index 0083ffe6b..fbc752687 100644 --- a/src/libstrongswan/Makefile.am +++ b/src/libstrongswan/Makefile.am @@ -6,12 +6,14 @@ asn1/asn1.c asn1/asn1_parser.c asn1/oid.c bio/bio_reader.c bio/bio_writer.c \ collections/blocking_queue.c collections/enumerator.c collections/hashtable.c \ collections/array.c \ collections/linked_list.c crypto/crypters/crypter.c crypto/hashers/hasher.c \ +crypto/hashers/hash_algorithm_set.c \ crypto/proposal/proposal_keywords.c crypto/proposal/proposal_keywords_static.c \ crypto/prfs/prf.c crypto/prfs/mac_prf.c crypto/pkcs5.c \ crypto/rngs/rng.c crypto/prf_plus.c crypto/signers/signer.c \ crypto/signers/mac_signer.c crypto/crypto_factory.c crypto/crypto_tester.c \ crypto/diffie_hellman.c crypto/aead.c crypto/transform.c \ crypto/iv/iv_gen_rand.c crypto/iv/iv_gen_seq.c \ +crypto/mgf1/mgf1.c crypto/mgf1/mgf1_bitspender.c \ credentials/credential_factory.c credentials/builder.c \ credentials/cred_encoding.c credentials/keys/private_key.c \ credentials/keys/public_key.c credentials/keys/shared_key.c \ @@ -60,13 +62,15 @@ library.h \ asn1/asn1.h asn1/asn1_parser.h asn1/oid.h bio/bio_reader.h bio/bio_writer.h \ collections/blocking_queue.h collections/enumerator.h collections/hashtable.h \ collections/linked_list.h collections/array.h collections/dictionary.h \ -crypto/crypters/crypter.h crypto/hashers/hasher.h crypto/mac.h \ +crypto/crypters/crypter.h crypto/hashers/hasher.h \ +crypto/hashers/hash_algorithm_set.h crypto/mac.h \ crypto/proposal/proposal_keywords.h crypto/proposal/proposal_keywords_static.h \ crypto/prfs/prf.h crypto/prfs/mac_prf.h crypto/rngs/rng.h crypto/nonce_gen.h \ crypto/prf_plus.h crypto/signers/signer.h crypto/signers/mac_signer.h \ crypto/crypto_factory.h crypto/crypto_tester.h crypto/diffie_hellman.h \ crypto/aead.h crypto/transform.h crypto/pkcs5.h crypto/iv/iv_gen.h \ crypto/iv/iv_gen_rand.h crypto/iv/iv_gen_seq.h \ +crypto/mgf1/mgf1.h crypto/mgf1/mgf1_bitspender.h \ credentials/credential_factory.h credentials/builder.h \ credentials/cred_encoding.h credentials/keys/private_key.h \ credentials/keys/public_key.h credentials/keys/shared_key.h \ @@ -101,8 +105,8 @@ utils/utils.h utils/chunk.h utils/debug.h utils/enum.h utils/identification.h \ utils/lexparser.h utils/optionsfrom.h utils/capabilities.h utils/backtrace.h \ utils/leak_detective.h utils/printf_hook/printf_hook.h \ utils/printf_hook/printf_hook_vstr.h utils/printf_hook/printf_hook_builtin.h \ -utils/parser_helper.h utils/test.h utils/integrity_checker.h utils/windows.h \ -utils/process.h utils/utils/strerror.h +utils/parser_helper.h utils/test.h utils/integrity_checker.h utils/process.h \ +utils/utils/strerror.h utils/compat/windows.h utils/compat/apple.h endif library.lo : $(top_builddir)/config.status @@ -133,7 +137,7 @@ if USE_WINDOWS threading/windows/rwlock.c \ threading/windows/spinlock.c \ threading/windows/semaphore.c \ - utils/windows.c + utils/compat/windows.c else libstrongswan_la_LIBADD += $(PTHREADLIB) endif @@ -425,6 +429,13 @@ if MONOLITHIC endif endif +if USE_FILES + SUBDIRS += plugins/files +if MONOLITHIC + libstrongswan_la_LIBADD += plugins/files/libstrongswan-files.la +endif +endif + if USE_WINHTTP SUBDIRS += plugins/winhttp if MONOLITHIC @@ -544,6 +555,13 @@ if MONOLITHIC endif endif +if USE_BLISS + SUBDIRS += plugins/bliss +if MONOLITHIC + libstrongswan_la_LIBADD += plugins/bliss/libstrongswan-bliss.la +endif +endif + if USE_TEST_VECTORS SUBDIRS += plugins/test_vectors if MONOLITHIC @@ -555,3 +573,6 @@ if MONOLITHIC SUBDIRS += . endif SUBDIRS += tests +if USE_BLISS + SUBDIRS += plugins/bliss/tests +endif diff --git a/src/libstrongswan/Makefile.in b/src/libstrongswan/Makefile.in index 40678cbde..99b18a757 100644 --- a/src/libstrongswan/Makefile.in +++ b/src/libstrongswan/Makefile.in @@ -97,7 +97,7 @@ host_triplet = @host@ @USE_WINDOWS_TRUE@ threading/windows/rwlock.c \ @USE_WINDOWS_TRUE@ threading/windows/spinlock.c \ @USE_WINDOWS_TRUE@ threading/windows/semaphore.c \ -@USE_WINDOWS_TRUE@ utils/windows.c +@USE_WINDOWS_TRUE@ utils/compat/windows.c @USE_WINDOWS_FALSE@am__append_4 = $(PTHREADLIB) @USE_DBGHELP_TRUE@am__append_5 = -ldbghelp @@ -173,42 +173,47 @@ host_triplet = @host@ @MONOLITHIC_TRUE@@USE_PEM_TRUE@am__append_75 = plugins/pem/libstrongswan-pem.la @USE_CURL_TRUE@am__append_76 = plugins/curl @MONOLITHIC_TRUE@@USE_CURL_TRUE@am__append_77 = plugins/curl/libstrongswan-curl.la -@USE_WINHTTP_TRUE@am__append_78 = plugins/winhttp -@MONOLITHIC_TRUE@@USE_WINHTTP_TRUE@am__append_79 = plugins/winhttp/libstrongswan-winhttp.la -@USE_UNBOUND_TRUE@am__append_80 = plugins/unbound -@MONOLITHIC_TRUE@@USE_UNBOUND_TRUE@am__append_81 = plugins/unbound/libstrongswan-unbound.la -@USE_SOUP_TRUE@am__append_82 = plugins/soup -@MONOLITHIC_TRUE@@USE_SOUP_TRUE@am__append_83 = plugins/soup/libstrongswan-soup.la -@USE_LDAP_TRUE@am__append_84 = plugins/ldap -@MONOLITHIC_TRUE@@USE_LDAP_TRUE@am__append_85 = plugins/ldap/libstrongswan-ldap.la -@USE_MYSQL_TRUE@am__append_86 = plugins/mysql -@MONOLITHIC_TRUE@@USE_MYSQL_TRUE@am__append_87 = plugins/mysql/libstrongswan-mysql.la -@USE_SQLITE_TRUE@am__append_88 = plugins/sqlite -@MONOLITHIC_TRUE@@USE_SQLITE_TRUE@am__append_89 = plugins/sqlite/libstrongswan-sqlite.la -@USE_PADLOCK_TRUE@am__append_90 = plugins/padlock -@MONOLITHIC_TRUE@@USE_PADLOCK_TRUE@am__append_91 = plugins/padlock/libstrongswan-padlock.la -@USE_OPENSSL_TRUE@am__append_92 = plugins/openssl -@MONOLITHIC_TRUE@@USE_OPENSSL_TRUE@am__append_93 = plugins/openssl/libstrongswan-openssl.la -@USE_GCRYPT_TRUE@am__append_94 = plugins/gcrypt -@MONOLITHIC_TRUE@@USE_GCRYPT_TRUE@am__append_95 = plugins/gcrypt/libstrongswan-gcrypt.la -@USE_FIPS_PRF_TRUE@am__append_96 = plugins/fips_prf -@MONOLITHIC_TRUE@@USE_FIPS_PRF_TRUE@am__append_97 = plugins/fips_prf/libstrongswan-fips-prf.la -@USE_AGENT_TRUE@am__append_98 = plugins/agent -@MONOLITHIC_TRUE@@USE_AGENT_TRUE@am__append_99 = plugins/agent/libstrongswan-agent.la -@USE_KEYCHAIN_TRUE@am__append_100 = plugins/keychain -@MONOLITHIC_TRUE@@USE_KEYCHAIN_TRUE@am__append_101 = plugins/keychain/libstrongswan-keychain.la -@USE_PKCS11_TRUE@am__append_102 = plugins/pkcs11 -@MONOLITHIC_TRUE@@USE_PKCS11_TRUE@am__append_103 = plugins/pkcs11/libstrongswan-pkcs11.la -@USE_CTR_TRUE@am__append_104 = plugins/ctr -@MONOLITHIC_TRUE@@USE_CTR_TRUE@am__append_105 = plugins/ctr/libstrongswan-ctr.la -@USE_CCM_TRUE@am__append_106 = plugins/ccm -@MONOLITHIC_TRUE@@USE_CCM_TRUE@am__append_107 = plugins/ccm/libstrongswan-ccm.la -@USE_GCM_TRUE@am__append_108 = plugins/gcm -@MONOLITHIC_TRUE@@USE_GCM_TRUE@am__append_109 = plugins/gcm/libstrongswan-gcm.la -@USE_NTRU_TRUE@am__append_110 = plugins/ntru -@MONOLITHIC_TRUE@@USE_NTRU_TRUE@am__append_111 = plugins/ntru/libstrongswan-ntru.la -@USE_TEST_VECTORS_TRUE@am__append_112 = plugins/test_vectors -@MONOLITHIC_TRUE@@USE_TEST_VECTORS_TRUE@am__append_113 = plugins/test_vectors/libstrongswan-test-vectors.la +@USE_FILES_TRUE@am__append_78 = plugins/files +@MONOLITHIC_TRUE@@USE_FILES_TRUE@am__append_79 = plugins/files/libstrongswan-files.la +@USE_WINHTTP_TRUE@am__append_80 = plugins/winhttp +@MONOLITHIC_TRUE@@USE_WINHTTP_TRUE@am__append_81 = plugins/winhttp/libstrongswan-winhttp.la +@USE_UNBOUND_TRUE@am__append_82 = plugins/unbound +@MONOLITHIC_TRUE@@USE_UNBOUND_TRUE@am__append_83 = plugins/unbound/libstrongswan-unbound.la +@USE_SOUP_TRUE@am__append_84 = plugins/soup +@MONOLITHIC_TRUE@@USE_SOUP_TRUE@am__append_85 = plugins/soup/libstrongswan-soup.la +@USE_LDAP_TRUE@am__append_86 = plugins/ldap +@MONOLITHIC_TRUE@@USE_LDAP_TRUE@am__append_87 = plugins/ldap/libstrongswan-ldap.la +@USE_MYSQL_TRUE@am__append_88 = plugins/mysql +@MONOLITHIC_TRUE@@USE_MYSQL_TRUE@am__append_89 = plugins/mysql/libstrongswan-mysql.la +@USE_SQLITE_TRUE@am__append_90 = plugins/sqlite +@MONOLITHIC_TRUE@@USE_SQLITE_TRUE@am__append_91 = plugins/sqlite/libstrongswan-sqlite.la +@USE_PADLOCK_TRUE@am__append_92 = plugins/padlock +@MONOLITHIC_TRUE@@USE_PADLOCK_TRUE@am__append_93 = plugins/padlock/libstrongswan-padlock.la +@USE_OPENSSL_TRUE@am__append_94 = plugins/openssl +@MONOLITHIC_TRUE@@USE_OPENSSL_TRUE@am__append_95 = plugins/openssl/libstrongswan-openssl.la +@USE_GCRYPT_TRUE@am__append_96 = plugins/gcrypt +@MONOLITHIC_TRUE@@USE_GCRYPT_TRUE@am__append_97 = plugins/gcrypt/libstrongswan-gcrypt.la +@USE_FIPS_PRF_TRUE@am__append_98 = plugins/fips_prf +@MONOLITHIC_TRUE@@USE_FIPS_PRF_TRUE@am__append_99 = plugins/fips_prf/libstrongswan-fips-prf.la +@USE_AGENT_TRUE@am__append_100 = plugins/agent +@MONOLITHIC_TRUE@@USE_AGENT_TRUE@am__append_101 = plugins/agent/libstrongswan-agent.la +@USE_KEYCHAIN_TRUE@am__append_102 = plugins/keychain +@MONOLITHIC_TRUE@@USE_KEYCHAIN_TRUE@am__append_103 = plugins/keychain/libstrongswan-keychain.la +@USE_PKCS11_TRUE@am__append_104 = plugins/pkcs11 +@MONOLITHIC_TRUE@@USE_PKCS11_TRUE@am__append_105 = plugins/pkcs11/libstrongswan-pkcs11.la +@USE_CTR_TRUE@am__append_106 = plugins/ctr +@MONOLITHIC_TRUE@@USE_CTR_TRUE@am__append_107 = plugins/ctr/libstrongswan-ctr.la +@USE_CCM_TRUE@am__append_108 = plugins/ccm +@MONOLITHIC_TRUE@@USE_CCM_TRUE@am__append_109 = plugins/ccm/libstrongswan-ccm.la +@USE_GCM_TRUE@am__append_110 = plugins/gcm +@MONOLITHIC_TRUE@@USE_GCM_TRUE@am__append_111 = plugins/gcm/libstrongswan-gcm.la +@USE_NTRU_TRUE@am__append_112 = plugins/ntru +@MONOLITHIC_TRUE@@USE_NTRU_TRUE@am__append_113 = plugins/ntru/libstrongswan-ntru.la +@USE_BLISS_TRUE@am__append_114 = plugins/bliss +@MONOLITHIC_TRUE@@USE_BLISS_TRUE@am__append_115 = plugins/bliss/libstrongswan-bliss.la +@USE_TEST_VECTORS_TRUE@am__append_116 = plugins/test_vectors +@MONOLITHIC_TRUE@@USE_TEST_VECTORS_TRUE@am__append_117 = plugins/test_vectors/libstrongswan-test-vectors.la +@USE_BLISS_TRUE@am__append_118 = plugins/bliss/tests subdir = src/libstrongswan DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ settings/settings_parser.h settings/settings_parser.c \ @@ -287,13 +292,14 @@ libstrongswan_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__append_95) $(am__append_97) $(am__append_99) \ $(am__append_101) $(am__append_103) $(am__append_105) \ $(am__append_107) $(am__append_109) $(am__append_111) \ - $(am__append_113) + $(am__append_113) $(am__append_115) $(am__append_117) am__libstrongswan_la_SOURCES_DIST = library.c asn1/asn1.c \ asn1/asn1_parser.c asn1/oid.c bio/bio_reader.c \ bio/bio_writer.c collections/blocking_queue.c \ collections/enumerator.c collections/hashtable.c \ collections/array.c collections/linked_list.c \ crypto/crypters/crypter.c crypto/hashers/hasher.c \ + crypto/hashers/hash_algorithm_set.c \ crypto/proposal/proposal_keywords.c \ crypto/proposal/proposal_keywords_static.c crypto/prfs/prf.c \ crypto/prfs/mac_prf.c crypto/pkcs5.c crypto/rngs/rng.c \ @@ -301,7 +307,8 @@ am__libstrongswan_la_SOURCES_DIST = library.c asn1/asn1.c \ crypto/signers/mac_signer.c crypto/crypto_factory.c \ crypto/crypto_tester.c crypto/diffie_hellman.c crypto/aead.c \ crypto/transform.c crypto/iv/iv_gen_rand.c \ - crypto/iv/iv_gen_seq.c credentials/credential_factory.c \ + crypto/iv/iv_gen_seq.c crypto/mgf1/mgf1.c \ + crypto/mgf1/mgf1_bitspender.c credentials/credential_factory.c \ credentials/builder.c credentials/cred_encoding.c \ credentials/keys/private_key.c credentials/keys/public_key.c \ credentials/keys/shared_key.c \ @@ -342,7 +349,7 @@ am__libstrongswan_la_SOURCES_DIST = library.c asn1/asn1.c \ threading/windows/thread.c threading/windows/thread_value.c \ threading/windows/mutex.c threading/windows/rwlock.c \ threading/windows/spinlock.c threading/windows/semaphore.c \ - utils/windows.c utils/leak_detective.c \ + utils/compat/windows.c utils/leak_detective.c \ utils/integrity_checker.c utils/printf_hook/printf_hook_vstr.c \ utils/printf_hook/printf_hook_builtin.c \ utils/printf_hook/printf_hook_glibc.c @@ -360,7 +367,7 @@ am__dirstamp = $(am__leading_dot)dirstamp @USE_WINDOWS_TRUE@ threading/windows/rwlock.lo \ @USE_WINDOWS_TRUE@ threading/windows/spinlock.lo \ @USE_WINDOWS_TRUE@ threading/windows/semaphore.lo \ -@USE_WINDOWS_TRUE@ utils/windows.lo +@USE_WINDOWS_TRUE@ utils/compat/windows.lo @USE_LEAK_DETECTIVE_TRUE@am__objects_3 = utils/leak_detective.lo @USE_INTEGRITY_TEST_TRUE@am__objects_4 = utils/integrity_checker.lo @USE_VSTR_TRUE@am__objects_5 = utils/printf_hook/printf_hook_vstr.lo @@ -372,6 +379,7 @@ am_libstrongswan_la_OBJECTS = library.lo asn1/asn1.lo \ collections/enumerator.lo collections/hashtable.lo \ collections/array.lo collections/linked_list.lo \ crypto/crypters/crypter.lo crypto/hashers/hasher.lo \ + crypto/hashers/hash_algorithm_set.lo \ crypto/proposal/proposal_keywords.lo \ crypto/proposal/proposal_keywords_static.lo crypto/prfs/prf.lo \ crypto/prfs/mac_prf.lo crypto/pkcs5.lo crypto/rngs/rng.lo \ @@ -379,10 +387,11 @@ am_libstrongswan_la_OBJECTS = library.lo asn1/asn1.lo \ crypto/signers/mac_signer.lo crypto/crypto_factory.lo \ crypto/crypto_tester.lo crypto/diffie_hellman.lo \ crypto/aead.lo crypto/transform.lo crypto/iv/iv_gen_rand.lo \ - crypto/iv/iv_gen_seq.lo credentials/credential_factory.lo \ - credentials/builder.lo credentials/cred_encoding.lo \ - credentials/keys/private_key.lo credentials/keys/public_key.lo \ - credentials/keys/shared_key.lo \ + crypto/iv/iv_gen_seq.lo crypto/mgf1/mgf1.lo \ + crypto/mgf1/mgf1_bitspender.lo \ + credentials/credential_factory.lo credentials/builder.lo \ + credentials/cred_encoding.lo credentials/keys/private_key.lo \ + credentials/keys/public_key.lo credentials/keys/shared_key.lo \ credentials/certificates/certificate.lo \ credentials/certificates/crl.lo \ credentials/certificates/ocsp_response.lo \ @@ -493,8 +502,8 @@ am__nobase_strongswan_include_HEADERS_DIST = library.h asn1/asn1.h \ collections/enumerator.h collections/hashtable.h \ collections/linked_list.h collections/array.h \ collections/dictionary.h crypto/crypters/crypter.h \ - crypto/hashers/hasher.h crypto/mac.h \ - crypto/proposal/proposal_keywords.h \ + crypto/hashers/hasher.h crypto/hashers/hash_algorithm_set.h \ + crypto/mac.h crypto/proposal/proposal_keywords.h \ crypto/proposal/proposal_keywords_static.h crypto/prfs/prf.h \ crypto/prfs/mac_prf.h crypto/rngs/rng.h crypto/nonce_gen.h \ crypto/prf_plus.h crypto/signers/signer.h \ @@ -502,6 +511,7 @@ am__nobase_strongswan_include_HEADERS_DIST = library.h asn1/asn1.h \ crypto/crypto_tester.h crypto/diffie_hellman.h crypto/aead.h \ crypto/transform.h crypto/pkcs5.h crypto/iv/iv_gen.h \ crypto/iv/iv_gen_rand.h crypto/iv/iv_gen_seq.h \ + crypto/mgf1/mgf1.h crypto/mgf1/mgf1_bitspender.h \ credentials/credential_factory.h credentials/builder.h \ credentials/cred_encoding.h credentials/keys/private_key.h \ credentials/keys/public_key.h credentials/keys/shared_key.h \ @@ -548,8 +558,9 @@ am__nobase_strongswan_include_HEADERS_DIST = library.h asn1/asn1.h \ utils/printf_hook/printf_hook.h \ utils/printf_hook/printf_hook_vstr.h \ utils/printf_hook/printf_hook_builtin.h utils/parser_helper.h \ - utils/test.h utils/integrity_checker.h utils/windows.h \ - utils/process.h utils/utils/strerror.h + utils/test.h utils/integrity_checker.h utils/process.h \ + utils/utils/strerror.h utils/compat/windows.h \ + utils/compat/apple.h HEADERS = $(nobase_strongswan_include_HEADERS) $(noinst_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive @@ -586,11 +597,12 @@ DIST_SUBDIRS = . plugins/af_alg plugins/aes plugins/des \ plugins/constraints plugins/acert plugins/pubkey plugins/pkcs1 \ plugins/pkcs7 plugins/pkcs8 plugins/pkcs12 plugins/pgp \ plugins/dnskey plugins/sshkey plugins/pem plugins/curl \ - plugins/winhttp plugins/unbound plugins/soup plugins/ldap \ - plugins/mysql plugins/sqlite plugins/padlock plugins/openssl \ - plugins/gcrypt plugins/fips_prf plugins/agent plugins/keychain \ - plugins/pkcs11 plugins/ctr plugins/ccm plugins/gcm \ - plugins/ntru plugins/test_vectors tests + plugins/files plugins/winhttp plugins/unbound plugins/soup \ + plugins/ldap plugins/mysql plugins/sqlite plugins/padlock \ + plugins/openssl plugins/gcrypt plugins/fips_prf plugins/agent \ + plugins/keychain plugins/pkcs11 plugins/ctr plugins/ccm \ + plugins/gcm plugins/ntru plugins/bliss plugins/test_vectors \ + tests plugins/bliss/tests DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ @@ -642,6 +654,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -702,10 +715,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -779,6 +794,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ @@ -843,14 +860,16 @@ libstrongswan_la_SOURCES = library.c asn1/asn1.c asn1/asn1_parser.c \ collections/blocking_queue.c collections/enumerator.c \ collections/hashtable.c collections/array.c \ collections/linked_list.c crypto/crypters/crypter.c \ - crypto/hashers/hasher.c crypto/proposal/proposal_keywords.c \ + crypto/hashers/hasher.c crypto/hashers/hash_algorithm_set.c \ + crypto/proposal/proposal_keywords.c \ crypto/proposal/proposal_keywords_static.c crypto/prfs/prf.c \ crypto/prfs/mac_prf.c crypto/pkcs5.c crypto/rngs/rng.c \ crypto/prf_plus.c crypto/signers/signer.c \ crypto/signers/mac_signer.c crypto/crypto_factory.c \ crypto/crypto_tester.c crypto/diffie_hellman.c crypto/aead.c \ crypto/transform.c crypto/iv/iv_gen_rand.c \ - crypto/iv/iv_gen_seq.c credentials/credential_factory.c \ + crypto/iv/iv_gen_seq.c crypto/mgf1/mgf1.c \ + crypto/mgf1/mgf1_bitspender.c credentials/credential_factory.c \ credentials/builder.c credentials/cred_encoding.c \ credentials/keys/private_key.c credentials/keys/public_key.c \ credentials/keys/shared_key.c \ @@ -898,13 +917,15 @@ settings/settings_types.h @USE_DEV_HEADERS_TRUE@asn1/asn1.h asn1/asn1_parser.h asn1/oid.h bio/bio_reader.h bio/bio_writer.h \ @USE_DEV_HEADERS_TRUE@collections/blocking_queue.h collections/enumerator.h collections/hashtable.h \ @USE_DEV_HEADERS_TRUE@collections/linked_list.h collections/array.h collections/dictionary.h \ -@USE_DEV_HEADERS_TRUE@crypto/crypters/crypter.h crypto/hashers/hasher.h crypto/mac.h \ +@USE_DEV_HEADERS_TRUE@crypto/crypters/crypter.h crypto/hashers/hasher.h \ +@USE_DEV_HEADERS_TRUE@crypto/hashers/hash_algorithm_set.h crypto/mac.h \ @USE_DEV_HEADERS_TRUE@crypto/proposal/proposal_keywords.h crypto/proposal/proposal_keywords_static.h \ @USE_DEV_HEADERS_TRUE@crypto/prfs/prf.h crypto/prfs/mac_prf.h crypto/rngs/rng.h crypto/nonce_gen.h \ @USE_DEV_HEADERS_TRUE@crypto/prf_plus.h crypto/signers/signer.h crypto/signers/mac_signer.h \ @USE_DEV_HEADERS_TRUE@crypto/crypto_factory.h crypto/crypto_tester.h crypto/diffie_hellman.h \ @USE_DEV_HEADERS_TRUE@crypto/aead.h crypto/transform.h crypto/pkcs5.h crypto/iv/iv_gen.h \ @USE_DEV_HEADERS_TRUE@crypto/iv/iv_gen_rand.h crypto/iv/iv_gen_seq.h \ +@USE_DEV_HEADERS_TRUE@crypto/mgf1/mgf1.h crypto/mgf1/mgf1_bitspender.h \ @USE_DEV_HEADERS_TRUE@credentials/credential_factory.h credentials/builder.h \ @USE_DEV_HEADERS_TRUE@credentials/cred_encoding.h credentials/keys/private_key.h \ @USE_DEV_HEADERS_TRUE@credentials/keys/public_key.h credentials/keys/shared_key.h \ @@ -939,8 +960,8 @@ settings/settings_types.h @USE_DEV_HEADERS_TRUE@utils/lexparser.h utils/optionsfrom.h utils/capabilities.h utils/backtrace.h \ @USE_DEV_HEADERS_TRUE@utils/leak_detective.h utils/printf_hook/printf_hook.h \ @USE_DEV_HEADERS_TRUE@utils/printf_hook/printf_hook_vstr.h utils/printf_hook/printf_hook_builtin.h \ -@USE_DEV_HEADERS_TRUE@utils/parser_helper.h utils/test.h utils/integrity_checker.h utils/windows.h \ -@USE_DEV_HEADERS_TRUE@utils/process.h utils/utils/strerror.h +@USE_DEV_HEADERS_TRUE@utils/parser_helper.h utils/test.h utils/integrity_checker.h utils/process.h \ +@USE_DEV_HEADERS_TRUE@utils/utils/strerror.h utils/compat/windows.h utils/compat/apple.h libstrongswan_la_LIBADD = $(DLLIB) $(BTLIB) $(SOCKLIB) $(RTLIB) \ $(BFDLIB) $(UNWINDLIB) $(am__append_2) $(am__append_4) \ @@ -961,7 +982,7 @@ libstrongswan_la_LIBADD = $(DLLIB) $(BTLIB) $(SOCKLIB) $(RTLIB) \ $(am__append_95) $(am__append_97) $(am__append_99) \ $(am__append_101) $(am__append_103) $(am__append_105) \ $(am__append_107) $(am__append_109) $(am__append_111) \ - $(am__append_113) + $(am__append_113) $(am__append_115) $(am__append_117) AM_CPPFLAGS = -I$(top_srcdir)/src/libstrongswan \ -DIPSEC_DIR=\"${ipsecdir}\" -DIPSEC_LIB_DIR=\"${ipseclibdir}\" \ -DPLUGINDIR=\"${plugindir}\" \ @@ -1011,7 +1032,9 @@ $(srcdir)/crypto/proposal/proposal_keywords_static.c @MONOLITHIC_FALSE@ $(am__append_98) $(am__append_100) \ @MONOLITHIC_FALSE@ $(am__append_102) $(am__append_104) \ @MONOLITHIC_FALSE@ $(am__append_106) $(am__append_108) \ -@MONOLITHIC_FALSE@ $(am__append_110) $(am__append_112) tests +@MONOLITHIC_FALSE@ $(am__append_110) $(am__append_112) \ +@MONOLITHIC_FALSE@ $(am__append_114) $(am__append_116) tests \ +@MONOLITHIC_FALSE@ $(am__append_118) # build plugins with their own Makefile ####################################### @@ -1038,7 +1061,9 @@ $(srcdir)/crypto/proposal/proposal_keywords_static.c @MONOLITHIC_TRUE@ $(am__append_98) $(am__append_100) \ @MONOLITHIC_TRUE@ $(am__append_102) $(am__append_104) \ @MONOLITHIC_TRUE@ $(am__append_106) $(am__append_108) \ -@MONOLITHIC_TRUE@ $(am__append_110) $(am__append_112) . tests +@MONOLITHIC_TRUE@ $(am__append_110) $(am__append_112) \ +@MONOLITHIC_TRUE@ $(am__append_114) $(am__append_116) . tests \ +@MONOLITHIC_TRUE@ $(am__append_118) all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-recursive @@ -1159,6 +1184,8 @@ crypto/hashers/$(DEPDIR)/$(am__dirstamp): @: > crypto/hashers/$(DEPDIR)/$(am__dirstamp) crypto/hashers/hasher.lo: crypto/hashers/$(am__dirstamp) \ crypto/hashers/$(DEPDIR)/$(am__dirstamp) +crypto/hashers/hash_algorithm_set.lo: crypto/hashers/$(am__dirstamp) \ + crypto/hashers/$(DEPDIR)/$(am__dirstamp) crypto/proposal/$(am__dirstamp): @$(MKDIR_P) crypto/proposal @: > crypto/proposal/$(am__dirstamp) @@ -1228,6 +1255,16 @@ crypto/iv/iv_gen_rand.lo: crypto/iv/$(am__dirstamp) \ crypto/iv/$(DEPDIR)/$(am__dirstamp) crypto/iv/iv_gen_seq.lo: crypto/iv/$(am__dirstamp) \ crypto/iv/$(DEPDIR)/$(am__dirstamp) +crypto/mgf1/$(am__dirstamp): + @$(MKDIR_P) crypto/mgf1 + @: > crypto/mgf1/$(am__dirstamp) +crypto/mgf1/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) crypto/mgf1/$(DEPDIR) + @: > crypto/mgf1/$(DEPDIR)/$(am__dirstamp) +crypto/mgf1/mgf1.lo: crypto/mgf1/$(am__dirstamp) \ + crypto/mgf1/$(DEPDIR)/$(am__dirstamp) +crypto/mgf1/mgf1_bitspender.lo: crypto/mgf1/$(am__dirstamp) \ + crypto/mgf1/$(DEPDIR)/$(am__dirstamp) credentials/$(am__dirstamp): @$(MKDIR_P) credentials @: > credentials/$(am__dirstamp) @@ -1517,8 +1554,14 @@ threading/windows/spinlock.lo: threading/windows/$(am__dirstamp) \ threading/windows/$(DEPDIR)/$(am__dirstamp) threading/windows/semaphore.lo: threading/windows/$(am__dirstamp) \ threading/windows/$(DEPDIR)/$(am__dirstamp) -utils/windows.lo: utils/$(am__dirstamp) \ - utils/$(DEPDIR)/$(am__dirstamp) +utils/compat/$(am__dirstamp): + @$(MKDIR_P) utils/compat + @: > utils/compat/$(am__dirstamp) +utils/compat/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) utils/compat/$(DEPDIR) + @: > utils/compat/$(DEPDIR)/$(am__dirstamp) +utils/compat/windows.lo: utils/compat/$(am__dirstamp) \ + utils/compat/$(DEPDIR)/$(am__dirstamp) utils/leak_detective.lo: utils/$(am__dirstamp) \ utils/$(DEPDIR)/$(am__dirstamp) utils/integrity_checker.lo: utils/$(am__dirstamp) \ @@ -1568,6 +1611,8 @@ mostlyclean-compile: -rm -f crypto/hashers/*.lo -rm -f crypto/iv/*.$(OBJEXT) -rm -f crypto/iv/*.lo + -rm -f crypto/mgf1/*.$(OBJEXT) + -rm -f crypto/mgf1/*.lo -rm -f crypto/prfs/*.$(OBJEXT) -rm -f crypto/prfs/*.lo -rm -f crypto/proposal/*.$(OBJEXT) @@ -1608,6 +1653,8 @@ mostlyclean-compile: -rm -f threading/windows/*.lo -rm -f utils/*.$(OBJEXT) -rm -f utils/*.lo + -rm -f utils/compat/*.$(OBJEXT) + -rm -f utils/compat/*.lo -rm -f utils/printf_hook/*.$(OBJEXT) -rm -f utils/printf_hook/*.lo -rm -f utils/utils/*.$(OBJEXT) @@ -1653,9 +1700,12 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@crypto/$(DEPDIR)/prf_plus.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@crypto/$(DEPDIR)/transform.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@crypto/crypters/$(DEPDIR)/crypter.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@crypto/hashers/$(DEPDIR)/hash_algorithm_set.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@crypto/hashers/$(DEPDIR)/hasher.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@crypto/iv/$(DEPDIR)/iv_gen_rand.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@crypto/iv/$(DEPDIR)/iv_gen_seq.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@crypto/mgf1/$(DEPDIR)/mgf1.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@crypto/mgf1/$(DEPDIR)/mgf1_bitspender.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@crypto/prfs/$(DEPDIR)/mac_prf.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@crypto/prfs/$(DEPDIR)/prf.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@crypto/proposal/$(DEPDIR)/proposal_keywords.Plo@am__quote@ @@ -1721,7 +1771,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/process.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/test.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/utils.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@utils/$(DEPDIR)/windows.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@utils/compat/$(DEPDIR)/windows.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@utils/printf_hook/$(DEPDIR)/printf_hook_builtin.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@utils/printf_hook/$(DEPDIR)/printf_hook_glibc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@utils/printf_hook/$(DEPDIR)/printf_hook_vstr.Plo@am__quote@ @@ -1774,6 +1824,7 @@ clean-libtool: -rm -rf crypto/crypters/.libs crypto/crypters/_libs -rm -rf crypto/hashers/.libs crypto/hashers/_libs -rm -rf crypto/iv/.libs crypto/iv/_libs + -rm -rf crypto/mgf1/.libs crypto/mgf1/_libs -rm -rf crypto/prfs/.libs crypto/prfs/_libs -rm -rf crypto/proposal/.libs crypto/proposal/_libs -rm -rf crypto/rngs/.libs crypto/rngs/_libs @@ -1794,6 +1845,7 @@ clean-libtool: -rm -rf threading/.libs threading/_libs -rm -rf threading/windows/.libs threading/windows/_libs -rm -rf utils/.libs utils/_libs + -rm -rf utils/compat/.libs utils/compat/_libs -rm -rf utils/printf_hook/.libs utils/printf_hook/_libs -rm -rf utils/utils/.libs utils/utils/_libs install-nobase_strongswan_includeHEADERS: $(nobase_strongswan_include_HEADERS) @@ -2035,6 +2087,8 @@ distclean-generic: -rm -f crypto/hashers/$(am__dirstamp) -rm -f crypto/iv/$(DEPDIR)/$(am__dirstamp) -rm -f crypto/iv/$(am__dirstamp) + -rm -f crypto/mgf1/$(DEPDIR)/$(am__dirstamp) + -rm -f crypto/mgf1/$(am__dirstamp) -rm -f crypto/prfs/$(DEPDIR)/$(am__dirstamp) -rm -f crypto/prfs/$(am__dirstamp) -rm -f crypto/proposal/$(DEPDIR)/$(am__dirstamp) @@ -2075,6 +2129,8 @@ distclean-generic: -rm -f threading/windows/$(am__dirstamp) -rm -f utils/$(DEPDIR)/$(am__dirstamp) -rm -f utils/$(am__dirstamp) + -rm -f utils/compat/$(DEPDIR)/$(am__dirstamp) + -rm -f utils/compat/$(am__dirstamp) -rm -f utils/printf_hook/$(DEPDIR)/$(am__dirstamp) -rm -f utils/printf_hook/$(am__dirstamp) -rm -f utils/utils/$(DEPDIR)/$(am__dirstamp) @@ -2094,7 +2150,7 @@ clean-am: clean-generic clean-ipseclibLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-recursive - -rm -rf ./$(DEPDIR) asn1/$(DEPDIR) bio/$(DEPDIR) collections/$(DEPDIR) credentials/$(DEPDIR) credentials/certificates/$(DEPDIR) credentials/containers/$(DEPDIR) credentials/keys/$(DEPDIR) credentials/sets/$(DEPDIR) crypto/$(DEPDIR) crypto/crypters/$(DEPDIR) crypto/hashers/$(DEPDIR) crypto/iv/$(DEPDIR) crypto/prfs/$(DEPDIR) crypto/proposal/$(DEPDIR) crypto/rngs/$(DEPDIR) crypto/signers/$(DEPDIR) database/$(DEPDIR) eap/$(DEPDIR) fetcher/$(DEPDIR) ipsec/$(DEPDIR) networking/$(DEPDIR) networking/streams/$(DEPDIR) pen/$(DEPDIR) plugins/$(DEPDIR) processing/$(DEPDIR) processing/jobs/$(DEPDIR) resolver/$(DEPDIR) selectors/$(DEPDIR) settings/$(DEPDIR) threading/$(DEPDIR) threading/windows/$(DEPDIR) utils/$(DEPDIR) utils/printf_hook/$(DEPDIR) utils/utils/$(DEPDIR) + -rm -rf ./$(DEPDIR) asn1/$(DEPDIR) bio/$(DEPDIR) collections/$(DEPDIR) credentials/$(DEPDIR) credentials/certificates/$(DEPDIR) credentials/containers/$(DEPDIR) credentials/keys/$(DEPDIR) credentials/sets/$(DEPDIR) crypto/$(DEPDIR) crypto/crypters/$(DEPDIR) crypto/hashers/$(DEPDIR) crypto/iv/$(DEPDIR) crypto/mgf1/$(DEPDIR) crypto/prfs/$(DEPDIR) crypto/proposal/$(DEPDIR) crypto/rngs/$(DEPDIR) crypto/signers/$(DEPDIR) database/$(DEPDIR) eap/$(DEPDIR) fetcher/$(DEPDIR) ipsec/$(DEPDIR) networking/$(DEPDIR) networking/streams/$(DEPDIR) pen/$(DEPDIR) plugins/$(DEPDIR) processing/$(DEPDIR) processing/jobs/$(DEPDIR) resolver/$(DEPDIR) selectors/$(DEPDIR) settings/$(DEPDIR) threading/$(DEPDIR) threading/windows/$(DEPDIR) utils/$(DEPDIR) utils/compat/$(DEPDIR) utils/printf_hook/$(DEPDIR) utils/utils/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -2141,7 +2197,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive - -rm -rf ./$(DEPDIR) asn1/$(DEPDIR) bio/$(DEPDIR) collections/$(DEPDIR) credentials/$(DEPDIR) credentials/certificates/$(DEPDIR) credentials/containers/$(DEPDIR) credentials/keys/$(DEPDIR) credentials/sets/$(DEPDIR) crypto/$(DEPDIR) crypto/crypters/$(DEPDIR) crypto/hashers/$(DEPDIR) crypto/iv/$(DEPDIR) crypto/prfs/$(DEPDIR) crypto/proposal/$(DEPDIR) crypto/rngs/$(DEPDIR) crypto/signers/$(DEPDIR) database/$(DEPDIR) eap/$(DEPDIR) fetcher/$(DEPDIR) ipsec/$(DEPDIR) networking/$(DEPDIR) networking/streams/$(DEPDIR) pen/$(DEPDIR) plugins/$(DEPDIR) processing/$(DEPDIR) processing/jobs/$(DEPDIR) resolver/$(DEPDIR) selectors/$(DEPDIR) settings/$(DEPDIR) threading/$(DEPDIR) threading/windows/$(DEPDIR) utils/$(DEPDIR) utils/printf_hook/$(DEPDIR) utils/utils/$(DEPDIR) + -rm -rf ./$(DEPDIR) asn1/$(DEPDIR) bio/$(DEPDIR) collections/$(DEPDIR) credentials/$(DEPDIR) credentials/certificates/$(DEPDIR) credentials/containers/$(DEPDIR) credentials/keys/$(DEPDIR) credentials/sets/$(DEPDIR) crypto/$(DEPDIR) crypto/crypters/$(DEPDIR) crypto/hashers/$(DEPDIR) crypto/iv/$(DEPDIR) crypto/mgf1/$(DEPDIR) crypto/prfs/$(DEPDIR) crypto/proposal/$(DEPDIR) crypto/rngs/$(DEPDIR) crypto/signers/$(DEPDIR) database/$(DEPDIR) eap/$(DEPDIR) fetcher/$(DEPDIR) ipsec/$(DEPDIR) networking/$(DEPDIR) networking/streams/$(DEPDIR) pen/$(DEPDIR) plugins/$(DEPDIR) processing/$(DEPDIR) processing/jobs/$(DEPDIR) resolver/$(DEPDIR) selectors/$(DEPDIR) settings/$(DEPDIR) threading/$(DEPDIR) threading/windows/$(DEPDIR) utils/$(DEPDIR) utils/compat/$(DEPDIR) utils/printf_hook/$(DEPDIR) utils/utils/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic diff --git a/src/libstrongswan/asn1/oid.c b/src/libstrongswan/asn1/oid.c index b479b0f4b..a750f7fcb 100644 --- a/src/libstrongswan/asn1/oid.c +++ b/src/libstrongswan/asn1/oid.c @@ -199,12 +199,12 @@ const oid_t oid_names[] = { { 0x02, 187, 0, 7, "ecdsa-with-SHA256" }, /* 186 */ { 0x03, 188, 0, 7, "ecdsa-with-SHA384" }, /* 187 */ { 0x04, 0, 0, 7, "ecdsa-with-SHA512" }, /* 188 */ - {0x2B, 391, 1, 0, "" }, /* 189 */ - { 0x06, 305, 1, 1, "dod" }, /* 190 */ + {0x2B, 413, 1, 0, "" }, /* 189 */ + { 0x06, 327, 1, 1, "dod" }, /* 190 */ { 0x01, 0, 1, 2, "internet" }, /* 191 */ - { 0x04, 256, 1, 3, "private" }, /* 192 */ + { 0x04, 278, 1, 3, "private" }, /* 192 */ { 0x01, 0, 1, 4, "enterprise" }, /* 193 */ - { 0x82, 210, 1, 5, "" }, /* 194 */ + { 0x82, 228, 1, 5, "" }, /* 194 */ { 0x37, 207, 1, 6, "Microsoft" }, /* 195 */ { 0x0A, 200, 1, 7, "" }, /* 196 */ { 0x03, 0, 1, 8, "" }, /* 197 */ @@ -219,248 +219,270 @@ const oid_t oid_names[] = { { 0x0A, 0, 0, 8, "msApplicationCertPolicies" }, /* 206 */ { 0xA0, 0, 1, 6, "" }, /* 207 */ { 0x2A, 0, 1, 7, "ITA" }, /* 208 */ - { 0x01, 0, 0, 8, "strongSwan" }, /* 209 */ - { 0x89, 217, 1, 5, "" }, /* 210 */ - { 0x31, 0, 1, 6, "" }, /* 211 */ - { 0x01, 0, 1, 7, "" }, /* 212 */ - { 0x01, 0, 1, 8, "" }, /* 213 */ - { 0x02, 0, 1, 9, "" }, /* 214 */ - { 0x02, 0, 1, 10, "" }, /* 215 */ - { 0x4B, 0, 0, 11, "TCGID" }, /* 216 */ - { 0xC1, 0, 1, 5, "" }, /* 217 */ - { 0x16, 0, 1, 6, "ntruCryptosystems" }, /* 218 */ - { 0x01, 0, 1, 7, "eess" }, /* 219 */ - { 0x01, 0, 1, 8, "eess1" }, /* 220 */ - { 0x01, 225, 1, 9, "eess1-algs" }, /* 221 */ - { 0x01, 223, 0, 10, "ntru-EESS1v1-SVES" }, /* 222 */ - { 0x02, 224, 0, 10, "ntru-EESS1v1-SVSSA" }, /* 223 */ - { 0x03, 0, 0, 10, "ntru-EESS1v1-NTRUSign" }, /* 224 */ - { 0x02, 255, 1, 9, "eess1-params" }, /* 225 */ - { 0x01, 227, 0, 10, "ees251ep1" }, /* 226 */ - { 0x02, 228, 0, 10, "ees347ep1" }, /* 227 */ - { 0x03, 229, 0, 10, "ees503ep1" }, /* 228 */ - { 0x07, 230, 0, 10, "ees251sp2" }, /* 229 */ - { 0x0C, 231, 0, 10, "ees251ep4" }, /* 230 */ - { 0x0D, 232, 0, 10, "ees251ep5" }, /* 231 */ - { 0x0E, 233, 0, 10, "ees251sp3" }, /* 232 */ - { 0x0F, 234, 0, 10, "ees251sp4" }, /* 233 */ - { 0x10, 235, 0, 10, "ees251sp5" }, /* 234 */ - { 0x11, 236, 0, 10, "ees251sp6" }, /* 235 */ - { 0x12, 237, 0, 10, "ees251sp7" }, /* 236 */ - { 0x13, 238, 0, 10, "ees251sp8" }, /* 237 */ - { 0x14, 239, 0, 10, "ees251sp9" }, /* 238 */ - { 0x22, 240, 0, 10, "ees401ep1" }, /* 239 */ - { 0x23, 241, 0, 10, "ees449ep1" }, /* 240 */ - { 0x24, 242, 0, 10, "ees677ep1" }, /* 241 */ - { 0x25, 243, 0, 10, "ees1087ep2" }, /* 242 */ - { 0x26, 244, 0, 10, "ees541ep1" }, /* 243 */ - { 0x27, 245, 0, 10, "ees613ep1" }, /* 244 */ - { 0x28, 246, 0, 10, "ees887ep1" }, /* 245 */ - { 0x29, 247, 0, 10, "ees1171ep1" }, /* 246 */ - { 0x2A, 248, 0, 10, "ees659ep1" }, /* 247 */ - { 0x2B, 249, 0, 10, "ees761ep1" }, /* 248 */ - { 0x2C, 250, 0, 10, "ees1087ep1" }, /* 249 */ - { 0x2D, 251, 0, 10, "ees1499ep1" }, /* 250 */ - { 0x2E, 252, 0, 10, "ees401ep2" }, /* 251 */ - { 0x2F, 253, 0, 10, "ees439ep1" }, /* 252 */ - { 0x30, 254, 0, 10, "ees593ep1" }, /* 253 */ - { 0x31, 0, 0, 10, "ees743ep1" }, /* 254 */ - { 0x03, 0, 0, 9, "eess1-encodingMethods" }, /* 255 */ - { 0x05, 0, 1, 3, "security" }, /* 256 */ - { 0x05, 0, 1, 4, "mechanisms" }, /* 257 */ - { 0x07, 302, 1, 5, "id-pkix" }, /* 258 */ - { 0x01, 263, 1, 6, "id-pe" }, /* 259 */ - { 0x01, 261, 0, 7, "authorityInfoAccess" }, /* 260 */ - { 0x03, 262, 0, 7, "qcStatements" }, /* 261 */ - { 0x07, 0, 0, 7, "ipAddrBlocks" }, /* 262 */ - { 0x02, 266, 1, 6, "id-qt" }, /* 263 */ - { 0x01, 265, 0, 7, "cps" }, /* 264 */ - { 0x02, 0, 0, 7, "unotice" }, /* 265 */ - { 0x03, 276, 1, 6, "id-kp" }, /* 266 */ - { 0x01, 268, 0, 7, "serverAuth" }, /* 267 */ - { 0x02, 269, 0, 7, "clientAuth" }, /* 268 */ - { 0x03, 270, 0, 7, "codeSigning" }, /* 269 */ - { 0x04, 271, 0, 7, "emailProtection" }, /* 270 */ - { 0x05, 272, 0, 7, "ipsecEndSystem" }, /* 271 */ - { 0x06, 273, 0, 7, "ipsecTunnel" }, /* 272 */ - { 0x07, 274, 0, 7, "ipsecUser" }, /* 273 */ - { 0x08, 275, 0, 7, "timeStamping" }, /* 274 */ - { 0x09, 0, 0, 7, "ocspSigning" }, /* 275 */ - { 0x08, 284, 1, 6, "id-otherNames" }, /* 276 */ - { 0x01, 278, 0, 7, "personalData" }, /* 277 */ - { 0x02, 279, 0, 7, "userGroup" }, /* 278 */ - { 0x03, 280, 0, 7, "id-on-permanentIdentifier" }, /* 279 */ - { 0x04, 281, 0, 7, "id-on-hardwareModuleName" }, /* 280 */ - { 0x05, 282, 0, 7, "xmppAddr" }, /* 281 */ - { 0x06, 283, 0, 7, "id-on-SIM" }, /* 282 */ - { 0x07, 0, 0, 7, "id-on-dnsSRV" }, /* 283 */ - { 0x0A, 289, 1, 6, "id-aca" }, /* 284 */ - { 0x01, 286, 0, 7, "authenticationInfo" }, /* 285 */ - { 0x02, 287, 0, 7, "accessIdentity" }, /* 286 */ - { 0x03, 288, 0, 7, "chargingIdentity" }, /* 287 */ - { 0x04, 0, 0, 7, "group" }, /* 288 */ - { 0x0B, 290, 0, 6, "subjectInfoAccess" }, /* 289 */ - { 0x30, 0, 1, 6, "id-ad" }, /* 290 */ - { 0x01, 299, 1, 7, "ocsp" }, /* 291 */ - { 0x01, 293, 0, 8, "basic" }, /* 292 */ - { 0x02, 294, 0, 8, "nonce" }, /* 293 */ - { 0x03, 295, 0, 8, "crl" }, /* 294 */ - { 0x04, 296, 0, 8, "response" }, /* 295 */ - { 0x05, 297, 0, 8, "noCheck" }, /* 296 */ - { 0x06, 298, 0, 8, "archiveCutoff" }, /* 297 */ - { 0x07, 0, 0, 8, "serviceLocator" }, /* 298 */ - { 0x02, 300, 0, 7, "caIssuers" }, /* 299 */ - { 0x03, 301, 0, 7, "timeStamping" }, /* 300 */ - { 0x05, 0, 0, 7, "caRepository" }, /* 301 */ - { 0x08, 0, 1, 5, "ipsec" }, /* 302 */ - { 0x02, 0, 1, 6, "certificate" }, /* 303 */ - { 0x02, 0, 0, 7, "iKEIntermediate" }, /* 304 */ - { 0x0E, 311, 1, 1, "oiw" }, /* 305 */ - { 0x03, 0, 1, 2, "secsig" }, /* 306 */ - { 0x02, 0, 1, 3, "algorithms" }, /* 307 */ - { 0x07, 309, 0, 4, "des-cbc" }, /* 308 */ - { 0x1A, 310, 0, 4, "sha-1" }, /* 309 */ - { 0x1D, 0, 0, 4, "sha-1WithRSASignature" }, /* 310 */ - { 0x24, 357, 1, 1, "TeleTrusT" }, /* 311 */ - { 0x03, 0, 1, 2, "algorithm" }, /* 312 */ - { 0x03, 0, 1, 3, "signatureAlgorithm" }, /* 313 */ - { 0x01, 318, 1, 4, "rsaSignature" }, /* 314 */ - { 0x02, 316, 0, 5, "rsaSigWithripemd160" }, /* 315 */ - { 0x03, 317, 0, 5, "rsaSigWithripemd128" }, /* 316 */ - { 0x04, 0, 0, 5, "rsaSigWithripemd256" }, /* 317 */ - { 0x02, 0, 1, 4, "ecSign" }, /* 318 */ - { 0x01, 320, 0, 5, "ecSignWithsha1" }, /* 319 */ - { 0x02, 321, 0, 5, "ecSignWithripemd160" }, /* 320 */ - { 0x03, 322, 0, 5, "ecSignWithmd2" }, /* 321 */ - { 0x04, 323, 0, 5, "ecSignWithmd5" }, /* 322 */ - { 0x05, 340, 1, 5, "ttt-ecg" }, /* 323 */ - { 0x01, 328, 1, 6, "fieldType" }, /* 324 */ - { 0x01, 0, 1, 7, "characteristictwoField" }, /* 325 */ - { 0x01, 0, 1, 8, "basisType" }, /* 326 */ - { 0x01, 0, 0, 9, "ipBasis" }, /* 327 */ - { 0x02, 330, 1, 6, "keyType" }, /* 328 */ - { 0x01, 0, 0, 7, "ecgPublicKey" }, /* 329 */ - { 0x03, 331, 0, 6, "curve" }, /* 330 */ - { 0x04, 338, 1, 6, "signatures" }, /* 331 */ - { 0x01, 333, 0, 7, "ecgdsa-with-RIPEMD160" }, /* 332 */ - { 0x02, 334, 0, 7, "ecgdsa-with-SHA1" }, /* 333 */ - { 0x03, 335, 0, 7, "ecgdsa-with-SHA224" }, /* 334 */ - { 0x04, 336, 0, 7, "ecgdsa-with-SHA256" }, /* 335 */ - { 0x05, 337, 0, 7, "ecgdsa-with-SHA384" }, /* 336 */ - { 0x06, 0, 0, 7, "ecgdsa-with-SHA512" }, /* 337 */ - { 0x05, 0, 1, 6, "module" }, /* 338 */ - { 0x01, 0, 0, 7, "1" }, /* 339 */ - { 0x08, 0, 1, 5, "ecStdCurvesAndGeneration" }, /* 340 */ - { 0x01, 0, 1, 6, "ellipticCurve" }, /* 341 */ - { 0x01, 0, 1, 7, "versionOne" }, /* 342 */ - { 0x01, 344, 0, 8, "brainpoolP160r1" }, /* 343 */ - { 0x02, 345, 0, 8, "brainpoolP160t1" }, /* 344 */ - { 0x03, 346, 0, 8, "brainpoolP192r1" }, /* 345 */ - { 0x04, 347, 0, 8, "brainpoolP192t1" }, /* 346 */ - { 0x05, 348, 0, 8, "brainpoolP224r1" }, /* 347 */ - { 0x06, 349, 0, 8, "brainpoolP224t1" }, /* 348 */ - { 0x07, 350, 0, 8, "brainpoolP256r1" }, /* 349 */ - { 0x08, 351, 0, 8, "brainpoolP256t1" }, /* 350 */ - { 0x09, 352, 0, 8, "brainpoolP320r1" }, /* 351 */ - { 0x0A, 353, 0, 8, "brainpoolP320t1" }, /* 352 */ - { 0x0B, 354, 0, 8, "brainpoolP384r1" }, /* 353 */ - { 0x0C, 355, 0, 8, "brainpoolP384t1" }, /* 354 */ - { 0x0D, 356, 0, 8, "brainpoolP512r1" }, /* 355 */ - { 0x0E, 0, 0, 8, "brainpoolP512t1" }, /* 356 */ - { 0x81, 0, 1, 1, "" }, /* 357 */ - { 0x04, 0, 1, 2, "Certicom" }, /* 358 */ - { 0x00, 0, 1, 3, "curve" }, /* 359 */ - { 0x01, 361, 0, 4, "sect163k1" }, /* 360 */ - { 0x02, 362, 0, 4, "sect163r1" }, /* 361 */ - { 0x03, 363, 0, 4, "sect239k1" }, /* 362 */ - { 0x04, 364, 0, 4, "sect113r1" }, /* 363 */ - { 0x05, 365, 0, 4, "sect113r2" }, /* 364 */ - { 0x06, 366, 0, 4, "secp112r1" }, /* 365 */ - { 0x07, 367, 0, 4, "secp112r2" }, /* 366 */ - { 0x08, 368, 0, 4, "secp160r1" }, /* 367 */ - { 0x09, 369, 0, 4, "secp160k1" }, /* 368 */ - { 0x0A, 370, 0, 4, "secp256k1" }, /* 369 */ - { 0x0F, 371, 0, 4, "sect163r2" }, /* 370 */ - { 0x10, 372, 0, 4, "sect283k1" }, /* 371 */ - { 0x11, 373, 0, 4, "sect283r1" }, /* 372 */ - { 0x16, 374, 0, 4, "sect131r1" }, /* 373 */ - { 0x17, 375, 0, 4, "sect131r2" }, /* 374 */ - { 0x18, 376, 0, 4, "sect193r1" }, /* 375 */ - { 0x19, 377, 0, 4, "sect193r2" }, /* 376 */ - { 0x1A, 378, 0, 4, "sect233k1" }, /* 377 */ - { 0x1B, 379, 0, 4, "sect233r1" }, /* 378 */ - { 0x1C, 380, 0, 4, "secp128r1" }, /* 379 */ - { 0x1D, 381, 0, 4, "secp128r2" }, /* 380 */ - { 0x1E, 382, 0, 4, "secp160r2" }, /* 381 */ - { 0x1F, 383, 0, 4, "secp192k1" }, /* 382 */ - { 0x20, 384, 0, 4, "secp224k1" }, /* 383 */ - { 0x21, 385, 0, 4, "secp224r1" }, /* 384 */ - { 0x22, 386, 0, 4, "secp384r1" }, /* 385 */ - { 0x23, 387, 0, 4, "secp521r1" }, /* 386 */ - { 0x24, 388, 0, 4, "sect409k1" }, /* 387 */ - { 0x25, 389, 0, 4, "sect409r1" }, /* 388 */ - { 0x26, 390, 0, 4, "sect571k1" }, /* 389 */ - { 0x27, 0, 0, 4, "sect571r1" }, /* 390 */ - {0x60, 445, 1, 0, "" }, /* 391 */ - { 0x86, 0, 1, 1, "" }, /* 392 */ - { 0x48, 0, 1, 2, "" }, /* 393 */ - { 0x01, 0, 1, 3, "organization" }, /* 394 */ - { 0x65, 421, 1, 4, "gov" }, /* 395 */ - { 0x03, 0, 1, 5, "csor" }, /* 396 */ - { 0x04, 0, 1, 6, "nistalgorithm" }, /* 397 */ - { 0x01, 408, 1, 7, "aes" }, /* 398 */ - { 0x02, 400, 0, 8, "id-aes128-CBC" }, /* 399 */ - { 0x06, 401, 0, 8, "id-aes128-GCM" }, /* 400 */ - { 0x07, 402, 0, 8, "id-aes128-CCM" }, /* 401 */ - { 0x16, 403, 0, 8, "id-aes192-CBC" }, /* 402 */ - { 0x1A, 404, 0, 8, "id-aes192-GCM" }, /* 403 */ - { 0x1B, 405, 0, 8, "id-aes192-CCM" }, /* 404 */ - { 0x2A, 406, 0, 8, "id-aes256-CBC" }, /* 405 */ - { 0x2E, 407, 0, 8, "id-aes256-GCM" }, /* 406 */ - { 0x2F, 0, 0, 8, "id-aes256-CCM" }, /* 407 */ - { 0x02, 0, 1, 7, "hashalgs" }, /* 408 */ - { 0x01, 410, 0, 8, "id-sha256" }, /* 409 */ - { 0x02, 411, 0, 8, "id-sha384" }, /* 410 */ - { 0x03, 412, 0, 8, "id-sha512" }, /* 411 */ - { 0x04, 413, 0, 8, "id-sha224" }, /* 412 */ - { 0x05, 414, 0, 8, "id-sha512-224" }, /* 413 */ - { 0x06, 415, 0, 8, "id-sha512-256" }, /* 414 */ - { 0x07, 416, 0, 8, "id-sha3-224" }, /* 415 */ - { 0x08, 417, 0, 8, "id-sha3-256" }, /* 416 */ - { 0x09, 418, 0, 8, "id-sha3-384" }, /* 417 */ - { 0x0A, 419, 0, 8, "id-sha3-512" }, /* 418 */ - { 0x0B, 420, 0, 8, "id-shake128" }, /* 419 */ - { 0x0C, 0, 0, 8, "id-shake256" }, /* 420 */ - { 0x86, 0, 1, 4, "" }, /* 421 */ - { 0xf8, 0, 1, 5, "" }, /* 422 */ - { 0x42, 435, 1, 6, "netscape" }, /* 423 */ - { 0x01, 430, 1, 7, "" }, /* 424 */ - { 0x01, 426, 0, 8, "nsCertType" }, /* 425 */ - { 0x03, 427, 0, 8, "nsRevocationUrl" }, /* 426 */ - { 0x04, 428, 0, 8, "nsCaRevocationUrl" }, /* 427 */ - { 0x08, 429, 0, 8, "nsCaPolicyUrl" }, /* 428 */ - { 0x0d, 0, 0, 8, "nsComment" }, /* 429 */ - { 0x03, 433, 1, 7, "directory" }, /* 430 */ - { 0x01, 0, 1, 8, "" }, /* 431 */ - { 0x03, 0, 0, 9, "employeeNumber" }, /* 432 */ - { 0x04, 0, 1, 7, "policy" }, /* 433 */ - { 0x01, 0, 0, 8, "nsSGC" }, /* 434 */ - { 0x45, 0, 1, 6, "verisign" }, /* 435 */ - { 0x01, 0, 1, 7, "pki" }, /* 436 */ - { 0x09, 0, 1, 8, "attributes" }, /* 437 */ - { 0x02, 439, 0, 9, "messageType" }, /* 438 */ - { 0x03, 440, 0, 9, "pkiStatus" }, /* 439 */ - { 0x04, 441, 0, 9, "failInfo" }, /* 440 */ - { 0x05, 442, 0, 9, "senderNonce" }, /* 441 */ - { 0x06, 443, 0, 9, "recipientNonce" }, /* 442 */ - { 0x07, 444, 0, 9, "transID" }, /* 443 */ - { 0x08, 0, 0, 9, "extensionReq" }, /* 444 */ - {0x67, 0, 1, 0, "" }, /* 445 */ - { 0x81, 0, 1, 1, "" }, /* 446 */ - { 0x05, 0, 1, 2, "" }, /* 447 */ - { 0x02, 0, 1, 3, "tcg-attribute" }, /* 448 */ - { 0x01, 450, 0, 4, "tcg-at-tpmManufacturer" }, /* 449 */ - { 0x02, 451, 0, 4, "tcg-at-tpmModel" }, /* 450 */ - { 0x03, 452, 0, 4, "tcg-at-tpmVersion" }, /* 451 */ - { 0x0F, 0, 0, 4, "tcg-at-tpmIdLabel" } /* 452 */ + { 0x01, 210, 0, 8, "strongSwan" }, /* 209 */ + { 0x02, 211, 0, 8, "cps" }, /* 210 */ + { 0x03, 212, 0, 8, "e-voting" }, /* 211 */ + { 0x05, 0, 1, 8, "BLISS" }, /* 212 */ + { 0x01, 215, 1, 9, "keyType" }, /* 213 */ + { 0x01, 0, 0, 10, "blissPublicKey" }, /* 214 */ + { 0x02, 224, 1, 9, "parameters" }, /* 215 */ + { 0x01, 217, 0, 10, "BLISS-I" }, /* 216 */ + { 0x02, 218, 0, 10, "BLISS-II" }, /* 217 */ + { 0x03, 219, 0, 10, "BLISS-III" }, /* 218 */ + { 0x04, 220, 0, 10, "BLISS-IV" }, /* 219 */ + { 0x05, 221, 0, 10, "BLISS-B-I" }, /* 220 */ + { 0x06, 222, 0, 10, "BLISS-B-II" }, /* 221 */ + { 0x07, 223, 0, 10, "BLISS-B-III" }, /* 222 */ + { 0x08, 0, 0, 10, "BLISS-B-IV" }, /* 223 */ + { 0x03, 0, 1, 9, "blissSigType" }, /* 224 */ + { 0x01, 226, 0, 10, "BLISS-with-SHA512" }, /* 225 */ + { 0x02, 227, 0, 10, "BLISS-with-SHA384" }, /* 226 */ + { 0x03, 0, 0, 10, "BLISS-with-SHA256" }, /* 227 */ + { 0x89, 235, 1, 5, "" }, /* 228 */ + { 0x31, 0, 1, 6, "" }, /* 229 */ + { 0x01, 0, 1, 7, "" }, /* 230 */ + { 0x01, 0, 1, 8, "" }, /* 231 */ + { 0x02, 0, 1, 9, "" }, /* 232 */ + { 0x02, 0, 1, 10, "" }, /* 233 */ + { 0x4B, 0, 0, 11, "TCGID" }, /* 234 */ + { 0x97, 239, 1, 5, "" }, /* 235 */ + { 0x55, 0, 1, 6, "" }, /* 236 */ + { 0x01, 0, 1, 7, "" }, /* 237 */ + { 0x02, 0, 0, 8, "blowfish-cbc" }, /* 238 */ + { 0xC1, 0, 1, 5, "" }, /* 239 */ + { 0x16, 0, 1, 6, "ntruCryptosystems" }, /* 240 */ + { 0x01, 0, 1, 7, "eess" }, /* 241 */ + { 0x01, 0, 1, 8, "eess1" }, /* 242 */ + { 0x01, 247, 1, 9, "eess1-algs" }, /* 243 */ + { 0x01, 245, 0, 10, "ntru-EESS1v1-SVES" }, /* 244 */ + { 0x02, 246, 0, 10, "ntru-EESS1v1-SVSSA" }, /* 245 */ + { 0x03, 0, 0, 10, "ntru-EESS1v1-NTRUSign" }, /* 246 */ + { 0x02, 277, 1, 9, "eess1-params" }, /* 247 */ + { 0x01, 249, 0, 10, "ees251ep1" }, /* 248 */ + { 0x02, 250, 0, 10, "ees347ep1" }, /* 249 */ + { 0x03, 251, 0, 10, "ees503ep1" }, /* 250 */ + { 0x07, 252, 0, 10, "ees251sp2" }, /* 251 */ + { 0x0C, 253, 0, 10, "ees251ep4" }, /* 252 */ + { 0x0D, 254, 0, 10, "ees251ep5" }, /* 253 */ + { 0x0E, 255, 0, 10, "ees251sp3" }, /* 254 */ + { 0x0F, 256, 0, 10, "ees251sp4" }, /* 255 */ + { 0x10, 257, 0, 10, "ees251sp5" }, /* 256 */ + { 0x11, 258, 0, 10, "ees251sp6" }, /* 257 */ + { 0x12, 259, 0, 10, "ees251sp7" }, /* 258 */ + { 0x13, 260, 0, 10, "ees251sp8" }, /* 259 */ + { 0x14, 261, 0, 10, "ees251sp9" }, /* 260 */ + { 0x22, 262, 0, 10, "ees401ep1" }, /* 261 */ + { 0x23, 263, 0, 10, "ees449ep1" }, /* 262 */ + { 0x24, 264, 0, 10, "ees677ep1" }, /* 263 */ + { 0x25, 265, 0, 10, "ees1087ep2" }, /* 264 */ + { 0x26, 266, 0, 10, "ees541ep1" }, /* 265 */ + { 0x27, 267, 0, 10, "ees613ep1" }, /* 266 */ + { 0x28, 268, 0, 10, "ees887ep1" }, /* 267 */ + { 0x29, 269, 0, 10, "ees1171ep1" }, /* 268 */ + { 0x2A, 270, 0, 10, "ees659ep1" }, /* 269 */ + { 0x2B, 271, 0, 10, "ees761ep1" }, /* 270 */ + { 0x2C, 272, 0, 10, "ees1087ep1" }, /* 271 */ + { 0x2D, 273, 0, 10, "ees1499ep1" }, /* 272 */ + { 0x2E, 274, 0, 10, "ees401ep2" }, /* 273 */ + { 0x2F, 275, 0, 10, "ees439ep1" }, /* 274 */ + { 0x30, 276, 0, 10, "ees593ep1" }, /* 275 */ + { 0x31, 0, 0, 10, "ees743ep1" }, /* 276 */ + { 0x03, 0, 0, 9, "eess1-encodingMethods" }, /* 277 */ + { 0x05, 0, 1, 3, "security" }, /* 278 */ + { 0x05, 0, 1, 4, "mechanisms" }, /* 279 */ + { 0x07, 324, 1, 5, "id-pkix" }, /* 280 */ + { 0x01, 285, 1, 6, "id-pe" }, /* 281 */ + { 0x01, 283, 0, 7, "authorityInfoAccess" }, /* 282 */ + { 0x03, 284, 0, 7, "qcStatements" }, /* 283 */ + { 0x07, 0, 0, 7, "ipAddrBlocks" }, /* 284 */ + { 0x02, 288, 1, 6, "id-qt" }, /* 285 */ + { 0x01, 287, 0, 7, "cps" }, /* 286 */ + { 0x02, 0, 0, 7, "unotice" }, /* 287 */ + { 0x03, 298, 1, 6, "id-kp" }, /* 288 */ + { 0x01, 290, 0, 7, "serverAuth" }, /* 289 */ + { 0x02, 291, 0, 7, "clientAuth" }, /* 290 */ + { 0x03, 292, 0, 7, "codeSigning" }, /* 291 */ + { 0x04, 293, 0, 7, "emailProtection" }, /* 292 */ + { 0x05, 294, 0, 7, "ipsecEndSystem" }, /* 293 */ + { 0x06, 295, 0, 7, "ipsecTunnel" }, /* 294 */ + { 0x07, 296, 0, 7, "ipsecUser" }, /* 295 */ + { 0x08, 297, 0, 7, "timeStamping" }, /* 296 */ + { 0x09, 0, 0, 7, "ocspSigning" }, /* 297 */ + { 0x08, 306, 1, 6, "id-otherNames" }, /* 298 */ + { 0x01, 300, 0, 7, "personalData" }, /* 299 */ + { 0x02, 301, 0, 7, "userGroup" }, /* 300 */ + { 0x03, 302, 0, 7, "id-on-permanentIdentifier" }, /* 301 */ + { 0x04, 303, 0, 7, "id-on-hardwareModuleName" }, /* 302 */ + { 0x05, 304, 0, 7, "xmppAddr" }, /* 303 */ + { 0x06, 305, 0, 7, "id-on-SIM" }, /* 304 */ + { 0x07, 0, 0, 7, "id-on-dnsSRV" }, /* 305 */ + { 0x0A, 311, 1, 6, "id-aca" }, /* 306 */ + { 0x01, 308, 0, 7, "authenticationInfo" }, /* 307 */ + { 0x02, 309, 0, 7, "accessIdentity" }, /* 308 */ + { 0x03, 310, 0, 7, "chargingIdentity" }, /* 309 */ + { 0x04, 0, 0, 7, "group" }, /* 310 */ + { 0x0B, 312, 0, 6, "subjectInfoAccess" }, /* 311 */ + { 0x30, 0, 1, 6, "id-ad" }, /* 312 */ + { 0x01, 321, 1, 7, "ocsp" }, /* 313 */ + { 0x01, 315, 0, 8, "basic" }, /* 314 */ + { 0x02, 316, 0, 8, "nonce" }, /* 315 */ + { 0x03, 317, 0, 8, "crl" }, /* 316 */ + { 0x04, 318, 0, 8, "response" }, /* 317 */ + { 0x05, 319, 0, 8, "noCheck" }, /* 318 */ + { 0x06, 320, 0, 8, "archiveCutoff" }, /* 319 */ + { 0x07, 0, 0, 8, "serviceLocator" }, /* 320 */ + { 0x02, 322, 0, 7, "caIssuers" }, /* 321 */ + { 0x03, 323, 0, 7, "timeStamping" }, /* 322 */ + { 0x05, 0, 0, 7, "caRepository" }, /* 323 */ + { 0x08, 0, 1, 5, "ipsec" }, /* 324 */ + { 0x02, 0, 1, 6, "certificate" }, /* 325 */ + { 0x02, 0, 0, 7, "iKEIntermediate" }, /* 326 */ + { 0x0E, 333, 1, 1, "oiw" }, /* 327 */ + { 0x03, 0, 1, 2, "secsig" }, /* 328 */ + { 0x02, 0, 1, 3, "algorithms" }, /* 329 */ + { 0x07, 331, 0, 4, "des-cbc" }, /* 330 */ + { 0x1A, 332, 0, 4, "sha-1" }, /* 331 */ + { 0x1D, 0, 0, 4, "sha-1WithRSASignature" }, /* 332 */ + { 0x24, 379, 1, 1, "TeleTrusT" }, /* 333 */ + { 0x03, 0, 1, 2, "algorithm" }, /* 334 */ + { 0x03, 0, 1, 3, "signatureAlgorithm" }, /* 335 */ + { 0x01, 340, 1, 4, "rsaSignature" }, /* 336 */ + { 0x02, 338, 0, 5, "rsaSigWithripemd160" }, /* 337 */ + { 0x03, 339, 0, 5, "rsaSigWithripemd128" }, /* 338 */ + { 0x04, 0, 0, 5, "rsaSigWithripemd256" }, /* 339 */ + { 0x02, 0, 1, 4, "ecSign" }, /* 340 */ + { 0x01, 342, 0, 5, "ecSignWithsha1" }, /* 341 */ + { 0x02, 343, 0, 5, "ecSignWithripemd160" }, /* 342 */ + { 0x03, 344, 0, 5, "ecSignWithmd2" }, /* 343 */ + { 0x04, 345, 0, 5, "ecSignWithmd5" }, /* 344 */ + { 0x05, 362, 1, 5, "ttt-ecg" }, /* 345 */ + { 0x01, 350, 1, 6, "fieldType" }, /* 346 */ + { 0x01, 0, 1, 7, "characteristictwoField" }, /* 347 */ + { 0x01, 0, 1, 8, "basisType" }, /* 348 */ + { 0x01, 0, 0, 9, "ipBasis" }, /* 349 */ + { 0x02, 352, 1, 6, "keyType" }, /* 350 */ + { 0x01, 0, 0, 7, "ecgPublicKey" }, /* 351 */ + { 0x03, 353, 0, 6, "curve" }, /* 352 */ + { 0x04, 360, 1, 6, "signatures" }, /* 353 */ + { 0x01, 355, 0, 7, "ecgdsa-with-RIPEMD160" }, /* 354 */ + { 0x02, 356, 0, 7, "ecgdsa-with-SHA1" }, /* 355 */ + { 0x03, 357, 0, 7, "ecgdsa-with-SHA224" }, /* 356 */ + { 0x04, 358, 0, 7, "ecgdsa-with-SHA256" }, /* 357 */ + { 0x05, 359, 0, 7, "ecgdsa-with-SHA384" }, /* 358 */ + { 0x06, 0, 0, 7, "ecgdsa-with-SHA512" }, /* 359 */ + { 0x05, 0, 1, 6, "module" }, /* 360 */ + { 0x01, 0, 0, 7, "1" }, /* 361 */ + { 0x08, 0, 1, 5, "ecStdCurvesAndGeneration" }, /* 362 */ + { 0x01, 0, 1, 6, "ellipticCurve" }, /* 363 */ + { 0x01, 0, 1, 7, "versionOne" }, /* 364 */ + { 0x01, 366, 0, 8, "brainpoolP160r1" }, /* 365 */ + { 0x02, 367, 0, 8, "brainpoolP160t1" }, /* 366 */ + { 0x03, 368, 0, 8, "brainpoolP192r1" }, /* 367 */ + { 0x04, 369, 0, 8, "brainpoolP192t1" }, /* 368 */ + { 0x05, 370, 0, 8, "brainpoolP224r1" }, /* 369 */ + { 0x06, 371, 0, 8, "brainpoolP224t1" }, /* 370 */ + { 0x07, 372, 0, 8, "brainpoolP256r1" }, /* 371 */ + { 0x08, 373, 0, 8, "brainpoolP256t1" }, /* 372 */ + { 0x09, 374, 0, 8, "brainpoolP320r1" }, /* 373 */ + { 0x0A, 375, 0, 8, "brainpoolP320t1" }, /* 374 */ + { 0x0B, 376, 0, 8, "brainpoolP384r1" }, /* 375 */ + { 0x0C, 377, 0, 8, "brainpoolP384t1" }, /* 376 */ + { 0x0D, 378, 0, 8, "brainpoolP512r1" }, /* 377 */ + { 0x0E, 0, 0, 8, "brainpoolP512t1" }, /* 378 */ + { 0x81, 0, 1, 1, "" }, /* 379 */ + { 0x04, 0, 1, 2, "Certicom" }, /* 380 */ + { 0x00, 0, 1, 3, "curve" }, /* 381 */ + { 0x01, 383, 0, 4, "sect163k1" }, /* 382 */ + { 0x02, 384, 0, 4, "sect163r1" }, /* 383 */ + { 0x03, 385, 0, 4, "sect239k1" }, /* 384 */ + { 0x04, 386, 0, 4, "sect113r1" }, /* 385 */ + { 0x05, 387, 0, 4, "sect113r2" }, /* 386 */ + { 0x06, 388, 0, 4, "secp112r1" }, /* 387 */ + { 0x07, 389, 0, 4, "secp112r2" }, /* 388 */ + { 0x08, 390, 0, 4, "secp160r1" }, /* 389 */ + { 0x09, 391, 0, 4, "secp160k1" }, /* 390 */ + { 0x0A, 392, 0, 4, "secp256k1" }, /* 391 */ + { 0x0F, 393, 0, 4, "sect163r2" }, /* 392 */ + { 0x10, 394, 0, 4, "sect283k1" }, /* 393 */ + { 0x11, 395, 0, 4, "sect283r1" }, /* 394 */ + { 0x16, 396, 0, 4, "sect131r1" }, /* 395 */ + { 0x17, 397, 0, 4, "sect131r2" }, /* 396 */ + { 0x18, 398, 0, 4, "sect193r1" }, /* 397 */ + { 0x19, 399, 0, 4, "sect193r2" }, /* 398 */ + { 0x1A, 400, 0, 4, "sect233k1" }, /* 399 */ + { 0x1B, 401, 0, 4, "sect233r1" }, /* 400 */ + { 0x1C, 402, 0, 4, "secp128r1" }, /* 401 */ + { 0x1D, 403, 0, 4, "secp128r2" }, /* 402 */ + { 0x1E, 404, 0, 4, "secp160r2" }, /* 403 */ + { 0x1F, 405, 0, 4, "secp192k1" }, /* 404 */ + { 0x20, 406, 0, 4, "secp224k1" }, /* 405 */ + { 0x21, 407, 0, 4, "secp224r1" }, /* 406 */ + { 0x22, 408, 0, 4, "secp384r1" }, /* 407 */ + { 0x23, 409, 0, 4, "secp521r1" }, /* 408 */ + { 0x24, 410, 0, 4, "sect409k1" }, /* 409 */ + { 0x25, 411, 0, 4, "sect409r1" }, /* 410 */ + { 0x26, 412, 0, 4, "sect571k1" }, /* 411 */ + { 0x27, 0, 0, 4, "sect571r1" }, /* 412 */ + {0x60, 467, 1, 0, "" }, /* 413 */ + { 0x86, 0, 1, 1, "" }, /* 414 */ + { 0x48, 0, 1, 2, "" }, /* 415 */ + { 0x01, 0, 1, 3, "organization" }, /* 416 */ + { 0x65, 443, 1, 4, "gov" }, /* 417 */ + { 0x03, 0, 1, 5, "csor" }, /* 418 */ + { 0x04, 0, 1, 6, "nistalgorithm" }, /* 419 */ + { 0x01, 430, 1, 7, "aes" }, /* 420 */ + { 0x02, 422, 0, 8, "id-aes128-CBC" }, /* 421 */ + { 0x06, 423, 0, 8, "id-aes128-GCM" }, /* 422 */ + { 0x07, 424, 0, 8, "id-aes128-CCM" }, /* 423 */ + { 0x16, 425, 0, 8, "id-aes192-CBC" }, /* 424 */ + { 0x1A, 426, 0, 8, "id-aes192-GCM" }, /* 425 */ + { 0x1B, 427, 0, 8, "id-aes192-CCM" }, /* 426 */ + { 0x2A, 428, 0, 8, "id-aes256-CBC" }, /* 427 */ + { 0x2E, 429, 0, 8, "id-aes256-GCM" }, /* 428 */ + { 0x2F, 0, 0, 8, "id-aes256-CCM" }, /* 429 */ + { 0x02, 0, 1, 7, "hashalgs" }, /* 430 */ + { 0x01, 432, 0, 8, "id-sha256" }, /* 431 */ + { 0x02, 433, 0, 8, "id-sha384" }, /* 432 */ + { 0x03, 434, 0, 8, "id-sha512" }, /* 433 */ + { 0x04, 435, 0, 8, "id-sha224" }, /* 434 */ + { 0x05, 436, 0, 8, "id-sha512-224" }, /* 435 */ + { 0x06, 437, 0, 8, "id-sha512-256" }, /* 436 */ + { 0x07, 438, 0, 8, "id-sha3-224" }, /* 437 */ + { 0x08, 439, 0, 8, "id-sha3-256" }, /* 438 */ + { 0x09, 440, 0, 8, "id-sha3-384" }, /* 439 */ + { 0x0A, 441, 0, 8, "id-sha3-512" }, /* 440 */ + { 0x0B, 442, 0, 8, "id-shake128" }, /* 441 */ + { 0x0C, 0, 0, 8, "id-shake256" }, /* 442 */ + { 0x86, 0, 1, 4, "" }, /* 443 */ + { 0xf8, 0, 1, 5, "" }, /* 444 */ + { 0x42, 457, 1, 6, "netscape" }, /* 445 */ + { 0x01, 452, 1, 7, "" }, /* 446 */ + { 0x01, 448, 0, 8, "nsCertType" }, /* 447 */ + { 0x03, 449, 0, 8, "nsRevocationUrl" }, /* 448 */ + { 0x04, 450, 0, 8, "nsCaRevocationUrl" }, /* 449 */ + { 0x08, 451, 0, 8, "nsCaPolicyUrl" }, /* 450 */ + { 0x0d, 0, 0, 8, "nsComment" }, /* 451 */ + { 0x03, 455, 1, 7, "directory" }, /* 452 */ + { 0x01, 0, 1, 8, "" }, /* 453 */ + { 0x03, 0, 0, 9, "employeeNumber" }, /* 454 */ + { 0x04, 0, 1, 7, "policy" }, /* 455 */ + { 0x01, 0, 0, 8, "nsSGC" }, /* 456 */ + { 0x45, 0, 1, 6, "verisign" }, /* 457 */ + { 0x01, 0, 1, 7, "pki" }, /* 458 */ + { 0x09, 0, 1, 8, "attributes" }, /* 459 */ + { 0x02, 461, 0, 9, "messageType" }, /* 460 */ + { 0x03, 462, 0, 9, "pkiStatus" }, /* 461 */ + { 0x04, 463, 0, 9, "failInfo" }, /* 462 */ + { 0x05, 464, 0, 9, "senderNonce" }, /* 463 */ + { 0x06, 465, 0, 9, "recipientNonce" }, /* 464 */ + { 0x07, 466, 0, 9, "transID" }, /* 465 */ + { 0x08, 0, 0, 9, "extensionReq" }, /* 466 */ + {0x67, 0, 1, 0, "" }, /* 467 */ + { 0x81, 0, 1, 1, "" }, /* 468 */ + { 0x05, 0, 1, 2, "" }, /* 469 */ + { 0x02, 0, 1, 3, "tcg-attribute" }, /* 470 */ + { 0x01, 472, 0, 4, "tcg-at-tpmManufacturer" }, /* 471 */ + { 0x02, 473, 0, 4, "tcg-at-tpmModel" }, /* 472 */ + { 0x03, 474, 0, 4, "tcg-at-tpmVersion" }, /* 473 */ + { 0x0F, 0, 0, 4, "tcg-at-tpmIdLabel" } /* 474 */ }; diff --git a/src/libstrongswan/asn1/oid.h b/src/libstrongswan/asn1/oid.h index 0933f236a..0f7c5d644 100644 --- a/src/libstrongswan/asn1/oid.h +++ b/src/libstrongswan/asn1/oid.h @@ -141,99 +141,112 @@ extern const oid_t oid_names[]; #define OID_MS_SMARTCARD_LOGON 202 #define OID_USER_PRINCIPAL_NAME 203 #define OID_STRONGSWAN 209 -#define OID_TCGID 216 -#define OID_AUTHORITY_INFO_ACCESS 260 -#define OID_IP_ADDR_BLOCKS 262 -#define OID_POLICY_QUALIFIER_CPS 264 -#define OID_POLICY_QUALIFIER_UNOTICE 265 -#define OID_SERVER_AUTH 267 -#define OID_CLIENT_AUTH 268 -#define OID_OCSP_SIGNING 275 -#define OID_XMPP_ADDR 281 -#define OID_AUTHENTICATION_INFO 285 -#define OID_ACCESS_IDENTITY 286 -#define OID_CHARGING_IDENTITY 287 -#define OID_GROUP 288 -#define OID_OCSP 291 -#define OID_BASIC 292 -#define OID_NONCE 293 -#define OID_CRL 294 -#define OID_RESPONSE 295 -#define OID_NO_CHECK 296 -#define OID_ARCHIVE_CUTOFF 297 -#define OID_SERVICE_LOCATOR 298 -#define OID_CA_ISSUERS 299 -#define OID_IKE_INTERMEDIATE 304 -#define OID_DES_CBC 308 -#define OID_SHA1 309 -#define OID_SHA1_WITH_RSA_OIW 310 -#define OID_ECGDSA_PUBKEY 329 -#define OID_ECGDSA_SIG_WITH_RIPEMD160 332 -#define OID_ECGDSA_SIG_WITH_SHA1 333 -#define OID_ECGDSA_SIG_WITH_SHA224 334 -#define OID_ECGDSA_SIG_WITH_SHA256 335 -#define OID_ECGDSA_SIG_WITH_SHA384 336 -#define OID_ECGDSA_SIG_WITH_SHA512 337 -#define OID_SECT163K1 360 -#define OID_SECT163R1 361 -#define OID_SECT239K1 362 -#define OID_SECT113R1 363 -#define OID_SECT113R2 364 -#define OID_SECT112R1 365 -#define OID_SECT112R2 366 -#define OID_SECT160R1 367 -#define OID_SECT160K1 368 -#define OID_SECT256K1 369 -#define OID_SECT163R2 370 -#define OID_SECT283K1 371 -#define OID_SECT283R1 372 -#define OID_SECT131R1 373 -#define OID_SECT131R2 374 -#define OID_SECT193R1 375 -#define OID_SECT193R2 376 -#define OID_SECT233K1 377 -#define OID_SECT233R1 378 -#define OID_SECT128R1 379 -#define OID_SECT128R2 380 -#define OID_SECT160R2 381 -#define OID_SECT192K1 382 -#define OID_SECT224K1 383 -#define OID_SECT224R1 384 -#define OID_SECT384R1 385 -#define OID_SECT521R1 386 -#define OID_SECT409K1 387 -#define OID_SECT409R1 388 -#define OID_SECT571K1 389 -#define OID_SECT571R1 390 -#define OID_AES128_CBC 399 -#define OID_AES128_GCM 400 -#define OID_AES128_CCM 401 -#define OID_AES192_CBC 402 -#define OID_AES192_GCM 403 -#define OID_AES192_CCM 404 -#define OID_AES256_CBC 405 -#define OID_AES256_GCM 406 -#define OID_AES256_CCM 407 -#define OID_SHA256 409 -#define OID_SHA384 410 -#define OID_SHA512 411 -#define OID_SHA224 412 -#define OID_NS_REVOCATION_URL 426 -#define OID_NS_CA_REVOCATION_URL 427 -#define OID_NS_CA_POLICY_URL 428 -#define OID_NS_COMMENT 429 -#define OID_EMPLOYEE_NUMBER 432 -#define OID_PKI_MESSAGE_TYPE 438 -#define OID_PKI_STATUS 439 -#define OID_PKI_FAIL_INFO 440 -#define OID_PKI_SENDER_NONCE 441 -#define OID_PKI_RECIPIENT_NONCE 442 -#define OID_PKI_TRANS_ID 443 -#define OID_TPM_MANUFACTURER 449 -#define OID_TPM_MODEL 450 -#define OID_TPM_VERSION 451 -#define OID_TPM_ID_LABEL 452 +#define OID_BLISS_PUBLICKEY 214 +#define OID_BLISS_I 216 +#define OID_BLISS_II 217 +#define OID_BLISS_III 218 +#define OID_BLISS_IV 219 +#define OID_BLISS_B_I 220 +#define OID_BLISS_B_II 221 +#define OID_BLISS_B_III 222 +#define OID_BLISS_B_IV 223 +#define OID_BLISS_WITH_SHA512 225 +#define OID_BLISS_WITH_SHA384 226 +#define OID_BLISS_WITH_SHA256 227 +#define OID_TCGID 234 +#define OID_BLOWFISH_CBC 238 +#define OID_AUTHORITY_INFO_ACCESS 282 +#define OID_IP_ADDR_BLOCKS 284 +#define OID_POLICY_QUALIFIER_CPS 286 +#define OID_POLICY_QUALIFIER_UNOTICE 287 +#define OID_SERVER_AUTH 289 +#define OID_CLIENT_AUTH 290 +#define OID_OCSP_SIGNING 297 +#define OID_XMPP_ADDR 303 +#define OID_AUTHENTICATION_INFO 307 +#define OID_ACCESS_IDENTITY 308 +#define OID_CHARGING_IDENTITY 309 +#define OID_GROUP 310 +#define OID_OCSP 313 +#define OID_BASIC 314 +#define OID_NONCE 315 +#define OID_CRL 316 +#define OID_RESPONSE 317 +#define OID_NO_CHECK 318 +#define OID_ARCHIVE_CUTOFF 319 +#define OID_SERVICE_LOCATOR 320 +#define OID_CA_ISSUERS 321 +#define OID_IKE_INTERMEDIATE 326 +#define OID_DES_CBC 330 +#define OID_SHA1 331 +#define OID_SHA1_WITH_RSA_OIW 332 +#define OID_ECGDSA_PUBKEY 351 +#define OID_ECGDSA_SIG_WITH_RIPEMD160 354 +#define OID_ECGDSA_SIG_WITH_SHA1 355 +#define OID_ECGDSA_SIG_WITH_SHA224 356 +#define OID_ECGDSA_SIG_WITH_SHA256 357 +#define OID_ECGDSA_SIG_WITH_SHA384 358 +#define OID_ECGDSA_SIG_WITH_SHA512 359 +#define OID_SECT163K1 382 +#define OID_SECT163R1 383 +#define OID_SECT239K1 384 +#define OID_SECT113R1 385 +#define OID_SECT113R2 386 +#define OID_SECT112R1 387 +#define OID_SECT112R2 388 +#define OID_SECT160R1 389 +#define OID_SECT160K1 390 +#define OID_SECT256K1 391 +#define OID_SECT163R2 392 +#define OID_SECT283K1 393 +#define OID_SECT283R1 394 +#define OID_SECT131R1 395 +#define OID_SECT131R2 396 +#define OID_SECT193R1 397 +#define OID_SECT193R2 398 +#define OID_SECT233K1 399 +#define OID_SECT233R1 400 +#define OID_SECT128R1 401 +#define OID_SECT128R2 402 +#define OID_SECT160R2 403 +#define OID_SECT192K1 404 +#define OID_SECT224K1 405 +#define OID_SECT224R1 406 +#define OID_SECT384R1 407 +#define OID_SECT521R1 408 +#define OID_SECT409K1 409 +#define OID_SECT409R1 410 +#define OID_SECT571K1 411 +#define OID_SECT571R1 412 +#define OID_AES128_CBC 421 +#define OID_AES128_GCM 422 +#define OID_AES128_CCM 423 +#define OID_AES192_CBC 424 +#define OID_AES192_GCM 425 +#define OID_AES192_CCM 426 +#define OID_AES256_CBC 427 +#define OID_AES256_GCM 428 +#define OID_AES256_CCM 429 +#define OID_SHA256 431 +#define OID_SHA384 432 +#define OID_SHA512 433 +#define OID_SHA224 434 +#define OID_NS_REVOCATION_URL 448 +#define OID_NS_CA_REVOCATION_URL 449 +#define OID_NS_CA_POLICY_URL 450 +#define OID_NS_COMMENT 451 +#define OID_EMPLOYEE_NUMBER 454 +#define OID_PKI_MESSAGE_TYPE 460 +#define OID_PKI_STATUS 461 +#define OID_PKI_FAIL_INFO 462 +#define OID_PKI_SENDER_NONCE 463 +#define OID_PKI_RECIPIENT_NONCE 464 +#define OID_PKI_TRANS_ID 465 +#define OID_TPM_MANUFACTURER 471 +#define OID_TPM_MODEL 472 +#define OID_TPM_VERSION 473 +#define OID_TPM_ID_LABEL 474 -#define OID_MAX 453 +#define OID_MAX 475 #endif /* OID_H_ */ diff --git a/src/libstrongswan/asn1/oid.txt b/src/libstrongswan/asn1/oid.txt index e545188d4..919d24c43 100644 --- a/src/libstrongswan/asn1/oid.txt +++ b/src/libstrongswan/asn1/oid.txt @@ -208,6 +208,24 @@ 0xA0 "" 0x2A "ITA" 0x01 "strongSwan" OID_STRONGSWAN + 0x02 "cps" + 0x03 "e-voting" + 0x05 "BLISS" + 0x01 "keyType" + 0x01 "blissPublicKey" OID_BLISS_PUBLICKEY + 0x02 "parameters" + 0x01 "BLISS-I" OID_BLISS_I + 0x02 "BLISS-II" OID_BLISS_II + 0x03 "BLISS-III" OID_BLISS_III + 0x04 "BLISS-IV" OID_BLISS_IV + 0x05 "BLISS-B-I" OID_BLISS_B_I + 0x06 "BLISS-B-II" OID_BLISS_B_II + 0x07 "BLISS-B-III" OID_BLISS_B_III + 0x08 "BLISS-B-IV" OID_BLISS_B_IV + 0x03 "blissSigType" + 0x01 "BLISS-with-SHA512" OID_BLISS_WITH_SHA512 + 0x02 "BLISS-with-SHA384" OID_BLISS_WITH_SHA384 + 0x03 "BLISS-with-SHA256" OID_BLISS_WITH_SHA256 0x89 "" 0x31 "" 0x01 "" @@ -215,6 +233,10 @@ 0x02 "" 0x02 "" 0x4B "TCGID" OID_TCGID + 0x97 "" + 0x55 "" + 0x01 "" + 0x02 "blowfish-cbc" OID_BLOWFISH_CBC 0xC1 "" 0x16 "ntruCryptosystems" 0x01 "eess" diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c index db08c6b96..0ca45a15b 100644 --- a/src/libstrongswan/credentials/auth_cfg.c +++ b/src/libstrongswan/credentials/auth_cfg.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2012 Tobias Brunner + * Copyright (C) 2008-2015 Tobias Brunner * Copyright (C) 2007-2009 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -49,6 +49,7 @@ ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_AC_CERT, "RULE_GROUP", "RULE_RSA_STRENGTH", "RULE_ECDSA_STRENGTH", + "RULE_BLISS_STRENGTH", "RULE_SIGNATURE_SCHEME", "RULE_CERT_POLICY", "HELPER_IM_CERT", @@ -71,6 +72,7 @@ static inline bool is_multi_value_rule(auth_rule_t type) case AUTH_RULE_EAP_VENDOR: case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: + case AUTH_RULE_BLISS_STRENGTH: case AUTH_RULE_IDENTITY: case AUTH_RULE_IDENTITY_LOOSE: case AUTH_RULE_EAP_IDENTITY: @@ -207,6 +209,7 @@ static void init_entry(entry_t *this, auth_rule_t type, va_list args) case AUTH_RULE_OCSP_VALIDATION: case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: + case AUTH_RULE_BLISS_STRENGTH: case AUTH_RULE_SIGNATURE_SCHEME: /* integer type */ this->value = (void*)(uintptr_t)va_arg(args, u_int); @@ -255,6 +258,7 @@ static bool entry_equals(entry_t *e1, entry_t *e2) case AUTH_RULE_OCSP_VALIDATION: case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: + case AUTH_RULE_BLISS_STRENGTH: case AUTH_RULE_SIGNATURE_SCHEME: { return e1->value == e2->value; @@ -345,6 +349,7 @@ static void destroy_entry_value(entry_t *entry) case AUTH_RULE_OCSP_VALIDATION: case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: + case AUTH_RULE_BLISS_STRENGTH: case AUTH_RULE_SIGNATURE_SCHEME: case AUTH_RULE_MAX: break; @@ -376,6 +381,7 @@ static void replace(private_auth_cfg_t *this, entry_enumerator_t *enumerator, case AUTH_RULE_OCSP_VALIDATION: case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: + case AUTH_RULE_BLISS_STRENGTH: case AUTH_RULE_SIGNATURE_SCHEME: /* integer type */ entry->value = (void*)(uintptr_t)va_arg(args, u_int); @@ -450,6 +456,7 @@ METHOD(auth_cfg_t, get, void*, case AUTH_RULE_EAP_VENDOR: case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: + case AUTH_RULE_BLISS_STRENGTH: return (void*)0; case AUTH_RULE_SIGNATURE_SCHEME: return (void*)HASH_UNKNOWN; @@ -513,6 +520,7 @@ METHOD(auth_cfg_t, complies, bool, signature_scheme_t scheme = SIGN_UNKNOWN; u_int strength = 0; auth_rule_t t1, t2; + char *key_type; void *value; e1 = constraints->create_enumerator(constraints); @@ -703,6 +711,7 @@ METHOD(auth_cfg_t, complies, bool, } case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: + case AUTH_RULE_BLISS_STRENGTH: { strength = (uintptr_t)value; break; @@ -797,30 +806,39 @@ METHOD(auth_cfg_t, complies, bool, e2 = create_enumerator(this); while (e2->enumerate(e2, &t2, &strength)) { - if (t2 == AUTH_RULE_RSA_STRENGTH || - t2 == AUTH_RULE_ECDSA_STRENGTH) + switch (t2) { - success = FALSE; - e1 = constraints->create_enumerator(constraints); - while (e1->enumerate(e1, &t1, &value)) + default: + continue; + case AUTH_RULE_RSA_STRENGTH: + key_type = "RSA"; + break; + case AUTH_RULE_ECDSA_STRENGTH: + key_type = "ECDSA"; + break; + case AUTH_RULE_BLISS_STRENGTH: + key_type = "BLISS"; + break; + } + success = FALSE; + e1 = constraints->create_enumerator(constraints); + while (e1->enumerate(e1, &t1, &value)) + { + if (t1 == t2 && (uintptr_t)value <= strength) { - if (t1 == t2 && (uintptr_t)value <= strength) - { - success = TRUE; - break; - } + success = TRUE; + break; } - e1->destroy(e1); - if (!success) + } + e1->destroy(e1); + if (!success) + { + if (log_error) { - if (log_error) - { - DBG1(DBG_CFG, "%s-%d signatures not acceptable", - t2 == AUTH_RULE_RSA_STRENGTH ? "RSA" : "ECDSA", - strength); - } - break; + DBG1(DBG_CFG, "%s-%d signatures not acceptable", + key_type, strength); } + break; } } e2->destroy(e2); @@ -891,6 +909,7 @@ static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy case AUTH_RULE_EAP_VENDOR: case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: + case AUTH_RULE_BLISS_STRENGTH: case AUTH_RULE_SIGNATURE_SCHEME: { add(this, type, (uintptr_t)value); @@ -1060,6 +1079,7 @@ METHOD(auth_cfg_t, clone_, auth_cfg_t*, case AUTH_RULE_OCSP_VALIDATION: case AUTH_RULE_RSA_STRENGTH: case AUTH_RULE_ECDSA_STRENGTH: + case AUTH_RULE_BLISS_STRENGTH: case AUTH_RULE_SIGNATURE_SCHEME: clone->add(clone, type, (uintptr_t)value); break; diff --git a/src/libstrongswan/credentials/auth_cfg.h b/src/libstrongswan/credentials/auth_cfg.h index 95b36d706..53f1b3805 100644 --- a/src/libstrongswan/credentials/auth_cfg.h +++ b/src/libstrongswan/credentials/auth_cfg.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2012 Tobias Brunner + * Copyright (C) 2008-2015 Tobias Brunner * Copyright (C) 2007-2009 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -102,6 +102,8 @@ enum auth_rule_t { AUTH_RULE_RSA_STRENGTH, /** required ECDSA public key strength, u_int in bits */ AUTH_RULE_ECDSA_STRENGTH, + /** required BLISS public key strength, u_int in bits */ + AUTH_RULE_BLISS_STRENGTH, /** required signature scheme, signature_scheme_t */ AUTH_RULE_SIGNATURE_SCHEME, /** certificatePolicy constraint, numerical OID as char* */ diff --git a/src/libstrongswan/credentials/cred_encoding.h b/src/libstrongswan/credentials/cred_encoding.h index a6c9c30af..b4d1f4c3c 100644 --- a/src/libstrongswan/credentials/cred_encoding.h +++ b/src/libstrongswan/credentials/cred_encoding.h @@ -144,6 +144,10 @@ enum cred_encoding_part_t { CRED_PART_PKCS10_ASN1_DER, /** a PGP encoded certificate */ CRED_PART_PGP_CERT, + /** a DER encoded BLISS public key */ + CRED_PART_BLISS_PUB_ASN1_DER, + /** a DER encoded BLISS private key */ + CRED_PART_BLISS_PRIV_ASN1_DER, CRED_PART_END, }; diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c index b0c8e48ba..371e6404d 100644 --- a/src/libstrongswan/credentials/credential_manager.c +++ b/src/libstrongswan/credentials/credential_manager.c @@ -698,6 +698,9 @@ static void get_key_strength(certificate_t *cert, auth_cfg_t *auth) case KEY_ECDSA: auth->add(auth, AUTH_RULE_ECDSA_STRENGTH, strength); break; + case KEY_BLISS: + auth->add(auth, AUTH_RULE_BLISS_STRENGTH, strength); + break; default: break; } diff --git a/src/libstrongswan/credentials/keys/public_key.c b/src/libstrongswan/credentials/keys/public_key.c index 37bba77d1..bd5915e60 100644 --- a/src/libstrongswan/credentials/keys/public_key.c +++ b/src/libstrongswan/credentials/keys/public_key.c @@ -1,6 +1,8 @@ /* + * Copyright (C) 2015 Tobias Brunner * Copyright (C) 2007 Martin Willi - * Hochschule fuer Technik Rapperswil + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -17,14 +19,15 @@ #include "public_key.h" -ENUM(key_type_names, KEY_ANY, KEY_DSA, +ENUM(key_type_names, KEY_ANY, KEY_BLISS, "ANY", "RSA", "ECDSA", - "DSA" + "DSA", + "BLISS" ); -ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_ECDSA_521, +ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_BLISS_WITH_SHA512, "UNKNOWN", "RSA_EMSA_PKCS1_NULL", "RSA_EMSA_PKCS1_MD5", @@ -41,6 +44,9 @@ ENUM(signature_scheme_names, SIGN_UNKNOWN, SIGN_ECDSA_521, "ECDSA-256", "ECDSA-384", "ECDSA-521", + "BLISS_WITH_SHA256", + "BLISS_WITH_SHA384", + "BLISS_WITH_SHA512", ); ENUM(encryption_scheme_names, ENCRYPT_UNKNOWN, ENCRYPT_RSA_OAEP_SHA512, @@ -130,8 +136,158 @@ signature_scheme_t signature_scheme_from_oid(int oid) return SIGN_ECDSA_WITH_SHA384_DER; case OID_ECDSA_WITH_SHA512: return SIGN_ECDSA_WITH_SHA512_DER; - default: - return SIGN_UNKNOWN; + case OID_BLISS_PUBLICKEY: + case OID_BLISS_WITH_SHA512: + return SIGN_BLISS_WITH_SHA512; + case OID_BLISS_WITH_SHA256: + return SIGN_BLISS_WITH_SHA256; + case OID_BLISS_WITH_SHA384: + return SIGN_BLISS_WITH_SHA384; } + return SIGN_UNKNOWN; } +/* + * Defined in header. + */ +int signature_scheme_to_oid(signature_scheme_t scheme) +{ + switch (scheme) + { + case SIGN_UNKNOWN: + case SIGN_RSA_EMSA_PKCS1_NULL: + case SIGN_ECDSA_WITH_NULL: + case SIGN_ECDSA_256: + case SIGN_ECDSA_384: + case SIGN_ECDSA_521: + break; + case SIGN_RSA_EMSA_PKCS1_MD5: + return OID_MD5_WITH_RSA; + case SIGN_RSA_EMSA_PKCS1_SHA1: + return OID_SHA1_WITH_RSA; + case SIGN_RSA_EMSA_PKCS1_SHA224: + return OID_SHA224_WITH_RSA; + case SIGN_RSA_EMSA_PKCS1_SHA256: + return OID_SHA256_WITH_RSA; + case SIGN_RSA_EMSA_PKCS1_SHA384: + return OID_SHA384_WITH_RSA; + case SIGN_RSA_EMSA_PKCS1_SHA512: + return OID_SHA512_WITH_RSA; + case SIGN_ECDSA_WITH_SHA1_DER: + return OID_ECDSA_WITH_SHA1; + case SIGN_ECDSA_WITH_SHA256_DER: + return OID_ECDSA_WITH_SHA256; + case SIGN_ECDSA_WITH_SHA384_DER: + return OID_ECDSA_WITH_SHA384; + case SIGN_ECDSA_WITH_SHA512_DER: + return OID_ECDSA_WITH_SHA512; + case SIGN_BLISS_WITH_SHA256: + return OID_BLISS_WITH_SHA256; + case SIGN_BLISS_WITH_SHA384: + return OID_BLISS_WITH_SHA384; + case SIGN_BLISS_WITH_SHA512: + return OID_BLISS_WITH_SHA512; + } + return OID_UNKNOWN; +} + +/** + * Map for signature schemes to the key type and maximum key size allowed. + * We only cover schemes with hash algorithms supported by IKEv2 signature + * authentication. + */ +static struct { + signature_scheme_t scheme; + key_type_t type; + int max_keysize; +} scheme_map[] = { + { SIGN_RSA_EMSA_PKCS1_SHA256, KEY_RSA, 3072 }, + { SIGN_RSA_EMSA_PKCS1_SHA384, KEY_RSA, 7680 }, + { SIGN_RSA_EMSA_PKCS1_SHA512, KEY_RSA, 0 }, + { SIGN_ECDSA_WITH_SHA256_DER, KEY_ECDSA, 256 }, + { SIGN_ECDSA_WITH_SHA384_DER, KEY_ECDSA, 384 }, + { SIGN_ECDSA_WITH_SHA512_DER, KEY_ECDSA, 0 }, + { SIGN_BLISS_WITH_SHA256, KEY_BLISS, 128 }, + { SIGN_BLISS_WITH_SHA384, KEY_BLISS, 192 }, + { SIGN_BLISS_WITH_SHA512, KEY_BLISS, 0 }, +}; + +/** + * Private data for signature scheme enumerator + */ +typedef struct { + enumerator_t public; + int index; + key_type_t type; + int size; +} private_enumerator_t; + +METHOD(enumerator_t, signature_schemes_enumerate, bool, + private_enumerator_t *this, signature_scheme_t *scheme) +{ + while (++this->index < countof(scheme_map)) + { + if (this->type == scheme_map[this->index].type && + (this->size <= scheme_map[this->index].max_keysize || + !scheme_map[this->index].max_keysize)) + { + *scheme = scheme_map[this->index].scheme; + return TRUE; + } + } + return FALSE; +} + +/* + * Defined in header. + */ +enumerator_t *signature_schemes_for_key(key_type_t type, int size) +{ + private_enumerator_t *this; + + INIT(this, + .public = { + .enumerate = (void*)_signature_schemes_enumerate, + .destroy = (void*)free, + }, + .index = -1, + .type = type, + .size = size, + ); + + return &this->public; +} + +/* + * Defined in header. + */ +key_type_t key_type_from_signature_scheme(signature_scheme_t scheme) +{ + switch (scheme) + { + case SIGN_UNKNOWN: + break; + case SIGN_RSA_EMSA_PKCS1_NULL: + case SIGN_RSA_EMSA_PKCS1_MD5: + case SIGN_RSA_EMSA_PKCS1_SHA1: + case SIGN_RSA_EMSA_PKCS1_SHA224: + case SIGN_RSA_EMSA_PKCS1_SHA256: + case SIGN_RSA_EMSA_PKCS1_SHA384: + case SIGN_RSA_EMSA_PKCS1_SHA512: + return KEY_RSA; + case SIGN_ECDSA_WITH_SHA1_DER: + case SIGN_ECDSA_WITH_SHA256_DER: + case SIGN_ECDSA_WITH_SHA384_DER: + case SIGN_ECDSA_WITH_SHA512_DER: + case SIGN_ECDSA_WITH_NULL: + case SIGN_ECDSA_256: + case SIGN_ECDSA_384: + case SIGN_ECDSA_521: + return KEY_ECDSA; + case SIGN_BLISS_WITH_SHA256: + case SIGN_BLISS_WITH_SHA384: + case SIGN_BLISS_WITH_SHA512: + return KEY_BLISS; + } + return KEY_ANY; +} diff --git a/src/libstrongswan/credentials/keys/public_key.h b/src/libstrongswan/credentials/keys/public_key.h index 2afcf8325..66e98b294 100644 --- a/src/libstrongswan/credentials/keys/public_key.h +++ b/src/libstrongswan/credentials/keys/public_key.h @@ -1,6 +1,8 @@ /* + * Copyright (C) 2015 Tobias Brunner * Copyright (C) 2007 Martin Willi - * Hochschule fuer Technik Rapperswil + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -42,6 +44,8 @@ enum key_type_t { KEY_ECDSA = 2, /** DSA */ KEY_DSA = 3, + /** BLISS */ + KEY_BLISS = 4, /** ElGamal, ... */ }; @@ -90,6 +94,12 @@ enum signature_scheme_t { SIGN_ECDSA_384, /** ECDSA on the P-521 curve with SHA-512 as in RFC 4754 */ SIGN_ECDSA_521, + /** BLISS with SHA-256 */ + SIGN_BLISS_WITH_SHA256, + /** BLISS with SHA-384 */ + SIGN_BLISS_WITH_SHA384, + /** BLISS with SHA-512 */ + SIGN_BLISS_WITH_SHA512, }; /** @@ -234,8 +244,35 @@ bool public_key_has_fingerprint(public_key_t *public, chunk_t fingerprint); * Conversion of ASN.1 signature or hash OID to signature scheme. * * @param oid ASN.1 OID - * @return signature_scheme, SIGN_UNKNOWN if OID is unsupported + * @return signature scheme, SIGN_UNKNOWN if OID is unsupported */ signature_scheme_t signature_scheme_from_oid(int oid); +/** + * Conversion of signature scheme to ASN.1 signature OID. + * + * @param scheme signature scheme + * @return ASN.1 OID, OID_UNKNOWN if not supported + */ +int signature_scheme_to_oid(signature_scheme_t scheme); + +/** + * Enumerate signature schemes that are appropriate for a key of the given type + * and size|strength. + * + * @param type type of the key + * @param size size or strength of the key + * @return enumerator over signature_scheme_t (increasing strength) + */ +enumerator_t *signature_schemes_for_key(key_type_t type, int size); + +/** + * Determine the type of key associated with a given signature scheme. + * + * @param scheme signature scheme + * @return key type (could be KEY_ANY) + */ +key_type_t key_type_from_signature_scheme(signature_scheme_t scheme); + + #endif /** PUBLIC_KEY_H_ @}*/ diff --git a/src/libstrongswan/credentials/sets/cert_cache.c b/src/libstrongswan/credentials/sets/cert_cache.c index 563f4bdd5..60720dc57 100644 --- a/src/libstrongswan/credentials/sets/cert_cache.c +++ b/src/libstrongswan/credentials/sets/cert_cache.c @@ -143,6 +143,7 @@ METHOD(cert_cache_t, issued_by, bool, private_cert_cache_t *this, certificate_t *subject, certificate_t *issuer, signature_scheme_t *schemep) { + certificate_t *cached_issuer = NULL; relation_t *found = NULL, *current; signature_scheme_t scheme; int i; @@ -154,39 +155,41 @@ METHOD(cert_cache_t, issued_by, bool, current->lock->read_lock(current->lock); if (current->subject) { - /* check for equal issuer */ if (issuer->equals(issuer, current->issuer)) { - /* reuse issuer instance in cache() */ - issuer = current->issuer; if (subject->equals(subject, current->subject)) { - /* write hit counter is not locked, but not critical */ current->hits++; - found = current;; + found = current; if (schemep) { *schemep = current->scheme; } } + else if (!cached_issuer) + { + cached_issuer = current->issuer->get_ref(current->issuer); + } } } current->lock->unlock(current->lock); if (found) { + DESTROY_IF(cached_issuer); return TRUE; } } - /* no cache hit, check and cache signature */ if (subject->issued_by(subject, issuer, &scheme)) { - cache(this, subject, issuer, scheme); + cache(this, subject, cached_issuer ?: issuer, scheme); if (schemep) { *schemep = scheme; } + DESTROY_IF(cached_issuer); return TRUE; } + DESTROY_IF(cached_issuer); return FALSE; } diff --git a/src/libstrongswan/credentials/sets/mem_cred.c b/src/libstrongswan/credentials/sets/mem_cred.c index d8f568d36..7ad011b5e 100644 --- a/src/libstrongswan/credentials/sets/mem_cred.c +++ b/src/libstrongswan/credentials/sets/mem_cred.c @@ -192,6 +192,24 @@ METHOD(mem_cred_t, add_cert_ref, certificate_t*, return add_cert_internal(this, trusted, cert); } +METHOD(mem_cred_t, get_cert_ref, certificate_t*, + private_mem_cred_t *this, certificate_t *cert) +{ + certificate_t *cached; + + this->lock->write_lock(this->lock); + if (this->untrusted->find_first(this->untrusted, + (linked_list_match_t)certificate_equals, + (void**)&cached, cert) == SUCCESS) + { + cert->destroy(cert); + cert = cached->get_ref(cached); + } + this->lock->unlock(this->lock); + + return cert; +} + METHOD(mem_cred_t, add_crl, bool, private_mem_cred_t *this, crl_t *crl) { @@ -736,6 +754,7 @@ mem_cred_t *mem_cred_create() }, .add_cert = _add_cert, .add_cert_ref = _add_cert_ref, + .get_cert_ref = _get_cert_ref, .add_crl = _add_crl, .add_key = _add_key, .add_shared = _add_shared, diff --git a/src/libstrongswan/credentials/sets/mem_cred.h b/src/libstrongswan/credentials/sets/mem_cred.h index d0dd51da1..3ce815abc 100644 --- a/src/libstrongswan/credentials/sets/mem_cred.h +++ b/src/libstrongswan/credentials/sets/mem_cred.h @@ -59,6 +59,18 @@ struct mem_cred_t { certificate_t *cert); /** + * Get an existing reference to the same certificate. + * + * Searches for the same certficate in the set, and returns a reference + * to it, destroying the passed certificate. If the passed certificate + * is not found, it is just returned. + * + * @param cert certificate to look up + * @return the same certificate, potentially different instance + */ + certificate_t* (*get_cert_ref)(mem_cred_t *this, certificate_t *cert); + + /** * Add an X.509 CRL to the credential set. * * @param crl CRL, gets owned by set diff --git a/src/libstrongswan/crypto/crypters/crypter.c b/src/libstrongswan/crypto/crypters/crypter.c index 8123adde5..1e73baa4e 100644 --- a/src/libstrongswan/crypto/crypters/crypter.c +++ b/src/libstrongswan/crypto/crypters/crypter.c @@ -96,6 +96,10 @@ encryption_algorithm_t encryption_algorithm_from_oid(int oid, size_t *key_size) alg = ENCR_CAMELLIA_CBC; alg_key_size = 256; break; + case OID_BLOWFISH_CBC: + alg = ENCR_BLOWFISH; + alg_key_size = 0; + break; default: alg = ENCR_UNDEFINED; alg_key_size = 0; @@ -154,6 +158,9 @@ int encryption_algorithm_to_oid(encryption_algorithm_t alg, size_t key_size) oid = OID_UNKNOWN; } break; + case ENCR_BLOWFISH: + oid = OID_BLOWFISH_CBC; + break; default: oid = OID_UNKNOWN; } diff --git a/src/libstrongswan/crypto/crypto_tester.c b/src/libstrongswan/crypto/crypto_tester.c index d09844bfa..15ed17381 100644 --- a/src/libstrongswan/crypto/crypto_tester.c +++ b/src/libstrongswan/crypto/crypto_tester.c @@ -580,13 +580,22 @@ METHOD(crypto_tester_t, test_signer, bool, break; } + data = chunk_create(vector->data, vector->len); key = chunk_create(vector->key, signer->get_key_size(signer)); if (!signer->set_key(signer, key)) { goto failure; } + /* do partial append mode and check if key gets set correctly */ + if (!signer->get_signature(signer, data, NULL)) + { + goto failure; + } + if (!signer->set_key(signer, key)) + { + goto failure; + } /* allocated signature */ - data = chunk_create(vector->data, vector->len); if (!signer->allocate_signature(signer, data, &mac)) { goto failure; @@ -905,13 +914,25 @@ METHOD(crypto_tester_t, test_prf, bool, break; } + seed = chunk_create(vector->seed, vector->len); key = chunk_create(vector->key, vector->key_size); if (!prf->set_key(prf, key)) { goto failure; } + if (alg != PRF_FIPS_SHA1_160) + { + /* do partial append mode and check if key gets set correctly */ + if (!prf->get_bytes(prf, seed, NULL)) + { + goto failure; + } + if (!prf->set_key(prf, key)) + { + goto failure; + } + } /* allocated bytes */ - seed = chunk_create(vector->seed, vector->len); if (!prf->allocate_bytes(prf, seed, &out)) { goto failure; @@ -942,7 +963,7 @@ METHOD(crypto_tester_t, test_prf, bool, goto failure; } /* bytes to existing buffer, using append mode */ - if (seed.len > 2) + if (alg != PRF_FIPS_SHA1_160 && seed.len > 2) { memset(out.ptr, 0, out.len); if (vector->stateful) diff --git a/src/libstrongswan/crypto/diffie_hellman.c b/src/libstrongswan/crypto/diffie_hellman.c index 87c9b21f8..0d4cd9109 100644 --- a/src/libstrongswan/crypto/diffie_hellman.c +++ b/src/libstrongswan/crypto/diffie_hellman.c @@ -42,15 +42,16 @@ ENUM_NEXT(diffie_hellman_group_names, MODP_1024_160, ECP_512_BP, ECP_521_BIT, "ECP_256_BP", "ECP_384_BP", "ECP_512_BP"); -ENUM_NEXT(diffie_hellman_group_names, MODP_NULL, MODP_CUSTOM, ECP_512_BP, - "MODP_NULL", - "MODP_CUSTOM"); -ENUM_NEXT(diffie_hellman_group_names, NTRU_112_BIT, NTRU_256_BIT, MODP_CUSTOM, +ENUM_NEXT(diffie_hellman_group_names, MODP_NULL, MODP_NULL, ECP_512_BP, + "MODP_NULL"); +ENUM_NEXT(diffie_hellman_group_names, NTRU_112_BIT, NTRU_256_BIT, MODP_NULL, "NTRU_112", "NTRU_128", "NTRU_192", "NTRU_256"); -ENUM_END(diffie_hellman_group_names, NTRU_256_BIT); +ENUM_NEXT(diffie_hellman_group_names, MODP_CUSTOM, MODP_CUSTOM, NTRU_256_BIT, + "MODP_CUSTOM"); +ENUM_END(diffie_hellman_group_names, MODP_CUSTOM); /** @@ -439,7 +440,7 @@ void diffie_hellman_init() { int i; - if (lib->settings->get_int(lib->settings, + if (lib->settings->get_bool(lib->settings, "%s.dh_exponent_ansi_x9_42", TRUE, lib->ns)) { for (i = 0; i < countof(dh_params); i++) @@ -463,7 +464,7 @@ diffie_hellman_params_t *diffie_hellman_get_params(diffie_hellman_group_t group) if (!dh_params[i].public.exp_len) { if (!dh_params[i].public.subgroup.len && - lib->settings->get_int(lib->settings, + lib->settings->get_bool(lib->settings, "%s.dh_exponent_ansi_x9_42", TRUE, lib->ns)) { dh_params[i].public.exp_len = dh_params[i].public.prime.len; @@ -500,3 +501,75 @@ bool diffie_hellman_group_is_ec(diffie_hellman_group_t group) return FALSE; } } + +/** + * See header. + */ +bool diffie_hellman_verify_value(diffie_hellman_group_t group, chunk_t value) +{ + diffie_hellman_params_t *params; + bool valid = FALSE; + + switch (group) + { + case MODP_768_BIT: + case MODP_1024_BIT: + case MODP_1536_BIT: + case MODP_2048_BIT: + case MODP_3072_BIT: + case MODP_4096_BIT: + case MODP_6144_BIT: + case MODP_8192_BIT: + case MODP_1024_160: + case MODP_2048_224: + case MODP_2048_256: + params = diffie_hellman_get_params(group); + if (params) + { + valid = value.len == params->prime.len; + } + break; + case ECP_192_BIT: + valid = value.len == 48; + break; + case ECP_224_BIT: + case ECP_224_BP: + valid = value.len == 56; + break; + case ECP_256_BIT: + case ECP_256_BP: + valid = value.len == 64; + break; + case ECP_384_BIT: + case ECP_384_BP: + valid = value.len == 96; + break; + case ECP_512_BP: + valid = value.len == 128; + break; + case ECP_521_BIT: + valid = value.len == 132; + break; + case NTRU_112_BIT: + case NTRU_128_BIT: + case NTRU_192_BIT: + case NTRU_256_BIT: + /* verification currently not supported, do in plugin */ + valid = FALSE; + break; + case MODP_NULL: + case MODP_CUSTOM: + valid = TRUE; + break; + case MODP_NONE: + /* fail */ + break; + /* compile-warn unhandled groups, fail verification */ + } + if (!valid) + { + DBG1(DBG_ENC, "invalid DH public value size (%zu bytes) for %N", + value.len, diffie_hellman_group_names, group); + } + return valid; +} diff --git a/src/libstrongswan/crypto/diffie_hellman.h b/src/libstrongswan/crypto/diffie_hellman.h index 105db22f1..4704cd0da 100644 --- a/src/libstrongswan/crypto/diffie_hellman.h +++ b/src/libstrongswan/crypto/diffie_hellman.h @@ -63,12 +63,14 @@ enum diffie_hellman_group_t { /** insecure NULL diffie hellman group for testing, in PRIVATE USE */ MODP_NULL = 1024, /** MODP group with custom generator/prime */ - MODP_CUSTOM = 1025, /** Parameters defined by IEEE 1363.1, in PRIVATE USE */ NTRU_112_BIT = 1030, NTRU_128_BIT = 1031, NTRU_192_BIT = 1032, - NTRU_256_BIT = 1033 + NTRU_256_BIT = 1033, + /** internally used DH group with additional parameters g and p, outside + * of PRIVATE USE (i.e. IKEv2 DH group range) so it can't be negotiated */ + MODP_CUSTOM = 65536, }; /** @@ -87,9 +89,10 @@ struct diffie_hellman_t { * Space for returned secret is allocated and must be freed by the caller. * * @param secret shared secret will be written into this chunk - * @return SUCCESS, FAILED if not both DH values are set + * @return TRUE if shared secret computed successfully */ - status_t (*get_shared_secret) (diffie_hellman_t *this, chunk_t *secret); + bool (*get_shared_secret)(diffie_hellman_t *this, chunk_t *secret) + __attribute__((warn_unused_result)); /** * Sets the public value of partner. @@ -97,8 +100,10 @@ struct diffie_hellman_t { * Chunk gets cloned and can be destroyed afterwards. * * @param value public value of partner + * @return TRUE if other public value verified and set */ - void (*set_other_public_value) (diffie_hellman_t *this, chunk_t value); + bool (*set_other_public_value)(diffie_hellman_t *this, chunk_t value) + __attribute__((warn_unused_result)); /** * Gets the own public value to transmit. @@ -106,8 +111,10 @@ struct diffie_hellman_t { * Space for returned chunk is allocated and must be freed by the caller. * * @param value public value of caller is stored at this location + * @return TRUE if public value retrieved */ - void (*get_my_public_value) (diffie_hellman_t *this, chunk_t *value); + bool (*get_my_public_value) (diffie_hellman_t *this, chunk_t *value) + __attribute__((warn_unused_result)); /** * Get the DH group used. @@ -168,8 +175,17 @@ diffie_hellman_params_t *diffie_hellman_get_params(diffie_hellman_group_t group) * Check if a given DH group is an ECDH group * * @param group group to check - * @return TUE if group is an ECP group + * @return TRUE if group is an ECP group */ bool diffie_hellman_group_is_ec(diffie_hellman_group_t group); +/** + * Check if a diffie hellman public value is valid for given group. + * + * @param group group the value is used in + * @param value public DH value to check + * @return TRUE if value looks valid for group + */ +bool diffie_hellman_verify_value(diffie_hellman_group_t group, chunk_t value); + #endif /** DIFFIE_HELLMAN_H_ @}*/ diff --git a/src/libstrongswan/crypto/hashers/hash_algorithm_set.c b/src/libstrongswan/crypto/hashers/hash_algorithm_set.c new file mode 100644 index 000000000..93b67cb13 --- /dev/null +++ b/src/libstrongswan/crypto/hashers/hash_algorithm_set.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2015 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "hash_algorithm_set.h" + +#include <collections/array.h> + +typedef struct private_hash_algorithm_set_t private_hash_algorithm_set_t; + +struct private_hash_algorithm_set_t { + + /** + * Public interface + */ + hash_algorithm_set_t public; + + /** + * Algorithms contained in the set + */ + array_t *algorithms; +}; + +/** + * Sort hash algorithms + */ +static int hash_sort(const void *a, const void *b, void *user) +{ + const hash_algorithm_t *ha = a, *hb = b; + return *ha - *hb; +} + +/** + * Find a hash algorithm + */ +static int hash_find(const void *a, const void *b) +{ + return hash_sort(a, b, NULL); +} + +METHOD(hash_algorithm_set_t, contains, bool, + private_hash_algorithm_set_t *this, hash_algorithm_t hash) +{ + return array_bsearch(this->algorithms, &hash, hash_find, NULL) != -1; +} + +METHOD(hash_algorithm_set_t, add, void, + private_hash_algorithm_set_t *this, hash_algorithm_t hash) +{ + if (!contains(this, hash)) + { + array_insert(this->algorithms, ARRAY_TAIL, &hash); + array_sort(this->algorithms, hash_sort, NULL); + } +} + +METHOD(hash_algorithm_set_t, count, int, + private_hash_algorithm_set_t *this) +{ + return array_count(this->algorithms); +} + +static bool hash_filter(void *data, void **in, hash_algorithm_t *out) +{ + *out = **(hash_algorithm_t**)in; + return TRUE; +} + +METHOD(hash_algorithm_set_t, create_enumerator, enumerator_t*, + private_hash_algorithm_set_t *this) +{ + return enumerator_create_filter(array_create_enumerator(this->algorithms), + (void*)hash_filter, NULL, NULL); +} + +METHOD(hash_algorithm_set_t, destroy, void, + private_hash_algorithm_set_t *this) +{ + array_destroy(this->algorithms); + free(this); +} + +/** + * Described in header + */ +hash_algorithm_set_t *hash_algorithm_set_create() +{ + private_hash_algorithm_set_t *this; + + INIT(this, + .public = { + .add = _add, + .contains = _contains, + .count = _count, + .create_enumerator = _create_enumerator, + .destroy = _destroy, + }, + .algorithms = array_create(sizeof(hash_algorithm_t), 0), + ); + + return &this->public; +}
\ No newline at end of file diff --git a/src/libstrongswan/crypto/hashers/hash_algorithm_set.h b/src/libstrongswan/crypto/hashers/hash_algorithm_set.h new file mode 100644 index 000000000..00e90cc2e --- /dev/null +++ b/src/libstrongswan/crypto/hashers/hash_algorithm_set.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2015 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup hash_algorithm_set hash_algorithm_set + * @{ @ingroup crypto + */ + +#ifndef HASH_ALGORITHM_SET_H_ +#define HASH_ALGORITHM_SET_H_ + +typedef struct hash_algorithm_set_t hash_algorithm_set_t; + +#include <library.h> +#include <crypto/hashers/hasher.h> + +/** + * A set of hash algorithms + */ +struct hash_algorithm_set_t { + + /** + * Add the given algorithm to the set. + * + * @param alg hash algorithm + */ + void (*add)(hash_algorithm_set_t *this, hash_algorithm_t alg); + + /** + * Check if the given algorithm is contained in the set. + * + * @param alg hash algorithm + * @return TRUE if contained in set + */ + bool (*contains)(hash_algorithm_set_t *this, hash_algorithm_t alg); + + /** + * Number of hash algorithms contained in the set. + * + * @return number of algorithms + */ + int (*count)(hash_algorithm_set_t *this); + + /** + * Enumerate the algorithms contained in the set. + * + * @return enumerator over hash_algorithm_t (sorted by identifier) + */ + enumerator_t *(*create_enumerator)(hash_algorithm_set_t *this); + + /** + * Destroy a hash_algorithm_set_t instance + */ + void (*destroy)(hash_algorithm_set_t *this); +}; + +/** + * Create a set of hash algorithms. + * + * @return hash_algorithm_set_t instance + */ +hash_algorithm_set_t *hash_algorithm_set_create(); + +#endif /** HASH_ALGORITHM_SET_H_ @}*/ diff --git a/src/libstrongswan/crypto/hashers/hasher.c b/src/libstrongswan/crypto/hashers/hasher.c index 13cbb5a59..38eebea9c 100644 --- a/src/libstrongswan/crypto/hashers/hasher.c +++ b/src/libstrongswan/crypto/hashers/hasher.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2012-2015 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -19,29 +19,31 @@ #include <asn1/oid.h> -ENUM(hash_algorithm_names, HASH_UNKNOWN, HASH_SHA512, +ENUM_BEGIN(hash_algorithm_names, HASH_SHA1, HASH_SHA512, + "HASH_SHA1", + "HASH_SHA256", + "HASH_SHA384", + "HASH_SHA512"); +ENUM_NEXT(hash_algorithm_names, HASH_UNKNOWN, HASH_SHA224, HASH_SHA512, "HASH_UNKNOWN", "HASH_MD2", "HASH_MD4", "HASH_MD5", - "HASH_SHA1", - "HASH_SHA224", - "HASH_SHA256", - "HASH_SHA384", - "HASH_SHA512" -); + "HASH_SHA224"); +ENUM_END(hash_algorithm_names, HASH_SHA224); -ENUM(hash_algorithm_short_names, HASH_UNKNOWN, HASH_SHA512, +ENUM_BEGIN(hash_algorithm_short_names, HASH_SHA1, HASH_SHA512, + "sha1", + "sha256", + "sha384", + "sha512"); +ENUM_NEXT(hash_algorithm_short_names, HASH_UNKNOWN, HASH_SHA224, HASH_SHA512, "unknown", "md2", "md4", "md5", - "sha1", - "sha224", - "sha256", - "sha384", - "sha512" -); + "sha224"); +ENUM_END(hash_algorithm_short_names, HASH_SHA224); /* * Described in header. @@ -249,6 +251,28 @@ integrity_algorithm_t hasher_algorithm_to_integrity(hash_algorithm_t alg, /* * Described in header. */ +bool hasher_algorithm_for_ikev2(hash_algorithm_t alg) +{ + switch (alg) + { + case HASH_SHA1: + case HASH_SHA256: + case HASH_SHA384: + case HASH_SHA512: + return TRUE; + case HASH_UNKNOWN: + case HASH_MD2: + case HASH_MD4: + case HASH_MD5: + case HASH_SHA224: + break; + } + return FALSE; +} + +/* + * Described in header. + */ int hasher_algorithm_to_oid(hash_algorithm_t alg) { int oid; @@ -323,8 +347,56 @@ int hasher_signature_algorithm_to_oid(hash_algorithm_t alg, key_type_t key) default: return OID_UNKNOWN; } + case KEY_BLISS: + switch (alg) + { + case HASH_SHA256: + return OID_BLISS_WITH_SHA256; + case HASH_SHA384: + return OID_BLISS_WITH_SHA384; + case HASH_SHA512: + return OID_BLISS_WITH_SHA512; + default: + return OID_UNKNOWN; + } default: return OID_UNKNOWN; } } +/* + * Defined in header. + */ +hash_algorithm_t hasher_from_signature_scheme(signature_scheme_t scheme) +{ + switch (scheme) + { + case SIGN_UNKNOWN: + case SIGN_RSA_EMSA_PKCS1_NULL: + case SIGN_ECDSA_WITH_NULL: + break; + case SIGN_RSA_EMSA_PKCS1_MD5: + return HASH_MD5; + case SIGN_RSA_EMSA_PKCS1_SHA1: + case SIGN_ECDSA_WITH_SHA1_DER: + return HASH_SHA1; + case SIGN_RSA_EMSA_PKCS1_SHA224: + return HASH_SHA224; + case SIGN_RSA_EMSA_PKCS1_SHA256: + case SIGN_ECDSA_WITH_SHA256_DER: + case SIGN_ECDSA_256: + case SIGN_BLISS_WITH_SHA256: + return HASH_SHA256; + case SIGN_RSA_EMSA_PKCS1_SHA384: + case SIGN_ECDSA_WITH_SHA384_DER: + case SIGN_ECDSA_384: + case SIGN_BLISS_WITH_SHA384: + return HASH_SHA384; + case SIGN_RSA_EMSA_PKCS1_SHA512: + case SIGN_ECDSA_WITH_SHA512_DER: + case SIGN_ECDSA_521: + case SIGN_BLISS_WITH_SHA512: + return HASH_SHA512; + } + return HASH_UNKNOWN; +} diff --git a/src/libstrongswan/crypto/hashers/hasher.h b/src/libstrongswan/crypto/hashers/hasher.h index 37ef0b6ab..772586308 100644 --- a/src/libstrongswan/crypto/hashers/hasher.h +++ b/src/libstrongswan/crypto/hashers/hasher.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Tobias Brunner + * Copyright (C) 2012-2015 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -32,19 +32,19 @@ typedef struct hasher_t hasher_t; #include <credentials/keys/public_key.h> /** - * Algorithms to use for hashing. + * Hash algorithms as defined for IKEv2 by RFC 7427 */ enum hash_algorithm_t { - /** not specified hash function */ - HASH_UNKNOWN = 0, - HASH_MD2 = 1, - HASH_MD4 = 2, - HASH_MD5 = 3, - HASH_SHA1 = 4, - HASH_SHA224 = 5, - HASH_SHA256 = 6, - HASH_SHA384 = 7, - HASH_SHA512 = 8 + HASH_SHA1 = 1, + HASH_SHA256 = 2, + HASH_SHA384 = 3, + HASH_SHA512 = 4, + /* use private use range for algorithms not defined/permitted by RFC 7427 */ + HASH_UNKNOWN = 1024, + HASH_MD2 = 1025, + HASH_MD4 = 1026, + HASH_MD5 = 1027, + HASH_SHA224 = 1028, }; #define HASH_SIZE_MD2 16 @@ -163,6 +163,14 @@ integrity_algorithm_t hasher_algorithm_to_integrity(hash_algorithm_t alg, size_t length); /** + * Check if the given algorithm may be used for IKEv2 signature authentication. + * + * @param alg hash algorithm + * @return TRUE if algorithm may be used, FALSE otherwise + */ +bool hasher_algorithm_for_ikev2(hash_algorithm_t alg); + +/** * Conversion of hash algorithm into ASN.1 OID. * * @param alg hash algorithm @@ -179,4 +187,12 @@ int hasher_algorithm_to_oid(hash_algorithm_t alg); */ int hasher_signature_algorithm_to_oid(hash_algorithm_t alg, key_type_t key); +/** + * Determine the hash algorithm associated with a given signature scheme. + * + * @param scheme signature scheme + * @return hash algorithm (could be HASH_UNKNOWN) + */ +hash_algorithm_t hasher_from_signature_scheme(signature_scheme_t scheme); + #endif /** HASHER_H_ @}*/ diff --git a/src/libstrongswan/plugins/ntru/ntru_mgf1.c b/src/libstrongswan/crypto/mgf1/mgf1.c index 2338db208..4bbcd6e99 100644 --- a/src/libstrongswan/plugins/ntru/ntru_mgf1.c +++ b/src/libstrongswan/crypto/mgf1/mgf1.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Andreas Steffen + * Copyright (C) 2013-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -13,23 +13,23 @@ * for more details. */ -#include "ntru_mgf1.h" +#include "mgf1.h" -#include <crypto/hashers/hasher.h> -#include <utils/debug.h> -#include <utils/test.h> +#include "crypto/hashers/hasher.h" +#include "utils/debug.h" +#include "utils/test.h" -typedef struct private_ntru_mgf1_t private_ntru_mgf1_t; +typedef struct private_mgf1_t private_mgf1_t; /** - * Private data of an ntru_mgf1_t object. + * Private data of an mgf1_t object. */ -struct private_ntru_mgf1_t { +struct private_mgf1_t { /** - * Public ntru_mgf1_t interface. + * Public mgf1_t interface. */ - ntru_mgf1_t public; + mgf1_t public; /** * Hasher the MGF1 Mask Generation Function is based on @@ -58,14 +58,14 @@ struct private_ntru_mgf1_t { }; -METHOD(ntru_mgf1_t, get_hash_size, size_t, - private_ntru_mgf1_t *this) +METHOD(mgf1_t, get_hash_size, size_t, + private_mgf1_t *this) { return this->hasher->get_hash_size(this->hasher); } -METHOD(ntru_mgf1_t, get_mask, bool, - private_ntru_mgf1_t *this, size_t mask_len, u_char *mask) +METHOD(mgf1_t, get_mask, bool, + private_mgf1_t *this, size_t mask_len, u_char *mask) { u_char buf[HASH_SIZE_SHA512]; size_t hash_len; @@ -102,8 +102,8 @@ METHOD(ntru_mgf1_t, get_mask, bool, return TRUE; } -METHOD(ntru_mgf1_t, allocate_mask, bool, - private_ntru_mgf1_t *this, size_t mask_len, chunk_t *mask) +METHOD(mgf1_t, allocate_mask, bool, + private_mgf1_t *this, size_t mask_len, chunk_t *mask) { if (mask_len == 0) { @@ -115,8 +115,8 @@ METHOD(ntru_mgf1_t, allocate_mask, bool, return get_mask(this, mask_len, mask->ptr); } -METHOD(ntru_mgf1_t, destroy, void, - private_ntru_mgf1_t *this) +METHOD(mgf1_t, destroy, void, + private_mgf1_t *this) { this->hasher->destroy(this->hasher); chunk_clear(&this->state); @@ -126,10 +126,10 @@ METHOD(ntru_mgf1_t, destroy, void, /* * Described in header. */ -ntru_mgf1_t *ntru_mgf1_create(hash_algorithm_t alg, chunk_t seed, +mgf1_t *mgf1_create(hash_algorithm_t alg, chunk_t seed, bool hash_seed) { - private_ntru_mgf1_t *this; + private_mgf1_t *this; hasher_t *hasher; size_t state_len; @@ -178,5 +178,3 @@ ntru_mgf1_t *ntru_mgf1_create(hash_algorithm_t alg, chunk_t seed, return &this->public; } - -EXPORT_FUNCTION_FOR_TESTS(ntru, ntru_mgf1_create); diff --git a/src/libstrongswan/plugins/ntru/ntru_mgf1.h b/src/libstrongswan/crypto/mgf1/mgf1.h index 53e90412a..592d31596 100644 --- a/src/libstrongswan/plugins/ntru/ntru_mgf1.h +++ b/src/libstrongswan/crypto/mgf1/mgf1.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Andreas Steffen + * Copyright (C) 2013-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -14,29 +14,29 @@ */ /** - * @defgroup ntru_mgf1 ntru_mgf1 - * @{ @ingroup ntru_p + * @defgroup mgf1 mgf1 + * @{ @ingroup crypto */ -#ifndef NTRU_MGF1_H_ -#define NTRU_MGF1_H_ +#ifndef MGF1_H_ +#define MGF1_H_ -typedef struct ntru_mgf1_t ntru_mgf1_t; +typedef struct mgf1_t mgf1_t; #include <library.h> /** * Implements the PKCS#1 MGF1 Mask Generation Function based on a hash function - * defined in section 10.2.1 of RFC 2437 + * defined in section 10.2.1 of RFC 2437 */ -struct ntru_mgf1_t { +struct mgf1_t { /** * Get the hash size of the underlying hash function * * @return hash size in bytes */ - size_t (*get_hash_size)(ntru_mgf1_t *this); + size_t (*get_hash_size)(mgf1_t *this); /** * Generate a mask pattern and copy it to an output buffer @@ -46,7 +46,7 @@ struct ntru_mgf1_t { * @param mask output buffer of minimum size mask_len * @return TRUE if successful */ - bool (*get_mask)(ntru_mgf1_t *this, size_t mask_len, u_char *mask); + bool (*get_mask)(mgf1_t *this, size_t mask_len, u_char *mask); /** * Generate a mask pattern and return it in an allocated chunk @@ -55,12 +55,12 @@ struct ntru_mgf1_t { * @param mask chunk containing generated mask * @return TRUE if successful */ - bool (*allocate_mask)(ntru_mgf1_t *this, size_t mask_len, chunk_t *mask); + bool (*allocate_mask)(mgf1_t *this, size_t mask_len, chunk_t *mask); /** * Destroy the MGF1 object */ - void (*destroy)(ntru_mgf1_t *this); + void (*destroy)(mgf1_t *this); }; /** @@ -68,10 +68,10 @@ struct ntru_mgf1_t { * * @param alg hash algorithm to be used by MGF1 * @param seed seed used by MGF1 to generate mask from - * @param hash_seed hash seed before using it as a seed from MGF1 + * @param hash_seed hash seed before using it as a seed for MGF1 */ -ntru_mgf1_t *ntru_mgf1_create(hash_algorithm_t alg, chunk_t seed, +mgf1_t *mgf1_create(hash_algorithm_t alg, chunk_t seed, bool hash_seed); -#endif /** NTRU_MGF1_H_ @}*/ +#endif /** MGF1_H_ @}*/ diff --git a/src/libstrongswan/crypto/mgf1/mgf1_bitspender.c b/src/libstrongswan/crypto/mgf1/mgf1_bitspender.c new file mode 100644 index 000000000..ef0a2bd01 --- /dev/null +++ b/src/libstrongswan/crypto/mgf1/mgf1_bitspender.c @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "mgf1_bitspender.h" + +#include <crypto/mgf1/mgf1.h> + +typedef struct private_mgf1_bitspender_t private_mgf1_bitspender_t; + +/** + * Private data structure for mgf1_bitspender_t object + */ +struct private_mgf1_bitspender_t { + /** + * Public interface. + */ + mgf1_bitspender_t public; + + /** + * MGF1 bit mask generator + */ + mgf1_t *mgf1; + + /** + * Octet storage (accommodates up to 64 octets) + */ + uint8_t octets[HASH_SIZE_SHA512]; + + /** + * Length of the returned hash value in octets + */ + int hash_len; + + /** + * Number of generated octets + */ + int octets_count; + + /** + * Number of available octets + */ + int octets_left; + + /** + * Bit storage (accommodates up to 32 bits) + */ + uint32_t bits; + + /** + * Number of available bits + */ + int bits_left; + + /** + * Byte storage (accommodates up to 4 bytes) + */ + uint8_t bytes[4]; + + /** + * Number of available bytes + */ + int bytes_left; + +}; + +METHOD(mgf1_bitspender_t, get_bits, bool, + private_mgf1_bitspender_t *this, int bits_needed, uint32_t *bits) +{ + int bits_now; + + *bits = 0x00000000; + + if (bits_needed == 0) + { + /* trivial */ + return TRUE; + } + if (bits_needed > 32) + { + /* too many bits requested */ + return FALSE; + } + + while (bits_needed) + { + if (this->bits_left == 0) + { + if (this->octets_left == 0) + { + /* get another block from MGF1 */ + if (!this->mgf1->get_mask(this->mgf1, this->hash_len, + this->octets)) + { + /* no block available */ + return FALSE; + } + this->octets_left = this->hash_len; + this->octets_count += this->hash_len; + } + this->bits = untoh32(this->octets + this->hash_len - + this->octets_left); + this->bits_left = 32; + this->octets_left -= 4; + } + if (bits_needed > this->bits_left) + { + bits_now = this->bits_left; + this->bits_left = 0; + bits_needed -= bits_now; + } + else + { + bits_now = bits_needed; + this->bits_left -= bits_needed; + bits_needed = 0; + } + if (bits_now == 32) + { + *bits = this->bits; + } + else + { + *bits <<= bits_now; + *bits |= this->bits >> this->bits_left; + if (this->bits_left) + { + this->bits &= 0xffffffff >> (32 - this->bits_left); + } + } + } + return TRUE; +} + +METHOD(mgf1_bitspender_t, get_byte, bool, + private_mgf1_bitspender_t *this, uint8_t *byte) +{ + if (this->bytes_left == 0) + { + if (this->octets_left == 0) + { + /* get another block from MGF1 */ + if (!this->mgf1->get_mask(this->mgf1, this->hash_len, this->octets)) + { + /* no block available */ + return FALSE; + } + this->octets_left = this->hash_len; + this->octets_count += this->hash_len; + } + memcpy(this->bytes, this->octets + this->hash_len - this->octets_left, 4); + this->bytes_left = 4; + this->octets_left -= 4; + } + *byte = this->bytes[4 - this->bytes_left--]; + + return TRUE; +} + +METHOD(mgf1_bitspender_t, destroy, void, + private_mgf1_bitspender_t *this) +{ + DBG2(DBG_LIB, "mgf1 generated %u octets", this->octets_count); + memwipe(this->octets, sizeof(this->octets)); + this->mgf1->destroy(this->mgf1); + free(this); +} + +/** + * See header. + */ +mgf1_bitspender_t *mgf1_bitspender_create(hash_algorithm_t alg, chunk_t seed, + bool hash_seed) +{ + private_mgf1_bitspender_t *this; + mgf1_t *mgf1; + + mgf1 = mgf1_create(alg, seed, hash_seed); + if (!mgf1) + { + return NULL; + } + DBG2(DBG_LIB, "mgf1 based on %N is seeded with %u octets", + hash_algorithm_short_names, alg, seed.len); + + INIT(this, + .public = { + .get_bits = _get_bits, + .get_byte = _get_byte, + .destroy = _destroy, + }, + .mgf1 = mgf1, + .hash_len = mgf1->get_hash_size(mgf1), + ); + + return &this->public; +} diff --git a/src/libstrongswan/crypto/mgf1/mgf1_bitspender.h b/src/libstrongswan/crypto/mgf1/mgf1_bitspender.h new file mode 100644 index 000000000..f7df8e834 --- /dev/null +++ b/src/libstrongswan/crypto/mgf1/mgf1_bitspender.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup mgf1_bitspender mgf1_bitspender + * @{ @ingroup mgf1 + */ + +#ifndef MGF1_BITSPENDER_H_ +#define MGF1_BITSPENDER_H_ + +#include <library.h> +#include <crypto/hashers/hasher.h> + +typedef struct mgf1_bitspender_t mgf1_bitspender_t; + +/** + * Generates a given number of pseudo-random bits at a time using MGF1 + */ +struct mgf1_bitspender_t { + + /** + * Get pseudo-random bits + * + * @param bits_needed Number of needed bits (1..32) + * @param bits Pseudo-random bits + * @result FALSE if internal MGF1 error occurred + */ + bool (*get_bits)(mgf1_bitspender_t *this, int bits_needed, uint32_t *bits); + + /** + * Get a pseudo-random byte + * + * @param byte Pseudo-random byte + * @result FALSE if internal MGF1 error occurred + */ + bool (*get_byte)(mgf1_bitspender_t *this, uint8_t *byte); + + /** + * Destroy mgf1_bitspender_t object + */ + void (*destroy)(mgf1_bitspender_t *this); +}; + +/** + * Create a mgf1_bitspender_t object + * + * @param alg Hash algorithm to be used with MGF1 + * @param seed Seed used to initialize MGF1 + * @param hash_seed Hash seed before using it as a seed for MFG1 + */ +mgf1_bitspender_t *mgf1_bitspender_create(hash_algorithm_t alg, chunk_t seed, + bool hash_seed); + +#endif /** MGF1_BITSPENDER_H_ @}*/ diff --git a/src/libstrongswan/crypto/pkcs5.c b/src/libstrongswan/crypto/pkcs5.c index 3b4df0e8a..478926f2f 100644 --- a/src/libstrongswan/crypto/pkcs5.c +++ b/src/libstrongswan/crypto/pkcs5.c @@ -108,13 +108,13 @@ struct private_pkcs5_t { * Verify padding of decrypted blob. * Length of blob is adjusted accordingly. */ -static bool verify_padding(chunk_t *blob) +static bool verify_padding(crypter_t *crypter, chunk_t *blob) { u_int8_t padding, count; padding = count = blob->ptr[blob->len - 1]; - if (padding > 8) + if (padding > crypter->get_block_size(crypter)) { return FALSE; } @@ -153,7 +153,7 @@ static bool decrypt_generic(private_pkcs5_t *this, chunk_t password, return FALSE; } memwipe(keymat.ptr, keymat.len); - if (verify_padding(decrypted)) + if (verify_padding(this->crypter, decrypted)) { return TRUE; } @@ -504,6 +504,7 @@ static bool parse_pbes2_params(private_pkcs5_t *this, chunk_t blob, int level0) { asn1_parser_t *parser; chunk_t object, params; + size_t keylen; int objectID; bool success = FALSE; @@ -533,20 +534,35 @@ static bool parse_pbes2_params(private_pkcs5_t *this, chunk_t blob, int level0) { int oid = asn1_parse_algorithmIdentifier(object, parser->get_level(parser) + 1, ¶ms); - if (oid != OID_3DES_EDE_CBC) + this->encr = encryption_algorithm_from_oid(oid, &keylen); + if (this->encr == ENCR_UNDEFINED) { /* unsupported encryption scheme */ goto end; } - if (this->keylen <= 0) - { /* default key length for DES-EDE3-CBC-Pad */ - this->keylen = 24; + /* prefer encoded key length */ + this->keylen = this->keylen ?: keylen / 8; + if (!this->keylen) + { /* set default key length for known algorithms */ + switch (this->encr) + { + case ENCR_DES: + this->keylen = 8; + break; + case ENCR_3DES: + this->keylen = 24; + break; + case ENCR_BLOWFISH: + this->keylen = 16; + break; + default: + goto end; + } } if (!asn1_parse_simple_object(¶ms, ASN1_OCTET_STRING, parser->get_level(parser) + 1, "IV")) { goto end; } - this->encr = ENCR_3DES; this->data.pbes2.iv = chunk_clone(params); break; } diff --git a/src/libstrongswan/ipsec/ipsec_types.c b/src/libstrongswan/ipsec/ipsec_types.c index 4bbd918a0..f2ee11ee8 100644 --- a/src/libstrongswan/ipsec/ipsec_types.c +++ b/src/libstrongswan/ipsec/ipsec_types.c @@ -48,7 +48,15 @@ bool mark_from_string(const char *value, mark_t *mark) { return FALSE; } - mark->value = strtoul(value, &endptr, 0); + if (strcasepfx(value, "%unique")) + { + mark->value = MARK_UNIQUE; + endptr = (char*)value + strlen("%unique"); + } + else + { + mark->value = strtoul(value, &endptr, 0); + } if (*endptr) { if (*endptr != '/') diff --git a/src/libstrongswan/ipsec/ipsec_types.h b/src/libstrongswan/ipsec/ipsec_types.h index c1465e097..fa122af30 100644 --- a/src/libstrongswan/ipsec/ipsec_types.h +++ b/src/libstrongswan/ipsec/ipsec_types.h @@ -169,9 +169,9 @@ struct mark_t { }; /** - * Special mark value that uses the reqid of the CHILD_SA as mark + * Special mark value that uses a unique mark for each CHILD_SA */ -#define MARK_REQID (0xFFFFFFFF) +#define MARK_UNIQUE (0xFFFFFFFF) /** * Try to parse a mark_t from the given string of the form mark[/mask]. diff --git a/src/libstrongswan/library.h b/src/libstrongswan/library.h index 2bd5e3523..3a6dd1ba4 100644 --- a/src/libstrongswan/library.h +++ b/src/libstrongswan/library.h @@ -79,6 +79,9 @@ * * @defgroup utils utils * @ingroup libstrongswan + * + * @defgroup compat compat + * @ingroup utils */ /** diff --git a/src/libstrongswan/networking/host.c b/src/libstrongswan/networking/host.c index 8d04a4ec9..07da3ef3b 100644 --- a/src/libstrongswan/networking/host.c +++ b/src/libstrongswan/networking/host.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2012 Tobias Brunner + * Copyright (C) 2006-2014 Tobias Brunner * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -528,6 +528,42 @@ host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port) /* * Described in header. */ +bool host_create_from_range(char *string, host_t **from, host_t **to) +{ + char *sep, *pos; + + sep = strchr(string, '-'); + if (!sep) + { + return FALSE; + } + for (pos = sep+1; *pos && *pos == ' '; pos++) + { + /* trim spaces before to address*/ + } + *to = host_create_from_string(pos, 0); + if (!*to) + { + return FALSE; + } + for (pos = sep-1; pos > string && *pos == ' '; pos--) + { + /* trim spaces behind from address */ + } + pos = strndup(string, pos - string + 1); + *from = host_create_from_string_and_family(pos, (*to)->get_family(*to), 0); + free(pos); + if (!*from) + { + (*to)->destroy(*to); + return FALSE; + } + return TRUE; +} + +/* + * Described in header. + */ host_t *host_create_from_subnet(char *string, int *bits) { char *pos, buf[64]; diff --git a/src/libstrongswan/networking/host.h b/src/libstrongswan/networking/host.h index 9c9b5035f..db6f4dd49 100644 --- a/src/libstrongswan/networking/host.h +++ b/src/libstrongswan/networking/host.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2009 Tobias Brunner + * Copyright (C) 2006-2014 Tobias Brunner * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2005 Jan Hutter @@ -24,6 +24,9 @@ #ifndef HOST_H_ #define HOST_H_ +#include <utils/utils.h> +#include <utils/chunk.h> + typedef enum host_diff_t host_diff_t; typedef struct host_t host_t; @@ -31,9 +34,6 @@ typedef struct host_t host_t; #include <stdio.h> #include <sys/types.h> -#include <utils/utils.h> -#include <utils/chunk.h> - /** * Representates a Host * @@ -181,6 +181,19 @@ host_t *host_create_from_chunk(int family, chunk_t address, u_int16_t port); host_t *host_create_from_sockaddr(sockaddr_t *sockaddr); /** + * Parse a range definition (1.2.3.0-1.2.3.5), return the two hosts. + * + * The two hosts are not ordered, from is simply the first, to is the second, + * from is not necessarily smaller. + * + * @param string string to parse + * @param from returns the first address (out) + * @param to returns the second address (out) + * @return TRUE if parsed successfully, FALSE otherwise + */ +bool host_create_from_range(char *string, host_t **from, host_t **to); + +/** * Create a host from a CIDR subnet definition (1.2.3.0/24), return bits. * * @param string string to parse diff --git a/src/libstrongswan/networking/host_resolver.c b/src/libstrongswan/networking/host_resolver.c index a7524ac23..bad87e434 100644 --- a/src/libstrongswan/networking/host_resolver.c +++ b/src/libstrongswan/networking/host_resolver.c @@ -163,20 +163,25 @@ static void *resolve_hosts(private_host_resolver_t *this) int error; bool old, timed_out; + /* default resolver threads to non-cancellable */ + thread_cancelability(FALSE); + while (TRUE) { this->mutex->lock(this->mutex); - thread_cleanup_push((thread_cleanup_t)this->mutex->unlock, this->mutex); while (this->queue->remove_first(this->queue, (void**)&query) != SUCCESS) { - old = thread_cancelability(TRUE); + if (this->disabled) + { + this->mutex->unlock(this->mutex); + return NULL; + } timed_out = this->new_query->timed_wait(this->new_query, this->mutex, NEW_QUERY_WAIT_TIMEOUT * 1000); - thread_cancelability(old); if (this->disabled) { - thread_cleanup_pop(TRUE); + this->mutex->unlock(this->mutex); return NULL; } else if (timed_out && (this->threads > this->min_threads)) @@ -185,13 +190,13 @@ static void *resolve_hosts(private_host_resolver_t *this) this->threads--; this->pool->remove(this->pool, thread, NULL); - thread_cleanup_pop(TRUE); + this->mutex->unlock(this->mutex); thread->detach(thread); return NULL; } } this->busy_threads++; - thread_cleanup_pop(TRUE); + this->mutex->unlock(this->mutex); memset(&hints, 0, sizeof(hints)); hints.ai_family = query->family; diff --git a/src/libstrongswan/networking/tun_device.c b/src/libstrongswan/networking/tun_device.c index ff2c4a337..81d215677 100644 --- a/src/libstrongswan/networking/tun_device.c +++ b/src/libstrongswan/networking/tun_device.c @@ -346,40 +346,27 @@ METHOD(tun_device_t, write_packet, bool, METHOD(tun_device_t, read_packet, bool, private_tun_device_t *this, chunk_t *packet) { + chunk_t data; ssize_t len; - fd_set set; bool old; - FD_ZERO(&set); - FD_SET(this->tunfd, &set); + data = chunk_alloca(get_mtu(this)); old = thread_cancelability(TRUE); - len = select(this->tunfd + 1, &set, NULL, NULL, NULL); + len = read(this->tunfd, data.ptr, data.len); thread_cancelability(old); - - if (len < 0) - { - DBG1(DBG_LIB, "select on TUN device %s failed: %s", this->if_name, - strerror(errno)); - return FALSE; - } - /* FIXME: this is quite expensive for lots of small packets, copy from - * local buffer instead? */ - *packet = chunk_alloc(get_mtu(this)); - len = read(this->tunfd, packet->ptr, packet->len); if (len < 0) { DBG1(DBG_LIB, "reading from TUN device %s failed: %s", this->if_name, strerror(errno)); - chunk_free(packet); return FALSE; } - packet->len = len; + data.len = len; #ifdef __APPLE__ /* UTUN's prepend packets with a 32-bit protocol number */ - packet->len -= sizeof(u_int32_t); - memmove(packet->ptr, packet->ptr + sizeof(u_int32_t), packet->len); + data = chunk_skip(data, sizeof(u_int32_t)); #endif + *packet = chunk_clone(data); return TRUE; } diff --git a/src/libstrongswan/networking/tun_device.h b/src/libstrongswan/networking/tun_device.h index 543125beb..880369ba7 100644 --- a/src/libstrongswan/networking/tun_device.h +++ b/src/libstrongswan/networking/tun_device.h @@ -31,8 +31,6 @@ typedef struct tun_device_t tun_device_t; * Class to create TUN devices * * Creating such a device requires the CAP_NET_ADMIN capability. - * - * @note The implementation is currently very Linux specific */ struct tun_device_t { @@ -42,7 +40,7 @@ struct tun_device_t { * @note This call blocks until a packet is available. It is a thread * cancellation point. * - * @param packet the packet read from the device + * @param packet the packet read from the device, allocated * @return TRUE if successful */ bool (*read_packet)(tun_device_t *this, chunk_t *packet); diff --git a/src/libstrongswan/plugins/acert/Makefile.in b/src/libstrongswan/plugins/acert/Makefile.in index 425e8f1a9..65542ea5d 100644 --- a/src/libstrongswan/plugins/acert/Makefile.in +++ b/src/libstrongswan/plugins/acert/Makefile.in @@ -227,6 +227,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/aes/Makefile.in b/src/libstrongswan/plugins/aes/Makefile.in index 11dcf2907..9d79c81ee 100644 --- a/src/libstrongswan/plugins/aes/Makefile.in +++ b/src/libstrongswan/plugins/aes/Makefile.in @@ -226,6 +226,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/af_alg/Makefile.in b/src/libstrongswan/plugins/af_alg/Makefile.in index 279000d88..4a86f9640 100644 --- a/src/libstrongswan/plugins/af_alg/Makefile.in +++ b/src/libstrongswan/plugins/af_alg/Makefile.in @@ -230,6 +230,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -290,10 +291,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -367,6 +370,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/af_alg/af_alg_prf.c b/src/libstrongswan/plugins/af_alg/af_alg_prf.c index 720738a84..2b7d51376 100644 --- a/src/libstrongswan/plugins/af_alg/af_alg_prf.c +++ b/src/libstrongswan/plugins/af_alg/af_alg_prf.c @@ -139,6 +139,7 @@ METHOD(prf_t, set_key, bool, { char buf[this->block_size]; + this->ops->reset(this->ops); if (this->xcbc) { /* The kernel currently does not support variable length XCBC keys, diff --git a/src/libstrongswan/plugins/af_alg/af_alg_signer.c b/src/libstrongswan/plugins/af_alg/af_alg_signer.c index 6ee380633..9ad01103a 100644 --- a/src/libstrongswan/plugins/af_alg/af_alg_signer.c +++ b/src/libstrongswan/plugins/af_alg/af_alg_signer.c @@ -156,6 +156,7 @@ METHOD(signer_t, get_block_size, size_t, METHOD(signer_t, set_key, bool, private_af_alg_signer_t *this, chunk_t key) { + this->ops->reset(this->ops); return this->ops->set_key(this->ops, key); } diff --git a/src/libstrongswan/plugins/agent/Makefile.in b/src/libstrongswan/plugins/agent/Makefile.in index c8e8112c5..292c2fd90 100644 --- a/src/libstrongswan/plugins/agent/Makefile.in +++ b/src/libstrongswan/plugins/agent/Makefile.in @@ -228,6 +228,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -288,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -365,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/bliss/Makefile.am b/src/libstrongswan/plugins/bliss/Makefile.am new file mode 100644 index 000000000..e2aaaf55c --- /dev/null +++ b/src/libstrongswan/plugins/bliss/Makefile.am @@ -0,0 +1,54 @@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/libstrongswan + +AM_CFLAGS = \ + $(PLUGIN_CFLAGS) \ + @COVERAGE_CFLAGS@ + +# these file are also used by bliss_huffman +noinst_LTLIBRARIES = libbliss-params.la +libbliss_params_la_SOURCES = \ + bliss_param_set.h bliss_param_set.c \ + bliss_fft_params.h bliss_fft_params.c + +# these files are also used by the tests, we can't directly refer to them +# because of the subdirectory, which would cause distclean to fail +noinst_LTLIBRARIES += libbliss.la +libbliss_la_SOURCES = \ + bliss_private_key.h bliss_private_key.c \ + bliss_public_key.h bliss_public_key.c \ + bliss_signature.h bliss_signature.c \ + bliss_utils.h bliss_utils.c \ + bliss_bitpacker.h bliss_bitpacker.c \ + bliss_fft.h bliss_fft.c \ + bliss_huffman_code.h bliss_huffman_code.c \ + bliss_huffman_code_1.c bliss_huffman_code_3.c bliss_huffman_code_4.c \ + bliss_huffman_coder.h bliss_huffman_coder.c \ + bliss_sampler.h bliss_sampler.c +libbliss_la_LIBADD = libbliss-params.la + +if MONOLITHIC +noinst_LTLIBRARIES += libstrongswan-bliss.la +else +plugin_LTLIBRARIES = libstrongswan-bliss.la +endif + +libstrongswan_bliss_la_SOURCES = \ + bliss_plugin.h bliss_plugin.c + +libstrongswan_bliss_la_LDFLAGS = -module -avoid-version + +libstrongswan_bliss_la_LIBADD = libbliss.la + +noinst_PROGRAMS = bliss_huffman + +bliss_huffman_SOURCES = bliss_huffman.c +bliss_huffman_LDADD = -lm libbliss-params.la + +recreate-bliss-huffman : bliss_huffman bliss_huffman_code.h + $(AM_V_GEN) \ + ./bliss_huffman 1 8 > $(srcdir)/bliss_huffman_code_1.c 2>/dev/null + $(AM_V_GEN) \ + ./bliss_huffman 3 16 > $(srcdir)/bliss_huffman_code_3.c 2>/dev/null + $(AM_V_GEN) \ + ./bliss_huffman 4 32 > $(srcdir)/bliss_huffman_code_4.c 2>/dev/null diff --git a/src/libstrongswan/plugins/bliss/Makefile.in b/src/libstrongswan/plugins/bliss/Makefile.in new file mode 100644 index 000000000..1361dd340 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/Makefile.in @@ -0,0 +1,862 @@ +# Makefile.in generated by automake 1.14.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@MONOLITHIC_TRUE@am__append_1 = libstrongswan-bliss.la +noinst_PROGRAMS = bliss_huffman$(EXEEXT) +subdir = src/libstrongswan/plugins/bliss +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ + $(top_srcdir)/m4/config/ltoptions.m4 \ + $(top_srcdir)/m4/config/ltsugar.m4 \ + $(top_srcdir)/m4/config/ltversion.m4 \ + $(top_srcdir)/m4/config/lt~obsolete.m4 \ + $(top_srcdir)/m4/macros/split-package-version.m4 \ + $(top_srcdir)/m4/macros/with.m4 \ + $(top_srcdir)/m4/macros/enable-disable.m4 \ + $(top_srcdir)/m4/macros/add-plugin.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(plugindir)" +LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) +libbliss_params_la_LIBADD = +am_libbliss_params_la_OBJECTS = bliss_param_set.lo bliss_fft_params.lo +libbliss_params_la_OBJECTS = $(am_libbliss_params_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libbliss_la_DEPENDENCIES = libbliss-params.la +am_libbliss_la_OBJECTS = bliss_private_key.lo bliss_public_key.lo \ + bliss_signature.lo bliss_utils.lo bliss_bitpacker.lo \ + bliss_fft.lo bliss_huffman_code.lo bliss_huffman_code_1.lo \ + bliss_huffman_code_3.lo bliss_huffman_code_4.lo \ + bliss_huffman_coder.lo bliss_sampler.lo +libbliss_la_OBJECTS = $(am_libbliss_la_OBJECTS) +libstrongswan_bliss_la_DEPENDENCIES = libbliss.la +am_libstrongswan_bliss_la_OBJECTS = bliss_plugin.lo +libstrongswan_bliss_la_OBJECTS = $(am_libstrongswan_bliss_la_OBJECTS) +libstrongswan_bliss_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_bliss_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_bliss_la_rpath = -rpath \ +@MONOLITHIC_FALSE@ $(plugindir) +@MONOLITHIC_TRUE@am_libstrongswan_bliss_la_rpath = +PROGRAMS = $(noinst_PROGRAMS) +am_bliss_huffman_OBJECTS = bliss_huffman.$(OBJEXT) +bliss_huffman_OBJECTS = $(am_bliss_huffman_OBJECTS) +bliss_huffman_DEPENDENCIES = libbliss-params.la +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libbliss_params_la_SOURCES) $(libbliss_la_SOURCES) \ + $(libstrongswan_bliss_la_SOURCES) $(bliss_huffman_SOURCES) +DIST_SOURCES = $(libbliss_params_la_SOURCES) $(libbliss_la_SOURCES) \ + $(libstrongswan_bliss_la_SOURCES) $(bliss_huffman_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BFDLIB = @BFDLIB@ +BTLIB = @BTLIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +COVERAGE_CFLAGS = @COVERAGE_CFLAGS@ +COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLIB = @DLLIB@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GEM = @GEM@ +GENHTML = @GENHTML@ +GPERF = @GPERF@ +GPRBUILD = @GPRBUILD@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQLCFLAG = @MYSQLCFLAG@ +MYSQLCONFIG = @MYSQLCONFIG@ +MYSQLLIB = @MYSQLLIB@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_LIB = @OPENSSL_LIB@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@ +PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@ +PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@ +PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ +PTHREADLIB = @PTHREADLIB@ +PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ +RANLIB = @RANLIB@ +RTLIB = @RTLIB@ +RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ +RUBYINCLUDE = @RUBYINCLUDE@ +RUBYLIB = @RUBYLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ +STRIP = @STRIP@ +UNWINDLIB = @UNWINDLIB@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +aikgen_plugins = @aikgen_plugins@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ +clearsilver_LIBS = @clearsilver_LIBS@ +cmd_plugins = @cmd_plugins@ +datadir = @datadir@ +datarootdir = @datarootdir@ +dbusservicedir = @dbusservicedir@ +dev_headers = @dev_headers@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +fips_mode = @fips_mode@ +gtk_CFLAGS = @gtk_CFLAGS@ +gtk_LIBS = @gtk_LIBS@ +h_plugins = @h_plugins@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +imcvdir = @imcvdir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ +ipsecdir = @ipsecdir@ +ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ +ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ +linux_headers = @linux_headers@ +localedir = @localedir@ +localstatedir = @localstatedir@ +maemo_CFLAGS = @maemo_CFLAGS@ +maemo_LIBS = @maemo_LIBS@ +manager_plugins = @manager_plugins@ +mandir = @mandir@ +medsrv_plugins = @medsrv_plugins@ +mkdir_p = @mkdir_p@ +nm_CFLAGS = @nm_CFLAGS@ +nm_LIBS = @nm_LIBS@ +nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ +oldincludedir = @oldincludedir@ +pcsclite_CFLAGS = @pcsclite_CFLAGS@ +pcsclite_LIBS = @pcsclite_LIBS@ +pdfdir = @pdfdir@ +piddir = @piddir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +pki_plugins = @pki_plugins@ +plugindir = @plugindir@ +pool_plugins = @pool_plugins@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +random_device = @random_device@ +resolv_conf = @resolv_conf@ +routing_table = @routing_table@ +routing_table_prio = @routing_table_prio@ +s_plugins = @s_plugins@ +sbindir = @sbindir@ +scepclient_plugins = @scepclient_plugins@ +scripts_plugins = @scripts_plugins@ +sharedstatedir = @sharedstatedir@ +soup_CFLAGS = @soup_CFLAGS@ +soup_LIBS = @soup_LIBS@ +srcdir = @srcdir@ +starter_plugins = @starter_plugins@ +strongswan_conf = @strongswan_conf@ +strongswan_options = @strongswan_options@ +swanctldir = @swanctldir@ +sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ +systemdsystemunitdir = @systemdsystemunitdir@ +t_plugins = @t_plugins@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +urandom_device = @urandom_device@ +xml_CFLAGS = @xml_CFLAGS@ +xml_LIBS = @xml_LIBS@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/libstrongswan + +AM_CFLAGS = \ + $(PLUGIN_CFLAGS) \ + @COVERAGE_CFLAGS@ + + +# these file are also used by bliss_huffman + +# these files are also used by the tests, we can't directly refer to them +# because of the subdirectory, which would cause distclean to fail +noinst_LTLIBRARIES = libbliss-params.la libbliss.la $(am__append_1) +libbliss_params_la_SOURCES = \ + bliss_param_set.h bliss_param_set.c \ + bliss_fft_params.h bliss_fft_params.c + +libbliss_la_SOURCES = \ + bliss_private_key.h bliss_private_key.c \ + bliss_public_key.h bliss_public_key.c \ + bliss_signature.h bliss_signature.c \ + bliss_utils.h bliss_utils.c \ + bliss_bitpacker.h bliss_bitpacker.c \ + bliss_fft.h bliss_fft.c \ + bliss_huffman_code.h bliss_huffman_code.c \ + bliss_huffman_code_1.c bliss_huffman_code_3.c bliss_huffman_code_4.c \ + bliss_huffman_coder.h bliss_huffman_coder.c \ + bliss_sampler.h bliss_sampler.c + +libbliss_la_LIBADD = libbliss-params.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-bliss.la +libstrongswan_bliss_la_SOURCES = \ + bliss_plugin.h bliss_plugin.c + +libstrongswan_bliss_la_LDFLAGS = -module -avoid-version +libstrongswan_bliss_la_LIBADD = libbliss.la +bliss_huffman_SOURCES = bliss_huffman.c +bliss_huffman_LDADD = -lm libbliss-params.la +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/bliss/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libstrongswan/plugins/bliss/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ + } + +uninstall-pluginLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ + done + +clean-pluginLTLIBRARIES: + -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) + @list='$(plugin_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libbliss-params.la: $(libbliss_params_la_OBJECTS) $(libbliss_params_la_DEPENDENCIES) $(EXTRA_libbliss_params_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libbliss_params_la_OBJECTS) $(libbliss_params_la_LIBADD) $(LIBS) + +libbliss.la: $(libbliss_la_OBJECTS) $(libbliss_la_DEPENDENCIES) $(EXTRA_libbliss_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libbliss_la_OBJECTS) $(libbliss_la_LIBADD) $(LIBS) + +libstrongswan-bliss.la: $(libstrongswan_bliss_la_OBJECTS) $(libstrongswan_bliss_la_DEPENDENCIES) $(EXTRA_libstrongswan_bliss_la_DEPENDENCIES) + $(AM_V_CCLD)$(libstrongswan_bliss_la_LINK) $(am_libstrongswan_bliss_la_rpath) $(libstrongswan_bliss_la_OBJECTS) $(libstrongswan_bliss_la_LIBADD) $(LIBS) + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +bliss_huffman$(EXEEXT): $(bliss_huffman_OBJECTS) $(bliss_huffman_DEPENDENCIES) $(EXTRA_bliss_huffman_DEPENDENCIES) + @rm -f bliss_huffman$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(bliss_huffman_OBJECTS) $(bliss_huffman_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_bitpacker.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_fft.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_fft_params.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_huffman.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_huffman_code.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_huffman_code_1.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_huffman_code_3.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_huffman_code_4.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_huffman_coder.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_param_set.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_private_key.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_public_key.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_sampler.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_signature.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_utils.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + clean-noinstPROGRAMS clean-pluginLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-pluginLTLIBRARIES + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES clean-noinstPROGRAMS \ + clean-pluginLTLIBRARIES cscopelist-am ctags ctags-am distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-pluginLTLIBRARIES \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am \ + uninstall-pluginLTLIBRARIES + + +recreate-bliss-huffman : bliss_huffman bliss_huffman_code.h + $(AM_V_GEN) \ + ./bliss_huffman 1 8 > $(srcdir)/bliss_huffman_code_1.c 2>/dev/null + $(AM_V_GEN) \ + ./bliss_huffman 3 16 > $(srcdir)/bliss_huffman_code_3.c 2>/dev/null + $(AM_V_GEN) \ + ./bliss_huffman 4 32 > $(srcdir)/bliss_huffman_code_4.c 2>/dev/null + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libstrongswan/plugins/bliss/bliss_bitpacker.c b/src/libstrongswan/plugins/bliss/bliss_bitpacker.c new file mode 100644 index 000000000..4d8446119 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_bitpacker.c @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY;https://www.hsr.ch/HSR-intern-Anmeldung.4409.0.html?&no_cache=1 without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "bliss_bitpacker.h" + +typedef struct private_bliss_bitpacker_t private_bliss_bitpacker_t; + +/** + * Private data structure for bliss_bitpacker_t object + */ +struct private_bliss_bitpacker_t { + /** + * Public interface. + */ + bliss_bitpacker_t public; + + /** + * Current number of bits written to buffer + */ + size_t bits; + + /** + * Bit buffer for up to 32 bits + */ + uint32_t bits_buf; + + /** + * Bits left in the bit buffer + */ + size_t bits_left; + + /** + * Buffer + */ + chunk_t buf; + + /** + * Read/Write pointer into buffer + */ + chunk_t pos; + +}; + +METHOD(bliss_bitpacker_t, get_bits, size_t, + private_bliss_bitpacker_t *this) +{ + return this->bits; +} + +METHOD(bliss_bitpacker_t, write_bits, bool, + private_bliss_bitpacker_t *this, uint32_t value, size_t bits) +{ + if (bits == 0) + { + return TRUE; + } + if (bits > 32) + { + return FALSE; + } + if (bits < 32) + { + value &= (1 << bits) - 1; + } + this->bits += bits; + + while (TRUE) + { + if (bits <= this->bits_left) + { + this->bits_buf |= value << (this->bits_left - bits); + this->bits_left -= bits; + return TRUE; + } + + this->bits_buf |= value >> (bits - this->bits_left); + value &= (1 << (bits - this->bits_left)) - 1; + bits -= this->bits_left; + + if (this->pos.len < 8) + { + return FALSE; + } + htoun32(this->pos.ptr, this->bits_buf); + this->pos = chunk_skip(this->pos, 4); + this->bits_buf = 0; + this->bits_left = 32; + } +} + +METHOD(bliss_bitpacker_t, read_bits, bool, + private_bliss_bitpacker_t *this, uint32_t *value, size_t bits) +{ + if (bits > 32) + { + return FALSE; + } + *value = 0; + + while (TRUE) + { + if (this->bits_left == 0) + { + if (this->pos.len < 4) + { + return FALSE; + } + this->bits_buf = untoh32(this->pos.ptr); + this->pos = chunk_skip(this->pos, 4); + this->bits_left = 32; + } + if (bits <= this->bits_left) + { + *value |= this->bits_buf >> (this->bits_left - bits); + this->bits_buf &= (1 << (this->bits_left - bits)) - 1; + this->bits_left -= bits; + + return TRUE; + } + *value |= this->bits_buf << (bits - this->bits_left); + bits -= this->bits_left; + this->bits_left = 0; + } +} + +METHOD(bliss_bitpacker_t, extract_buf, chunk_t, + private_bliss_bitpacker_t *this) +{ + chunk_t buf; + + htoun32(this->pos.ptr, this->bits_buf); + this->pos.len -= 4; + buf = this->buf; + buf.len = this->buf.len - this->pos.len - this->bits_left/8; + this->buf = this->pos = chunk_empty; + + return buf; +} + +METHOD(bliss_bitpacker_t, destroy, void, + private_bliss_bitpacker_t *this) +{ + free(this->buf.ptr); + free(this); +} + +/** + * See header. + */ +bliss_bitpacker_t *bliss_bitpacker_create(uint16_t max_bits) +{ + private_bliss_bitpacker_t *this; + + INIT(this, + .public = { + .get_bits = _get_bits, + .write_bits = _write_bits, + .read_bits = _read_bits, + .extract_buf = _extract_buf, + .destroy = _destroy, + }, + .bits_left = 32, + .buf = chunk_alloc(round_up(max_bits, 32)/8), + ); + + this->pos = this->buf; + + return &this->public; +} + +/** + * See header. + */ +bliss_bitpacker_t *bliss_bitpacker_create_from_data(chunk_t data) +{ + private_bliss_bitpacker_t *this; + + INIT(this, + .public = { + .get_bits = _get_bits, + .write_bits = _write_bits, + .read_bits = _read_bits, + .extract_buf = _extract_buf, + .destroy = _destroy, + }, + .bits = 8 * data.len, + .buf = chunk_alloc(round_up(data.len, 4)), + ); + + memset(this->buf.ptr + this->buf.len - 4, 0x00, 4); + memcpy(this->buf.ptr, data.ptr, data.len); + this->pos = this->buf; + + return &this->public; +} diff --git a/src/libstrongswan/plugins/bliss/bliss_bitpacker.h b/src/libstrongswan/plugins/bliss/bliss_bitpacker.h new file mode 100644 index 000000000..2fe6cba1c --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_bitpacker.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup bliss_bitpacker bliss_bitpacker + * @{ @ingroup bliss_p + */ + +#ifndef BLISS_BITPACKER_H_ +#define BLISS_BITPACKER_H_ + +#include <library.h> + +typedef struct bliss_bitpacker_t bliss_bitpacker_t; + +/** + * Reads and writes a variable number of bits in packed format + * from and to an octet buffer + */ +struct bliss_bitpacker_t { + + /** + * Get the number of bits written into buffer + * + * @result Number of bits written + */ + size_t (*get_bits)(bliss_bitpacker_t *this); + + /** + * Get the prime modulus of the Number Theoretic Transform + * + * @param value Value to be written + * @param bits Number of bits to be written + * @result TRUE if value could be written into buffer + */ + bool (*write_bits)(bliss_bitpacker_t *this, uint32_t value, size_t bits); + + + /** + * Get the prime modulus of the Number Theoretic Transform + * + * @param value Value returned + * @param bits Number of bits to be read + * @result TRUE if value could be read from buffer + */ + bool (*read_bits)(bliss_bitpacker_t *this, uint32_t *value, size_t bits); + + /** + * Detach the internal octet buffer and return it + */ + chunk_t (*extract_buf)(bliss_bitpacker_t *this); + + /** + * Destroy bliss_bitpacker_t object + */ + void (*destroy)(bliss_bitpacker_t *this); +}; + +/** + * Create a bliss_bitpacker_t object for writing + * + * @param max_bits Total number of bits to be stored + */ +bliss_bitpacker_t* bliss_bitpacker_create(uint16_t max_bits); + +/** + * Create a bliss_bitpacker_t object for reading + * + * @param data Packed array of bits + */ +bliss_bitpacker_t* bliss_bitpacker_create_from_data(chunk_t data); + +#endif /** BLISS_BITPACKER_H_ @}*/ diff --git a/src/libstrongswan/plugins/bliss/bliss_fft.c b/src/libstrongswan/plugins/bliss/bliss_fft.c new file mode 100644 index 000000000..033c2144e --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_fft.c @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "bliss_fft.h" + +typedef struct private_bliss_fft_t private_bliss_fft_t; + +/** + * Private data structure for bliss_fft_t object + */ +struct private_bliss_fft_t { + /** + * Public interface. + */ + bliss_fft_t public; + + /** + * FFT parameter set used as constants + */ + bliss_fft_params_t *p; + +}; + +METHOD(bliss_fft_t, get_size, uint16_t, + private_bliss_fft_t *this) +{ + return this->p->n; +} + +METHOD(bliss_fft_t, get_modulus, uint16_t, + private_bliss_fft_t *this) +{ + return this->p->q; +} + +/** + * Do an FFT butterfly operation + * + * x[i1] ---|+|------- x[i1] + * \/ + * /\ w[iw] + * x[i2] ---|-|--|*|-- x[i2] + * + */ +static void butterfly(private_bliss_fft_t *this, uint32_t *x, int i1,int i2, + int iw) +{ + uint32_t xp, xm; + + xp = x[i1] + x[i2]; + xm = x[i1] + (this->p->q - x[i2]); + if (xp >= this->p->q) + { + xp -= this->p->q; + } + x[i1] = xp; + x[i2] = (xm * this->p->w[iw]) % this->p->q; +} + +/** + * Trivial butterfly operation of last FFT stage + */ +static void butterfly_last(private_bliss_fft_t *this, uint32_t *x, int i1) +{ + uint32_t xp, xm; + int i2 = i1 + 1; + + xp = x[i1] + x[i2]; + xm = x[i1] + (this->p->q - x[i2]); + if (xp >= this->p->q) + { + xp -= this->p->q; + } + if (xm >= this->p->q) + { + xm -= this->p->q; + } + x[i1] = xp; + x[i2] = xm; +} + +METHOD(bliss_fft_t, transform, void, + private_bliss_fft_t *this, uint32_t *a, uint32_t *b, bool inverse) +{ + int stage, i, j, k, m, n, t, iw, i_rev; + uint16_t q; + uint32_t tmp; + + /* we are going to use the transform size n and the modulus q a lot */ + n = this->p->n; + q = this->p->q; + + if (!inverse) + { + /* apply linear phase needed for negative wrapped convolution */ + for (i = 0; i < n; i++) + { + b[i] = (a[i] * this->p->w[i]) % q; + } + } + else if (a != b) + { + /* copy if input and output array are not the same */ + for (i = 0; i < n; i++) + { + b[i] = a[i]; + } + } + + m = n; + k = 1; + + for (stage = this->p->stages; stage > 0; stage--) + { + m >>= 1; + t = 0; + + for (j = 0; j < k; j++) + { + if (stage == 1) + { + butterfly_last(this, b, t); + } + else + { + for (i = 0; i < m; i++) + { + iw = 2 * (inverse ? (n - i * k) : (i * k)); + butterfly(this, b, t + i, t + i + m, iw); + } + } + t += 2*m; + } + k <<= 1; + } + + /* Sort output in bit-reverse order */ + for (i = 0; i < n; i++) + { + i_rev = this->p->rev[i]; + + if (i_rev > i) + { + tmp = b[i]; + b[i] = b[i_rev]; + b[i_rev] = tmp; + } + } + + /** + * Compensate the linear phase needed for negative wrapped convolution + * and normalize the output array with 1/n mod q after the inverse FFT. + */ + if (inverse) + { + for (i = 0; i < n; i++) + { + b[i] = (((b[i] * this->p->w[2*n - i]) % q) * this->p->n_inv) % q; + } + } +} + +METHOD(bliss_fft_t, destroy, void, + private_bliss_fft_t *this) +{ + free(this); +} + +/** + * See header. + */ +bliss_fft_t *bliss_fft_create(bliss_fft_params_t *params) +{ + private_bliss_fft_t *this; + + INIT(this, + .public = { + .get_size = _get_size, + .get_modulus = _get_modulus, + .transform = _transform, + .destroy = _destroy, + }, + .p = params, + ); + + return &this->public; +} diff --git a/src/libstrongswan/plugins/bliss/bliss_fft.h b/src/libstrongswan/plugins/bliss/bliss_fft.h new file mode 100644 index 000000000..a79edd2be --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_fft.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup bliss_fft bliss_fft + * @{ @ingroup bliss_p + */ + +#ifndef BLISS_FFT_H_ +#define BLISS_FFT_H_ + +#include "bliss_fft_params.h" + +#include <library.h> + +typedef struct bliss_fft_t bliss_fft_t; + +/** + * Implements a Number Theoretic Transform (NTT) via the FFT algorithm + */ +struct bliss_fft_t { + + /** + * Get the size of the Number Theoretic Transform + * + * @result Transform size + */ + uint16_t (*get_size)(bliss_fft_t *this); + + /** + * Get the prime modulus of the Number Theoretic Transform + * + * @result Prime modulus + */ + uint16_t (*get_modulus)(bliss_fft_t *this); + + /** + * Compute the [inverse] NTT of a polynomial + * + * @param a Coefficient of input polynomial + * @param b Coefficient of output polynomial + * @param inverse TRUE if the inverse NTT has to be computed + */ + void (*transform)(bliss_fft_t *this, uint32_t *a, uint32_t *b, bool inverse); + + /** + * Destroy bliss_fft_t object + */ + void (*destroy)(bliss_fft_t *this); +}; + +/** + * Create a bliss_fft_t object for a given FFT parameter set + * + * @param params FFT parameters + */ +bliss_fft_t *bliss_fft_create(bliss_fft_params_t *params); + +#endif /** BLISS_FFT_H_ @}*/ diff --git a/src/libstrongswan/plugins/bliss/bliss_fft_params.c b/src/libstrongswan/plugins/bliss/bliss_fft_params.c new file mode 100644 index 000000000..c892c06e6 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_fft_params.c @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "bliss_fft_params.h" + +/** + * FFT parameters for q = 12289 and 2n = 1024 + */ +static uint16_t w_12289_1024[] = { + 1, 49, 2401, 7048, 1260, 295, 2166, 7822, 2319, 3030, + 1002, 12231, 9447, 8210, 9042, 654, 7468, 9551, 1017, 677, + 8595, 3329, 3364, 5079, 3091, 3991, 11224, 9260, 11336, 2459, + 9890, 5339, 3542, 1512, 354, 5057, 2013, 325, 3636, 6118, + 4846, 3963, 9852, 3477, 10616, 4046, 1630, 6136, 5728, 10314, + 1537, 1579, 3637, 6167, 7247, 11011, 11112, 3772, 493, 11868, + 3949, 9166, 6730, 10256, 10984, 9789, 390, 6821, 2426, 8273, + 12129, 4449, 9088, 2908, 7313, 1956, 9821, 1958, 9919, 6760, + 11726, 9280, 27, 1323, 3382, 5961, 9442, 7965, 9326, 2281, + 1168, 8076, 2476, 10723, 9289, 468, 10643, 5369, 5012, 12097, + + 2881, 5990, 10863, 3860, 4805, 1954, 9723, 9445, 8112, 4240, + 11136, 4948, 8961, 8974, 9611, 3957, 9558, 1360, 5195, 8775, + 12149, 5429, 7952, 8689, 7935, 7856, 3985, 10930, 7143, 5915, + 7188, 8120, 4632, 5766, 12176, 6752, 11334, 2361, 5088, 3532, + 1022, 922, 8311, 1702, 9664, 6554, 1632, 6234, 10530, 12121, + 4057, 2169, 7969, 9522, 11885, 4782, 827, 3656, 7098, 3710, + 9744, 10474, 9377, 4780, 729, 11143, 5291, 1190, 9154, 6142, + 6022, 142, 6958, 9139, 5407, 6874, 5023, 347, 4714, 9784, + 145, 7105, 4053, 1973, 10654, 5908, 6845, 3602, 4452, 9235, + 10111, 3879, 5736, 10706, 8456, 8807, 1428, 8527, 12286, 12142, + + 5086, 3434, 8509, 11404, 5791, 1112, 5332, 3199, 9283, 174, + 8526, 12237, 9741, 10327, 2174, 8214, 9238, 10258, 11082, 2302, + 2197, 9341, 3016, 316, 3195, 9087, 2859, 4912, 7197, 8561, + 1663, 7753, 11227, 9407, 6250, 11314, 1381, 6224, 10040, 400, + 7311, 1858, 5019, 151, 7399, 6170, 7394, 5925, 7678, 7552, + 1378, 6077, 2837, 3834, 3531, 973, 10810, 1263, 442, 9369, + 4388, 6099, 3915, 7500, 11119, 4115, 5011, 12048, 480, 11231, + 9603, 3565, 2639, 6421, 7404, 6415, 7110, 4298, 1689, 9027, + 12208, 8320, 2143, 6695, 8541, 683, 8889, 5446, 8785, 350, + 4861, 4698, 9000, 10885, 4938, 8471, 9542, 576, 3646, 6608, + + 4278, 709, 10163, 6427, 7698, 8532, 242, 11858, 3459, 9734, + 9984, 9945, 8034, 418, 8193, 8209, 8993, 10542, 420, 8291, + 722, 10800, 773, 1010, 334, 4077, 3149, 6833, 3014, 218, + 10682, 7280, 339, 4322, 2865, 5206, 9314, 1693, 9223, 9523, + 11934, 7183, 7875, 4916, 7393, 5876, 5277, 504, 118, 5782, + 671, 8301, 1212, 10232, 9808, 1321, 3284, 1159, 7635, 5445, + 8736, 10238, 10102, 3438, 8705, 8719, 9405, 6152, 6512, 11863, + 3704, 9450, 8357, 3956, 9509, 11248, 10436, 7515, 11854, 3263, + 130, 6370, 4905, 6854, 4043, 1483, 11222, 9162, 6534, 652, + 7370, 4749, 11499, 10446, 8005, 11286, 9, 441, 9320, 1987, + + 11340, 2655, 7205, 8953, 8582, 2692, 9018, 11767, 11289, 156, + 7644, 5886, 5767, 12225, 9153, 6093, 3621, 5383, 5698, 8844, + 3241, 11341, 2704, 9606, 3712, 9842, 2987, 11184, 7300, 1319, + 3186, 8646, 5828, 2925, 8146, 5906, 6747, 11089, 2645, 6715, + 9521, 11836, 2381, 6068, 2396, 6803, 1544, 1922, 8155, 6347, + 3778, 787, 1696, 9370, 4437, 8500, 10963, 8760, 11414, 6281, + 544, 2078, 3510, 12233, 9545, 723, 10849, 3174, 8058, 1594, + 4372, 5315, 2366, 5333, 3248, 11684, 7222, 9786, 243, 11907, + 5860, 4493, 11244, 10240, 10200, 8240, 10512, 11239, 9995, 10484, + 9867, 4212, 9764, 11454, 8241, 10561, 1351, 4754, 11744, 10162, + + 6378, 5297, 1484, 11271, 11563, 1293, 1912, 7665, 6915, 7032, + 476, 11035, 12288, 12240, 9888, 5241, 11029, 11994, 10123, 4467, + 9970, 9259, 11287, 58, 2842, 4079, 3247, 11635, 4821, 2738, + 11272, 11612, 3694, 8960, 8925, 7210, 9198, 8298, 1065, 3029, + 953, 9830, 2399, 6950, 8747, 10777, 11935, 7232, 10276, 11964, + 8653, 6171, 7443, 8326, 2437, 8812, 1673, 8243, 10659, 6153, + 6561, 1975, 10752, 10710, 8652, 6122, 5042, 1278, 1177, 8517, + 11796, 421, 8340, 3123, 5559, 2033, 1305, 2500, 11899, 5468, + 9863, 4016, 160, 7840, 3201, 9381, 4976, 10333, 2468, 10331, + 2370, 5529, 563, 3009, 12262, 10966, 8907, 6328, 2847, 4324, + + 2963, 10008, 11121, 4213, 9813, 1566, 3000, 11821, 1646, 6920, + 7277, 192, 9408, 6299, 1426, 8429, 7484, 10335, 2566, 2844, + 4177, 8049, 1153, 7341, 3328, 3315, 2678, 8332, 2731, 10929, + 7094, 3514, 140, 6860, 4337, 3600, 4354, 4433, 8304, 1359, + 5146, 6374, 5101, 4169, 7657, 6523, 113, 5537, 955, 9928, + 7201, 8757, 11267, 11367, 3978, 10587, 2625, 5735, 10657, 6055, + 1759, 168, 8232, 10120, 4320, 2767, 404, 7507, 11462, 8633, + 5191, 8579, 2545, 1815, 2912, 7509, 11560, 1146, 6998, 11099, + 3135, 6147, 6267, 12147, 5331, 3150, 6882, 5415, 7266, 11942, + 7575, 2505, 12144, 5184, 8236, 10316, 1635, 6381, 5444, 8687, + + 7837, 3054, 2178, 8410, 6553, 1583, 3833, 3482, 10861, 3762, + 3, 147, 7203, 8855, 3780, 885, 6498, 11177, 6957, 9090, + 3006, 12115, 3763, 52, 2548, 1962, 10115, 4075, 3051, 2031, + 1207, 9987, 10092, 2948, 9273, 11973, 9094, 3202, 9430, 7377, + 5092, 3728, 10626, 4536, 1062, 2882, 6039, 975, 10908, 6065, + 2249, 11889, 4978, 10431, 7270, 12138, 4890, 6119, 4895, 6364, + 4611, 4737, 10911, 6212, 9452, 8455, 8758, 11316, 1479, 11026, + 11847, 2920, 7901, 6190, 8374, 4789, 1170, 8174, 7278, 241, + 11809, 1058, 2686, 8724, 9650, 5868, 4885, 5874, 5179, 7991, + 10600, 3262, 81, 3969, 10146, 5594, 3748, 11606, 3400, 6843, + + 3504, 11939, 7428, 7591, 3289, 1404, 7351, 3818, 2747, 11713, + 8643, 5681, 8011, 11580, 2126, 5862, 4591, 3757, 12047, 431, + 8830, 2555, 2305, 2344, 4255, 11871, 4096, 4080, 3296, 1747, + 11869, 3998, 11567, 1489, 11516, 11279, 11955, 8212, 9140, 5456, + 9275, 12071, 1607, 5009, 11950, 7967, 9424, 7083, 2975, 10596, + 3066, 2766, 355, 5106, 4414, 7373, 4896, 6413, 7012, 11785, + 12171, 6507, 11618, 3988, 11077, 2057, 2481, 10968, 9005, 11130, + 4654, 6844, 3553, 2051, 2187, 8851, 3584, 3570, 2884, 6137, + 5777, 426, 8585, 2839, 3932, 8333, 2780, 1041, 1853, 4774, + 435, 9026, 12159, 5919, 7384, 5435, 8246, 10806, 1067, 3127, + + 5755, 11637, 4919, 7540, 790, 1843, 4284, 1003, 12280, 11848, + 2969, 10302, 949, 9634, 5084, 3336, 3707, 9597, 3271, 522, + 1000, 12133, 4645, 6403, 6522, 64, 3136, 6196, 8668, 6906, + 6591, 3445, 9048, 948, 9585, 2683, 8577, 2447, 9302, 1105, + 4989, 10970, 9103, 3643, 6461, 9364, 4143, 6383, 5542, 1200, + 9644, 5574, 2768, 453, 9908, 6221, 9893, 5486, 10745, 10367, + 4134, 5942, 8511, 11502, 10593, 2919, 7852, 3789, 1326, 3529, + 875, 6008, 11745, 10211, 8779, 56, 2744, 11566, 1440, 9115, + 4231, 10695, 7917, 6974, 9923, 6956, 9041, 605, 5067, 2503, + 12046, 382, 6429, 7796, 1045, 2049, 2089, 4049, 1777, 1050, + + 2294, 1805, 2422, 8077, 2525, 835, 4048, 1728, 10938, 7535, + 545, 2127, 5911, 6992, 10805, 1018, 726, 10996, 10377, 4624, + 5374, 5257, 11813, 1254, 1 +}; + +/** + * Bit-reversed indices for n = 512 + */ +static uint16_t rev_512[] = { + 0, 256, 128, 384, 64, 320, 192, 448, 32, 288, + 160, 416, 96, 352, 224, 480, 16, 272, 144, 400, + 80, 336, 208, 464, 48, 304, 176, 432, 112, 368, + 240, 496, 8, 264, 136, 392, 72, 328, 200, 456, + 40, 296, 168, 424, 104, 360, 232, 488, 24, 280, + 152, 408, 88, 344, 216, 472, 56, 312, 184, 440, + 120, 376, 248, 504, 4, 260, 132, 388, 68, 324, + 196, 452, 36, 292, 164, 420, 100, 356, 228, 484, + 20, 276, 148, 404, 84, 340, 212, 468, 52, 308, + 180, 436, 116, 372, 244, 500, 12, 268, 140, 396, + + 76, 332, 204, 460, 44, 300, 172, 428, 108, 364, + 236, 492, 28, 284, 156, 412, 92, 348, 220, 476, + 60, 316, 188, 444, 124, 380, 252, 508, 2, 258, + 130, 386, 66, 322, 194, 450, 34, 290, 162, 418, + 98, 354, 226, 482, 18, 274, 146, 402, 82, 338, + 210, 466, 50, 306, 178, 434, 114, 370, 242, 498, + 10, 266, 138, 394, 74, 330, 202, 458, 42, 298, + 170, 426, 106, 362, 234, 490, 26, 282, 154, 410, + 90, 346, 218, 474, 58, 314, 186, 442, 122, 378, + 250, 506, 6, 262, 134, 390, 70, 326, 198, 454, + + 38, 294, 166, 422, 102, 358, 230, 486, 22, 278, + 150, 406, 86, 342, 214, 470, 54, 310, 182, 438, + 118, 374, 246, 502, 14, 270, 142, 398, 78, 334, + 206, 462, 46, 302, 174, 430, 110, 366, 238, 494, + 30, 286, 158, 414, 94, 350, 222, 478, 62, 318, + 190, 446, 126, 382, 254, 510, 1, 257, 129, 385, + 65, 321, 193, 449, 33, 289, 161, 417, 97, 353, + 225, 481, 17, 273, 145, 401, 81, 337, 209, 465, + 49, 305, 177, 433, 113, 369, 241, 497, 9, 265, + 137, 393, 73, 329, 201, 457, 41, 297, 169, 425, + + 105, 361, 233, 489, 25, 281, 153, 409, 89, 345, + 217, 473, 57, 313, 185, 441, 121, 377, 249, 505, + 5, 261, 133, 389, 69, 325, 197, 453, 37, 293, + 165, 421, 101, 357, 229, 485, 21, 277, 149, 405, + 85, 341, 213, 469, 53, 309, 181, 437, 117, 373, + 245, 501, 13, 269, 141, 397, 77, 333, 205, 461, + 45, 301, 173, 429, 109, 365, 237, 493, 29, 285, + 157, 413, 93, 349, 221, 477, 61, 317, 189, 445, + 125, 381, 253, 509, 3, 259, 131, 387, 67, 323, + 195, 451, 35, 291, 163, 419, 99, 355, 227, 483, + + 19, 275, 147, 403, 83, 339, 211, 467, 51, 307, + 179, 435, 115, 371, 243, 499, 11, 267, 139, 395, + 75, 331, 203, 459, 43, 299, 171, 427, 107, 363, + 235, 491, 27, 283, 155, 411, 91, 347, 219, 475, + 59, 315, 187, 443, 123, 379, 251, 507, 7, 263, + 135, 391, 71, 327, 199, 455, 39, 295, 167, 423, + 103, 359, 231, 487, 23, 279, 151, 407, 87, 343, + 215, 471, 55, 311, 183, 439, 119, 375, 247, 503, + 15, 271, 143, 399, 79, 335, 207, 463, 47, 303, + 175, 431, 111, 367, 239, 495, 31, 287, 159, 415, + + 95, 351, 223, 479, 63, 319, 191, 447, 127, 383, + 255, 511 +}; + +bliss_fft_params_t bliss_fft_12289_512 = { + 12289, 512, 12265, 9, w_12289_1024, rev_512 +}; + +/** + * FFT parameters for q = 17 and n = 16 + */ +static uint16_t w_17_16[] = { + 1, 3, 9, 10, 13, 5, 15, 11, 16, 14, 8, 7, 4, 12, 2, 6, 1 }; + +/** + * Bit-reversed indices for n = 8 + */ +static uint16_t rev_8[] = { 0, 4, 2, 6, 1, 5, 3, 7 }; + +bliss_fft_params_t bliss_fft_17_8 = { 17, 8, 15, 3, w_17_16, rev_8 }; diff --git a/src/libstrongswan/plugins/bliss/bliss_fft_params.h b/src/libstrongswan/plugins/bliss/bliss_fft_params.h new file mode 100644 index 000000000..31b151b67 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_fft_params.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup bliss_fft_params bliss_fft_params + * @{ @ingroup bliss_p + */ + +#ifndef BLISS_FFT_PARAMS_H_ +#define BLISS_FFT_PARAMS_H_ + +#include <library.h> + +typedef struct bliss_fft_params_t bliss_fft_params_t; + +/** + * Defines the parameters for an NTT computed via the FFT algorithm + */ +struct bliss_fft_params_t { + + /** + * Prime modulus + */ + uint16_t q; + + /** + * Size of the FFT with the condition k * n = q-1 + */ + uint16_t n; + + /** + * Inverse of n mod q used for normalization of the FFT + */ + uint16_t n_inv; + + /** + * Number of FFT stages stages = log2(n) + */ + uint16_t stages; + + /** + * FFT twiddle factors (n-th roots of unity) + */ + uint16_t *w; + + /** + * FFT bit reversal + */ + uint16_t *rev; + +}; + +/** + * FFT parameters for q = 12289 and n = 512 + */ +extern bliss_fft_params_t bliss_fft_12289_512; + +/** + * FFT parameters for q = 17 and n = 8 + */ +extern bliss_fft_params_t bliss_fft_17_8; + +#endif /** BLISS_FFT_PARAMS_H_ @}*/ diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman.c b/src/libstrongswan/plugins/bliss/bliss_huffman.c new file mode 100644 index 000000000..647234fd8 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_huffman.c @@ -0,0 +1,433 @@ +/* + * Copyright (C) 2014 Tobias Brunner + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "bliss_param_set.h" + +#include <library.h> + +#include <stdio.h> +#include <math.h> + +typedef struct tuple_t tuple_t; + +struct tuple_t { + int8_t z1; + int8_t z2; + uint16_t index; + uint16_t bits; + uint32_t code; +}; + +typedef struct node_t node_t; + +struct node_t { + node_t *next; + node_t *l; + node_t *r; + tuple_t *tuple; + double p; + uint16_t depth; + uint16_t index; +}; + +static void print_node(node_t *node) +{ + if (node->tuple) + { + fprintf(stderr, "(%1d,%2d)", node->tuple->z1, node->tuple->z2); + } + else + { + fprintf(stderr, " "); + } + fprintf(stderr, " %18.16f\n", node->p); +} + +static double code_node(node_t *node, int *index, uint8_t bits, uint32_t code) +{ + double code_length = 0; + + node->index = (*index)++; + + if (node->tuple) + { + node->tuple->code = code; + node->tuple->bits = bits; + code_length += node->p * bits; + } + if (node->l) + { + code_length += code_node(node->l, index, bits + 1, (code << 1)); + } + if (node->r) + { + code_length += code_node(node->r, index, bits + 1, (code << 1) + 1); + } + + return code_length; + +} + +static void write_node(node_t *node) +{ + int16_t node_0, node_1, tuple; + + node_0 = node->l ? node->l->index : BLISS_HUFFMAN_CODE_NO_NODE; + node_1 = node->r ? node->r->index : BLISS_HUFFMAN_CODE_NO_NODE; + tuple = node->tuple ? node->tuple->index : BLISS_HUFFMAN_CODE_NO_TUPLE; + + printf("\t{ %3d, %3d, %3d }, /* %3d: ", node_0, node_1, tuple, node->index); + + if (node->tuple) + { + printf("(%d,%2d) %2u bit%s ", node->tuple->z1, node->tuple->z2, + node->tuple->bits, (node->tuple->bits == 1) ? " " : "s"); + } + printf("*/\n"); + + if (node->l) + { + write_node(node->l); + } + if (node->r) + { + write_node(node->r); + } +} + +static void write_header(void) +{ + printf("/*\n"); + printf(" * Copyright (C) 2014 Andreas Steffen\n"); + printf(" * HSR Hochschule fuer Technik Rapperswil\n"); + printf(" *\n"); + printf(" * Optimum Huffman code for BLISS-X signatures\n"); + printf(" *\n"); + printf(" * This file has been automatically generated by the" + " bliss_huffman utility\n"); + printf(" * Do not edit manually!\n"); + printf(" */\n\n"); +}; + +static void write_code_tables(int bliss_type, int n_z1, int n_z2, node_t *nodes, + tuple_t **tuples) +{ + int index, i, k; + uint32_t bit; + double code_length; + + printf("#include \"bliss_huffman_code.h\"\n\n"); + + printf("static bliss_huffman_code_node_t nodes[] = {\n"); + index = 0; + code_length = code_node(nodes, &index, 0, 0); + write_node(nodes); + printf("};\n\n"); + + printf("static bliss_huffman_code_tuple_t tuples[] = {\n"); + index = 0; + for (i = 0; i < n_z1; i++) + { + if (i > 0) + { + printf("\n"); + } + for (k = 1 - n_z2; k < n_z2; k++) + { + printf("\t{ %5u, %2u }, /* %3d: (%1d,%2d) ", + tuples[index]->code, tuples[index]->bits, index, i, k); + bit = 1 << (tuples[index]->bits - 1); + while (bit) + { + printf("%s", (tuples[index]->code & bit) ? "1" : "0"); + bit >>= 1; + } + printf(" */\n"); + index++; + } + } + printf("};\n\n"); + printf("/* code_length = %6.4f bits/tuple (%d bits) */\n\n", + code_length, (int)(512 * code_length + 1)); + + printf("bliss_huffman_code_t bliss_huffman_code_%d = {\n", bliss_type); + printf("\t.n_z1 = %d,\n", n_z1); + printf("\t.n_z2 = %d,\n", n_z2); + printf("\t.tuples = tuples,\n"); + printf("\t.nodes = nodes\n"); + printf("};\n"); +} + +static void destroy_node(node_t *node) +{ + if (node->l) + { + destroy_node(node->l); + } + if (node->r) + { + destroy_node(node->r); + } + free(node->tuple); + free(node); +} + +static void remove_node(node_t *list, node_t **last, node_t *node) +{ + node_t *current, *prev; + + for (current = list->next, prev = list; current; + prev = current, current = current->next) + { + if (current == node) + { + prev->next = current->next; + if (*last == current) + { + *last = prev->next ?: prev; + } + break; + } + } +} + +/** + * Generate a Huffman code for the optimum encoding of BLISS signatures + */ +int main(int argc, char *argv[]) +{ + bliss_param_set_t *set; + int dx, bliss_type, depth = 1, groups, groups_left, pairs = 1; + int i_max = 9, k_max = 8, index_max = (2*k_max - 1) * i_max; + int i, i_top, k, k_top; + uint16_t index; + double p, p_z1[i_max], p_z2[k_max], x_z1[i_max], x_z2[k_max]; + double t, x, x0, p_sum, entropy = 0, erf_i, erf_k, erf_0 = 0; + tuple_t *tuple, *tuples[index_max]; + node_t *node, *node_l, *node_r, *nodes = NULL; + node_t *node_list, *node_last; + + if (argc < 2) + { + fprintf(stderr, "usage: bliss_huffman <bliss type> [<pairs>]\n"); + exit(1); + } + if (argc > 2) + { + pairs = atoi(argv[2]); + } + fprintf(stderr, "%d code pairs with constant length\n\n", pairs); + groups_left = groups = pairs >> 1; + + bliss_type = atoi(argv[1]); + set = bliss_param_set_get_by_id(bliss_type); + if (!set) + { + fprintf(stderr, "bliss type %d unsupported\n", bliss_type); + exit(1); + } + write_header(); + printf("/*\n"); + printf(" * Design: sigma = %u\n", set->sigma); + printf(" *\n"); + + t = 1/(sqrt(2) * set->sigma); + + /* Probability distribution for z1 */ + i_top = (set->B_inf + 255) / 256; + p_sum = 0; + x = 0; + + for (i = 0; i < i_top; i++) + { + x = min(x + 256, set->B_inf); + erf_i = erf(t*x); + p_z1[i] = erf_i - erf_0; + p_sum += p_z1[i]; + erf_0 = erf_i; + x_z1[i] = x; + } + + /* Normalize and print the probability distribution for z1 */ + printf(" * i p_z1[i]\n"); + x0 = 0; + + for (i = 0; i < i_top; i++) + { + p_z1[i] /= p_sum; + printf(" * %2d %18.16f %4.0f .. %4.0f\n", i, p_z1[i], x0, x_z1[i]); + x0 = x_z1[i]; + } + printf(" *\n"); + + /* Probability distribution for z2 */ + dx = 1 << set->d; + k_top = 1 + set->B_inf / dx; + x = (dx >> 1) - 0.5; + p_sum = 0; + + for (k = 0; k < k_top; k++) + { + + erf_k = erf(t*x) / 2; + p_z2[k] = (k == 0) ? 2*erf_k : erf_k - erf_0; + p_sum += (k == 0) ? p_z2[k] : 2*p_z2[k]; + erf_0 = erf_k; + x_z2[k] = x; + x += dx; + } + + /* Normalize the probability distribution for z2 */ + for (k = 0; k < k_top; k++) + { + p_z2[k] /= p_sum; + } + + /* Print the probability distribution for z2 */ + printf(" * k p_z2[k] dx = %d\n", dx); + + for (k = 1 - k_top; k < k_top; k++) + { + + printf(" * %2d %18.16f ",k, p_z2[abs(k)]); + if (k < 0) + { + printf(" %7.1f ..%7.1f\n", -x_z2[-k], -x_z2[-k-1]); + } + else if (k == 0) + { + printf(" %7.1f ..%7.1f\n", -x_z2[k], x_z2[k]); + } + else + { + printf(" %7.1f ..%7.1f\n", x_z2[k-1], x_z2[k]); + } + } + printf(" *\n"); + + /* Compute probabilities of tuples (z1, z2) */ + INIT(node_list); + node_last = node_list; + printf(" * (i, k) p\n"); + p_sum =0; + index = 0; + + for (i = 0; i < i_top; i++) + { + for (k = 1 - k_top; k < k_top; k++) + { + p = p_z1[i] * p_z2[abs(k)]; + printf(" * (%1d,%2d) %18.16f\n", i, k, p); + p_sum += p; + entropy += -log(p) * p; + + INIT(tuple, + .z1 = i, + .z2 = k, + .index = index, + ); + tuples[index++] = tuple; + + INIT(node, + .p = p, + .tuple = tuple, + ); + node_last->next = node; + node_last = node; + } + printf(" *\n"); + } + entropy /= log(2); + printf(" * p_sum %18.16f\n", p_sum); + printf(" *\n"); + printf(" * entropy = %6.4f bits/tuple (%d bits)\n", + entropy, (int)(512 * entropy)); + printf(" */\n\n"); + + /* Build Huffman tree */ + while (node_list->next != node_last) + { + node_r = node_l = NULL; + + for (node = node_list->next; node; node = node->next) + { + if (pairs > 0) + { + if (!node->tuple) + { + continue; + } + } + else if (groups_left > 0) + { + if (node->tuple || node->depth != depth) + { + continue; + } + } + if (node_r == NULL || node->p < node_r->p) + { + node_l = node_r; + node_r = node; + } + else if (node_l == NULL || node->p < node_l->p) + { + node_l = node; + } + } + + INIT(node, + .l = node_l, + .r = node_r, + .p = node_l->p + node_r->p, + .depth = 1 + max(node_l->depth, node_r->depth), + .tuple = NULL, + ); + print_node(node_r); + print_node(node_l); + fprintf(stderr, " %18.16f", node->p); + + remove_node(node_list, &node_last, node_l); + remove_node(node_list, &node_last, node_r); + node_last->next = node; + node_last = node; + + if (pairs > 0) + { + pairs--; + } + else if (groups > 0) + { + if (--groups_left == 0) + { + groups >>= 1; + groups_left = groups; + depth++; + } + } + fprintf(stderr, "\n\n"); + } + + + nodes = node_list->next; + + write_code_tables(bliss_type, i_top, k_top, nodes, tuples); + + destroy_node(nodes); + destroy_node(node_list); + exit(0); +} + diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman_code.c b/src/libstrongswan/plugins/bliss/bliss_huffman_code.c new file mode 100644 index 000000000..e31cd9d3c --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_huffman_code.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "bliss_huffman_code.h" + +extern bliss_huffman_code_t bliss_huffman_code_1; +extern bliss_huffman_code_t bliss_huffman_code_3; +extern bliss_huffman_code_t bliss_huffman_code_4; + +/** + * See header. + */ +bliss_huffman_code_t* bliss_huffman_code_get_by_id(bliss_param_set_id_t id) +{ + switch (id) + { + case BLISS_I: + case BLISS_B_I: + return &bliss_huffman_code_1; + case BLISS_III: + case BLISS_B_III: + return &bliss_huffman_code_3; + case BLISS_IV: + case BLISS_B_IV: + return &bliss_huffman_code_4; + default: + return NULL; + } +} + diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman_code.h b/src/libstrongswan/plugins/bliss/bliss_huffman_code.h new file mode 100644 index 000000000..df8511b2e --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_huffman_code.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup bliss_huffman_code bliss_huffman_code + * @{ @ingroup bliss_p + */ + +#ifndef BLISS_HUFFMAN_CODE_H_ +#define BLISS_HUFFMAN_CODE_H_ + +#include "bliss_param_set.h" + +#include <library.h> + +typedef struct bliss_huffman_code_t bliss_huffman_code_t; +typedef struct bliss_huffman_code_tuple_t bliss_huffman_code_tuple_t; +typedef struct bliss_huffman_code_node_t bliss_huffman_code_node_t; + +struct bliss_huffman_code_tuple_t { + uint32_t code; + uint16_t bits; +}; + +#define BLISS_HUFFMAN_CODE_NO_TUPLE -1 +#define BLISS_HUFFMAN_CODE_NO_NODE -1 + +struct bliss_huffman_code_node_t { + int16_t node_0; + int16_t node_1; + int16_t tuple; +}; + +/** + * Defines the Huffman code for the optimum encoding of a BLISS signature + */ +struct bliss_huffman_code_t { + + /** + * Range of z1: 0..n_z1-1 + */ + uint16_t n_z1; + + /** + * Range of z2: -n_z2..n_z2 + */ + uint16_t n_z2; + + /** + * Table of tuple codewords + */ + bliss_huffman_code_tuple_t *tuples; + + /** + * Table of binary decision nodes + */ + bliss_huffman_code_node_t *nodes; +}; + +/** + * Get Optimum Huffman code for BLISS signature given by BLISS parameter set ID + * + * @param id BLISS parameter set ID + * @return Optimum Huffman code for BLISS signature +*/ +bliss_huffman_code_t* bliss_huffman_code_get_by_id(bliss_param_set_id_t id); + +#endif /** BLISS_HUFFMAN_CODE_H_ @}*/ diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman_code_1.c b/src/libstrongswan/plugins/bliss/bliss_huffman_code_1.c new file mode 100644 index 000000000..1bf433fd1 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_huffman_code_1.c @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * Optimum Huffman code for BLISS-X signatures + * + * This file has been automatically generated by the bliss_huffman utility + * Do not edit manually! + */ + +/* + * Design: sigma = 215 + * + * i p_z1[i] + * 0 0.7662277087816564 0 .. 256 + * 1 0.2165251006508514 256 .. 512 + * 2 0.0168930510015114 512 .. 768 + * 3 0.0003522302274478 768 .. 1024 + * 4 0.0000019067136680 1024 .. 1280 + * 5 0.0000000026239598 1280 .. 1536 + * 6 0.0000000000009052 1536 .. 1792 + * 7 0.0000000000000001 1792 .. 2047 + * + * k p_z2[k] dx = 1024 + * -1 0.0086781953089156 -1535.5 .. -511.5 + * 0 0.9826436093821688 -511.5 .. 511.5 + * 1 0.0086781953089156 511.5 .. 1535.5 + * + * (i, k) p + * (0,-1) 0.0066494737079101 + * (0, 0) 0.7529287613658361 + * (0, 1) 0.0066494737079101 + * + * (1,-1) 0.0018790471127307 + * (1, 0) 0.2127670064253900 + * (1, 1) 0.0018790471127307 + * + * (2,-1) 0.0001466011959546 + * (2, 0) 0.0165998486096022 + * (2, 1) 0.0001466011959546 + * + * (3,-1) 0.0000030567227075 + * (3, 0) 0.0003461167820328 + * (3, 1) 0.0000030567227075 + * + * (4,-1) 0.0000000165468336 + * (4, 0) 0.0000018736200007 + * (4, 1) 0.0000000165468336 + * + * (5,-1) 0.0000000000227712 + * (5, 0) 0.0000000025784174 + * (5, 1) 0.0000000000227712 + * + * (6,-1) 0.0000000000000079 + * (6, 0) 0.0000000000008895 + * (6, 1) 0.0000000000000079 + * + * (7,-1) 0.0000000000000000 + * (7, 0) 0.0000000000000001 + * (7, 1) 0.0000000000000000 + * + * p_sum 0.9999999999999998 + * + * entropy = 1.0195 bits/tuple (521 bits) + */ + +#include "bliss_huffman_code.h" + +static bliss_huffman_code_node_t nodes[] = { + { 1, 2, -1 }, /* 0: */ + { -1, -1, 1 }, /* 1: (0, 0) 1 bit */ + { 3, 4, -1 }, /* 2: */ + { -1, -1, 4 }, /* 3: (1, 0) 2 bits */ + { 5, 46, -1 }, /* 4: */ + { 6, 45, -1 }, /* 5: */ + { 7, 8, -1 }, /* 6: */ + { -1, -1, 0 }, /* 7: (0,-1) 5 bits */ + { 9, 44, -1 }, /* 8: */ + { 10, 11, -1 }, /* 9: */ + { -1, -1, 3 }, /* 10: (1,-1) 7 bits */ + { 12, 13, -1 }, /* 11: */ + { -1, -1, 10 }, /* 12: (3, 0) 8 bits */ + { 14, 29, -1 }, /* 13: */ + { 15, 22, -1 }, /* 14: */ + { 16, 19, -1 }, /* 15: */ + { 17, 18, -1 }, /* 16: */ + { -1, -1, 8 }, /* 17: (2, 1) 12 bits */ + { -1, -1, 6 }, /* 18: (2,-1) 12 bits */ + { 20, 21, -1 }, /* 19: */ + { -1, -1, 11 }, /* 20: (3, 1) 12 bits */ + { -1, -1, 9 }, /* 21: (3,-1) 12 bits */ + { 23, 26, -1 }, /* 22: */ + { 24, 25, -1 }, /* 23: */ + { -1, -1, 13 }, /* 24: (4, 0) 12 bits */ + { -1, -1, 14 }, /* 25: (4, 1) 12 bits */ + { 27, 28, -1 }, /* 26: */ + { -1, -1, 12 }, /* 27: (4,-1) 12 bits */ + { -1, -1, 16 }, /* 28: (5, 0) 12 bits */ + { 30, 37, -1 }, /* 29: */ + { 31, 34, -1 }, /* 30: */ + { 32, 33, -1 }, /* 31: */ + { -1, -1, 17 }, /* 32: (5, 1) 12 bits */ + { -1, -1, 15 }, /* 33: (5,-1) 12 bits */ + { 35, 36, -1 }, /* 34: */ + { -1, -1, 19 }, /* 35: (6, 0) 12 bits */ + { -1, -1, 20 }, /* 36: (6, 1) 12 bits */ + { 38, 41, -1 }, /* 37: */ + { 39, 40, -1 }, /* 38: */ + { -1, -1, 18 }, /* 39: (6,-1) 12 bits */ + { -1, -1, 22 }, /* 40: (7, 0) 12 bits */ + { 42, 43, -1 }, /* 41: */ + { -1, -1, 23 }, /* 42: (7, 1) 12 bits */ + { -1, -1, 21 }, /* 43: (7,-1) 12 bits */ + { -1, -1, 5 }, /* 44: (1, 1) 6 bits */ + { -1, -1, 2 }, /* 45: (0, 1) 4 bits */ + { -1, -1, 7 }, /* 46: (2, 0) 3 bits */ +}; + +static bliss_huffman_code_tuple_t tuples[] = { + { 24, 5 }, /* 0: (0,-1) 11000 */ + { 0, 1 }, /* 1: (0, 0) 0 */ + { 13, 4 }, /* 2: (0, 1) 1101 */ + + { 100, 7 }, /* 3: (1,-1) 1100100 */ + { 2, 2 }, /* 4: (1, 0) 10 */ + { 51, 6 }, /* 5: (1, 1) 110011 */ + + { 3249, 12 }, /* 6: (2,-1) 110010110001 */ + { 7, 3 }, /* 7: (2, 0) 111 */ + { 3248, 12 }, /* 8: (2, 1) 110010110000 */ + + { 3251, 12 }, /* 9: (3,-1) 110010110011 */ + { 202, 8 }, /* 10: (3, 0) 11001010 */ + { 3250, 12 }, /* 11: (3, 1) 110010110010 */ + + { 3254, 12 }, /* 12: (4,-1) 110010110110 */ + { 3252, 12 }, /* 13: (4, 0) 110010110100 */ + { 3253, 12 }, /* 14: (4, 1) 110010110101 */ + + { 3257, 12 }, /* 15: (5,-1) 110010111001 */ + { 3255, 12 }, /* 16: (5, 0) 110010110111 */ + { 3256, 12 }, /* 17: (5, 1) 110010111000 */ + + { 3260, 12 }, /* 18: (6,-1) 110010111100 */ + { 3258, 12 }, /* 19: (6, 0) 110010111010 */ + { 3259, 12 }, /* 20: (6, 1) 110010111011 */ + + { 3263, 12 }, /* 21: (7,-1) 110010111111 */ + { 3261, 12 }, /* 22: (7, 0) 110010111101 */ + { 3262, 12 }, /* 23: (7, 1) 110010111110 */ +}; + +/* code_length = 1.3189 bits/tuple (676 bits) */ + +bliss_huffman_code_t bliss_huffman_code_1 = { + .n_z1 = 8, + .n_z2 = 2, + .tuples = tuples, + .nodes = nodes +}; diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman_code_3.c b/src/libstrongswan/plugins/bliss/bliss_huffman_code_3.c new file mode 100644 index 000000000..37a8084d4 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_huffman_code_3.c @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * Optimum Huffman code for BLISS-X signatures + * + * This file has been automatically generated by the bliss_huffman utility + * Do not edit manually! + */ + +/* + * Design: sigma = 250 + * + * i p_z1[i] + * 0 0.6941647250930416 0 .. 256 + * 1 0.2652752755116807 256 .. 512 + * 2 0.0384337021454129 512 .. 768 + * 3 0.0020842622589255 768 .. 1024 + * 4 0.0000417294572050 1024 .. 1280 + * 5 0.0000003047309681 1280 .. 1536 + * 6 0.0000000008027661 1536 .. 1760 + * + * k p_z2[k] dx = 512 + * -3 0.0000001543959154 -1791.5 ..-1279.5 + * -2 0.0010701394583782 -1279.5 .. -767.5 + * -1 0.1523201563502276 -767.5 .. -255.5 + * 0 0.6932190995909575 -255.5 .. 255.5 + * 1 0.1523201563502276 255.5 .. 767.5 + * 2 0.0010701394583782 767.5 .. 1279.5 + * 3 0.0000001543959154 1279.5 .. 1791.5 + * + * (i, k) p + * (0,-3) 0.0000001071761982 + * (0,-2) 0.0007428530629363 + * (0,-1) 0.1057352794589848 + * (0, 0) 0.4812082456968029 + * (0, 1) 0.1057352794589848 + * (0, 2) 0.0007428530629363 + * (0, 3) 0.0000001071761982 + * + * (1,-3) 0.0000000409574190 + * (1,-2) 0.0002838815396572 + * (1,-1) 0.0404067714417889 + * (1, 0) 0.1838938876339505 + * (1, 1) 0.0404067714417889 + * (1, 2) 0.0002838815396572 + * (1, 3) 0.0000000409574190 + * + * (2,-3) 0.0000000059340066 + * (2,-2) 0.0000411294211974 + * (2,-1) 0.0058542275199074 + * (2, 0) 0.0266429763951902 + * (2, 1) 0.0058542275199074 + * (2, 2) 0.0000411294211974 + * (2, 3) 0.0000000059340066 + * + * (3,-3) 0.0000000003218016 + * (3,-2) 0.0000022304512849 + * (3,-1) 0.0003174751531544 + * (3, 0) 0.0014448504064437 + * (3, 1) 0.0003174751531544 + * (3, 2) 0.0000022304512849 + * (3, 3) 0.0000000003218016 + * + * (4,-3) 0.0000000000064429 + * (4,-2) 0.0000000446563387 + * (4,-1) 0.0000063562374459 + * (4, 0) 0.0000289276567501 + * (4, 1) 0.0000063562374459 + * (4, 2) 0.0000000446563387 + * (4, 3) 0.0000000000064429 + * + * (5,-3) 0.0000000000000470 + * (5,-2) 0.0000000003261046 + * (5,-1) 0.0000000464166687 + * (5, 0) 0.0000002112453273 + * (5, 1) 0.0000000464166687 + * (5, 2) 0.0000000003261046 + * (5, 3) 0.0000000000000470 + * + * (6,-3) 0.0000000000000001 + * (6,-2) 0.0000000000008591 + * (6,-1) 0.0000000001222775 + * (6, 0) 0.0000000005564928 + * (6, 1) 0.0000000001222775 + * (6, 2) 0.0000000000008591 + * (6, 3) 0.0000000000000001 + * + * p_sum 0.9999999999999999 + * + * entropy = 2.2879 bits/tuple (1171 bits) + */ + +#include "bliss_huffman_code.h" + +static bliss_huffman_code_node_t nodes[] = { + { 1, 96, -1 }, /* 0: */ + { 2, 93, -1 }, /* 1: */ + { 3, 4, -1 }, /* 2: */ + { -1, -1, 10 }, /* 3: (1, 0) 3 bits */ + { 5, 8, -1 }, /* 4: */ + { 6, 7, -1 }, /* 5: */ + { -1, -1, 11 }, /* 6: (1, 1) 5 bits */ + { -1, -1, 9 }, /* 7: (1,-1) 5 bits */ + { 9, 10, -1 }, /* 8: */ + { -1, -1, 17 }, /* 9: (2, 0) 5 bits */ + { 11, 92, -1 }, /* 10: */ + { 12, 13, -1 }, /* 11: */ + { -1, -1, 16 }, /* 12: (2,-1) 7 bits */ + { 14, 89, -1 }, /* 13: */ + { 15, 16, -1 }, /* 14: */ + { -1, -1, 24 }, /* 15: (3, 0) 9 bits */ + { 17, 86, -1 }, /* 16: */ + { 18, 85, -1 }, /* 17: */ + { 19, 20, -1 }, /* 18: */ + { -1, -1, 8 }, /* 19: (1,-2) 12 bits */ + { 21, 84, -1 }, /* 20: */ + { 22, 53, -1 }, /* 21: */ + { 23, 38, -1 }, /* 22: */ + { 24, 31, -1 }, /* 23: */ + { 25, 28, -1 }, /* 24: */ + { 26, 27, -1 }, /* 25: */ + { -1, -1, 15 }, /* 26: (2,-2) 18 bits */ + { -1, -1, 31 }, /* 27: (4, 0) 18 bits */ + { 29, 30, -1 }, /* 28: */ + { -1, -1, 32 }, /* 29: (4, 1) 18 bits */ + { -1, -1, 30 }, /* 30: (4,-1) 18 bits */ + { 32, 35, -1 }, /* 31: */ + { 33, 34, -1 }, /* 32: */ + { -1, -1, 26 }, /* 33: (3, 2) 18 bits */ + { -1, -1, 22 }, /* 34: (3,-2) 18 bits */ + { 36, 37, -1 }, /* 35: */ + { -1, -1, 38 }, /* 36: (5, 0) 18 bits */ + { -1, -1, 6 }, /* 37: (0, 3) 18 bits */ + { 39, 46, -1 }, /* 38: */ + { 40, 43, -1 }, /* 39: */ + { 41, 42, -1 }, /* 40: */ + { -1, -1, 0 }, /* 41: (0,-3) 18 bits */ + { -1, -1, 39 }, /* 42: (5, 1) 18 bits */ + { 44, 45, -1 }, /* 43: */ + { -1, -1, 37 }, /* 44: (5,-1) 18 bits */ + { -1, -1, 33 }, /* 45: (4, 2) 18 bits */ + { 47, 50, -1 }, /* 46: */ + { 48, 49, -1 }, /* 47: */ + { -1, -1, 29 }, /* 48: (4,-2) 18 bits */ + { -1, -1, 13 }, /* 49: (1, 3) 18 bits */ + { 51, 52, -1 }, /* 50: */ + { -1, -1, 7 }, /* 51: (1,-3) 18 bits */ + { -1, -1, 20 }, /* 52: (2, 3) 18 bits */ + { 54, 69, -1 }, /* 53: */ + { 55, 62, -1 }, /* 54: */ + { 56, 59, -1 }, /* 55: */ + { 57, 58, -1 }, /* 56: */ + { -1, -1, 14 }, /* 57: (2,-3) 18 bits */ + { -1, -1, 45 }, /* 58: (6, 0) 18 bits */ + { 60, 61, -1 }, /* 59: */ + { -1, -1, 40 }, /* 60: (5, 2) 18 bits */ + { -1, -1, 36 }, /* 61: (5,-2) 18 bits */ + { 63, 66, -1 }, /* 62: */ + { 64, 65, -1 }, /* 63: */ + { -1, -1, 27 }, /* 64: (3, 3) 18 bits */ + { -1, -1, 21 }, /* 65: (3,-3) 18 bits */ + { 67, 68, -1 }, /* 66: */ + { -1, -1, 46 }, /* 67: (6, 1) 18 bits */ + { -1, -1, 44 }, /* 68: (6,-1) 18 bits */ + { 70, 77, -1 }, /* 69: */ + { 71, 74, -1 }, /* 70: */ + { 72, 73, -1 }, /* 71: */ + { -1, -1, 34 }, /* 72: (4, 3) 18 bits */ + { -1, -1, 28 }, /* 73: (4,-3) 18 bits */ + { 75, 76, -1 }, /* 74: */ + { -1, -1, 47 }, /* 75: (6, 2) 18 bits */ + { -1, -1, 43 }, /* 76: (6,-2) 18 bits */ + { 78, 81, -1 }, /* 77: */ + { 79, 80, -1 }, /* 78: */ + { -1, -1, 41 }, /* 79: (5, 3) 18 bits */ + { -1, -1, 35 }, /* 80: (5,-3) 18 bits */ + { 82, 83, -1 }, /* 81: */ + { -1, -1, 48 }, /* 82: (6, 3) 18 bits */ + { -1, -1, 42 }, /* 83: (6,-3) 18 bits */ + { -1, -1, 19 }, /* 84: (2, 2) 13 bits */ + { -1, -1, 25 }, /* 85: (3, 1) 11 bits */ + { 87, 88, -1 }, /* 86: */ + { -1, -1, 23 }, /* 87: (3,-1) 11 bits */ + { -1, -1, 12 }, /* 88: (1, 2) 11 bits */ + { 90, 91, -1 }, /* 89: */ + { -1, -1, 5 }, /* 90: (0, 2) 9 bits */ + { -1, -1, 1 }, /* 91: (0,-2) 9 bits */ + { -1, -1, 18 }, /* 92: (2, 1) 6 bits */ + { 94, 95, -1 }, /* 93: */ + { -1, -1, 4 }, /* 94: (0, 1) 3 bits */ + { -1, -1, 2 }, /* 95: (0,-1) 3 bits */ + { -1, -1, 3 }, /* 96: (0, 0) 1 bit */ +}; + +static bliss_huffman_code_tuple_t tuples[] = { + { 59976, 18 }, /* 0: (0,-3) 001110101001001000 */ + { 119, 9 }, /* 1: (0,-2) 001110111 */ + { 3, 3 }, /* 2: (0,-1) 011 */ + { 1, 1 }, /* 3: (0, 0) 1 */ + { 2, 3 }, /* 4: (0, 1) 010 */ + { 118, 9 }, /* 5: (0, 2) 001110110 */ + { 59975, 18 }, /* 6: (0, 3) 001110101001000111 */ + + { 59982, 18 }, /* 7: (1,-3) 001110101001001110 */ + { 936, 12 }, /* 8: (1,-2) 001110101000 */ + { 5, 5 }, /* 9: (1,-1) 00101 */ + { 0, 3 }, /* 10: (1, 0) 000 */ + { 4, 5 }, /* 11: (1, 1) 00100 */ + { 471, 11 }, /* 12: (1, 2) 00111010111 */ + { 59981, 18 }, /* 13: (1, 3) 001110101001001101 */ + + { 59984, 18 }, /* 14: (2,-3) 001110101001010000 */ + { 59968, 18 }, /* 15: (2,-2) 001110101001000000 */ + { 28, 7 }, /* 16: (2,-1) 0011100 */ + { 6, 5 }, /* 17: (2, 0) 00110 */ + { 15, 6 }, /* 18: (2, 1) 001111 */ + { 1875, 13 }, /* 19: (2, 2) 0011101010011 */ + { 59983, 18 }, /* 20: (2, 3) 001110101001001111 */ + + { 59989, 18 }, /* 21: (3,-3) 001110101001010101 */ + { 59973, 18 }, /* 22: (3,-2) 001110101001000101 */ + { 470, 11 }, /* 23: (3,-1) 00111010110 */ + { 116, 9 }, /* 24: (3, 0) 001110100 */ + { 469, 11 }, /* 25: (3, 1) 00111010101 */ + { 59972, 18 }, /* 26: (3, 2) 001110101001000100 */ + { 59988, 18 }, /* 27: (3, 3) 001110101001010100 */ + + { 59993, 18 }, /* 28: (4,-3) 001110101001011001 */ + { 59980, 18 }, /* 29: (4,-2) 001110101001001100 */ + { 59971, 18 }, /* 30: (4,-1) 001110101001000011 */ + { 59969, 18 }, /* 31: (4, 0) 001110101001000001 */ + { 59970, 18 }, /* 32: (4, 1) 001110101001000010 */ + { 59979, 18 }, /* 33: (4, 2) 001110101001001011 */ + { 59992, 18 }, /* 34: (4, 3) 001110101001011000 */ + + { 59997, 18 }, /* 35: (5,-3) 001110101001011101 */ + { 59987, 18 }, /* 36: (5,-2) 001110101001010011 */ + { 59978, 18 }, /* 37: (5,-1) 001110101001001010 */ + { 59974, 18 }, /* 38: (5, 0) 001110101001000110 */ + { 59977, 18 }, /* 39: (5, 1) 001110101001001001 */ + { 59986, 18 }, /* 40: (5, 2) 001110101001010010 */ + { 59996, 18 }, /* 41: (5, 3) 001110101001011100 */ + + { 59999, 18 }, /* 42: (6,-3) 001110101001011111 */ + { 59995, 18 }, /* 43: (6,-2) 001110101001011011 */ + { 59991, 18 }, /* 44: (6,-1) 001110101001010111 */ + { 59985, 18 }, /* 45: (6, 0) 001110101001010001 */ + { 59990, 18 }, /* 46: (6, 1) 001110101001010110 */ + { 59994, 18 }, /* 47: (6, 2) 001110101001011010 */ + { 59998, 18 }, /* 48: (6, 3) 001110101001011110 */ +}; + +/* code_length = 2.3227 bits/tuple (1190 bits) */ + +bliss_huffman_code_t bliss_huffman_code_3 = { + .n_z1 = 7, + .n_z2 = 4, + .tuples = tuples, + .nodes = nodes +}; diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman_code_4.c b/src/libstrongswan/plugins/bliss/bliss_huffman_code_4.c new file mode 100644 index 000000000..c4f709c93 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_huffman_code_4.c @@ -0,0 +1,435 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * Optimum Huffman code for BLISS-X signatures + * + * This file has been automatically generated by the bliss_huffman utility + * Do not edit manually! + */ + +/* + * Design: sigma = 271 + * + * i p_z1[i] + * 0 0.6551621276225426 0 .. 256 + * 1 0.2859860850630749 256 .. 512 + * 2 0.0542541135599810 512 .. 768 + * 3 0.0044399624814222 768 .. 1024 + * 4 0.0001553928373912 1024 .. 1280 + * 5 0.0000023066278552 1280 .. 1536 + * 6 0.0000000118077330 1536 .. 1613 + * + * k p_z2[k] dx = 256 + * -6 0.0000001026458579 -1663.5 ..-1407.5 + * -5 0.0000106295703648 -1407.5 ..-1151.5 + * -4 0.0004651193817805 -1151.5 .. -895.5 + * -3 0.0086670703658387 -895.5 .. -639.5 + * -2 0.0693723939195647 -639.5 .. -383.5 + * -1 0.2404908493690626 -383.5 .. -127.5 + * 0 0.3619876694950614 -127.5 .. 127.5 + * 1 0.2404908493690626 127.5 .. 383.5 + * 2 0.0693723939195647 383.5 .. 639.5 + * 3 0.0086670703658387 639.5 .. 895.5 + * 4 0.0004651193817805 895.5 .. 1151.5 + * 5 0.0000106295703648 1151.5 .. 1407.5 + * 6 0.0000001026458579 1407.5 .. 1663.5 + * + * (i, k) p + * (0,-6) 0.0000000672496787 + * (0,-5) 0.0000069640919359 + * (0,-4) 0.0003047286037658 + * (0,-3) 0.0056783362611372 + * (0,-2) 0.0454501651986111 + * (0,-1) 0.1575604965463875 + * (0, 0) 0.2371606117195102 + * (0, 1) 0.1575604965463875 + * (0, 2) 0.0454501651986111 + * (0, 3) 0.0056783362611372 + * (0, 4) 0.0003047286037658 + * (0, 5) 0.0000069640919359 + * (0, 6) 0.0000000672496787 + * + * (1,-6) 0.0000000293552870 + * (1,-5) 0.0000030399092145 + * (1,-4) 0.0001330176710824 + * (1,-3) 0.0024786615228924 + * (1,-2) 0.0198395393485098 + * (1,-1) 0.0687770365045519 + * (1, 0) 0.1035234364399989 + * (1, 1) 0.0687770365045519 + * (1, 2) 0.0198395393485098 + * (1, 3) 0.0024786615228924 + * (1, 4) 0.0001330176710824 + * (1, 5) 0.0000030399092145 + * (1, 6) 0.0000000293552870 + * + * (2,-6) 0.0000000055689600 + * (2,-5) 0.0000005766979177 + * (2,-4) 0.0000252346397581 + * (2,-3) 0.0004702242198606 + * (2,-2) 0.0037637377376398 + * (2,-1) 0.0130476178518054 + * (2, 0) 0.0196393201280979 + * (2, 1) 0.0130476178518054 + * (2, 2) 0.0037637377376398 + * (2, 3) 0.0004702242198606 + * (2, 4) 0.0000252346397581 + * (2, 5) 0.0000005766979177 + * (2, 6) 0.0000000055689600 + * + * (3,-6) 0.0000000004557438 + * (3,-5) 0.0000000471948936 + * (3,-4) 0.0000020651126045 + * (3,-3) 0.0000384814672482 + * (3,-2) 0.0003080108262493 + * (3,-1) 0.0010677703483240 + * (3, 0) 0.0016072116712955 + * (3, 1) 0.0010677703483240 + * (3, 2) 0.0003080108262493 + * (3, 3) 0.0000384814672482 + * (3, 4) 0.0000020651126045 + * (3, 5) 0.0000000471948936 + * (3, 6) 0.0000000004557438 + * + * (4,-6) 0.0000000000159504 + * (4,-5) 0.0000000016517591 + * (4,-4) 0.0000000722762205 + * (4,-3) 0.0000013468006560 + * (4,-2) 0.0000107799731278 + * (4,-1) 0.0000373705554501 + * (4, 0) 0.0000562502910635 + * (4, 1) 0.0000373705554501 + * (4, 2) 0.0000107799731278 + * (4, 3) 0.0000013468006560 + * (4, 4) 0.0000000722762205 + * (4, 5) 0.0000000016517591 + * (4, 6) 0.0000000000159504 + * + * (5,-6) 0.0000000000002368 + * (5,-5) 0.0000000000245185 + * (5,-4) 0.0000000010728573 + * (5,-3) 0.0000000199917059 + * (5,-2) 0.0000001600162962 + * (5,-1) 0.0000005547228921 + * (5, 0) 0.0000008349708417 + * (5, 1) 0.0000005547228921 + * (5, 2) 0.0000001600162962 + * (5, 3) 0.0000000199917059 + * (5, 4) 0.0000000010728573 + * (5, 5) 0.0000000000245185 + * (5, 6) 0.0000000000002368 + * + * (6,-6) 0.0000000000000012 + * (6,-5) 0.0000000000001255 + * (6,-4) 0.0000000000054920 + * (6,-3) 0.0000000001023385 + * (6,-2) 0.0000000008191307 + * (6,-1) 0.0000000028396517 + * (6, 0) 0.0000000042742538 + * (6, 1) 0.0000000028396517 + * (6, 2) 0.0000000008191307 + * (6, 3) 0.0000000001023385 + * (6, 4) 0.0000000000054920 + * (6, 5) 0.0000000000001255 + * (6, 6) 0.0000000000000012 + * + * p_sum 1.0000000000000011 + * + * entropy = 3.3640 bits/tuple (1722 bits) + */ + +#include "bliss_huffman_code.h" + +static bliss_huffman_code_node_t nodes[] = { + { 1, 160, -1 }, /* 0: */ + { 2, 5, -1 }, /* 1: */ + { 3, 4, -1 }, /* 2: */ + { -1, -1, 7 }, /* 3: (0, 1) 3 bits */ + { -1, -1, 5 }, /* 4: (0,-1) 3 bits */ + { 6, 157, -1 }, /* 5: */ + { 7, 156, -1 }, /* 6: */ + { 8, 11, -1 }, /* 7: */ + { 9, 10, -1 }, /* 8: */ + { -1, -1, 17 }, /* 9: (1,-2) 6 bits */ + { -1, -1, 32 }, /* 10: (2, 0) 6 bits */ + { 12, 155, -1 }, /* 11: */ + { 13, 18, -1 }, /* 12: */ + { 14, 15, -1 }, /* 13: */ + { -1, -1, 3 }, /* 14: (0,-3) 8 bits */ + { 16, 17, -1 }, /* 15: */ + { -1, -1, 22 }, /* 16: (1, 3) 9 bits */ + { -1, -1, 16 }, /* 17: (1,-3) 9 bits */ + { 19, 154, -1 }, /* 18: */ + { 20, 23, -1 }, /* 19: */ + { 21, 22, -1 }, /* 20: */ + { -1, -1, 46 }, /* 21: (3, 1) 10 bits */ + { -1, -1, 44 }, /* 22: (3,-1) 10 bits */ + { 24, 151, -1 }, /* 23: */ + { 25, 88, -1 }, /* 24: */ + { 26, 57, -1 }, /* 25: */ + { 27, 42, -1 }, /* 26: */ + { 28, 35, -1 }, /* 27: */ + { 29, 32, -1 }, /* 28: */ + { 30, 31, -1 }, /* 29: */ + { -1, -1, 2 }, /* 30: (0,-4) 16 bits */ + { -1, -1, 23 }, /* 31: (1, 4) 16 bits */ + { 33, 34, -1 }, /* 32: */ + { -1, -1, 15 }, /* 33: (1,-4) 16 bits */ + { -1, -1, 58 }, /* 34: (4, 0) 16 bits */ + { 36, 39, -1 }, /* 35: */ + { 37, 38, -1 }, /* 36: */ + { -1, -1, 48 }, /* 37: (3, 3) 16 bits */ + { -1, -1, 42 }, /* 38: (3,-3) 16 bits */ + { 40, 41, -1 }, /* 39: */ + { -1, -1, 59 }, /* 40: (4, 1) 16 bits */ + { -1, -1, 57 }, /* 41: (4,-1) 16 bits */ + { 43, 50, -1 }, /* 42: */ + { 44, 47, -1 }, /* 43: */ + { 45, 46, -1 }, /* 44: */ + { -1, -1, 36 }, /* 45: (2, 4) 16 bits */ + { -1, -1, 28 }, /* 46: (2,-4) 16 bits */ + { 48, 49, -1 }, /* 47: */ + { -1, -1, 60 }, /* 48: (4, 2) 16 bits */ + { -1, -1, 56 }, /* 49: (4,-2) 16 bits */ + { 51, 54, -1 }, /* 50: */ + { 52, 53, -1 }, /* 51: */ + { -1, -1, 11 }, /* 52: (0, 5) 16 bits */ + { -1, -1, 1 }, /* 53: (0,-5) 16 bits */ + { 55, 56, -1 }, /* 54: */ + { -1, -1, 24 }, /* 55: (1, 5) 16 bits */ + { -1, -1, 14 }, /* 56: (1,-5) 16 bits */ + { 58, 73, -1 }, /* 57: */ + { 59, 66, -1 }, /* 58: */ + { 60, 63, -1 }, /* 59: */ + { 61, 62, -1 }, /* 60: */ + { -1, -1, 49 }, /* 61: (3, 4) 16 bits */ + { -1, -1, 41 }, /* 62: (3,-4) 16 bits */ + { 64, 65, -1 }, /* 63: */ + { -1, -1, 61 }, /* 64: (4, 3) 16 bits */ + { -1, -1, 55 }, /* 65: (4,-3) 16 bits */ + { 67, 70, -1 }, /* 66: */ + { 68, 69, -1 }, /* 67: */ + { -1, -1, 71 }, /* 68: (5, 0) 16 bits */ + { -1, -1, 37 }, /* 69: (2, 5) 16 bits */ + { 71, 72, -1 }, /* 70: */ + { -1, -1, 27 }, /* 71: (2,-5) 16 bits */ + { -1, -1, 72 }, /* 72: (5, 1) 16 bits */ + { 74, 81, -1 }, /* 73: */ + { 75, 78, -1 }, /* 74: */ + { 76, 77, -1 }, /* 75: */ + { -1, -1, 70 }, /* 76: (5,-1) 16 bits */ + { -1, -1, 73 }, /* 77: (5, 2) 16 bits */ + { 79, 80, -1 }, /* 78: */ + { -1, -1, 69 }, /* 79: (5,-2) 16 bits */ + { -1, -1, 62 }, /* 80: (4, 4) 16 bits */ + { 82, 85, -1 }, /* 81: */ + { 83, 84, -1 }, /* 82: */ + { -1, -1, 54 }, /* 83: (4,-4) 16 bits */ + { -1, -1, 12 }, /* 84: (0, 6) 16 bits */ + { 86, 87, -1 }, /* 85: */ + { -1, -1, 0 }, /* 86: (0,-6) 16 bits */ + { -1, -1, 50 }, /* 87: (3, 5) 16 bits */ + { 89, 120, -1 }, /* 88: */ + { 90, 105, -1 }, /* 89: */ + { 91, 98, -1 }, /* 90: */ + { 92, 95, -1 }, /* 91: */ + { 93, 94, -1 }, /* 92: */ + { -1, -1, 40 }, /* 93: (3,-5) 16 bits */ + { -1, -1, 25 }, /* 94: (1, 6) 16 bits */ + { 96, 97, -1 }, /* 95: */ + { -1, -1, 13 }, /* 96: (1,-6) 16 bits */ + { -1, -1, 74 }, /* 97: (5, 3) 16 bits */ + { 99, 102, -1 }, /* 98: */ + { 100, 101, -1 }, /* 99: */ + { -1, -1, 68 }, /* 100: (5,-3) 16 bits */ + { -1, -1, 38 }, /* 101: (2, 6) 16 bits */ + { 103, 104, -1 }, /* 102: */ + { -1, -1, 26 }, /* 103: (2,-6) 16 bits */ + { -1, -1, 84 }, /* 104: (6, 0) 16 bits */ + { 106, 113, -1 }, /* 105: */ + { 107, 110, -1 }, /* 106: */ + { 108, 109, -1 }, /* 107: */ + { -1, -1, 85 }, /* 108: (6, 1) 16 bits */ + { -1, -1, 83 }, /* 109: (6,-1) 16 bits */ + { 111, 112, -1 }, /* 110: */ + { -1, -1, 63 }, /* 111: (4, 5) 16 bits */ + { -1, -1, 53 }, /* 112: (4,-5) 16 bits */ + { 114, 117, -1 }, /* 113: */ + { 115, 116, -1 }, /* 114: */ + { -1, -1, 75 }, /* 115: (5, 4) 16 bits */ + { -1, -1, 67 }, /* 116: (5,-4) 16 bits */ + { 118, 119, -1 }, /* 117: */ + { -1, -1, 86 }, /* 118: (6, 2) 16 bits */ + { -1, -1, 82 }, /* 119: (6,-2) 16 bits */ + { 121, 136, -1 }, /* 120: */ + { 122, 129, -1 }, /* 121: */ + { 123, 126, -1 }, /* 122: */ + { 124, 125, -1 }, /* 123: */ + { -1, -1, 51 }, /* 124: (3, 6) 16 bits */ + { -1, -1, 39 }, /* 125: (3,-6) 16 bits */ + { 127, 128, -1 }, /* 126: */ + { -1, -1, 87 }, /* 127: (6, 3) 16 bits */ + { -1, -1, 81 }, /* 128: (6,-3) 16 bits */ + { 130, 133, -1 }, /* 129: */ + { 131, 132, -1 }, /* 130: */ + { -1, -1, 76 }, /* 131: (5, 5) 16 bits */ + { -1, -1, 66 }, /* 132: (5,-5) 16 bits */ + { 134, 135, -1 }, /* 133: */ + { -1, -1, 64 }, /* 134: (4, 6) 16 bits */ + { -1, -1, 52 }, /* 135: (4,-6) 16 bits */ + { 137, 144, -1 }, /* 136: */ + { 138, 141, -1 }, /* 137: */ + { 139, 140, -1 }, /* 138: */ + { -1, -1, 88 }, /* 139: (6, 4) 16 bits */ + { -1, -1, 80 }, /* 140: (6,-4) 16 bits */ + { 142, 143, -1 }, /* 141: */ + { -1, -1, 77 }, /* 142: (5, 6) 16 bits */ + { -1, -1, 65 }, /* 143: (5,-6) 16 bits */ + { 145, 148, -1 }, /* 144: */ + { 146, 147, -1 }, /* 145: */ + { -1, -1, 89 }, /* 146: (6, 5) 16 bits */ + { -1, -1, 79 }, /* 147: (6,-5) 16 bits */ + { 149, 150, -1 }, /* 148: */ + { -1, -1, 90 }, /* 149: (6, 6) 16 bits */ + { -1, -1, 78 }, /* 150: (6,-6) 16 bits */ + { 152, 153, -1 }, /* 151: */ + { -1, -1, 29 }, /* 152: (2,-3) 11 bits */ + { -1, -1, 47 }, /* 153: (3, 2) 11 bits */ + { -1, -1, 34 }, /* 154: (2, 2) 8 bits */ + { -1, -1, 33 }, /* 155: (2, 1) 6 bits */ + { -1, -1, 20 }, /* 156: (1, 1) 4 bits */ + { 158, 159, -1 }, /* 157: */ + { -1, -1, 18 }, /* 158: (1,-1) 4 bits */ + { -1, -1, 8 }, /* 159: (0, 2) 4 bits */ + { 161, 162, -1 }, /* 160: */ + { -1, -1, 6 }, /* 161: (0, 0) 2 bits */ + { 163, 164, -1 }, /* 162: */ + { -1, -1, 19 }, /* 163: (1, 0) 3 bits */ + { 165, 166, -1 }, /* 164: */ + { -1, -1, 4 }, /* 165: (0,-2) 4 bits */ + { 167, 180, -1 }, /* 166: */ + { 168, 169, -1 }, /* 167: */ + { -1, -1, 31 }, /* 168: (2,-1) 6 bits */ + { 170, 179, -1 }, /* 169: */ + { 171, 172, -1 }, /* 170: */ + { -1, -1, 30 }, /* 171: (2,-2) 8 bits */ + { 173, 174, -1 }, /* 172: */ + { -1, -1, 45 }, /* 173: (3, 0) 9 bits */ + { 175, 178, -1 }, /* 174: */ + { 176, 177, -1 }, /* 175: */ + { -1, -1, 43 }, /* 176: (3,-2) 11 bits */ + { -1, -1, 10 }, /* 177: (0, 4) 11 bits */ + { -1, -1, 35 }, /* 178: (2, 3) 10 bits */ + { -1, -1, 9 }, /* 179: (0, 3) 7 bits */ + { -1, -1, 21 }, /* 180: (1, 2) 5 bits */ +}; + +static bliss_huffman_code_tuple_t tuples[] = { + { 19102, 16 }, /* 0: (0,-6) 0100101010011110 */ + { 19085, 16 }, /* 1: (0,-5) 0100101010001101 */ + { 19072, 16 }, /* 2: (0,-4) 0100101010000000 */ + { 72, 8 }, /* 3: (0,-3) 01001000 */ + { 14, 4 }, /* 4: (0,-2) 1110 */ + { 1, 3 }, /* 5: (0,-1) 001 */ + { 2, 2 }, /* 6: (0, 0) 10 */ + { 0, 3 }, /* 7: (0, 1) 000 */ + { 7, 4 }, /* 8: (0, 2) 0111 */ + { 123, 7 }, /* 9: (0, 3) 1111011 */ + { 1965, 11 }, /* 10: (0, 4) 11110101101 */ + { 19084, 16 }, /* 11: (0, 5) 0100101010001100 */ + { 19101, 16 }, /* 12: (0, 6) 0100101010011101 */ + + { 19106, 16 }, /* 13: (1,-6) 0100101010100010 */ + { 19087, 16 }, /* 14: (1,-5) 0100101010001111 */ + { 19074, 16 }, /* 15: (1,-4) 0100101010000010 */ + { 147, 9 }, /* 16: (1,-3) 010010011 */ + { 16, 6 }, /* 17: (1,-2) 010000 */ + { 6, 4 }, /* 18: (1,-1) 0110 */ + { 6, 3 }, /* 19: (1, 0) 110 */ + { 5, 4 }, /* 20: (1, 1) 0101 */ + { 31, 5 }, /* 21: (1, 2) 11111 */ + { 146, 9 }, /* 22: (1, 3) 010010010 */ + { 19073, 16 }, /* 23: (1, 4) 0100101010000001 */ + { 19086, 16 }, /* 24: (1, 5) 0100101010001110 */ + { 19105, 16 }, /* 25: (1, 6) 0100101010100001 */ + + { 19110, 16 }, /* 26: (2,-6) 0100101010100110 */ + { 19094, 16 }, /* 27: (2,-5) 0100101010010110 */ + { 19081, 16 }, /* 28: (2,-4) 0100101010001001 */ + { 598, 11 }, /* 29: (2,-3) 01001010110 */ + { 244, 8 }, /* 30: (2,-2) 11110100 */ + { 60, 6 }, /* 31: (2,-1) 111100 */ + { 17, 6 }, /* 32: (2, 0) 010001 */ + { 19, 6 }, /* 33: (2, 1) 010011 */ + { 75, 8 }, /* 34: (2, 2) 01001011 */ + { 983, 10 }, /* 35: (2, 3) 1111010111 */ + { 19080, 16 }, /* 36: (2, 4) 0100101010001000 */ + { 19093, 16 }, /* 37: (2, 5) 0100101010010101 */ + { 19109, 16 }, /* 38: (2, 6) 0100101010100101 */ + + { 19121, 16 }, /* 39: (3,-6) 0100101010110001 */ + { 19104, 16 }, /* 40: (3,-5) 0100101010100000 */ + { 19089, 16 }, /* 41: (3,-4) 0100101010010001 */ + { 19077, 16 }, /* 42: (3,-3) 0100101010000101 */ + { 1964, 11 }, /* 43: (3,-2) 11110101100 */ + { 297, 10 }, /* 44: (3,-1) 0100101001 */ + { 490, 9 }, /* 45: (3, 0) 111101010 */ + { 296, 10 }, /* 46: (3, 1) 0100101000 */ + { 599, 11 }, /* 47: (3, 2) 01001010111 */ + { 19076, 16 }, /* 48: (3, 3) 0100101010000100 */ + { 19088, 16 }, /* 49: (3, 4) 0100101010010000 */ + { 19103, 16 }, /* 50: (3, 5) 0100101010011111 */ + { 19120, 16 }, /* 51: (3, 6) 0100101010110000 */ + + { 19127, 16 }, /* 52: (4,-6) 0100101010110111 */ + { 19115, 16 }, /* 53: (4,-5) 0100101010101011 */ + { 19100, 16 }, /* 54: (4,-4) 0100101010011100 */ + { 19091, 16 }, /* 55: (4,-3) 0100101010010011 */ + { 19083, 16 }, /* 56: (4,-2) 0100101010001011 */ + { 19079, 16 }, /* 57: (4,-1) 0100101010000111 */ + { 19075, 16 }, /* 58: (4, 0) 0100101010000011 */ + { 19078, 16 }, /* 59: (4, 1) 0100101010000110 */ + { 19082, 16 }, /* 60: (4, 2) 0100101010001010 */ + { 19090, 16 }, /* 61: (4, 3) 0100101010010010 */ + { 19099, 16 }, /* 62: (4, 4) 0100101010011011 */ + { 19114, 16 }, /* 63: (4, 5) 0100101010101010 */ + { 19126, 16 }, /* 64: (4, 6) 0100101010110110 */ + + { 19131, 16 }, /* 65: (5,-6) 0100101010111011 */ + { 19125, 16 }, /* 66: (5,-5) 0100101010110101 */ + { 19117, 16 }, /* 67: (5,-4) 0100101010101101 */ + { 19108, 16 }, /* 68: (5,-3) 0100101010100100 */ + { 19098, 16 }, /* 69: (5,-2) 0100101010011010 */ + { 19096, 16 }, /* 70: (5,-1) 0100101010011000 */ + { 19092, 16 }, /* 71: (5, 0) 0100101010010100 */ + { 19095, 16 }, /* 72: (5, 1) 0100101010010111 */ + { 19097, 16 }, /* 73: (5, 2) 0100101010011001 */ + { 19107, 16 }, /* 74: (5, 3) 0100101010100011 */ + { 19116, 16 }, /* 75: (5, 4) 0100101010101100 */ + { 19124, 16 }, /* 76: (5, 5) 0100101010110100 */ + { 19130, 16 }, /* 77: (5, 6) 0100101010111010 */ + + { 19135, 16 }, /* 78: (6,-6) 0100101010111111 */ + { 19133, 16 }, /* 79: (6,-5) 0100101010111101 */ + { 19129, 16 }, /* 80: (6,-4) 0100101010111001 */ + { 19123, 16 }, /* 81: (6,-3) 0100101010110011 */ + { 19119, 16 }, /* 82: (6,-2) 0100101010101111 */ + { 19113, 16 }, /* 83: (6,-1) 0100101010101001 */ + { 19111, 16 }, /* 84: (6, 0) 0100101010100111 */ + { 19112, 16 }, /* 85: (6, 1) 0100101010101000 */ + { 19118, 16 }, /* 86: (6, 2) 0100101010101110 */ + { 19122, 16 }, /* 87: (6, 3) 0100101010110010 */ + { 19128, 16 }, /* 88: (6, 4) 0100101010111000 */ + { 19132, 16 }, /* 89: (6, 5) 0100101010111100 */ + { 19134, 16 }, /* 90: (6, 6) 0100101010111110 */ +}; + +/* code_length = 3.3967 bits/tuple (1740 bits) */ + +bliss_huffman_code_t bliss_huffman_code_4 = { + .n_z1 = 7, + .n_z2 = 7, + .tuples = tuples, + .nodes = nodes +}; diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman_coder.c b/src/libstrongswan/plugins/bliss/bliss_huffman_coder.c new file mode 100644 index 000000000..018ae0efa --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_huffman_coder.c @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY;https://www.hsr.ch/HSR-intern-Anmeldung.4409.0.html?&no_cache=1 without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "bliss_huffman_coder.h" + +typedef struct private_bliss_huffman_coder_t private_bliss_huffman_coder_t; + +/** + * Private data structure for bliss_huffman_coder_t object + */ +struct private_bliss_huffman_coder_t { + /** + * Public interface. + */ + bliss_huffman_coder_t public; + + /** + * Bitpacker to write to or read from + */ + bliss_bitpacker_t *packer; + + /** + * Huffman code table to be used + */ + bliss_huffman_code_t *code; + + /** + * Maximum index into tuples table + */ + int index_max; + + /** + * Number of encoded or decoded bits + */ + size_t bits; + +}; + +METHOD(bliss_huffman_coder_t, get_bits, size_t, + private_bliss_huffman_coder_t *this) +{ + return this->bits; +} + +METHOD(bliss_huffman_coder_t, encode, bool, + private_bliss_huffman_coder_t *this, int32_t z1, int16_t z2) +{ + uint32_t code; + uint16_t bits; + int index; + + index = z1 * (2*this->code->n_z2 - 1) + z2 + this->code->n_z2 - 1; + if (index >= this->index_max) + { + DBG1(DBG_LIB, "index exceeded in Huffman encoding table"); + return FALSE; + } + code = this->code->tuples[index].code; + bits = this->code->tuples[index].bits; + if (!this->packer->write_bits(this->packer, code, bits)) + { + DBG1(DBG_LIB, "bitpacker exceeded its buffer"); + return FALSE; + } + this->bits += bits; + + return TRUE; +} + +METHOD(bliss_huffman_coder_t, decode, bool, + private_bliss_huffman_coder_t *this, int32_t *z1, int16_t *z2) +{ + bliss_huffman_code_node_t *node; + uint32_t bit; + + node = this->code->nodes; + while (node->tuple == BLISS_HUFFMAN_CODE_NO_TUPLE) + { + if (node->node_0 == BLISS_HUFFMAN_CODE_NO_NODE || + node->node_1 == BLISS_HUFFMAN_CODE_NO_NODE) + { + DBG1(DBG_LIB, "error in Huffman decoding table"); + return FALSE; + } + if (!this->packer->read_bits(this->packer, &bit, 1)) + { + DBG1(DBG_LIB, "bitpacker depleted its buffer"); + return FALSE; + } + node = &this->code->nodes[bit ? node->node_1 : node->node_0]; + this->bits++; + } + *z1 = node->tuple / (2*this->code->n_z2 - 1); + *z2 = node->tuple - (2*this->code->n_z2 - 1) * (*z1) - this->code->n_z2 + 1; + + return TRUE; +} + +METHOD(bliss_huffman_coder_t, destroy, void, + private_bliss_huffman_coder_t *this) +{ + free(this); +} + +/** + * See header. + */ +bliss_huffman_coder_t *bliss_huffman_coder_create(bliss_huffman_code_t *code, + bliss_bitpacker_t *packer) +{ + private_bliss_huffman_coder_t *this; + + INIT(this, + .public = { + .get_bits = _get_bits, + .encode = _encode, + .decode = _decode, + .destroy = _destroy, + }, + .packer = packer, + .code = code, + .index_max = (2*code->n_z2 - 1) * code->n_z1, + ); + + return &this->public; +} diff --git a/src/libstrongswan/plugins/bliss/bliss_huffman_coder.h b/src/libstrongswan/plugins/bliss/bliss_huffman_coder.h new file mode 100644 index 000000000..59abc49c6 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_huffman_coder.h @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup bliss_huffman_coder bliss_huffman_coder + * @{ @ingroup bliss_p + */ + +#ifndef BLISS_HUFFMAN_CODER_H_ +#define BLISS_HUFFMAN_CODER_H_ + +#include "bliss_huffman_code.h" +#include "bliss_bitpacker.h" + +#include <library.h> + +typedef struct bliss_huffman_coder_t bliss_huffman_coder_t; + +/** + * Encodes and decodes binary Huffman codes + */ +struct bliss_huffman_coder_t { + + /** + * Get number of encoded or decoded bits + * + * @result Number of bits + */ + size_t (*get_bits)(bliss_huffman_coder_t *this); + + /** + * Encode a (z1, z2) tuple using a Huffman code + * + * @param z1 z1 value to be encoded + * @param z2 z2 value to be encoded + * @result TRUE if value could be encoded + */ + bool (*encode)(bliss_huffman_coder_t *this, int32_t z1, int16_t z2); + + + /** + * Decode a (z1, z2) tuple using a Huffman code + * + * @param z1 Decoded z1 value returned + * @param z2 Decoded z2 value returned + * @result TRUE if value could be decoded from bitpacker + */ + bool (*decode)(bliss_huffman_coder_t *this, int32_t *z1, int16_t *z2); + + /** + * Destroy bliss_huffman_coder_t object + */ + void (*destroy)(bliss_huffman_coder_t *this); +}; + +/** + * Create a bliss_huffman_coder_t object + * + * @param code Huffman code table + * @param packer Bitpacker to write to or read from + */ +bliss_huffman_coder_t* bliss_huffman_coder_create(bliss_huffman_code_t *code, + bliss_bitpacker_t *packer); + +#endif /** BLISS_HUFFMAN_CODER_H_ @}*/ diff --git a/src/libstrongswan/plugins/bliss/bliss_param_set.c b/src/libstrongswan/plugins/bliss/bliss_param_set.c new file mode 100644 index 000000000..3781a588f --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_param_set.c @@ -0,0 +1,339 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "bliss_param_set.h" + +#include <asn1/oid.h> + +ENUM(bliss_param_set_id_names, BLISS_I, BLISS_B_IV, + "BLISS-I", + "BLISS-II", + "BLISS-III", + "BLISS-IV", + "BLISS-B-I", + "BLISS-B-II", + "BLISS-B-III", + "BLISS-B-IV" +); + +/** + * sigma = 215, k_sigma = ceiling[ sqrt(2*ln 2) * sigma ] = 254 + * + * c[i] = exp(-2^i/f), i = 0..20, with f = k_sigma^2 / ln 2 = 93'076.9 + */ +static uint8_t c_bliss_i[] = { + 255, 255, 75, 191, 247, 94, 30, 51, 147, 246, 89, 59, 99, 248, 26, 128, + 255, 254, 151, 128, 109, 166, 88, 143, 30, 175, 149, 20, 240, 81, 138, 111, + 255, 253, 47, 2, 214, 243, 188, 76, 236, 235, 40, 62, 54, 35, 33, 205, + 255, 250, 94, 13, 156, 120, 121, 216, 255, 120, 90, 11, 39, 232, 120, 111, + 255, 244, 188, 58, 242, 219, 157, 174, 6, 31, 131, 75, 88, 109, 112, 107, + 255, 233, 120, 244, 202, 151, 25, 10, 197, 109, 113, 255, 157, 89, 182, 141, + 255, 210, 243, 229, 18, 88, 50, 239, 130, 192, 12, 167, 62, 254, 211, 202, + 255, 165, 239, 183, 102, 186, 123, 249, 251, 59, 116, 143, 50, 174, 125, 198, + 255, 75, 255, 30, 65, 137, 228, 148, 14, 17, 113, 251, 81, 177, 151, 168, + 254, 152, 124, 205, 192, 136, 102, 79, 5, 62, 214, 95, 36, 223, 7, 20, + 253, 50, 242, 124, 187, 59, 68, 224, 90, 156, 53, 202, 9, 44, 191, 226, + 250, 109, 189, 110, 40, 124, 88, 12, 83, 78, 176, 86, 12, 102, 13, 41, + 244, 250, 133, 6, 3, 13, 45, 9, 120, 121, 150, 237, 69, 190, 62, 16, + 234, 110, 130, 187, 138, 174, 82, 229, 217, 154, 88, 138, 228, 153, 230, 13, + 214, 174, 54, 179, 117, 116, 223, 152, 97, 84, 31, 99, 68, 150, 122, 244, + 180, 7, 186, 2, 112, 3, 68, 13, 123, 133, 244, 184, 232, 216, 133, 18, + 126, 154, 221, 207, 32, 206, 66, 171, 94, 100, 164, 194, 117, 191, 1, 209, + 62, 156, 208, 7, 129, 173, 200, 3, 23, 248, 140, 60, 69, 217, 195, 235, + 15, 80, 84, 209, 213, 2, 107, 160, 1, 152, 43, 130, 93, 95, 241, 218, + 0, 234, 131, 37, 182, 53, 201, 231, 26, 2, 151, 161, 13, 214, 150, 145, + 0, 0, 214, 212, 4, 32, 184, 94, 84, 90, 244, 139, 48, 69, 33, 38 +}; + +/** + * sigma = 250, k_sigma = ceiling[ sqrt(2*ln 2) * sigma ] = 295 + * + * c[i] = exp(-2^i/f), i = 0..20, with f = k_sigma^2 / ln 2 = 125'550.5 + */ +static uint8_t c_bliss_iii[] = { + 255, 255, 122, 95, 16, 128, 14, 195, 60, 90, 166, 191, 205, 26, 144, 204, + 255, 254, 244, 190, 102, 192, 187, 141, 169, 92, 33, 30, 170, 141, 184, 56, + 255, 253, 233, 125, 228, 131, 93, 148, 121, 92, 52, 122, 149, 96, 29, 66, + 255, 251, 211, 0, 37, 9, 199, 244, 213, 217, 122, 205, 171, 200, 198, 5, + 255, 247, 166, 17, 185, 251, 90, 150, 1, 28, 7, 205, 125, 46, 84, 201, + 255, 239, 76, 105, 50, 114, 159, 235, 215, 165, 204, 182, 125, 143, 228, 222, + 255, 222, 153, 233, 85, 187, 45, 204, 236, 229, 38, 180, 20, 161, 7, 167, + 255, 189, 56, 46, 38, 4, 83, 8, 151, 137, 136, 1, 9, 180, 58, 204, + 255, 122, 129, 199, 240, 52, 248, 193, 76, 26, 160, 32, 195, 250, 217, 25, + 254, 245, 73, 44, 68, 229, 150, 74, 228, 74, 124, 249, 123, 94, 108, 127, + 253, 235, 168, 56, 252, 93, 188, 160, 249, 137, 236, 65, 62, 182, 153, 63, + 251, 219, 163, 110, 233, 251, 114, 216, 230, 35, 59, 210, 107, 100, 184, 16, + 247, 200, 110, 236, 134, 237, 213, 111, 240, 149, 109, 22, 216, 213, 237, 145, + 239, 212, 98, 249, 238, 1, 227, 248, 242, 51, 211, 134, 154, 115, 189, 83, + 224, 174, 65, 2, 190, 158, 9, 6, 184, 13, 130, 104, 247, 102, 38, 160, + 197, 49, 104, 97, 61, 210, 19, 115, 208, 54, 91, 27, 209, 227, 33, 26, + 151, 229, 20, 46, 200, 238, 35, 134, 72, 183, 253, 160, 193, 155, 117, 103, + 90, 32, 10, 204, 78, 83, 191, 230, 0, 221, 219, 6, 43, 252, 185, 95, + 31, 186, 139, 154, 90, 155, 17, 9, 42, 139, 40, 111, 246, 175, 4, 15, + 3, 238, 181, 190, 138, 94, 50, 234, 128, 193, 95, 36, 65, 236, 170, 208, + 0, 15, 118, 216, 230, 142, 121, 211, 13, 168, 207, 126, 145, 176, 24, 201 +}; + +/** + * sigma = 271, k_sigma = ceiling[ sqrt(2*ln 2) * sigma ] = 320 + * + * c[i] = exp(-2^i/f), i = 0..21, with f = k_sigma^2 / ln 2 = 147'732.0 + */ +static uint8_t c_bliss_iv[] = { + 255, 255, 142, 111, 102, 2, 141, 87, 150, 42, 18, 70, 6, 224, 18, 70, + 255, 255, 28, 222, 254, 102, 20, 78, 133, 78, 189, 107, 29, 7, 23, 193, + 255, 254, 57, 190, 198, 79, 181, 181, 108, 75, 142, 145, 45, 238, 193, 29, + 255, 252, 115, 128, 178, 170, 212, 166, 120, 157, 85, 96, 209, 180, 211, 83, + 255, 248, 231, 13, 253, 108, 245, 46, 238, 155, 30, 99, 141, 228, 149, 239, + 255, 241, 206, 78, 90, 132, 83, 172, 228, 179, 119, 115, 240, 51, 216, 6, + 255, 227, 157, 102, 46, 28, 61, 128, 58, 114, 174, 136, 8, 224, 133, 84, + 255, 199, 61, 242, 19, 216, 133, 241, 240, 22, 146, 43, 92, 57, 82, 248, + 255, 142, 136, 121, 160, 225, 119, 214, 241, 44, 159, 34, 133, 118, 96, 60, + 255, 29, 67, 61, 254, 49, 27, 152, 48, 124, 184, 87, 66, 214, 63, 133, + 254, 59, 79, 77, 206, 26, 238, 42, 69, 81, 191, 149, 146, 76, 255, 232, + 252, 121, 191, 28, 11, 107, 141, 223, 234, 42, 226, 50, 138, 102, 16, 97, + 248, 255, 234, 37, 109, 169, 103, 25, 240, 109, 93, 165, 177, 22, 133, 100, + 242, 48, 213, 124, 209, 49, 33, 48, 57, 237, 202, 62, 102, 132, 219, 48, + 229, 32, 92, 240, 188, 88, 70, 34, 179, 94, 244, 70, 25, 123, 76, 140, + 205, 18, 234, 94, 14, 226, 237, 76, 192, 18, 240, 50, 79, 63, 34, 96, + 164, 71, 76, 192, 111, 161, 157, 188, 19, 189, 133, 246, 67, 127, 6, 28, + 105, 107, 110, 50, 56, 199, 208, 174, 16, 95, 153, 106, 217, 198, 194, 179, + 43, 105, 77, 122, 127, 254, 146, 221, 44, 235, 61, 22, 179, 9, 113, 118, + 7, 92, 139, 87, 204, 239, 111, 200, 41, 129, 122, 49, 69, 113, 122, 239, + 0, 54, 49, 19, 64, 40, 218, 222, 60, 82, 186, 246, 64, 155, 184, 47, + 0, 0, 11, 120, 189, 135, 113, 62, 143, 175, 118, 239, 190, 120, 189, 250 +}; + +/** + * BLISS signature parameter set definitions + */ +static bliss_param_set_t bliss_param_sets[] = { + + /* BLISS-I scheme */ + { + .id = BLISS_I, + .oid = OID_BLISS_I, + .strength = 128, + .q = 12289, + .q_bits = 14, + .q2_inv = 6145, + .n = 512, + .n_bits = 9, + .fft_params = &bliss_fft_12289_512, + .non_zero1 = 154, + .non_zero2 = 0, + .kappa = 23, + .nks_max = 46479, + .p_max = 0, /* not needed */ + .sigma = 215, + .k_sigma = 254, + .k_sigma_bits = 8, + .c = c_bliss_i, + .c_cols = 16, + .c_rows = 21, + .z1_bits = 12, + .d = 10, + .p = 24, + .M = 46539, /* with alpha = 1.000 */ + .B_inf = 2047, /* reduced from 2100 due to 12 bit z1 encoding */ + .B_l2 = 12872 * 12872 + }, + + /* BLISS-III scheme */ + { + .id = BLISS_III, + .oid = OID_BLISS_III, + .strength = 160, + .q = 12289, + .q_bits = 14, + .q2_inv = 6145, + .n = 512, + .n_bits = 9, + .fft_params = &bliss_fft_12289_512, + .non_zero1 = 216, + .non_zero2 = 16, + .kappa = 30, + .nks_max = 128626, + .p_max = 0, /* not needed */ + .sigma = 250, + .k_sigma = 295, + .k_sigma_bits = 9, + .c = c_bliss_iii, + .c_cols = 16, + .c_rows = 21, + .z1_bits = 12, + .d = 9, + .p = 48, + .M = 128113, /* with alpha = 0.700 */ + .B_inf = 1760, + .B_l2 = 10206 * 10206 + }, + + /* BLISS-IV scheme */ + { + .id = BLISS_IV, + .oid = OID_BLISS_IV, + .strength = 192, + .q = 12289, + .q_bits = 14, + .q2_inv = 6145, + .n = 512, + .n_bits = 9, + .fft_params = &bliss_fft_12289_512, + .non_zero1 = 231, + .non_zero2 = 31, + .kappa = 39, + .nks_max = 244669, + .p_max = 0, /* not needed */ + .sigma = 271, + .k_sigma = 320, + .k_sigma_bits = 9, + .c = c_bliss_iv, + .c_cols = 16, + .c_rows = 22, + .z1_bits = 12, + .d = 8, + .p = 96, + .M = 244186, /* with alpha = 0.550 */ + .B_inf = 1613, + .B_l2 = 9901 * 9901 + }, + + /* BLISS-B-I scheme */ + { + .id = BLISS_B_I, + .oid = OID_BLISS_B_I, + .strength = 128, + .q = 12289, + .q_bits = 14, + .q2_inv = 6145, + .n = 512, + .n_bits = 9, + .fft_params = &bliss_fft_12289_512, + .non_zero1 = 154, + .non_zero2 = 0, + .kappa = 23, + .nks_max = 0, /* not needed */ + .p_max = 17825, + .sigma = 215, + .k_sigma = 254, + .k_sigma_bits = 8, + .c = c_bliss_i, + .c_cols = 16, + .c_rows = 21, + .z1_bits = 12, + .d = 10, + .p = 24, + .M = 17954, /* with alpha = 1.610 */ + .B_inf = 2047, /* reduced from 2100 due to 12 bit z1 encoding */ + .B_l2 = 12872 * 12872 + }, + + /* BLISS-B-III scheme */ + { + .id = BLISS_B_III, + .oid = OID_BLISS_B_III, + .strength = 160, + .q = 12289, + .q_bits = 14, + .q2_inv = 6145, + .n = 512, + .n_bits = 9, + .fft_params = &bliss_fft_12289_512, + .non_zero1 = 216, + .non_zero2 = 16, + .kappa = 30, + .nks_max = 0, /* not needed */ + .p_max = 42270, + .sigma = 250, + .k_sigma = 295, + .k_sigma_bits = 9, + .c = c_bliss_iii, + .c_cols = 16, + .c_rows = 21, + .z1_bits = 12, + .d = 9, + .p = 48, + .M = 42455, /* with alpha = 1.216 */ + .B_inf = 1760, + .B_l2 = 10206 * 10206 + }, + + /* BLISS-B-IV scheme */ + { + .id = BLISS_B_IV, + .oid = OID_BLISS_B_IV, + .strength = 192, + .q = 12289, + .q_bits = 14, + .q2_inv = 6145, + .n = 512, + .n_bits = 9, + .fft_params = &bliss_fft_12289_512, + .non_zero1 = 231, + .non_zero2 = 31, + .kappa = 39, + .nks_max = 0, /* not needed */ + .p_max = 69576, + .sigma = 271, + .k_sigma = 320, + .k_sigma_bits = 9, + .c = c_bliss_iv, + .c_cols = 16, + .c_rows = 22, + .z1_bits = 12, + .d = 8, + .p = 96, + .M = 70034, /* with alpha = 1.027 */ + .B_inf = 1613, + .B_l2 = 9901 * 9901 + } + +}; + +/** + * See header. + */ +bliss_param_set_t* bliss_param_set_get_by_id(bliss_param_set_id_t id) +{ + int i; + + for (i = 0; i < countof(bliss_param_sets); i++) + { + if (bliss_param_sets[i].id == id) + { + return &bliss_param_sets[i]; + } + } + return NULL; +} + + +/** + * See header. + */ +bliss_param_set_t* bliss_param_set_get_by_oid(int oid) +{ + int i; + + for (i = 0; i < countof(bliss_param_sets); i++) + { + if (bliss_param_sets[i].oid == oid) + { + return &bliss_param_sets[i]; + } + } + return NULL; +} diff --git a/src/libstrongswan/plugins/bliss/bliss_param_set.h b/src/libstrongswan/plugins/bliss/bliss_param_set.h new file mode 100644 index 000000000..33a8009ff --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_param_set.h @@ -0,0 +1,201 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup bliss_param_set bliss_param_set + * @{ @ingroup bliss_p + */ + +#ifndef BLISS_PARAM_SET_H_ +#define BLISS_PARAM_SET_H_ + +typedef enum bliss_param_set_id_t bliss_param_set_id_t; +typedef struct bliss_param_set_t bliss_param_set_t; + +#include "bliss_fft_params.h" +#include "bliss_huffman_code.h" + +#include <library.h> + +/** + * BLISS signature parameter set ID list + */ +enum bliss_param_set_id_t { + BLISS_I = 1, + BLISS_II = 2, + BLISS_III = 3, + BLISS_IV = 4, + BLISS_B_I = 5, + BLISS_B_II = 6, + BLISS_B_III = 7, + BLISS_B_IV = 8 +}; + +extern enum_name_t *bliss_param_set_id_names; + +/** + * BLISS + */ +struct bliss_param_set_t { + + /** + * BLISS parameter set ID + */ + bliss_param_set_id_t id; + + /** + * BLISS parameter set OID + */ + int oid; + + /** + * Security strength in bits + */ + uint16_t strength; + + /** + * Prime modulus + */ + uint16_t q; + + /** + * Number of bits in q + */ + uint16_t q_bits; + + /** + * Inverse of (q + 2) mod 2q + */ + uint16_t q2_inv; + + /** + * Ring dimension equal to the number of polynomial coefficients + */ + uint16_t n; + + /** + * Number of bits in n + */ + uint16_t n_bits; + + /** + * FFT parameters + */ + bliss_fft_params_t *fft_params; + + /** + * Number of [-1, +1] secret key coefficients + */ + uint16_t non_zero1; + + /** + * Number of [-2, +2] secret key coefficients + */ + uint16_t non_zero2; + + /** + * Number of secret key terms that go into Nk(S) norm + */ + uint16_t kappa; + + /** + * Maximum Nk(S) tolerable NK(S) norm (BLISS only) + */ + uint32_t nks_max; + + /** + * Maximum value Pmax for ||Sc'||^2 norm (BLISS-B only) + */ + uint32_t p_max; + + /** + * Standard deviation sigma + */ + uint16_t sigma; + + /** + * k_sigma = ceiling[ sqrt(2*ln 2) * sigma ] + */ + uint16_t k_sigma; + + /** + * Number of bits in k_sigma + */ + uint16_t k_sigma_bits; + + /** + * Coefficients for Bernoulli sampling with exponential biases + */ + uint8_t *c; + + /** + * Number of columns in Bernoulli coefficient table + */ + size_t c_cols; + + /** + * Number of rows in Bernoulli coefficient table + */ + size_t c_rows; + + /** + * Number of bits in z1 + */ + uint16_t z1_bits; + + /** + * Number of z2 bits to be dropped after rounding + */ + uint16_t d; + + /** + * Modulus p = floor(2q / 2^d) applied after bit dropping + */ + uint16_t p; + + /** + * M = sigma^2 / alpha_rejection^2 + */ + uint32_t M; + + /** + * B_infinity bound + */ + uint16_t B_inf; + + /** + * B_verify bound + */ + uint32_t B_l2; + +}; + +/** + * Get BLISS signature parameter set by BLISS parameter set ID + * + * @param id BLISS parameter set ID + * @return BLISS parameter set +*/ +bliss_param_set_t* bliss_param_set_get_by_id(bliss_param_set_id_t id); + +/** + * Get BLISS signature parameter set by BLISS parameter set OID + * + * @param oid BLISS parameter set OID + * @return BLISS parameter set +*/ +bliss_param_set_t* bliss_param_set_get_by_oid(int oid); + +#endif /** BLISS_PARAM_SET_H_ @}*/ diff --git a/src/libstrongswan/plugins/bliss/bliss_plugin.c b/src/libstrongswan/plugins/bliss/bliss_plugin.c new file mode 100644 index 000000000..07597c318 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_plugin.c @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "bliss_plugin.h" +#include "bliss_private_key.h" +#include "bliss_public_key.h" + +#include <library.h> + +typedef struct private_bliss_plugin_t private_bliss_plugin_t; + +/** + * private data of bliss_plugin + */ +struct private_bliss_plugin_t { + + /** + * public functions + */ + bliss_plugin_t public; +}; + +METHOD(plugin_t, get_name, char*, + private_bliss_plugin_t *this) +{ + return "bliss"; +} + +METHOD(plugin_t, get_features, int, + private_bliss_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + /* private/public keys */ + PLUGIN_REGISTER(PRIVKEY, bliss_private_key_load, TRUE), + PLUGIN_PROVIDE(PRIVKEY, KEY_BLISS), + PLUGIN_REGISTER(PRIVKEY, bliss_private_key_load, TRUE), + PLUGIN_PROVIDE(PRIVKEY, KEY_ANY), + PLUGIN_REGISTER(PRIVKEY_GEN, bliss_private_key_gen, FALSE), + PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_BLISS), + PLUGIN_DEPENDS(RNG, RNG_TRUE), + PLUGIN_REGISTER(PUBKEY, bliss_public_key_load, TRUE), + PLUGIN_PROVIDE(PUBKEY, KEY_BLISS), + PLUGIN_REGISTER(PUBKEY, bliss_public_key_load, TRUE), + PLUGIN_PROVIDE(PUBKEY, KEY_ANY), + /* signature schemes, private */ + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_BLISS_WITH_SHA256), + PLUGIN_DEPENDS(HASHER, HASH_SHA256), + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_BLISS_WITH_SHA384), + PLUGIN_DEPENDS(HASHER, HASH_SHA384), + PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_BLISS_WITH_SHA512), + PLUGIN_DEPENDS(HASHER, HASH_SHA512), + /* signature verification schemes */ + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_BLISS_WITH_SHA256), + PLUGIN_DEPENDS(HASHER, HASH_SHA256), + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_BLISS_WITH_SHA384), + PLUGIN_DEPENDS(HASHER, HASH_SHA384), + PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_BLISS_WITH_SHA512), + PLUGIN_DEPENDS(HASHER, HASH_SHA512), + }; + *features = f; + + return countof(f); +} + +METHOD(plugin_t, destroy, void, + private_bliss_plugin_t *this) +{ + free(this); +} + +/* + * see header file + */ +plugin_t *bliss_plugin_create() +{ + private_bliss_plugin_t *this; + + INIT(this, + .public = { + .plugin = { + .get_name = _get_name, + .get_features = _get_features, + .destroy = _destroy, + }, + }, + ); + + return &this->public.plugin; +} diff --git a/src/libstrongswan/plugins/bliss/bliss_plugin.h b/src/libstrongswan/plugins/bliss/bliss_plugin.h new file mode 100644 index 000000000..d3d80ac5d --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_plugin.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup bliss_p bliss + * @ingroup plugins + * + * @defgroup bliss_plugin bliss_plugin + * @{ @ingroup bliss_p + */ + +#ifndef BLISS_PLUGIN_H_ +#define BLISS_PLUGIN_H_ + +#include <plugins/plugin.h> + +typedef struct bliss_plugin_t bliss_plugin_t; + +/** + * Plugin implementing the BLISS post-quantu authentication algorithm + */ +struct bliss_plugin_t { + + /** + * implements plugin interface + */ + plugin_t plugin; +}; + +#endif /** BLISS_PLUGIN_H_ @}*/ diff --git a/src/libstrongswan/plugins/bliss/bliss_private_key.c b/src/libstrongswan/plugins/bliss/bliss_private_key.c new file mode 100644 index 000000000..e1064d2f2 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_private_key.c @@ -0,0 +1,1316 @@ +/* + * Copyright (C) 2014-2015 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "bliss_private_key.h" +#include "bliss_public_key.h" +#include "bliss_param_set.h" +#include "bliss_utils.h" +#include "bliss_sampler.h" +#include "bliss_signature.h" +#include "bliss_bitpacker.h" +#include "bliss_fft.h" + +#include <crypto/mgf1/mgf1_bitspender.h> +#include <asn1/asn1.h> +#include <asn1/asn1_parser.h> +#include <asn1/oid.h> + +#define _GNU_SOURCE +#include <stdlib.h> + +typedef struct private_bliss_private_key_t private_bliss_private_key_t; + +#define SECRET_KEY_TRIALS_MAX 50 + +/** + * Private data of a bliss_private_key_t object. + */ +struct private_bliss_private_key_t { + /** + * Public interface for this signer. + */ + bliss_private_key_t public; + + /** + * BLISS signature parameter set + */ + bliss_param_set_t *set; + + /** + * BLISS secret key S1 (coefficients of polynomial f) + */ + int8_t *s1; + + /** + * BLISS secret key S2 (coefficients of polynomial 2g + 1) + */ + int8_t *s2; + + /** + * NTT of BLISS public key a (coefficients of polynomial (2g + 1)/f) + */ + uint32_t *A; + + /** + * reference count + */ + refcount_t ref; +}; + +METHOD(private_key_t, get_type, key_type_t, + private_bliss_private_key_t *this) +{ + return KEY_BLISS; +} + +/** + * Multiply secret vector s with binary challenge vector c + */ +static void multiply_by_c(int8_t *s, int n, uint16_t *c_indices, + uint16_t kappa, int32_t *product) +{ + int i, j, index; + + for (i = 0; i < n; i++) + { + product[i] = 0; + + for (j = 0; j < kappa; j++) + { + index = c_indices[j]; + if (i - index < 0) + { + product[i] -= s[i - index + n]; + } + else + { + product[i] += s[i - index]; + } + } + } +} + +/** + * BLISS-B GreedySC algorithm + */ +static void greedy_sc(int8_t *s1, int8_t *s2, int n, uint16_t *c_indices, + uint16_t kappa, int32_t *v1, int32_t *v2) +{ + int i, j, index; + int32_t sign; + + for (i = 0; i < n; i++) + { + v1[i] = v2[i] = 0; + } + for (j = 0; j < kappa; j++) + { + index = c_indices[j]; + sign = 0; + + for (i = 0; i < index; i++) + { + sign -= (v1[i] * s1[i - index + n] + v2[i] * s2[i - index + n]); + } + for (i = index; i < n; i++) + { + sign += (v1[i] * s1[i - index] + v2[i] * s2[i - index]); + } + for (i = 0; i < index; i++) + { + if (sign > 0) + { + v1[i] += s1[i - index + n]; + v2[i] += s2[i - index + n]; + } + else + { + v1[i] -= s1[i - index + n]; + v2[i] -= s2[i - index + n]; + } + } + for (i = index; i < n; i++) + { + if (sign > 0) + { + v1[i] -= s1[i - index]; + v2[i] -= s2[i - index]; + } + else + { + v1[i] += s1[i - index]; + v2[i] += s2[i - index]; + } + } + } +} + +/** + * Compute a BLISS signature + */ +static bool sign_bliss(private_bliss_private_key_t *this, hash_algorithm_t alg, + chunk_t data, chunk_t *signature) +{ + bliss_fft_t *fft; + bliss_signature_t *sig; + bliss_sampler_t *sampler = NULL; + rng_t *rng; + hasher_t *hasher; + hash_algorithm_t mgf1_alg; + size_t mgf1_seed_len; + uint8_t mgf1_seed_buf[HASH_SIZE_SHA512], data_hash_buf[HASH_SIZE_SHA512]; + chunk_t mgf1_seed, data_hash; + uint16_t q, q2, p, p2, *c_indices, tests = 0; + uint32_t *ay; + int32_t *y1, *y2, *z1, *z2, *u, *s1c, *s2c; + int32_t y1_min = 0, y1i, y1_max = 0, y2_min = 0, y2i, y2_max = 0; + int32_t scalar, norm, ui; + int16_t *ud, *uz2d, *z2d, value; + int i, n; + double mean1 = 0, mean2 = 0, sigma1 = 0, sigma2 = 0; + bool accepted, positive, success = FALSE, use_bliss_b; + + /* Initialize signature */ + *signature = chunk_empty; + + /* Create data hash */ + hasher = lib->crypto->create_hasher(lib->crypto, alg); + if (!hasher) + { + return FALSE; + } + data_hash = chunk_create(data_hash_buf, hasher->get_hash_size(hasher)); + + if (!hasher->get_hash(hasher, data, data_hash_buf)) + { + hasher->destroy(hasher); + return FALSE; + } + hasher->destroy(hasher); + + /* Create SHA512 hasher for c_indices oracle */ + hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA512); + if (!hasher) + { + return FALSE; + } + + /* Set MGF1 hash algorithm and seed length based on security strength */ + if (this->set->strength > 160) + { + mgf1_alg = HASH_SHA256; + mgf1_seed_len = HASH_SIZE_SHA256; + } + else + { + mgf1_alg = HASH_SHA1; + mgf1_seed_len = HASH_SIZE_SHA1; + } + mgf1_seed = chunk_create(mgf1_seed_buf, mgf1_seed_len); + + rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG); + if (!rng) + { + hasher->destroy(hasher); + return FALSE; + } + + /* Initialize a couple of needed variables */ + n = this->set->n; + q = this->set->q; + p = this->set->p; + q2 = 2 * q; + p2 = p / 2; + ay = malloc(n * sizeof(uint32_t)); + z2 = malloc(n * sizeof(int32_t)); + s1c = malloc(n * sizeof(int32_t)); + s2c = malloc(n * sizeof(int32_t)); + u = malloc(n * sizeof(int32_t)); + uz2d = malloc(n * sizeof(int16_t)); + + sig = bliss_signature_create(this->set); + sig->get_parameters(sig, &z1, &z2d, &c_indices); + y1 = z1; + y2 = z2; + ud = z2d; + + fft = bliss_fft_create(this->set->fft_params); + + /* Use of the enhanced BLISS-B signature algorithm? */ + switch (this->set->id) + { + default: + case BLISS_I: + case BLISS_II: + case BLISS_III: + case BLISS_IV: + use_bliss_b = FALSE; + break; + case BLISS_B_I: + case BLISS_B_II: + case BLISS_B_III: + case BLISS_B_IV: + use_bliss_b = TRUE; + break; + } + + while (true) + { + tests++; + + if (!rng->get_bytes(rng, mgf1_seed_len, mgf1_seed_buf)) + { + goto end; + } + DESTROY_IF(sampler); + + sampler = bliss_sampler_create(mgf1_alg, mgf1_seed, this->set); + if (!sampler) + { + goto end; + } + + /* Gaussian sampling for vectors y1 and y2 */ + for (i = 0; i < n; i++) + { + if (!sampler->gaussian(sampler, &y1i) || + !sampler->gaussian(sampler, &y2i)) + { + goto end; + } + y1[i] = y1i; + y2[i] = y2i; + + /* Collect statistical data on rejection sampling */ + if (i == 0) + { + y1_min = y1_max = y1i; + y2_min = y2_max = y2i; + } + else + { + if (y1i < y1_min) + { + y1_min = y1i; + } + else if (y1i > y1_max) + { + y1_max = y1i; + } + if (y2i < y2_min) + { + y2_min = y2i; + } + else if (y2i > y2_max) + { + y2_max = y2i; + } + } + mean1 += y1i; + mean2 += y2i; + sigma1 += y1i * y1i; + sigma2 += y2i * y2i; + + ay[i] = y1i < 0 ? q + y1i : y1i; + } + + /* Compute statistics on vectors y1 and y2 */ + mean1 /= n; + mean2 /= n; + sigma1 /= n; + sigma2 /= n; + sigma2 -= mean1 * mean1; + sigma2 -= mean2 * mean2; + DBG2(DBG_LIB, "y1 = %d..%d (sigma2 = %5.0f, mean = %4.1f)", + y1_min, y1_max, sigma1, mean1); + DBG2(DBG_LIB, "y2 = %d..%d (sigma2 = %5.0f, mean = %4.1f)", + y2_min, y2_max, sigma2, mean2); + + fft->transform(fft, ay, ay, FALSE); + + for (i = 0; i < n; i++) + { + ay[i] = (this->A[i] * ay[i]) % q; + } + fft->transform(fft, ay, ay, TRUE); + + for (i = 0; i < n; i++) + { + ui = 2 * this->set->q2_inv * (int32_t)ay[i] + y2[i]; + u[i] = ((ui < 0) ? q2 + ui : ui) % q2; + } + bliss_utils_round_and_drop(this->set, u, ud); + + /* Detailed debugging information */ + DBG3(DBG_LIB, " i u[i] ud[i]"); + for (i = 0; i < n; i++) + { + DBG3(DBG_LIB, "%3d %6d %4d", i, u[i], ud[i]); + } + + if (!bliss_utils_generate_c(hasher, data_hash, ud, n, this->set->kappa, + c_indices)) + { + goto end; + } + + if (use_bliss_b) + { + /* Compute v = (s1c, s2c) with the GreedySC algorithm */ + greedy_sc(this->s1, this->s2, n, c_indices, this->set->kappa, + s1c, s2c); + + /* Compute norm = ||v||^2 = ||Sc'||^2 */ + norm = bliss_utils_scalar_product(s1c, s1c, n) + + bliss_utils_scalar_product(s2c, s2c, n); + + /* Just in case. ||v||^2 <= P_max should always be fulfilled */ + if (norm > this->set->p_max) + { + goto end; + } + } + else + { + /* Compute s*c */ + multiply_by_c(this->s1, n, c_indices, this->set->kappa, s1c); + multiply_by_c(this->s2, n, c_indices, this->set->kappa, s2c); + + /* Compute norm = |Sc||^2 */ + norm = bliss_utils_scalar_product(s1c, s1c, n) + + bliss_utils_scalar_product(s2c, s2c, n); + } + + if (!sampler->bernoulli_exp(sampler, this->set->M - norm, &accepted)) + { + goto end; + } + if (use_bliss_b) + { + DBG2(DBG_LIB, "norm2(s1*c') + norm2(s2*c') = %u (%u max), %s", + norm, this->set->p_max, accepted ? "accepted" : "rejected"); + + } + else + { + DBG2(DBG_LIB, "norm2(s1*c) + norm2(s2*c) = %u, %s", + norm, accepted ? "accepted" : "rejected"); + } + if (!accepted) + { + continue; + } + + /* Compute z */ + if (!sampler->sign(sampler, &positive)) + { + goto end; + } + for (i = 0; i < n; i++) + { + if (positive) + { + z1[i] = y1[i] + s1c[i]; + z2[i] = y2[i] + s2c[i]; + } + else + { + z1[i] = y1[i] - s1c[i]; + z2[i] = y2[i] - s2c[i]; + } + } + /* Reject with probability 1/cosh(scalar/sigma^2) */ + scalar = bliss_utils_scalar_product(z1, s1c, n) + + bliss_utils_scalar_product(z2, s2c, n); + + if (!sampler->bernoulli_cosh(sampler, scalar, &accepted)) + { + goto end; + } + DBG2(DBG_LIB, "scalar(z1,s1*c) + scalar(z2,s2*c) = %d, %s", + scalar, accepted ? "accepted" : "rejected"); + if (!accepted) + { + continue; + } + + /* Compute z2 with dropped bits */ + for (i = 0; i < n; i++) + { + u[i] -= z2[i]; + if (u[i] < 0) + { + u[i] += q2; + } + else if (u[i] >= q2) + { + u[i] -= q2; + } + } + bliss_utils_round_and_drop(this->set, u, uz2d); + + for (i = 0; i < n; i++) + { + value = ud[i] - uz2d[i]; + if (value <= -p2) + { + value += p; + } + else if (value > p2) + { + value -= p; + } + z2d[i] = value; + } + + if (!bliss_utils_check_norms(this->set, z1, z2d)) + { + continue; + } + + *signature = sig->get_encoding(sig); + if (signature->len == 0) + { + DBG1(DBG_LIB, "inefficient Huffman coding of signature"); + continue; + } + DBG2(DBG_LIB, "signature generation needed %u round%s", tests, + (tests == 1) ? "" : "s"); + break; + } + success = TRUE; + +end: + /* cleanup */ + DESTROY_IF(sampler); + hasher->destroy(hasher); + sig->destroy(sig); + fft->destroy(fft); + rng->destroy(rng); + memwipe(s1c, n * sizeof(int32_t)); + memwipe(s2c, n * sizeof(int32_t)); + free(s1c); + free(s2c); + free(ay); + free(z2); + free(u); + free(uz2d); + + return success; +} + +METHOD(private_key_t, sign, bool, + private_bliss_private_key_t *this, signature_scheme_t scheme, + chunk_t data, chunk_t *signature) +{ + switch (scheme) + { + case SIGN_BLISS_WITH_SHA256: + return sign_bliss(this, HASH_SHA256, data, signature); + case SIGN_BLISS_WITH_SHA384: + return sign_bliss(this, HASH_SHA384, data, signature); + case SIGN_BLISS_WITH_SHA512: + return sign_bliss(this, HASH_SHA512, data, signature); + default: + DBG1(DBG_LIB, "signature scheme %N not supported with BLISS", + signature_scheme_names, scheme); + return FALSE; + } +} + +METHOD(private_key_t, decrypt, bool, + private_bliss_private_key_t *this, encryption_scheme_t scheme, + chunk_t crypto, chunk_t *plain) +{ + DBG1(DBG_LIB, "encryption scheme %N not supported", + encryption_scheme_names, scheme); + return FALSE; +} + +METHOD(private_key_t, get_keysize, int, + private_bliss_private_key_t *this) +{ + return this->set->strength; +} + +METHOD(private_key_t, get_public_key, public_key_t*, + private_bliss_private_key_t *this) +{ + public_key_t *public; + chunk_t pubkey; + + pubkey = bliss_public_key_info_encode(this->set->oid, this->A, this->set); + public = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_BLISS, + BUILD_BLOB_ASN1_DER, pubkey, BUILD_END); + free(pubkey.ptr); + + return public; +} + +METHOD(private_key_t, get_encoding, bool, + private_bliss_private_key_t *this, cred_encoding_type_t type, + chunk_t *encoding) +{ + switch (type) + { + case PRIVKEY_ASN1_DER: + case PRIVKEY_PEM: + { + chunk_t s1, s2, pubkey; + bliss_bitpacker_t *packer; + size_t s_bits; + int8_t value; + bool success = TRUE; + int i; + + pubkey = bliss_public_key_encode(this->A, this->set); + + /* Use either 2 or 3 bits per array element */ + s_bits = 2 + (this->set->non_zero2 > 0); + + /* Encode secret s1 */ + packer = bliss_bitpacker_create(s_bits * this->set->n); + for (i = 0; i < this->set->n; i++) + { + packer->write_bits(packer, this->s1[i], s_bits); + } + s1 = packer->extract_buf(packer); + packer->destroy(packer); + + /* Encode secret s2 */ + packer = bliss_bitpacker_create(s_bits * this->set->n); + for (i = 0; i < this->set->n; i++) + { + value = this->s2[i]; + if (i == 0) + { + value -= 1; + } + value /= 2; + packer->write_bits(packer, value, s_bits); + } + s2 = packer->extract_buf(packer); + packer->destroy(packer); + + *encoding = asn1_wrap(ASN1_SEQUENCE, "mmss", + asn1_build_known_oid(this->set->oid), + asn1_bitstring("m", pubkey), + asn1_bitstring("m", s1), + asn1_bitstring("m", s2) + ); + if (type == PRIVKEY_PEM) + { + chunk_t asn1_encoding = *encoding; + + success = lib->encoding->encode(lib->encoding, PRIVKEY_PEM, + NULL, encoding, CRED_PART_BLISS_PRIV_ASN1_DER, + asn1_encoding, CRED_PART_END); + chunk_clear(&asn1_encoding); + } + return success; + } + default: + return FALSE; + } +} + +METHOD(private_key_t, get_fingerprint, bool, + private_bliss_private_key_t *this, cred_encoding_type_t type, chunk_t *fp) +{ + bool success; + + if (lib->encoding->get_cache(lib->encoding, type, this, fp)) + { + return TRUE; + } + success = bliss_public_key_fingerprint(this->set->oid, this->A, + this->set, type, fp); + if (success) + { + lib->encoding->cache(lib->encoding, type, this, *fp); + } + return success; +} + +METHOD(private_key_t, get_ref, private_key_t*, + private_bliss_private_key_t *this) +{ + ref_get(&this->ref); + return &this->public.key; +} + +METHOD(private_key_t, destroy, void, + private_bliss_private_key_t *this) +{ + if (ref_put(&this->ref)) + { + lib->encoding->clear_cache(lib->encoding, this); + if (this->s1) + { + memwipe(this->s1, this->set->n * sizeof(int8_t)); + free(this->s1); + } + if (this->s2) + { + memwipe(this->s2, this->set->n * sizeof(int8_t)); + free(this->s2); + } + free(this->A); + free(this); + } +} + +/** + * Internal generic constructor + */ +static private_bliss_private_key_t *bliss_private_key_create_empty(void) +{ + private_bliss_private_key_t *this; + + INIT(this, + .public = { + .key = { + .get_type = _get_type, + .sign = _sign, + .decrypt = _decrypt, + .get_keysize = _get_keysize, + .get_public_key = _get_public_key, + .equals = private_key_equals, + .belongs_to = private_key_belongs_to, + .get_fingerprint = _get_fingerprint, + .has_fingerprint = private_key_has_fingerprint, + .get_encoding = _get_encoding, + .get_ref = _get_ref, + .destroy = _destroy, + }, + }, + .ref = 1, + ); + return this; +} + +/** + * Compute the scalar product of a vector x with a negative wrapped vector y + */ +static int16_t wrapped_product(int8_t *x, int8_t *y, int n, int shift) +{ + int16_t product = 0; + int i; + + for (i = 0; i < n - shift; i++) + { + product += x[i] * y[i + shift]; + } + for (i = n - shift; i < n; i++) + { + product -= x[i] * y[i + shift - n]; + } + return product; +} + +/** + * Apply a negative wrapped rotation to a vector x + */ +static void wrap(int16_t *x, int n, int shift, int16_t *x_wrapped) +{ + int i; + + for (i = 0; i < n - shift; i++) + { + x_wrapped[i + shift] = x[i]; + } + for (i = n - shift; i < n; i++) + { + x_wrapped[i + shift - n] = -x[i]; + } +} + +/** + * int16_t compare function needed for qsort() + */ +static int compare(const int16_t *a, const int16_t *b) +{ + int16_t temp = *a - *b; + + if (temp > 0) + { + return 1; + } + else if (temp < 0) + { + return -1; + } + else + { + return 0; + } +} + +/** + * Compute the Nk(S) norm of S = (s1, s2) + */ +static uint32_t nks_norm(int8_t *s1, int8_t *s2, int n, uint16_t kappa) +{ + int16_t t[n], t_wrapped[n], max_kappa[n]; + uint32_t nks = 0; + int i, j; + + for (i = 0; i < n; i++) + { + t[i] = wrapped_product(s1, s1, n, i) + wrapped_product(s2, s2, n, i); + } + + for (i = 0; i < n; i++) + { + wrap(t, n, i, t_wrapped); + qsort(t_wrapped, n, sizeof(int16_t), (__compar_fn_t)compare); + max_kappa[i] = 0; + + for (j = 1; j <= kappa; j++) + { + max_kappa[i] += t_wrapped[n - j]; + } + } + qsort(max_kappa, n, sizeof(int16_t), (__compar_fn_t)compare); + + for (i = 1; i <= kappa; i++) + { + nks += max_kappa[n - i]; + } + return nks; +} + +/** + * Compute the inverse x1 of x modulo q as x^(-1) = x^(q-2) mod q + */ +static uint32_t invert(uint32_t x, uint16_t q) +{ + uint32_t x1, x2; + uint16_t q2; + int i, i_max; + + q2 = q - 2; + x1 = (q2 & 1) ? x : 1; + x2 = x; + i_max = 15; + + while ((q2 & (1 << i_max)) == 0) + { + i_max--; + } + for (i = 1; i <= i_max; i++) + { + x2 = (x2 * x2) % q; + + if (q2 & (1 << i)) + { + x1 = (x1 * x2) % q; + } + } + + return x1; +} + +/** + * Create a vector with sparse and small coefficients from seed + */ +static int8_t* create_vector_from_seed(private_bliss_private_key_t *this, + hash_algorithm_t alg, chunk_t seed) +{ + mgf1_bitspender_t *bitspender; + uint32_t index, sign; + int8_t *vector; + int non_zero; + + bitspender = mgf1_bitspender_create(alg, seed, FALSE); + if (!bitspender) + { + return NULL; + } + + vector = malloc(sizeof(int8_t) * this->set->n); + memset(vector, 0x00, this->set->n); + + non_zero = this->set->non_zero1; + while (non_zero) + { + if (!bitspender->get_bits(bitspender, this->set->n_bits, &index)) + { + free(vector); + return NULL; + } + if (vector[index] != 0) + { + continue; + } + + if (!bitspender->get_bits(bitspender, 1, &sign)) + { + free(vector); + return NULL; + } + vector[index] = sign ? 1 : -1; + non_zero--; + } + + non_zero = this->set->non_zero2; + while (non_zero) + { + if (!bitspender->get_bits(bitspender, this->set->n_bits, &index)) + { + free(vector); + return NULL; + } + if (vector[index] != 0) + { + continue; + } + + if (!bitspender->get_bits(bitspender, 1, &sign)) + { + free(vector); + return NULL; + } + vector[index] = sign ? 2 : -2; + non_zero--; + } + bitspender->destroy(bitspender); + + return vector; +} + +/** + * Generate the secret key S = (s1, s2) fulfilling the Nk(S) norm + */ +static bool create_secret(private_bliss_private_key_t *this, rng_t *rng, + int8_t **s1, int8_t **s2, int *trials) +{ + uint8_t seed_buf[32]; + uint8_t *f, *g; + uint32_t l2_norm, nks; + int i, n; + chunk_t seed; + size_t seed_len; + hash_algorithm_t alg; + + n = this->set->n; + *s1 = NULL; + *s2 = NULL; + + /* Set MGF1 hash algorithm and seed length based on security strength */ + if (this->set->strength > 160) + { + alg = HASH_SHA256; + seed_len = HASH_SIZE_SHA256; + } + else + { + alg = HASH_SHA1; + seed_len = HASH_SIZE_SHA1; + } + seed = chunk_create(seed_buf, seed_len); + + while (*trials < SECRET_KEY_TRIALS_MAX) + { + (*trials)++; + + if (!rng->get_bytes(rng, seed_len, seed_buf)) + { + return FALSE; + } + f = create_vector_from_seed(this, alg, seed); + if (f == NULL) + { + return FALSE; + } + if (!rng->get_bytes(rng, seed_len, seed_buf)) + { + free(f); + return FALSE; + } + g = create_vector_from_seed(this, alg, seed); + if (g == NULL) + { + free(f); + return FALSE; + } + + /* Compute 2g + 1 */ + for (i = 0; i < n; i++) + { + g[i] *= 2; + } + g[0] += 1; + + l2_norm = wrapped_product(f, f, n, 0) + wrapped_product(g, g, n, 0); + nks = nks_norm(f, g, n, this->set->kappa); + + switch (this->set->id) + { + case BLISS_I: + case BLISS_II: + case BLISS_III: + case BLISS_IV: + DBG2(DBG_LIB, "l2 norm of s1||s2: %d, Nk(S): %u (%u max)", + l2_norm, nks, this->set->nks_max); + if (nks < this->set->nks_max) + { + *s1 = f; + *s2 = g; + return TRUE; + } + free(f); + free(g); + break; + case BLISS_B_I: + case BLISS_B_II: + case BLISS_B_III: + case BLISS_B_IV: + DBG2(DBG_LIB, "l2 norm of s1||s2: %d, Nk(S): %u", + l2_norm, nks); + *s1 = f; + *s2 = g; + return TRUE; + } + } + + return FALSE; +} + +/** + * See header. + */ +bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args) +{ + private_bliss_private_key_t *this; + u_int key_size = BLISS_B_I; + int i, n, trials = 0; + uint32_t *S1, *S2, *a; + uint16_t q; + bool success = FALSE; + bliss_param_set_t *set; + bliss_fft_t *fft; + rng_t *rng; + + while (TRUE) + { + switch (va_arg(args, builder_part_t)) + { + case BUILD_KEY_SIZE: + key_size = va_arg(args, u_int); + continue; + case BUILD_END: + break; + default: + return NULL; + } + break; + } + + if (lib->settings->get_bool(lib->settings, "%s.plugins.bliss.use_bliss_b", + TRUE, lib->ns)) + { + switch (key_size) + { + case BLISS_I: + key_size = BLISS_B_I; + break; + case BLISS_II: + key_size = BLISS_B_II; + break; + case BLISS_III: + key_size = BLISS_B_III; + break; + case BLISS_IV: + key_size = BLISS_B_IV; + break; + default: + break; + } + } + + /* Only BLISS or BLISS-B types I, III, or IV are currently supported */ + set = bliss_param_set_get_by_id(key_size); + if (!set) + { + DBG1(DBG_LIB, "BLISS parameter set %u not supported", key_size); + return NULL; + } + + /* Some shortcuts for often used variables */ + n = set->n; + q = set->q; + + if (set->fft_params->n != n || set->fft_params->q != q) + { + DBG1(DBG_LIB, "FFT parameters do not match BLISS parameters"); + return NULL; + } + this = bliss_private_key_create_empty(); + this->set = set; + + /* We derive the public key from the private key using the FFT */ + fft = bliss_fft_create(set->fft_params); + + /* Some vectors needed to derive the publi key */ + S1 = malloc(n * sizeof(uint32_t)); + S2 = malloc(n * sizeof(uint32_t)); + a = malloc(n * sizeof(uint32_t)); + this->A = malloc(n * sizeof(uint32_t)); + + /* Instantiate a true random generator */ + rng = lib->crypto->create_rng(lib->crypto, RNG_TRUE); + + /* Loop until we have an invertible polynomial s1 */ + do + { + if (!create_secret(this, rng, &this->s1, &this->s2, &trials)) + { + break; + } + + /* Convert signed arrays to unsigned arrays before FFT */ + for (i = 0; i < n; i++) + { + S1[i] = (this->s1[i] < 0) ? this->s1[i] + q : this->s1[i]; + S2[i] = (this->s2[i] > 0) ? q - this->s2[i] : -this->s2[i]; + } + fft->transform(fft, S1, S1, FALSE); + fft->transform(fft, S2, S2, FALSE); + + success = TRUE; + for (i = 0; i < n; i++) + { + if (S1[i] == 0) + { + DBG1(DBG_LIB, "S1[%d] is zero - s1 is not invertible", i); + free(this->s1); + free(this->s2); + this->s1 = NULL; + this->s2 = NULL; + success = FALSE; + break; + } + this->A[i] = invert(S1[i], q); + this->A[i] = (S2[i] * this->A[i]) % q; + } + } + while (!success && trials < SECRET_KEY_TRIALS_MAX); + + DBG1(DBG_LIB, "secret key generation %s after %d trial%s", + success ? "succeeded" : "failed", trials, (trials == 1) ? "" : "s"); + + if (success) + { + fft->transform(fft, this->A, a, TRUE); + + DBG4(DBG_LIB, " i f g a F G A"); + for (i = 0; i < n; i++) + { + DBG4(DBG_LIB, "%4d %3d %3d %5u %5u %5u %5u", + i, this->s1[i], this->s2[i], a[i], S1[i], S2[i], this->A[i]); + } + } + else + { + destroy(this); + } + + /* Cleanup */ + fft->destroy(fft); + rng->destroy(rng); + memwipe(S1, n * sizeof(uint32_t)); + memwipe(S2, n * sizeof(uint32_t)); + free(S1); + free(S2); + free(a); + + return success ? &this->public : NULL; +} + +/** + * ASN.1 definition of a BLISS private key + */ +static const asn1Object_t privkeyObjects[] = { + { 0, "BLISSPrivateKey", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ + { 1, "keyType", ASN1_OID, ASN1_BODY }, /* 1 */ + { 1, "public", ASN1_BIT_STRING, ASN1_BODY }, /* 2 */ + { 1, "secret1", ASN1_BIT_STRING, ASN1_BODY }, /* 3 */ + { 1, "secret2", ASN1_BIT_STRING, ASN1_BODY }, /* 4 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } +}; +#define PRIV_KEY_TYPE 1 +#define PRIV_KEY_PUBLIC 2 +#define PRIV_KEY_SECRET1 3 +#define PRIV_KEY_SECRET2 4 + +/** + * See header. + */ +bliss_private_key_t *bliss_private_key_load(key_type_t type, va_list args) +{ + private_bliss_private_key_t *this; + chunk_t key = chunk_empty, object; + bliss_bitpacker_t *packer; + asn1_parser_t *parser; + size_t s_bits = 0; + int8_t s, s_min = 0, s_max = 0; + uint32_t s_sign = 0x02, s_mask = 0xfffffffc, value; + bool success = FALSE; + int objectID, oid, i; + + while (TRUE) + { + switch (va_arg(args, builder_part_t)) + { + case BUILD_BLOB_ASN1_DER: + key = va_arg(args, chunk_t); + continue; + case BUILD_END: + break; + default: + return NULL; + } + break; + } + + if (key.len == 0) + { + return NULL; + } + this = bliss_private_key_create_empty(); + + parser = asn1_parser_create(privkeyObjects, key); + parser->set_flags(parser, FALSE, TRUE); + + while (parser->iterate(parser, &objectID, &object)) + { + switch (objectID) + { + case PRIV_KEY_TYPE: + oid = asn1_known_oid(object); + if (oid == OID_UNKNOWN) + { + goto end; + } + this->set = bliss_param_set_get_by_oid(oid); + if (this->set == NULL) + { + goto end; + } + if (lib->settings->get_bool(lib->settings, + "%s.plugins.bliss.use_bliss_b",TRUE, lib->ns)) + { + switch (this->set->id) + { + case BLISS_I: + this->set = bliss_param_set_get_by_id(BLISS_B_I); + break; + case BLISS_III: + this->set = bliss_param_set_get_by_id(BLISS_B_III); + break; + case BLISS_IV: + this->set = bliss_param_set_get_by_id(BLISS_B_IV); + break; + default: + break; + } + } + if (this->set->non_zero2) + { + s_min = -2; + s_max = 2; + s_bits = 3; + } + else + { + s_min = -1; + s_max = 1; + s_bits = 2; + } + s_sign = 1 << (s_bits - 1); + s_mask = ((1 << (32 - s_bits)) - 1) << s_bits; + break; + case PRIV_KEY_PUBLIC: + if (!bliss_public_key_from_asn1(object, this->set, &this->A)) + { + goto end; + } + break; + case PRIV_KEY_SECRET1: + if (object.len != 1 + (s_bits * this->set->n + 7)/8) + { + goto end; + } + this->s1 = malloc(this->set->n); + + /* Skip unused bits octet */ + object = chunk_skip(object, 1); + packer = bliss_bitpacker_create_from_data(object); + for (i = 0; i < this->set->n; i++) + { + packer->read_bits(packer, &value, s_bits); + s = (value & s_sign) ? value | s_mask : value; + if (s < s_min || s > s_max) + { + packer->destroy(packer); + goto end; + } + this->s1[i] = s; + } + packer->destroy(packer); + break; + case PRIV_KEY_SECRET2: + if (object.len != 1 + (s_bits * this->set->n + 7)/8) + { + goto end; + } + this->s2 = malloc(this->set->n); + + /* Skip unused bits octet */ + object = chunk_skip(object, 1); + packer = bliss_bitpacker_create_from_data(object); + for (i = 0; i < this->set->n; i++) + { + packer->read_bits(packer, &value, s_bits); + s = (value & s_sign) ? value | s_mask : value; + if (s < s_min || s > s_max) + { + packer->destroy(packer); + goto end; + } + this->s2[i] = 2 * s; + if (i == 0) + { + this->s2[0] += 1; + } + } + packer->destroy(packer); + break; + } + } + success = parser->success(parser); + +end: + parser->destroy(parser); + if (!success) + { + destroy(this); + return NULL; + } + + return &this->public; +} + diff --git a/src/libstrongswan/plugins/bliss/bliss_private_key.h b/src/libstrongswan/plugins/bliss/bliss_private_key.h new file mode 100644 index 000000000..cb4ff807a --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_private_key.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup bliss_private_key bliss_private_key + * @{ @ingroup bliss_p + */ + +#ifndef BLISS_PRIVATE_KEY_H_ +#define BLISS_PRIVATE_KEY_H_ + +#include <credentials/builder.h> +#include <credentials/keys/private_key.h> + +typedef struct bliss_private_key_t bliss_private_key_t; + +/** + * Private_key_t implementation of BLISS signature algorithm. + */ +struct bliss_private_key_t { + + /** + * Implements private_key_t interface + */ + private_key_t key; +}; + +/** + * Generate a BLISS private key. + * + * Accepts the BUILD_KEY_SIZE argument. + * + * @param type type of the key, must be KEY_BLISS + * @param args builder_part_t argument list + * @return generated key, NULL on failure + */ +bliss_private_key_t *bliss_private_key_gen(key_type_t type, va_list args); + +/** + * Load a BLISS private key. + * + * Accepts BUILD_BLISS_* components. + * + * @param type type of the key, must be KEY_BLISS + * @param args builder_part_t argument list + * @return loaded key, NULL on failure + */ +bliss_private_key_t *bliss_private_key_load(key_type_t type, va_list args); + +#endif /** BLISS_PRIVATE_KEY_H_ @}*/ diff --git a/src/libstrongswan/plugins/bliss/bliss_public_key.c b/src/libstrongswan/plugins/bliss/bliss_public_key.c new file mode 100644 index 000000000..0175b0f8e --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_public_key.c @@ -0,0 +1,515 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "bliss_public_key.h" +#include "bliss_signature.h" +#include "bliss_bitpacker.h" +#include "bliss_fft.h" +#include "bliss_utils.h" + +#include <asn1/asn1.h> +#include <asn1/asn1_parser.h> +#include <asn1/oid.h> + +typedef struct private_bliss_public_key_t private_bliss_public_key_t; + +/** + * Private data structure with signing context. + */ +struct private_bliss_public_key_t { + /** + * Public interface for this signer. + */ + bliss_public_key_t public; + + /** + * BLISS signature parameter set + */ + bliss_param_set_t *set; + + /** + * NTT of BLISS public key a (coefficients of polynomial (2g + 1)/f) + */ + uint32_t *A; + + /** + * reference counter + */ + refcount_t ref; +}; + +METHOD(public_key_t, get_type, key_type_t, + private_bliss_public_key_t *this) +{ + return KEY_BLISS; +} + +/** + * Verify a BLISS signature based on a SHA-512 hash + */ +static bool verify_bliss(private_bliss_public_key_t *this, hash_algorithm_t alg, + chunk_t data, chunk_t signature) +{ + int i, n; + int32_t *z1, *u; + int16_t *ud, *z2d; + uint16_t q, q2, p, *c_indices, *indices; + uint32_t *az; + uint8_t data_hash_buf[HASH_SIZE_SHA512]; + chunk_t data_hash; + hasher_t *hasher; + bliss_fft_t *fft; + bliss_signature_t *sig; + bool success = FALSE; + + /* Create data hash */ + hasher = lib->crypto->create_hasher(lib->crypto, alg); + if (!hasher ) + { + return FALSE; + } + data_hash = chunk_create(data_hash_buf, hasher->get_hash_size(hasher)); + + if (!hasher->get_hash(hasher, data, data_hash_buf)) + { + hasher->destroy(hasher); + return FALSE; + } + hasher->destroy(hasher); + + /* Create SHA512 hasher for c_indices oracle */ + hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA512); + if (!hasher) + { + return FALSE; + } + + sig = bliss_signature_create_from_data(this->set, signature); + if (!sig) + { + hasher->destroy(hasher); + return FALSE; + } + sig->get_parameters(sig, &z1, &z2d, &c_indices); + + if (!bliss_utils_check_norms(this->set, z1, z2d)) + { + hasher->destroy(hasher); + sig->destroy(sig); + return FALSE; + } + + /* Initialize a couple of needed variables */ + n = this->set->n; + q = this->set->q; + p = this->set->p; + q2 = 2 * q; + az = malloc(n * sizeof(uint32_t)); + u = malloc(n * sizeof(int32_t)); + ud = malloc(n * sizeof(int16_t)); + indices = malloc(this->set->kappa * sizeof(uint16_t)); + + for (i = 0; i < n; i++) + { + az[i] = z1[i] < 0 ? q + z1[i] : z1[i]; + } + fft = bliss_fft_create(this->set->fft_params); + fft->transform(fft, az, az, FALSE); + + for (i = 0; i < n; i++) + { + az[i] = (this->A[i] * az[i]) % q; + } + fft->transform(fft, az, az, TRUE); + + for (i = 0; i < n; i++) + { + u[i] = (2 * this->set->q2_inv * az[i]) % q2; + } + + for (i = 0; i < this->set->kappa; i++) + { + u[c_indices[i]] = (u[c_indices[i]] + q * this->set->q2_inv) % q2; + } + bliss_utils_round_and_drop(this->set, u, ud); + + for (i = 0; i < n; i++) + { + ud[i] += z2d[i]; + if (ud[i] < 0) + { + ud[i] += p; + } + else if (ud[i] >= p) + { + ud[i] -= p; + } + } + + /* Detailed debugging information */ + DBG3(DBG_LIB, " i u[i] ud[i] z2d[i]"); + for (i = 0; i < n; i++) + { + DBG3(DBG_LIB, "%3d %6d %4d %4d", i, u[i], ud[i], z2d[i]); + } + + if (!bliss_utils_generate_c(hasher, data_hash, ud, n, this->set->kappa, + indices)) + { + goto end; + } + + for (i = 0; i < this->set->kappa; i++) + { + if (indices[i] != c_indices[i]) + { + DBG1(DBG_LIB, "signature verification failed"); + goto end; + } + } + success = TRUE; + +end: + /* cleanup */ + hasher->destroy(hasher); + sig->destroy(sig); + fft->destroy(fft); + free(az); + free(u); + free(ud); + free(indices); + + return success; +} + +METHOD(public_key_t, verify, bool, + private_bliss_public_key_t *this, signature_scheme_t scheme, + chunk_t data, chunk_t signature) +{ + switch (scheme) + { + case SIGN_BLISS_WITH_SHA256: + return verify_bliss(this, HASH_SHA256, data, signature); + case SIGN_BLISS_WITH_SHA384: + return verify_bliss(this, HASH_SHA384, data, signature); + case SIGN_BLISS_WITH_SHA512: + return verify_bliss(this, HASH_SHA512, data, signature); + default: + DBG1(DBG_LIB, "signature scheme %N not supported by BLISS", + signature_scheme_names, scheme); + return FALSE; + } +} + +METHOD(public_key_t, encrypt_, bool, + private_bliss_public_key_t *this, encryption_scheme_t scheme, + chunk_t plain, chunk_t *crypto) +{ + DBG1(DBG_LIB, "encryption scheme %N not supported", + encryption_scheme_names, scheme); + return FALSE; +} + +METHOD(public_key_t, get_keysize, int, + private_bliss_public_key_t *this) +{ + return this->set->strength; +} + +METHOD(public_key_t, get_encoding, bool, + private_bliss_public_key_t *this, cred_encoding_type_t type, + chunk_t *encoding) +{ + bool success = TRUE; + + *encoding = bliss_public_key_info_encode(this->set->oid, this->A, this->set); + + if (type != PUBKEY_SPKI_ASN1_DER) + { + chunk_t asn1_encoding = *encoding; + + success = lib->encoding->encode(lib->encoding, type, + NULL, encoding, CRED_PART_BLISS_PUB_ASN1_DER, + asn1_encoding, CRED_PART_END); + chunk_clear(&asn1_encoding); + } + return success; +} + +METHOD(public_key_t, get_fingerprint, bool, + private_bliss_public_key_t *this, cred_encoding_type_t type, chunk_t *fp) +{ + bool success; + + if (lib->encoding->get_cache(lib->encoding, type, this, fp)) + { + return TRUE; + } + success = bliss_public_key_fingerprint(this->set->oid, this->A, + this->set, type, fp); + if (success) + { + lib->encoding->cache(lib->encoding, type, this, *fp); + } + return success; +} + +METHOD(public_key_t, get_ref, public_key_t*, + private_bliss_public_key_t *this) +{ + ref_get(&this->ref); + return &this->public.key; +} + +METHOD(public_key_t, destroy, void, + private_bliss_public_key_t *this) +{ + if (ref_put(&this->ref)) + { + lib->encoding->clear_cache(lib->encoding, this); + free(this->A); + free(this); + } +} + +/** + * ASN.1 definition of a BLISS public key + */ +static const asn1Object_t pubkeyObjects[] = { + { 0, "subjectPublicKeyInfo",ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */ + { 1, "algorithm", ASN1_EOC, ASN1_RAW }, /* 1 */ + { 1, "subjectPublicKey", ASN1_BIT_STRING, ASN1_BODY }, /* 2 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } +}; +#define BLISS_SUBJECT_PUBLIC_KEY_ALGORITHM 1 +#define BLISS_SUBJECT_PUBLIC_KEY 2 + +/** + * See header. + */ +bliss_public_key_t *bliss_public_key_load(key_type_t type, va_list args) +{ + private_bliss_public_key_t *this; + chunk_t blob = chunk_empty, object, param; + asn1_parser_t *parser; + bool success = FALSE; + int objectID, oid; + + while (TRUE) + { + switch (va_arg(args, builder_part_t)) + { + case BUILD_BLOB_ASN1_DER: + blob = va_arg(args, chunk_t); + continue; + case BUILD_END: + break; + default: + return NULL; + } + break; + } + + if (blob.len == 0) + { + return NULL; + } + + INIT(this, + .public = { + .key = { + .get_type = _get_type, + .verify = _verify, + .encrypt = _encrypt_, + .equals = public_key_equals, + .get_keysize = _get_keysize, + .get_fingerprint = _get_fingerprint, + .has_fingerprint = public_key_has_fingerprint, + .get_encoding = _get_encoding, + .get_ref = _get_ref, + .destroy = _destroy, + }, + }, + .ref = 1, + ); + + parser = asn1_parser_create(pubkeyObjects, blob); + + while (parser->iterate(parser, &objectID, &object)) + { + switch (objectID) + { + case BLISS_SUBJECT_PUBLIC_KEY_ALGORITHM: + { + oid = asn1_parse_algorithmIdentifier(object, + parser->get_level(parser)+1, ¶m); + if (oid != OID_BLISS_PUBLICKEY) + { + goto end; + } + if (!asn1_parse_simple_object(¶m, ASN1_OID, + parser->get_level(parser)+3, "blissKeyType")) + { + goto end; + } + oid = asn1_known_oid(param); + if (oid == OID_UNKNOWN) + { + goto end; + } + this->set = bliss_param_set_get_by_oid(oid); + if (this->set == NULL) + { + goto end; + } + break; + } + case BLISS_SUBJECT_PUBLIC_KEY: + if (!bliss_public_key_from_asn1(object, this->set, &this->A)) + { + goto end; + } + break; + } + } + success = parser->success(parser); + +end: + parser->destroy(parser); + if (!success) + { + destroy(this); + return NULL; + } + + return &this->public; +} + +/** + * See header. + */ +bool bliss_public_key_from_asn1(chunk_t object, bliss_param_set_t *set, + uint32_t **pubkey) +{ + bliss_bitpacker_t *packer; + uint32_t coefficient; + uint16_t needed_bits; + int i; + + /* skip initial bit string octet defining unused bits */ + object = chunk_skip(object, 1); + + needed_bits = set->n * set->q_bits; + + if (8 * object.len < needed_bits) + { + return FALSE; + } + *pubkey = malloc(set->n * sizeof(uint32_t)); + + packer = bliss_bitpacker_create_from_data(object); + + for (i = 0; i < set->n; i++) + { + packer->read_bits(packer, &coefficient, set->q_bits); + if (coefficient >= set->q) + { + packer->destroy(packer); + return FALSE; + } + (*pubkey)[i] = coefficient; + } + packer->destroy(packer); + + return TRUE; +} + +/** + * See header. + */ +chunk_t bliss_public_key_encode(uint32_t *pubkey, bliss_param_set_t *set) +{ + bliss_bitpacker_t *packer; + chunk_t encoding; + int i; + + packer = bliss_bitpacker_create(set->n * set->q_bits); + + for (i = 0; i < set->n; i++) + { + packer->write_bits(packer, pubkey[i], set->q_bits); + } + encoding = packer->extract_buf(packer); + packer->destroy(packer); + + return encoding; +} + +/** + * See header. + */ +chunk_t bliss_public_key_info_encode(int oid, uint32_t *pubkey, + bliss_param_set_t *set) +{ + chunk_t encoding, pubkey_encoding; + + pubkey_encoding = bliss_public_key_encode(pubkey, set); + + encoding = asn1_wrap(ASN1_SEQUENCE, "mm", + asn1_wrap(ASN1_SEQUENCE, "mm", + asn1_build_known_oid(OID_BLISS_PUBLICKEY), + asn1_build_known_oid(oid)), + asn1_bitstring("m", pubkey_encoding)); + + return encoding; +} + +/** + * See header. + */ +bool bliss_public_key_fingerprint(int oid, uint32_t *pubkey, + bliss_param_set_t *set, + cred_encoding_type_t type, chunk_t *fp) +{ + hasher_t *hasher; + chunk_t key; + + switch (type) + { + case KEYID_PUBKEY_SHA1: + key = bliss_public_key_encode(pubkey, set); + break; + case KEYID_PUBKEY_INFO_SHA1: + key = bliss_public_key_info_encode(oid, pubkey, set); + break; + default: + return FALSE; + } + + hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); + if (!hasher || !hasher->allocate_hash(hasher, key, fp)) + { + DBG1(DBG_LIB, "SHA1 hash algorithm not supported, fingerprinting failed"); + DESTROY_IF(hasher); + free(key.ptr); + + return FALSE; + } + hasher->destroy(hasher); + free(key.ptr); + + return TRUE; +} + diff --git a/src/libstrongswan/plugins/bliss/bliss_public_key.h b/src/libstrongswan/plugins/bliss/bliss_public_key.h new file mode 100644 index 000000000..cd8f231b2 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_public_key.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup bliss_public_key bliss_public_key + * @{ @ingroup bliss_p + */ + +#ifndef BLISS_PUBLIC_KEY_H_ +#define BLISS_PUBLIC_KEY_H_ + +#include "bliss_param_set.h" + +#include <credentials/builder.h> +#include <credentials/cred_encoding.h> +#include <credentials/keys/public_key.h> + +typedef struct bliss_public_key_t bliss_public_key_t; + +/** + * public_key_t implementation of BLISS signature algorithm + */ +struct bliss_public_key_t { + + /** + * Implements the public_key_t interface + */ + public_key_t key; +}; + +/** + * Load a BLISS public key. + * + * Accepts BUILD_BLISS_* components. + * + * @param type type of the key, must be KEY_BLISS + * @param args builder_part_t argument list + * @return loaded key, NULL on failure + */ +bliss_public_key_t *bliss_public_key_load(key_type_t type, va_list args); + +/* The following functions are shared with the bliss_private_key class */ + +/** + * Parse an ASN.1 BIT STRING into an array of public key coefficients + * + * @param object packed subjectPublicKey + * @param set BLISS parameter set for public key vector + * @param pubkey coefficients of public key vector + * @return TRUE if parsing successful + */ +bool bliss_public_key_from_asn1(chunk_t object, bliss_param_set_t *set, + uint32_t **pubkey); + +/** + * Encode a raw BLISS subjectPublicKey in ASN.1 DER format + * + * @param pubkey coefficients of public key vector + * @param set BLISS parameter set for the public key vector + * @result ASN.1 encoded subjectPublicKey + */ +chunk_t bliss_public_key_encode(uint32_t *pubkey, bliss_param_set_t *set); + +/** + * Encode a BLISS subjectPublicKeyInfo record in ASN.1 DER format + * + * @param oid BLISS public key type OID + * @param pubkey coefficients of public key vector + * @param set BLISS parameter set for the public key vector + * @result ASN.1 encoded subjectPublicKeyInfo record + */ +chunk_t bliss_public_key_info_encode(int oid, uint32_t *pubkey, + bliss_param_set_t *set); + +/** + * Generate a BLISS public key fingerprint + * + * @param oid BLISS public key type OID + * @param pubkey coefficients of public key vector + * @param set BLISS parameter set for the public key vector + * @param type type of fingerprint to be generated + * @param fp generated fingerprint (must be freed by caller) + * @result TRUE if generation was successful + */ +bool bliss_public_key_fingerprint(int oid, uint32_t *pubkey, + bliss_param_set_t *set, + cred_encoding_type_t type, chunk_t *fp); + +#endif /** BLISS_PUBLIC_KEY_H_ @}*/ diff --git a/src/libstrongswan/plugins/bliss/bliss_sampler.c b/src/libstrongswan/plugins/bliss/bliss_sampler.c new file mode 100644 index 000000000..fa45a2fac --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_sampler.c @@ -0,0 +1,250 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "bliss_sampler.h" + +typedef struct private_bliss_sampler_t private_bliss_sampler_t; + +#include <crypto/mgf1/mgf1_bitspender.h> + +/** + * Private data of a bliss_sampler_t object. + */ +struct private_bliss_sampler_t { + + /** + * Public interface. + */ + bliss_sampler_t public; + + /** + * BLISS parameter the rejection sampling is to be based on + */ + bliss_param_set_t *set; + + /** + * Bitspender used for random rejection sampling + */ + mgf1_bitspender_t *bitspender; + +}; + +METHOD(bliss_sampler_t, bernoulli_exp, bool, + private_bliss_sampler_t *this, uint32_t x, bool *accepted) +{ + uint32_t x_mask; + uint8_t *c, u; + int i; + + x_mask = 1 << (this->set->c_rows - 1); + c = this->set->c; + c += (this->set->c_rows - 1) * this->set->c_cols; + + while (x_mask > 0) + { + if (x & x_mask) + { + for (i = 0; i < this->set->c_cols; i++) + { + if (!this->bitspender->get_byte(this->bitspender, &u)) + { + return FALSE; + } + if (u < c[i]) + { + break; + } + else if (u > c[i]) + { + *accepted = FALSE; + return TRUE; + } + } + } + x_mask >>= 1; + c -= this->set->c_cols; + } + + *accepted = TRUE; + return TRUE; +} + +METHOD(bliss_sampler_t, bernoulli_cosh, bool, + private_bliss_sampler_t *this, int32_t x, bool *accepted) +{ + uint32_t u; + + x = 2 * (x < 0 ? -x : x); + + while (TRUE) + { + if (!bernoulli_exp(this, x, accepted)) + { + return FALSE; + } + if (*accepted) + { + return TRUE; + } + if (!this->bitspender->get_bits(this->bitspender, 1, &u)) + { + return FALSE; + } + if (u) + { + continue; + } + if (!bernoulli_exp(this, x, accepted)) + { + return FALSE; + } + if (!(*accepted)) + { + return TRUE; + } + } +} + +#define MAX_SAMPLE_INDEX 16 + +METHOD(bliss_sampler_t, pos_binary, bool, + private_bliss_sampler_t *this, uint32_t *x) +{ + uint32_t u, i; + + while (TRUE) + { + for (i = 0; i <= MAX_SAMPLE_INDEX; i++) + { + if (!this->bitspender->get_bits(this->bitspender, + i ? (2*i - 1) : 1, &u)) + { + return FALSE; + } + if (u == 0) + { + *x = i; + return TRUE; + } + if ((u >> 1) != 0) + { + break; + } + } + if (i > MAX_SAMPLE_INDEX) + { + return FALSE; + } + } +} + +METHOD(bliss_sampler_t, gaussian, bool, + private_bliss_sampler_t *this, int32_t *z) +{ + uint32_t u, x, y, z_pos; + bool accepted; + + while (TRUE) + { + if (!pos_binary(this, &x)) + { + return FALSE; + } + + do + { + if (!this->bitspender->get_bits(this->bitspender, + this->set->k_sigma_bits, &y)) + { + return FALSE; + } + } + while (y >= this->set->k_sigma); + + if (!bernoulli_exp(this, y * (y + 2*this->set->k_sigma * x), &accepted)) + { + return FALSE; + } + if (accepted) + { + if (!this->bitspender->get_bits(this->bitspender, 1, &u)) + { + return FALSE; + } + if (x || y || u) + { + break; + } + } + } + + z_pos = this->set->k_sigma * x + y; + *z = u ? z_pos : -z_pos; + + return TRUE; +} + +METHOD(bliss_sampler_t, sign, bool, + private_bliss_sampler_t *this, bool *positive) +{ + uint32_t u; + + if (!this->bitspender->get_bits(this->bitspender, 1, &u)) + { + return FALSE; + } + *positive = u; + + return TRUE; +} + +METHOD(bliss_sampler_t, destroy, void, + private_bliss_sampler_t *this) +{ + this->bitspender->destroy(this->bitspender); + free(this); +} + + +/** + * See header. + */ +bliss_sampler_t *bliss_sampler_create(hash_algorithm_t alg, chunk_t seed, + bliss_param_set_t *set) +{ + private_bliss_sampler_t *this; + mgf1_bitspender_t *bitspender; + + bitspender = mgf1_bitspender_create(alg, seed, FALSE); + if (!bitspender) + { + return NULL; + } + + INIT(this, + .public = { + .bernoulli_exp = _bernoulli_exp, + .bernoulli_cosh = _bernoulli_cosh, + .pos_binary = _pos_binary, + .gaussian = _gaussian, + .sign = _sign, + .destroy = _destroy, + }, + .set = set, + .bitspender = bitspender, + ); + + return &this->public; +} diff --git a/src/libstrongswan/plugins/bliss/bliss_sampler.h b/src/libstrongswan/plugins/bliss/bliss_sampler.h new file mode 100644 index 000000000..2c75d4480 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_sampler.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup bliss_sampler bliss_sampler + * @{ @ingroup bliss_p + */ + +#ifndef BLISS_SAMPLER_H_ +#define BLISS_SAMPLER_H_ + +typedef struct bliss_sampler_t bliss_sampler_t; + +#include "bliss_param_set.h" + +#include <library.h> +#include <crypto/hashers/hasher.h> + +/** + * Implementation various rejection sampling algorithms. + */ +struct bliss_sampler_t { + + /** + * Sample according to exp(-x/(2*sigma^2)) + * + * @param x Value to be sampled + * @param accepted TRUE if value is accepted, FALSE if rejected + * @result TRUE if sampling was successful + */ + bool (*bernoulli_exp)(bliss_sampler_t *this, uint32_t x, bool *accepted); + + /** + * Sample according to 1/cosh(x/sigma^2) + * + * @param x Value to be sampled + * @param accepted TRUE if value is accepted, FALSE if rejected + * @result TRUE if sampling was successful + */ + bool (*bernoulli_cosh)(bliss_sampler_t *this, int32_t x, bool *accepted); + + /** + * Sample according to 2^(-x^2) for positive x + * + * @param x Generated value + * @result TRUE if sampling was successful + */ + bool (*pos_binary)(bliss_sampler_t *this, uint32_t *x); + + /** + * Sample according to the Gaussian distribution exp(-x^2/(2*sigma^2)) + * + * @param z Generated value with Gaussian distribution + * @result TRUE if sampling was successful + */ + bool (*gaussian)(bliss_sampler_t *this, int32_t *z); + + /** + * Sample the sign according to the binary distribution + * + * @param positive TRUE if positive + * @result TRUE if sampling was successful + */ + bool (*sign)(bliss_sampler_t *this, bool *positive); + + /** + * Destroy bliss_sampler_t object + */ + void (*destroy)(bliss_sampler_t *this); +}; + +/** + * Create a bliss_sampler_t object. + * + * @param alg Hash algorithm to be used for the internal bitspender + * @param seed Seed used to initialize the internal bitspender + * @param set BLISS parameter set to be used + */ +bliss_sampler_t *bliss_sampler_create(hash_algorithm_t alg, chunk_t seed, + bliss_param_set_t *set); + +#endif /** BLISS_SAMPLER_H_ @}*/ diff --git a/src/libstrongswan/plugins/bliss/bliss_signature.c b/src/libstrongswan/plugins/bliss/bliss_signature.c new file mode 100644 index 000000000..e603da399 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_signature.c @@ -0,0 +1,233 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "bliss_signature.h" +#include "bliss_bitpacker.h" +#include "bliss_huffman_coder.h" + + +typedef struct private_bliss_signature_t private_bliss_signature_t; + +/** + * Private data of a bliss_signature_t object. + */ +struct private_bliss_signature_t { + /** + * Public interface for this signer. + */ + bliss_signature_t public; + + /** + * BLISS signature parameter set + */ + bliss_param_set_t *set; + + /** + * BLISS signature vector z1 of size n + */ + int32_t *z1; + + /** + * BLISS signature vector z2d of size n + */ + int16_t *z2d; + + /** + * Indices of sparse BLISS challenge vector c of size kappa + */ + uint16_t *c_indices; + +}; + +METHOD(bliss_signature_t, get_encoding, chunk_t, + private_bliss_signature_t *this) +{ + bliss_bitpacker_t *packer; + bliss_huffman_coder_t *coder; + bliss_huffman_code_t *code; + int32_t z1; + uint32_t z1_sign; + uint16_t z2d_bits; + chunk_t encoding = chunk_empty; + int i; + + z2d_bits = this->set->z1_bits - this->set->d; + + /* Get Huffman code for this BLISS parameter set */ + code = bliss_huffman_code_get_by_id(this->set->id); + if (!code) + { + DBG1(DBG_LIB, "no Huffman code found for parameter set %N", + bliss_param_set_id_names, this->set->id); + return chunk_empty; + } + + packer = bliss_bitpacker_create(this->set->n * this->set->z1_bits + + this->set->n * z2d_bits + + this->set->kappa * this->set->n_bits); + coder = bliss_huffman_coder_create(code, packer); + + for (i = 0; i < this->set->n; i++) + { + /* determine and remove the sign of z1[i]*/ + z1_sign = this->z1[i] < 0; + z1 = z1_sign ? -this->z1[i] : this->z1[i]; + + if (!packer->write_bits(packer, z1_sign, 1) || + !packer->write_bits(packer, z1 & 0xff, 8) || + !coder->encode(coder, z1 >> 8, this->z2d[i])) + { + goto end; + } + } + for (i = 0; i < this->set->kappa; i++) + { + if (!packer->write_bits(packer, this->c_indices[i], this->set->n_bits)) + { + goto end; + } + } + encoding = packer->extract_buf(packer); + + DBG2(DBG_LIB, "efficiency of Huffman coder is %6.4f bits/tuple (%u bits)", + coder->get_bits(coder)/(double)(this->set->n), + coder->get_bits(coder)); + DBG2(DBG_LIB, "generated BLISS signature (%u bits encoded in %u bytes)", + packer->get_bits(packer), encoding.len); + + end: + coder->destroy(coder); + packer->destroy(packer); + return encoding; +} + +METHOD(bliss_signature_t, get_parameters, void, + private_bliss_signature_t *this, int32_t **z1, int16_t **z2d, + uint16_t **c_indices) +{ + *z1 = this->z1; + *z2d = this->z2d; + *c_indices = this->c_indices; +} + +METHOD(bliss_signature_t, destroy, void, + private_bliss_signature_t *this) +{ + free(this->z1); + free(this->z2d); + free(this->c_indices); + free(this); +} + +/** + * See header. + */ +bliss_signature_t *bliss_signature_create(bliss_param_set_t *set) +{ + private_bliss_signature_t *this; + + INIT(this, + .public = { + .get_encoding = _get_encoding, + .get_parameters = _get_parameters, + .destroy = _destroy, + }, + .set = set, + .z1 = malloc(set->n * sizeof(int32_t)), + .z2d = malloc(set->n * sizeof(int16_t)), + .c_indices = malloc(set->n * sizeof(uint16_t)), + ); + + return &this->public; +} + +/** + * See header. + */ +bliss_signature_t *bliss_signature_create_from_data(bliss_param_set_t *set, + chunk_t encoding) +{ + private_bliss_signature_t *this; + bliss_bitpacker_t *packer; + bliss_huffman_coder_t *coder; + bliss_huffman_code_t *code; + uint32_t z1_sign, z1_low, value; + int32_t z1; + int16_t z2; + int i; + + /* Get Huffman code for this BLISS parameter set */ + code = bliss_huffman_code_get_by_id(set->id); + if (!code) + { + DBG1(DBG_LIB, "no Huffman code found for parameter set %N", + bliss_param_set_id_names, set->id); + return NULL; + } + + if (encoding.len == 0) + { + DBG1(DBG_LIB, "zero length BLISS signature"); + return NULL; + } + + INIT(this, + .public = { + .get_encoding = _get_encoding, + .get_parameters = _get_parameters, + .destroy = _destroy, + }, + .set = set, + .z1 = malloc(set->n * sizeof(int32_t)), + .z2d = malloc(set->n * sizeof(int16_t)), + .c_indices = malloc(set->n * sizeof(uint16_t)), + ); + + packer = bliss_bitpacker_create_from_data(encoding); + coder = bliss_huffman_coder_create(code, packer); + + for (i = 0; i < set->n; i++) + { + if (!packer->read_bits(packer, &z1_sign, 1) || + !packer->read_bits(packer, &z1_low, 8) || + !coder->decode(coder, &z1, &z2)) + { + DBG1(DBG_LIB, "truncated BLISS signature encoding of z1/z2"); + coder->destroy(coder); + packer->destroy(packer); + destroy(this); + return NULL; + } + z1 = (z1 << 8) + z1_low; + this->z1[i] = z1_sign ? -z1 : z1; + this->z2d[i] = z2; + } + coder->destroy(coder); + + for (i = 0; i < set->kappa; i++) + { + if (!packer->read_bits(packer, &value, set->n_bits)) + { + DBG1(DBG_LIB, "truncated BLISS signature encoding of c_indices"); + packer->destroy(packer); + destroy(this); + return NULL; + } + this->c_indices[i] = value; + } + packer->destroy(packer); + + return &this->public; +} diff --git a/src/libstrongswan/plugins/bliss/bliss_signature.h b/src/libstrongswan/plugins/bliss/bliss_signature.h new file mode 100644 index 000000000..d37f5398b --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_signature.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup bliss_signature bliss_signature + * @{ @ingroup bliss_p + */ + +#ifndef BLISS_SIGNATURE_H_ +#define BLISS_SIGNATURE_H_ + +typedef struct bliss_signature_t bliss_signature_t; + +#include "bliss_param_set.h" + +#include <library.h> + +/** + * Public interface of BLISS signature object + */ +struct bliss_signature_t { + + /** + * Get compressed binary encoding of BLISS signature + * + * @result binary encoding of BLISS signature + */ + chunk_t (*get_encoding)(bliss_signature_t *this); + + /** + * Get signature parameters extracted from compressd binary encoding + * + * @param z1 signature vector z1 of size n + * @param z2d signature vector z2d of size n + * @param c_indices indices of sparse binary challenge vector of size kappa + */ + void (*get_parameters)(bliss_signature_t *this, int32_t **z1, int16_t **z2d, + uint16_t **c_indices); + + /** + * Destroy bliss_signature_t object + */ + void (*destroy)(bliss_signature_t *this); + +}; + +/** + * Create a BLISS signature object. + * + * @param set BLISS parameter set + */ +bliss_signature_t *bliss_signature_create(bliss_param_set_t *set); + +/** + * Create a BLISS signature object from encoding. + * + * @param set BLISS parameter set + * @param encoding binary signature encoding + */ +bliss_signature_t *bliss_signature_create_from_data(bliss_param_set_t *set, + chunk_t encoding); + +#endif /** BLISS_SIGNATURE_H_ @}*/ diff --git a/src/libstrongswan/plugins/bliss/bliss_utils.c b/src/libstrongswan/plugins/bliss/bliss_utils.c new file mode 100644 index 000000000..5a069989c --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_utils.c @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "bliss_utils.h" + +#include <asn1/asn1.h> +#include <crypto/hashers/hasher.h> +#include <utils/debug.h> + +/** + * See header. + */ +int32_t bliss_utils_scalar_product(int32_t *x, int32_t *y, int n) +{ + int32_t product = 0; + int i; + + for (i = 0; i < n; i++) + { + product += x[i] * y[i]; + } + + return product; +} + +/** + * See header. + */ +void bliss_utils_round_and_drop(bliss_param_set_t *set, int32_t *x, int16_t *xd) +{ + int32_t factor; + int i; + + factor = 1 << set->d; + + for (i = 0; i < set->n; i++) + { + xd[i] = ((x[i] + (factor >> 1)) / factor) % set->p; + } +} + +/** + * See header. + */ +bool bliss_utils_generate_c(hasher_t *hasher, chunk_t data_hash, uint16_t *ud, + int n, uint16_t kappa, uint16_t *c_indices) +{ + int i, j; + uint64_t extra_bits; + uint16_t index, rounds = 0; + uint8_t hash[HASH_SIZE_SHA512], un16_buf[2]; + chunk_t un16 = { un16_buf, 2 }; + bool index_taken[n]; + + while (TRUE) + { + if (!hasher->get_hash(hasher, data_hash, NULL)) + { + return FALSE; + } + + for (i = 0; i < n; i++) + { + htoun16(un16_buf, ud[i]); + if (!hasher->get_hash(hasher, un16, NULL)) + { + return FALSE; + } + index_taken[i] = FALSE; + } + + htoun16(un16_buf, rounds++); + if (!hasher->get_hash(hasher, un16, hash)) + { + return FALSE; + } + + extra_bits = untoh64(hash + sizeof(hash) - sizeof(uint64_t)); + + for (i = 0, j = 0; j < sizeof(hash); j++) + { + index = 2 * (uint16_t)hash[i] + (extra_bits & 1); + if (!index_taken[index]) + { + c_indices[i++] = index; + index_taken[index] = TRUE; + } + if (i == kappa) + { + return TRUE; + } + } + } +} + +/** + * See header. + */ +bool bliss_utils_check_norms(bliss_param_set_t *set, int32_t *z1, int16_t *z2d) +{ + int32_t z2ds[set->n]; + int32_t z1_min, z1_max, norm; + int16_t z2d_min, z2d_max; + int i; + + /* some statistics on the values of z1 and z2d */ + z1_min = z1_max = z1[0]; + z2d_min = z2d_max = z2d[0]; + + for (i = 1; i < set->n; i++) + { + if (z1[i] < z1_min) + { + z1_min = z1[i]; + } + else if (z1[i] > z1_max) + { + z1_max = z1[i]; + } + if (z2d[i] < z2d_min) + { + z2d_min = z2d[i]; + } + else if (z2d[i] > z2d_max) + { + z2d_max = z2d[i]; + } + } + DBG2(DBG_LIB, "z1 = %d..%d, z2d = %d..%d", z1_min, z1_max, z2d_min, z2d_max); + + /* Restriction on infinite norm */ + for (i = 0; i < set->n; i++) + { + z2ds[i] = (1 << set->d) * z2d[i]; + + if (z1[i] >= set->B_inf || z2ds[i] >= set->B_inf || + z1[i] <= -set->B_inf || z2ds[i] <= -set->B_inf) + { + DBG2(DBG_LIB, "signature rejected due to excessive infinite norm"); + return FALSE; + } + } + + /* Restriction on l2-norm */ + norm = bliss_utils_scalar_product(z1, z1, set->n) + + bliss_utils_scalar_product(z2ds, z2ds, set->n); + + if (norm >= set->B_l2) + { + DBG2(DBG_LIB, "signature rejected due to excessive l2-norm"); + return FALSE; + } + + return TRUE; +} diff --git a/src/libstrongswan/plugins/bliss/bliss_utils.h b/src/libstrongswan/plugins/bliss/bliss_utils.h new file mode 100644 index 000000000..063fd91c8 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/bliss_utils.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup bliss_utils bliss_utils + * @{ @ingroup bliss_p + */ + +#ifndef BLISS_UTILS_H_ +#define BLISS_UTILS_H_ + +#include "bliss_param_set.h" + +#include <library.h> + +/** + * Compute the scalar product of two vectors of size n + * + * @param x input vector of size n + * @param y input vector of size n + * @param n size of input vectors x and y + * @result scalar product of x and y + */ +int32_t bliss_utils_scalar_product(int32_t *x, int32_t *y, int n); + +/** + * Drop d bits but round first + * + * @param set BLISS parameter set + * @param x input vector x of size n + * @param xd rounded vector x with d bits dropped + */ +void bliss_utils_round_and_drop(bliss_param_set_t *set, int32_t *x, int16_t *xd); + +/** + * Generate the binary challenge vector c as an array of kappa indices + * + * @param hasher hasher used as an oracle + * @param data_hash hash of the data to be signed + * @param ud input vector ud of size n + * @param n size of input vector ud + * @param kappa parameter kappa + * @param c_indices indexes of non-zero challenge coefficients + */ +bool bliss_utils_generate_c(hasher_t *hasher, chunk_t data_hash, uint16_t *ud, + int n, uint16_t kappa, uint16_t *c_indices); + +/** + * Check the infinity and l2 norms of the vectors z1 and z2d << d + * + * @param set BLISS parameter set + * @param z1 input vector + * @param z2d input vector + * @result TRUE if infinite and l2 norms do not exceed boundaries + */ +bool bliss_utils_check_norms(bliss_param_set_t *set, int32_t *z1, int16_t *z2d); + +#endif /** BLISS_UTILS_H_ @}*/ diff --git a/src/libstrongswan/plugins/bliss/tests/Makefile.am b/src/libstrongswan/plugins/bliss/tests/Makefile.am new file mode 100644 index 000000000..bd87753f5 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/tests/Makefile.am @@ -0,0 +1,27 @@ +TESTS = bliss_tests + +check_PROGRAMS = $(TESTS) + +bliss_tests_SOURCES = \ + suites/test_bliss_fft.c \ + suites/test_bliss_bitpacker.c \ + suites/test_bliss_huffman.c \ + suites/test_bliss_keys.c \ + suites/test_bliss_sampler.c \ + suites/test_bliss_signature.c \ + suites/test_bliss_sign.c \ + bliss_tests.h bliss_tests.c + +bliss_tests_CFLAGS = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libstrongswan/tests \ + -I$(top_srcdir)/src/libstrongswan/plugins/bliss \ + -DPLUGINDIR=\""$(abs_top_builddir)/src/libstrongswan/plugins\"" \ + -DPLUGINS=\""${s_plugins}\"" \ + @COVERAGE_CFLAGS@ + +bliss_tests_LDFLAGS = @COVERAGE_LDFLAGS@ +bliss_tests_LDADD = \ + $(top_builddir)/src/libstrongswan/libstrongswan.la \ + $(top_builddir)/src/libstrongswan/tests/libtest.la \ + ../libbliss.la diff --git a/src/libstrongswan/plugins/bliss/tests/Makefile.in b/src/libstrongswan/plugins/bliss/tests/Makefile.in new file mode 100644 index 000000000..5a1ce3d50 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/tests/Makefile.in @@ -0,0 +1,985 @@ +# Makefile.in generated by automake 1.14.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +TESTS = bliss_tests$(EXEEXT) +check_PROGRAMS = $(am__EXEEXT_1) +subdir = src/libstrongswan/plugins/bliss/tests +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ + $(top_srcdir)/m4/config/ltoptions.m4 \ + $(top_srcdir)/m4/config/ltsugar.m4 \ + $(top_srcdir)/m4/config/ltversion.m4 \ + $(top_srcdir)/m4/config/lt~obsolete.m4 \ + $(top_srcdir)/m4/macros/split-package-version.m4 \ + $(top_srcdir)/m4/macros/with.m4 \ + $(top_srcdir)/m4/macros/enable-disable.m4 \ + $(top_srcdir)/m4/macros/add-plugin.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__EXEEXT_1 = bliss_tests$(EXEEXT) +am__dirstamp = $(am__leading_dot)dirstamp +am_bliss_tests_OBJECTS = suites/bliss_tests-test_bliss_fft.$(OBJEXT) \ + suites/bliss_tests-test_bliss_bitpacker.$(OBJEXT) \ + suites/bliss_tests-test_bliss_huffman.$(OBJEXT) \ + suites/bliss_tests-test_bliss_keys.$(OBJEXT) \ + suites/bliss_tests-test_bliss_sampler.$(OBJEXT) \ + suites/bliss_tests-test_bliss_signature.$(OBJEXT) \ + suites/bliss_tests-test_bliss_sign.$(OBJEXT) \ + bliss_tests-bliss_tests.$(OBJEXT) +bliss_tests_OBJECTS = $(am_bliss_tests_OBJECTS) +bliss_tests_DEPENDENCIES = \ + $(top_builddir)/src/libstrongswan/libstrongswan.la \ + $(top_builddir)/src/libstrongswan/tests/libtest.la \ + ../libbliss.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +bliss_tests_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(bliss_tests_CFLAGS) \ + $(CFLAGS) $(bliss_tests_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(bliss_tests_SOURCES) +DIST_SOURCES = $(bliss_tests_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red='[0;31m'; \ + grn='[0;32m'; \ + lgn='[1;32m'; \ + blu='[1;34m'; \ + mgn='[0;35m'; \ + brg='[1m'; \ + std='[m'; \ + fi; \ +} +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BFDLIB = @BFDLIB@ +BTLIB = @BTLIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +COVERAGE_CFLAGS = @COVERAGE_CFLAGS@ +COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLIB = @DLLIB@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GEM = @GEM@ +GENHTML = @GENHTML@ +GPERF = @GPERF@ +GPRBUILD = @GPRBUILD@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQLCFLAG = @MYSQLCFLAG@ +MYSQLCONFIG = @MYSQLCONFIG@ +MYSQLLIB = @MYSQLLIB@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_LIB = @OPENSSL_LIB@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@ +PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@ +PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@ +PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ +PTHREADLIB = @PTHREADLIB@ +PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ +RANLIB = @RANLIB@ +RTLIB = @RTLIB@ +RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ +RUBYINCLUDE = @RUBYINCLUDE@ +RUBYLIB = @RUBYLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ +STRIP = @STRIP@ +UNWINDLIB = @UNWINDLIB@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +aikgen_plugins = @aikgen_plugins@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ +clearsilver_LIBS = @clearsilver_LIBS@ +cmd_plugins = @cmd_plugins@ +datadir = @datadir@ +datarootdir = @datarootdir@ +dbusservicedir = @dbusservicedir@ +dev_headers = @dev_headers@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +fips_mode = @fips_mode@ +gtk_CFLAGS = @gtk_CFLAGS@ +gtk_LIBS = @gtk_LIBS@ +h_plugins = @h_plugins@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +imcvdir = @imcvdir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ +ipsecdir = @ipsecdir@ +ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ +ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ +linux_headers = @linux_headers@ +localedir = @localedir@ +localstatedir = @localstatedir@ +maemo_CFLAGS = @maemo_CFLAGS@ +maemo_LIBS = @maemo_LIBS@ +manager_plugins = @manager_plugins@ +mandir = @mandir@ +medsrv_plugins = @medsrv_plugins@ +mkdir_p = @mkdir_p@ +nm_CFLAGS = @nm_CFLAGS@ +nm_LIBS = @nm_LIBS@ +nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ +oldincludedir = @oldincludedir@ +pcsclite_CFLAGS = @pcsclite_CFLAGS@ +pcsclite_LIBS = @pcsclite_LIBS@ +pdfdir = @pdfdir@ +piddir = @piddir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +pki_plugins = @pki_plugins@ +plugindir = @plugindir@ +pool_plugins = @pool_plugins@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +random_device = @random_device@ +resolv_conf = @resolv_conf@ +routing_table = @routing_table@ +routing_table_prio = @routing_table_prio@ +s_plugins = @s_plugins@ +sbindir = @sbindir@ +scepclient_plugins = @scepclient_plugins@ +scripts_plugins = @scripts_plugins@ +sharedstatedir = @sharedstatedir@ +soup_CFLAGS = @soup_CFLAGS@ +soup_LIBS = @soup_LIBS@ +srcdir = @srcdir@ +starter_plugins = @starter_plugins@ +strongswan_conf = @strongswan_conf@ +strongswan_options = @strongswan_options@ +swanctldir = @swanctldir@ +sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ +systemdsystemunitdir = @systemdsystemunitdir@ +t_plugins = @t_plugins@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +urandom_device = @urandom_device@ +xml_CFLAGS = @xml_CFLAGS@ +xml_LIBS = @xml_LIBS@ +bliss_tests_SOURCES = \ + suites/test_bliss_fft.c \ + suites/test_bliss_bitpacker.c \ + suites/test_bliss_huffman.c \ + suites/test_bliss_keys.c \ + suites/test_bliss_sampler.c \ + suites/test_bliss_signature.c \ + suites/test_bliss_sign.c \ + bliss_tests.h bliss_tests.c + +bliss_tests_CFLAGS = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libstrongswan/tests \ + -I$(top_srcdir)/src/libstrongswan/plugins/bliss \ + -DPLUGINDIR=\""$(abs_top_builddir)/src/libstrongswan/plugins\"" \ + -DPLUGINS=\""${s_plugins}\"" \ + @COVERAGE_CFLAGS@ + +bliss_tests_LDFLAGS = @COVERAGE_LDFLAGS@ +bliss_tests_LDADD = \ + $(top_builddir)/src/libstrongswan/libstrongswan.la \ + $(top_builddir)/src/libstrongswan/tests/libtest.la \ + ../libbliss.la + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/bliss/tests/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libstrongswan/plugins/bliss/tests/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +suites/$(am__dirstamp): + @$(MKDIR_P) suites + @: > suites/$(am__dirstamp) +suites/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) suites/$(DEPDIR) + @: > suites/$(DEPDIR)/$(am__dirstamp) +suites/bliss_tests-test_bliss_fft.$(OBJEXT): suites/$(am__dirstamp) \ + suites/$(DEPDIR)/$(am__dirstamp) +suites/bliss_tests-test_bliss_bitpacker.$(OBJEXT): \ + suites/$(am__dirstamp) suites/$(DEPDIR)/$(am__dirstamp) +suites/bliss_tests-test_bliss_huffman.$(OBJEXT): \ + suites/$(am__dirstamp) suites/$(DEPDIR)/$(am__dirstamp) +suites/bliss_tests-test_bliss_keys.$(OBJEXT): suites/$(am__dirstamp) \ + suites/$(DEPDIR)/$(am__dirstamp) +suites/bliss_tests-test_bliss_sampler.$(OBJEXT): \ + suites/$(am__dirstamp) suites/$(DEPDIR)/$(am__dirstamp) +suites/bliss_tests-test_bliss_signature.$(OBJEXT): \ + suites/$(am__dirstamp) suites/$(DEPDIR)/$(am__dirstamp) +suites/bliss_tests-test_bliss_sign.$(OBJEXT): suites/$(am__dirstamp) \ + suites/$(DEPDIR)/$(am__dirstamp) + +bliss_tests$(EXEEXT): $(bliss_tests_OBJECTS) $(bliss_tests_DEPENDENCIES) $(EXTRA_bliss_tests_DEPENDENCIES) + @rm -f bliss_tests$(EXEEXT) + $(AM_V_CCLD)$(bliss_tests_LINK) $(bliss_tests_OBJECTS) $(bliss_tests_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f suites/*.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bliss_tests-bliss_tests.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/bliss_tests-test_bliss_bitpacker.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/bliss_tests-test_bliss_fft.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/bliss_tests-test_bliss_huffman.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/bliss_tests-test_bliss_keys.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/bliss_tests-test_bliss_sampler.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/bliss_tests-test_bliss_sign.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/bliss_tests-test_bliss_signature.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +suites/bliss_tests-test_bliss_fft.o: suites/test_bliss_fft.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_fft.o -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_fft.Tpo -c -o suites/bliss_tests-test_bliss_fft.o `test -f 'suites/test_bliss_fft.c' || echo '$(srcdir)/'`suites/test_bliss_fft.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_fft.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_fft.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_fft.c' object='suites/bliss_tests-test_bliss_fft.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_fft.o `test -f 'suites/test_bliss_fft.c' || echo '$(srcdir)/'`suites/test_bliss_fft.c + +suites/bliss_tests-test_bliss_fft.obj: suites/test_bliss_fft.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_fft.obj -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_fft.Tpo -c -o suites/bliss_tests-test_bliss_fft.obj `if test -f 'suites/test_bliss_fft.c'; then $(CYGPATH_W) 'suites/test_bliss_fft.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_fft.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_fft.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_fft.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_fft.c' object='suites/bliss_tests-test_bliss_fft.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_fft.obj `if test -f 'suites/test_bliss_fft.c'; then $(CYGPATH_W) 'suites/test_bliss_fft.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_fft.c'; fi` + +suites/bliss_tests-test_bliss_bitpacker.o: suites/test_bliss_bitpacker.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_bitpacker.o -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_bitpacker.Tpo -c -o suites/bliss_tests-test_bliss_bitpacker.o `test -f 'suites/test_bliss_bitpacker.c' || echo '$(srcdir)/'`suites/test_bliss_bitpacker.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_bitpacker.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_bitpacker.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_bitpacker.c' object='suites/bliss_tests-test_bliss_bitpacker.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_bitpacker.o `test -f 'suites/test_bliss_bitpacker.c' || echo '$(srcdir)/'`suites/test_bliss_bitpacker.c + +suites/bliss_tests-test_bliss_bitpacker.obj: suites/test_bliss_bitpacker.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_bitpacker.obj -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_bitpacker.Tpo -c -o suites/bliss_tests-test_bliss_bitpacker.obj `if test -f 'suites/test_bliss_bitpacker.c'; then $(CYGPATH_W) 'suites/test_bliss_bitpacker.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_bitpacker.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_bitpacker.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_bitpacker.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_bitpacker.c' object='suites/bliss_tests-test_bliss_bitpacker.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_bitpacker.obj `if test -f 'suites/test_bliss_bitpacker.c'; then $(CYGPATH_W) 'suites/test_bliss_bitpacker.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_bitpacker.c'; fi` + +suites/bliss_tests-test_bliss_huffman.o: suites/test_bliss_huffman.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_huffman.o -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_huffman.Tpo -c -o suites/bliss_tests-test_bliss_huffman.o `test -f 'suites/test_bliss_huffman.c' || echo '$(srcdir)/'`suites/test_bliss_huffman.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_huffman.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_huffman.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_huffman.c' object='suites/bliss_tests-test_bliss_huffman.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_huffman.o `test -f 'suites/test_bliss_huffman.c' || echo '$(srcdir)/'`suites/test_bliss_huffman.c + +suites/bliss_tests-test_bliss_huffman.obj: suites/test_bliss_huffman.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_huffman.obj -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_huffman.Tpo -c -o suites/bliss_tests-test_bliss_huffman.obj `if test -f 'suites/test_bliss_huffman.c'; then $(CYGPATH_W) 'suites/test_bliss_huffman.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_huffman.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_huffman.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_huffman.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_huffman.c' object='suites/bliss_tests-test_bliss_huffman.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_huffman.obj `if test -f 'suites/test_bliss_huffman.c'; then $(CYGPATH_W) 'suites/test_bliss_huffman.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_huffman.c'; fi` + +suites/bliss_tests-test_bliss_keys.o: suites/test_bliss_keys.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_keys.o -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_keys.Tpo -c -o suites/bliss_tests-test_bliss_keys.o `test -f 'suites/test_bliss_keys.c' || echo '$(srcdir)/'`suites/test_bliss_keys.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_keys.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_keys.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_keys.c' object='suites/bliss_tests-test_bliss_keys.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_keys.o `test -f 'suites/test_bliss_keys.c' || echo '$(srcdir)/'`suites/test_bliss_keys.c + +suites/bliss_tests-test_bliss_keys.obj: suites/test_bliss_keys.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_keys.obj -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_keys.Tpo -c -o suites/bliss_tests-test_bliss_keys.obj `if test -f 'suites/test_bliss_keys.c'; then $(CYGPATH_W) 'suites/test_bliss_keys.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_keys.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_keys.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_keys.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_keys.c' object='suites/bliss_tests-test_bliss_keys.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_keys.obj `if test -f 'suites/test_bliss_keys.c'; then $(CYGPATH_W) 'suites/test_bliss_keys.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_keys.c'; fi` + +suites/bliss_tests-test_bliss_sampler.o: suites/test_bliss_sampler.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_sampler.o -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_sampler.Tpo -c -o suites/bliss_tests-test_bliss_sampler.o `test -f 'suites/test_bliss_sampler.c' || echo '$(srcdir)/'`suites/test_bliss_sampler.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_sampler.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_sampler.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_sampler.c' object='suites/bliss_tests-test_bliss_sampler.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_sampler.o `test -f 'suites/test_bliss_sampler.c' || echo '$(srcdir)/'`suites/test_bliss_sampler.c + +suites/bliss_tests-test_bliss_sampler.obj: suites/test_bliss_sampler.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_sampler.obj -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_sampler.Tpo -c -o suites/bliss_tests-test_bliss_sampler.obj `if test -f 'suites/test_bliss_sampler.c'; then $(CYGPATH_W) 'suites/test_bliss_sampler.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_sampler.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_sampler.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_sampler.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_sampler.c' object='suites/bliss_tests-test_bliss_sampler.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_sampler.obj `if test -f 'suites/test_bliss_sampler.c'; then $(CYGPATH_W) 'suites/test_bliss_sampler.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_sampler.c'; fi` + +suites/bliss_tests-test_bliss_signature.o: suites/test_bliss_signature.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_signature.o -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_signature.Tpo -c -o suites/bliss_tests-test_bliss_signature.o `test -f 'suites/test_bliss_signature.c' || echo '$(srcdir)/'`suites/test_bliss_signature.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_signature.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_signature.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_signature.c' object='suites/bliss_tests-test_bliss_signature.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_signature.o `test -f 'suites/test_bliss_signature.c' || echo '$(srcdir)/'`suites/test_bliss_signature.c + +suites/bliss_tests-test_bliss_signature.obj: suites/test_bliss_signature.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_signature.obj -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_signature.Tpo -c -o suites/bliss_tests-test_bliss_signature.obj `if test -f 'suites/test_bliss_signature.c'; then $(CYGPATH_W) 'suites/test_bliss_signature.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_signature.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_signature.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_signature.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_signature.c' object='suites/bliss_tests-test_bliss_signature.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_signature.obj `if test -f 'suites/test_bliss_signature.c'; then $(CYGPATH_W) 'suites/test_bliss_signature.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_signature.c'; fi` + +suites/bliss_tests-test_bliss_sign.o: suites/test_bliss_sign.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_sign.o -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_sign.Tpo -c -o suites/bliss_tests-test_bliss_sign.o `test -f 'suites/test_bliss_sign.c' || echo '$(srcdir)/'`suites/test_bliss_sign.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_sign.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_sign.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_sign.c' object='suites/bliss_tests-test_bliss_sign.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_sign.o `test -f 'suites/test_bliss_sign.c' || echo '$(srcdir)/'`suites/test_bliss_sign.c + +suites/bliss_tests-test_bliss_sign.obj: suites/test_bliss_sign.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT suites/bliss_tests-test_bliss_sign.obj -MD -MP -MF suites/$(DEPDIR)/bliss_tests-test_bliss_sign.Tpo -c -o suites/bliss_tests-test_bliss_sign.obj `if test -f 'suites/test_bliss_sign.c'; then $(CYGPATH_W) 'suites/test_bliss_sign.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_sign.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/bliss_tests-test_bliss_sign.Tpo suites/$(DEPDIR)/bliss_tests-test_bliss_sign.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_bliss_sign.c' object='suites/bliss_tests-test_bliss_sign.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o suites/bliss_tests-test_bliss_sign.obj `if test -f 'suites/test_bliss_sign.c'; then $(CYGPATH_W) 'suites/test_bliss_sign.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_bliss_sign.c'; fi` + +bliss_tests-bliss_tests.o: bliss_tests.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT bliss_tests-bliss_tests.o -MD -MP -MF $(DEPDIR)/bliss_tests-bliss_tests.Tpo -c -o bliss_tests-bliss_tests.o `test -f 'bliss_tests.c' || echo '$(srcdir)/'`bliss_tests.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/bliss_tests-bliss_tests.Tpo $(DEPDIR)/bliss_tests-bliss_tests.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bliss_tests.c' object='bliss_tests-bliss_tests.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o bliss_tests-bliss_tests.o `test -f 'bliss_tests.c' || echo '$(srcdir)/'`bliss_tests.c + +bliss_tests-bliss_tests.obj: bliss_tests.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -MT bliss_tests-bliss_tests.obj -MD -MP -MF $(DEPDIR)/bliss_tests-bliss_tests.Tpo -c -o bliss_tests-bliss_tests.obj `if test -f 'bliss_tests.c'; then $(CYGPATH_W) 'bliss_tests.c'; else $(CYGPATH_W) '$(srcdir)/bliss_tests.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/bliss_tests-bliss_tests.Tpo $(DEPDIR)/bliss_tests-bliss_tests.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bliss_tests.c' object='bliss_tests-bliss_tests.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bliss_tests_CFLAGS) $(CFLAGS) -c -o bliss_tests-bliss_tests.obj `if test -f 'bliss_tests.c'; then $(CYGPATH_W) 'bliss_tests.c'; else $(CYGPATH_W) '$(srcdir)/bliss_tests.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f suites/$(DEPDIR)/$(am__dirstamp) + -rm -f suites/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) suites/$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) suites/$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libstrongswan/plugins/bliss/tests/bliss_tests.c b/src/libstrongswan/plugins/bliss/tests/bliss_tests.c new file mode 100644 index 000000000..de21e77b7 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/tests/bliss_tests.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include <test_runner.h> + +#include <library.h> + +/* declare test suite constructors */ +#define TEST_SUITE(x) test_suite_t* x(); +#include "bliss_tests.h" +#undef TEST_SUITE + +static test_configuration_t tests[] = { +#define TEST_SUITE(x) \ + { .suite = x, }, +#include "bliss_tests.h" + { .suite = NULL, } +}; + +static bool test_runner_init(bool init) +{ + if (init) + { + char *plugins, *plugindir; + + plugins = lib->settings->get_str(lib->settings, + "tests.load", PLUGINS); + plugindir = lib->settings->get_str(lib->settings, + "tests.plugindir", PLUGINDIR); + plugin_loader_add_plugindirs(plugindir, plugins); + if (!lib->plugins->load(lib->plugins, plugins)) + { + return FALSE; + } + } + else + { + lib->processor->set_threads(lib->processor, 0); + lib->processor->cancel(lib->processor); + lib->plugins->unload(lib->plugins); + } + return TRUE; +} + +int main(int argc, char *argv[]) +{ + return test_runner_run("bliss", tests, test_runner_init); +} diff --git a/src/libstrongswan/plugins/bliss/tests/bliss_tests.h b/src/libstrongswan/plugins/bliss/tests/bliss_tests.h new file mode 100644 index 000000000..f0959cc08 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/tests/bliss_tests.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2014-2015 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +TEST_SUITE(bliss_fft_suite_create) +TEST_SUITE(bliss_bitpacker_suite_create) +TEST_SUITE(bliss_huffman_suite_create) +TEST_SUITE(bliss_keys_suite_create) +TEST_SUITE(bliss_sampler_suite_create) +TEST_SUITE(bliss_signature_suite_create) +TEST_SUITE(bliss_sign_suite_create) + diff --git a/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_bitpacker.c b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_bitpacker.c new file mode 100644 index 000000000..6a728e280 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_bitpacker.c @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "test_suite.h" + +#include <bliss_bitpacker.h> + +static uint32_t bits[] = { 0, 1, 2, 3, 4, 7, 1, 14, 2, 29, 3, 28, 67, 0x2fe3a9c1}; + +static chunk_t packed_bits = chunk_from_chars(0x6e, 0x71, 0xe1, 0x74, + 0x37, 0x21, 0x97, 0xf1, + 0xd4, 0xe0, 0x80); + +START_TEST(test_bliss_sign_bitpacker_write) +{ + chunk_t buf; + bliss_bitpacker_t *packer; + int i; + + packer = bliss_bitpacker_create(81); + + for (i = 0; i < 13; i++) + { + ck_assert(packer->write_bits(packer, bits[i], 1 + i/2)); + } + ck_assert(packer->write_bits(packer, bits[13], 32)); + + buf = packer->extract_buf(packer); + ck_assert_int_eq(packer->get_bits(packer), 81); + ck_assert_chunk_eq(buf, packed_bits); + + packer->destroy(packer); + free(buf.ptr); +} +END_TEST + +START_TEST(test_bliss_sign_bitpacker_read) +{ + uint32_t value; + bliss_bitpacker_t *packer; + int i; + + packer = bliss_bitpacker_create_from_data(packed_bits); + + ck_assert(!packer->read_bits(packer, &value, 33)); + + for (i = 0; i < 13; i++) + { + ck_assert(packer->read_bits(packer, &value, 1 + i/2)); + ck_assert_int_eq(value, bits[i]); + } + ck_assert(packer->read_bits(packer, &value, 32)); + ck_assert_int_eq(value, bits[13]); + + packer->destroy(packer); +} +END_TEST + +START_TEST(test_bliss_sign_bitpacker_fail) +{ + bliss_bitpacker_t *packer; + uint32_t value; + + packer = bliss_bitpacker_create(32); + ck_assert( packer->write_bits(packer, 0xff, 0)); + ck_assert(!packer->write_bits(packer, 0, 33)); + ck_assert( packer->write_bits(packer, 0x7f2a3b01, 31)); + ck_assert(!packer->write_bits(packer, 3, 2)); + packer->destroy(packer); + + packer = bliss_bitpacker_create_from_data( + chunk_from_chars(0x7f, 0x2a, 0x3b, 0x01)); + ck_assert(!packer->read_bits(packer, &value, 33)); + ck_assert( packer->read_bits(packer, &value, 31)); + ck_assert(!packer->read_bits(packer, &value, 2)); + packer->destroy(packer); +} +END_TEST + +Suite *bliss_bitpacker_suite_create() +{ + Suite *s; + TCase *tc; + + s = suite_create("bliss_bitpacker"); + + tc = tcase_create("bitpacker_write"); + tcase_add_test(tc, test_bliss_sign_bitpacker_write); + suite_add_tcase(s, tc); + + tc = tcase_create("bitpacker_read"); + tcase_add_test(tc, test_bliss_sign_bitpacker_read); + suite_add_tcase(s, tc); + + tc = tcase_create("bitpacker_fail"); + tcase_add_test(tc, test_bliss_sign_bitpacker_fail); + suite_add_tcase(s, tc); + + return s; +} diff --git a/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_fft.c b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_fft.c new file mode 100644 index 000000000..009aaf802 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_fft.c @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "test_suite.h" + +#include <bliss_fft.h> + +static bliss_fft_params_t *fft_params[] = { + &bliss_fft_17_8, + &bliss_fft_12289_512 +}; + +START_TEST(test_bliss_fft_impulse) +{ + bliss_fft_t *fft; + uint16_t n = fft_params[_i]->n; + uint32_t x[n], X[n]; + int i; + + for (i = 0; i < n; i++) + { + x[i] = 0; + } + x[0] = 1; + + fft = bliss_fft_create(fft_params[_i]); + fft->transform(fft, x, X, FALSE); + + for (i = 0; i < n; i++) + { + ck_assert(X[i] == 1); + } + fft->transform(fft, X, x, TRUE); + + for (i = 0; i < n; i++) + { + ck_assert(x[i] == (i == 0)); + } + fft->destroy(fft); +} +END_TEST + +START_TEST(test_bliss_fft_wrap) +{ + bliss_fft_t *fft; + uint16_t n = fft_params[_i]->n; + uint16_t q = fft_params[_i]->q; + uint32_t x[n],y[n], X[n], Y[n]; + int i, j; + + for (i = 0; i < n; i++) + { + x[i] = i; + y[i] = 0; + } + fft = bliss_fft_create(fft_params[_i]); + ck_assert(fft->get_size(fft) == n); + ck_assert(fft->get_modulus(fft) == q); + fft->transform(fft, x, X, FALSE); + + for (j = 0; j < n; j++) + { + y[j] = 1; + fft->transform(fft, y, Y, FALSE); + + for (i = 0; i < n; i++) + { + Y[i] = (X[i] * Y[i]) % q; + } + fft->transform(fft, Y, Y, TRUE); + + for (i = 0; i < n; i++) + { + ck_assert(Y[i] == ( i < j ? q - n - i + j : i - j)); + } + y[j] = 0; + } + fft->destroy(fft); +} +END_TEST + +Suite *bliss_fft_suite_create() +{ + Suite *s; + TCase *tc; + + s = suite_create("bliss_fft"); + + tc = tcase_create("impulse"); + tcase_add_loop_test(tc, test_bliss_fft_impulse, 0, countof(fft_params)); + suite_add_tcase(s, tc); + + tc = tcase_create("negative_wrap"); + tcase_add_loop_test(tc, test_bliss_fft_wrap, 0, countof(fft_params)); + suite_add_tcase(s, tc); + + return s; +} diff --git a/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_huffman.c b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_huffman.c new file mode 100644 index 000000000..5447d0741 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_huffman.c @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2015 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "test_suite.h" + +#include <bliss_huffman_coder.h> + +static chunk_t data = chunk_from_chars(0x5f, 0x71, 0x9e, 0x4c); + +START_TEST(test_bliss_huffman_encode) +{ + bliss_bitpacker_t *packer; + bliss_huffman_code_t *code; + bliss_huffman_coder_t *coder; + chunk_t encoding; + + packer = bliss_bitpacker_create(32); + ck_assert(packer); + + code = bliss_huffman_code_get_by_id(BLISS_B_I); + ck_assert(code); + + coder = bliss_huffman_coder_create(code, packer); + ck_assert(coder); + + ck_assert( coder->encode(coder, 0, 0)); /* 0 */ + ck_assert( coder->encode(coder, 1, 0)); /* 10 */ + ck_assert( coder->encode(coder, 2, 0)); /* 111 */ + ck_assert( coder->encode(coder, 0, 1)); /* 1101 */ + ck_assert( coder->encode(coder, 0, -1)); /* 11000 */ + ck_assert( coder->encode(coder, 1, 1)); /* 110011 */ + ck_assert( coder->encode(coder, 1, -1)); /* 1100100 */ + ck_assert(!coder->encode(coder, 3, 0)); /* 11001010 */ + ck_assert(!coder->encode(coder, 8, 0)); /* - */ + + encoding = packer->extract_buf(packer); + ck_assert(chunk_equals(encoding, data)); + + chunk_free(&encoding); + coder->destroy(coder); + packer->destroy(packer); +} +END_TEST + +START_TEST(test_bliss_huffman_decode) +{ + bliss_bitpacker_t *packer; + bliss_huffman_code_t *code; + bliss_huffman_coder_t *coder; + int32_t z1; + int16_t z2; + + packer = bliss_bitpacker_create_from_data(data); + ck_assert(packer); + + code = bliss_huffman_code_get_by_id(BLISS_II); + ck_assert(!code); + code = bliss_huffman_code_get_by_id(BLISS_B_II); + ck_assert(!code); + code = bliss_huffman_code_get_by_id(BLISS_B_I); + ck_assert(code); + + coder = bliss_huffman_coder_create(code, packer); + ck_assert(coder); + + ck_assert(coder->decode(coder, &z1, &z2)); /* 0 */ + ck_assert(z1 == 0 && z2 == 0); + + ck_assert(coder->decode(coder, &z1, &z2)); /* 10 */ + ck_assert(z1 == 1 && z2 == 0); + + ck_assert(coder->decode(coder, &z1, &z2)); /* 111 */ + ck_assert(z1 == 2 && z2 == 0); + + ck_assert(coder->decode(coder, &z1, &z2)); /* 1101 */ + ck_assert(z1 == 0 && z2 == 1); + + ck_assert(coder->decode(coder, &z1, &z2)); /* 11000 */ + ck_assert(z1 == 0 && z2 == -1); + + ck_assert(coder->decode(coder, &z1, &z2)); /* 110011 */ + ck_assert(z1 == 1 && z2 == 1); + + ck_assert(coder->decode(coder, &z1, &z2)); /* 1100100 */ + ck_assert(z1 == 1 && z2 == -1); + + ck_assert(!coder->decode(coder, &z1, &z2)); /* 11001010 */ + + coder->destroy(coder); + packer->destroy(packer); +} +END_TEST + +Suite *bliss_huffman_suite_create() +{ + Suite *s; + TCase *tc; + + s = suite_create("bliss_huffman"); + + tc = tcase_create("huffman_encode"); + tcase_add_test(tc, test_bliss_huffman_encode); + suite_add_tcase(s, tc); + + tc = tcase_create("huffman_decode"); + tcase_add_test(tc, test_bliss_huffman_decode); + suite_add_tcase(s, tc); + + return s; +} diff --git a/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_keys.c b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_keys.c new file mode 100644 index 000000000..f48bc1d79 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_keys.c @@ -0,0 +1,249 @@ +/* + * Copyright (C) 2015 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "test_suite.h" + +#include <bliss_private_key.h> +#include <bliss_public_key.h> + +static chunk_t privkey_chunk[] = { + {NULL, 0}, + chunk_from_chars(0x30, 0x00), + chunk_from_chars(0x30, 0x01), + chunk_from_chars(0x30, 0x03, 0x06, 0x01, 0x01), + chunk_from_chars(0x30, 0x0d, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, + 0xa0, 0x2a, 0x05, 0x02, 0x06), + chunk_from_chars(0x30, 0x0f, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, + 0xa0, 0x2a, 0x05, 0x02, 0x05, 0x03, 0x00), + chunk_from_chars(0x30, 0x82, 0x04, 0x9a, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, + 0x01, 0x82, 0xa0, 0x2a, 0x05, 0x02, 0x05, 0x03, 0x82, 0x03, + 0x81, 0x00, 0x81, 0xe5, 0xd2, 0x71, 0xeb, 0x98, 0xe5, 0x24, + 0x34, 0xe4, 0x8a, 0x27, 0x23, 0x7d, 0x7d, 0x2c, 0xa3, 0xa7, + 0x3f, 0x87, 0xad, 0xae, 0xfa, 0xe4, 0x66, 0x1c, 0xef, 0x69, + 0x63, 0x5e, 0x91, 0xda, 0x41, 0x45, 0xd5, 0x8a, 0xb5, 0x26, + 0x33, 0x32, 0xe0, 0xa2, 0x9b, 0x52, 0x5e, 0x49, 0x5d, 0x0d, + 0x62, 0x72, 0x68, 0xa5, 0x94, 0x24, 0x03, 0x98, 0x48, 0x60, + 0x4a, 0x98, 0x97, 0x0d, 0x60, 0x7d, 0x00, 0x4f, 0xb9, 0xaf, + 0xcb, 0x6b, 0x41, 0x3d, 0x5b, 0xe4, 0x3e, 0x9a, 0xee, 0x06, + /* 100 */ 0xa1, 0xd0, 0x93, 0x53, 0x88, 0x58, 0x83, 0xb2, 0x44, 0xa1, + 0x16, 0x58, 0x3d, 0x32, 0xa1, 0x29, 0x85, 0x1a, 0x24, 0xc8, + 0xb8, 0x8c, 0x1f, 0x43, 0xbb, 0x4b, 0xdd, 0x8e, 0x72, 0xd3, + 0xf4, 0xfc, 0x02, 0x69, 0x47, 0xa5, 0x9d, 0xd0, 0xfc, 0xa6, + 0x94, 0x2e, 0x02, 0x6d, 0x85, 0x2c, 0x6d, 0xe3, 0x91, 0xd5, + 0xf1, 0x54, 0xbd, 0x1e, 0x63, 0x6b, 0xee, 0x28, 0xf9, 0xc6, + 0xec, 0x05, 0x99, 0xd5, 0xdd, 0xe5, 0x72, 0x9b, 0xbc, 0xa7, + 0x5a, 0x4a, 0x46, 0x3e, 0xec, 0xd7, 0x0b, 0xc5, 0x23, 0x00, + 0xdc, 0x08, 0x09, 0x57, 0x44, 0x2e, 0x43, 0x0f, 0xea, 0xca, + 0x2a, 0x31, 0xbe, 0xf3, 0x04, 0x8f, 0x8b, 0xa6, 0x3c, 0x35, + /* 200 */ 0x80, 0x2b, 0xe2, 0x18, 0x22, 0xfd, 0xe9, 0x39, 0x57, 0xed, + 0x77, 0x1d, 0x32, 0x02, 0x48, 0x2c, 0x85, 0x53, 0x9f, 0x4a, + 0xd8, 0x86, 0x4d, 0xd2, 0x26, 0x19, 0x12, 0x19, 0xa2, 0xb5, + 0xdf, 0x02, 0x50, 0xe4, 0x32, 0x9a, 0x27, 0xd0, 0x9e, 0x49, + 0x4a, 0x13, 0x9a, 0xfc, 0x07, 0x98, 0x60, 0x65, 0xf4, 0xc1, + 0x6c, 0x9a, 0x15, 0x28, 0x74, 0x5c, 0xd0, 0xa8, 0xe6, 0x2e, + 0x1f, 0xe9, 0xe6, 0x2b, 0xc8, 0x46, 0xe9, 0x26, 0xb0, 0xf0, + 0x8a, 0xe6, 0x8c, 0x9b, 0xbf, 0x64, 0xa0, 0x59, 0x33, 0x4f, + 0xc0, 0x0c, 0x16, 0x72, 0x89, 0x79, 0x2a, 0x3a, 0x5e, 0x3d, + 0x40, 0xbb, 0x73, 0xa9, 0xc0, 0x52, 0x70, 0x57, 0x06, 0xc1, + /* 300 */ 0xe7, 0x70, 0xb8, 0x6d, 0x1b, 0x50, 0x61, 0x85, 0xee, 0x3e, + 0xe5, 0x5a, 0x8a, 0x75, 0x9f, 0x1e, 0xb7, 0xea, 0x54, 0x5a, + 0x8f, 0x52, 0xc2, 0xae, 0x2c, 0x7a, 0x58, 0xe6, 0xcb, 0xa6, + 0x9b, 0x68, 0x84, 0x79, 0xf2, 0x82, 0x05, 0x57, 0xaa, 0xd5, + 0x51, 0x82, 0xec, 0x84, 0x63, 0xce, 0xf4, 0xa7, 0xdf, 0x4e, + 0xac, 0x7d, 0xdd, 0xc3, 0x02, 0x68, 0xe0, 0x35, 0xa1, 0x92, + 0x29, 0x02, 0x2c, 0xa0, 0xe4, 0x29, 0x66, 0xd3, 0xe8, 0xd9, + 0x52, 0x0f, 0x3b, 0xec, 0x53, 0x63, 0x57, 0xc3, 0xd2, 0x59, + 0x38, 0xe7, 0x74, 0xf4, 0x1d, 0x03, 0x88, 0x3c, 0xe9, 0x97, + 0x37, 0xd7, 0x12, 0x66, 0x2a, 0xb5, 0xf8, 0xcd, 0x10, 0x87, + /* 400 */ 0x5d, 0x6a, 0x69, 0xbb, 0x9b, 0xc5, 0x55, 0x3c, 0x09, 0x46, + 0x04, 0x57, 0xc0, 0x2f, 0x77, 0x89, 0xe2, 0x88, 0x15, 0x6b, + 0x71, 0x56, 0xe1, 0xa2, 0x30, 0x71, 0x5f, 0x1d, 0x27, 0x12, + 0xbf, 0xc3, 0x55, 0xde, 0xe5, 0x9c, 0x4e, 0xb8, 0xc6, 0xec, + 0x96, 0x3a, 0x5d, 0x6d, 0xe9, 0xd3, 0xf8, 0x28, 0xda, 0x3f, + 0x75, 0x24, 0xd0, 0x34, 0x50, 0xa6, 0x28, 0x65, 0x6a, 0xe9, + 0xa6, 0x89, 0xe5, 0x5d, 0x45, 0xaf, 0x63, 0x34, 0xaf, 0x31, + 0x29, 0x82, 0xe6, 0x03, 0x80, 0x5c, 0x34, 0x28, 0xd1, 0x9f, + 0xca, 0xd3, 0x96, 0xcb, 0x31, 0xde, 0xdb, 0xf0, 0x07, 0x2b, + 0xc5, 0xbc, 0x29, 0xd1, 0x11, 0xf4, 0x23, 0x3b, 0x14, 0xb5, + /* 500 */ 0xa6, 0xf1, 0x02, 0x9e, 0x66, 0xbe, 0xdc, 0xc4, 0xca, 0xf7, + 0xc0, 0x81, 0x92, 0x7c, 0xea, 0xe3, 0x42, 0x54, 0x8a, 0x6f, + 0x0a, 0x2a, 0xa7, 0x2a, 0x92, 0xab, 0x09, 0xb1, 0x61, 0x91, + 0xaa, 0x90, 0x54, 0xa3, 0x76, 0x64, 0xe2, 0xfd, 0x81, 0x9a, + 0x4c, 0x35, 0x11, 0x28, 0xf3, 0x14, 0x97, 0x1b, 0x61, 0xa4, + 0x67, 0x43, 0xae, 0x90, 0x6b, 0xe4, 0x29, 0x34, 0xec, 0x08, + 0xbc, 0x6a, 0x82, 0x45, 0xc7, 0x7d, 0xdc, 0xd0, 0x03, 0x98, + 0x29, 0x63, 0x05, 0x94, 0xb2, 0xb9, 0x04, 0xce, 0x34, 0x9a, + 0x64, 0xae, 0x9a, 0xa9, 0x11, 0xa5, 0x13, 0x07, 0xcc, 0x92, + 0xe9, 0xe5, 0x98, 0x13, 0x13, 0x8f, 0x8b, 0xb2, 0x77, 0x75, + /* 600 */ 0x2a, 0x6f, 0xb1, 0xa6, 0x98, 0xbf, 0x50, 0xaf, 0xa7, 0x15, + 0x2a, 0xe6, 0xdf, 0x41, 0xb6, 0x5e, 0x72, 0xb2, 0x74, 0xf2, + 0x38, 0x88, 0x41, 0x56, 0x53, 0xea, 0x83, 0x23, 0x8a, 0x6d, + 0x6c, 0x64, 0x6c, 0xa6, 0x04, 0x79, 0x51, 0x92, 0x89, 0xbe, + 0x2a, 0x54, 0xd8, 0x5a, 0x8d, 0x5b, 0x9c, 0xfc, 0x62, 0x05, + 0x0f, 0xbd, 0x85, 0x12, 0x57, 0x45, 0x96, 0x2e, 0x8f, 0x76, + 0xd4, 0x33, 0xfb, 0x4a, 0xc2, 0x9f, 0x57, 0x96, 0xb3, 0xa2, + 0xc6, 0xa6, 0x95, 0x3c, 0x9e, 0x7e, 0x15, 0x12, 0xd7, 0xe4, + 0x65, 0x05, 0x5d, 0x72, 0xc2, 0x28, 0x10, 0xa9, 0x68, 0xa9, + 0x01, 0xfe, 0x9e, 0x36, 0x07, 0x80, 0x41, 0xc8, 0xa3, 0x5f, + /* 700 */ 0x18, 0x3b, 0x38, 0x09, 0x95, 0xe2, 0x87, 0xad, 0x03, 0xfd, + 0xdd, 0xa6, 0xe9, 0x8e, 0xa8, 0x3a, 0xc9, 0x45, 0x7b, 0xdc, + 0xc2, 0x6a, 0x30, 0x78, 0xaa, 0xba, 0x32, 0xe9, 0x8a, 0x65, + 0x48, 0x13, 0x5b, 0x29, 0x18, 0x2e, 0x5c, 0x68, 0x8d, 0x71, + 0x01, 0x09, 0xab, 0x7d, 0x1a, 0xe9, 0x09, 0x74, 0x1b, 0xe1, + 0x90, 0x00, 0xb9, 0xda, 0xa3, 0x03, 0xb7, 0x6c, 0xdd, 0x40, + 0xb6, 0xe3, 0xde, 0xa6, 0x7b, 0xe9, 0x3d, 0x41, 0x4d, 0xc7, + 0xad, 0xa5, 0xf9, 0x8b, 0x88, 0xd4, 0x1a, 0x75, 0xb5, 0xb6, + 0x9f, 0x51, 0x9b, 0x8b, 0xd7, 0xa4, 0x02, 0xb0, 0x62, 0x45, + 0xdd, 0x6c, 0x11, 0x35, 0x03, 0x77, 0x1c, 0xdb, 0xc5, 0xac, + /* 800 */ 0x60, 0x37, 0x20, 0x15, 0xaf, 0xbd, 0xae, 0x76, 0x51, 0xd2, + 0xfb, 0x63, 0x23, 0x19, 0x81, 0xa6, 0x59, 0x7b, 0x68, 0x00, + 0x3d, 0x68, 0x89, 0x6b, 0x5a, 0x29, 0xbd, 0x4f, 0xc1, 0x50, + 0xe4, 0x98, 0x85, 0xe6, 0x1a, 0xdd, 0xc8, 0xe4, 0xa1, 0x2b, + 0x99, 0x42, 0x81, 0x4d, 0x07, 0xf4, 0x24, 0x93, 0x88, 0xfe, + 0x40, 0x90, 0x5a, 0x56, 0x0b, 0x7f, 0x8d, 0x14, 0x82, 0x6d, + 0xaf, 0xf6, 0x0a, 0x3d, 0xe6, 0x64, 0xb5, 0x48, 0x01, 0x37, + 0xfe, 0xf3, 0xba, 0x67, 0xcc, 0xd2, 0xba, 0x32, 0x76, 0xe8, + 0xa7, 0x41, 0x1f, 0x2a, 0xfc, 0xa9, 0x72, 0x66, 0xc7, 0xd5, + 0x76, 0x02, 0x6b, 0x77, 0xba, 0x6c, 0xd4, 0x84, 0x68, 0x0e, + /* 900 */ 0x62, 0xc8, 0x43, 0xb0, 0x81, 0xd5, 0x8f, 0xdb, 0x42, 0xc9, + 0xf4, 0xaf, 0x71, 0xbd, 0xb9, 0x6c, 0xd6, 0xdc, 0x03, 0x81, + 0x81, 0x00, 0xc5, 0x10, 0x40, 0x33, 0x0f, 0xc0, 0x14, 0x01, + 0x00, 0x03, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x4c, 0x0f, 0x10, + 0x03, 0x10, 0x00, 0x00, 0x01, 0xc0, 0x43, 0x40, 0x03, 0x5c, + 0x00, 0x07, 0xc0, 0x51, 0x34, 0x01, 0x30, 0x0c, 0x00, 0x00, + 0x04, 0xc0, 0x3d, 0x40, 0x03, 0x07, 0x40, 0xd3, 0x50, 0x0c, + 0x04, 0x03, 0x00, 0x11, 0x41, 0x30, 0x00, 0xc1, 0xc0, 0xc3, + 0x03, 0x5f, 0x04, 0x30, 0x01, 0x40, 0x40, 0x00, 0x40, 0x40, + 0x10, 0x40, 0x05, 0x05, 0x00, 0x53, 0x00, 0x04, 0x50, 0x00, + /* 1000 */ 0x00, 0x00, 0x0c, 0x00, 0x51, 0x00, 0x00, 0x00, 0x04, 0xc7, + 0x01, 0x50, 0xc0, 0x11, 0x00, 0x04, 0x03, 0xc0, 0x04, 0x00, + 0x70, 0x4c, 0x31, 0x03, 0xc0, 0x40, 0xc4, 0x40, 0x40, 0xc0, + 0x0c, 0x0c, 0xf1, 0x40, 0xc1, 0x31, 0x70, 0x17, 0xc0, 0x30, + 0xc1, 0x04, 0x0c, 0x04, 0x00, 0xc4, 0x01, 0x00, 0x34, 0x00, + 0x03, 0x81, 0x81, 0x00, 0xcc, 0x00, 0x50, 0x30, 0xc4, 0x13, + 0x0f, 0xf0, 0x43, 0x01, 0x33, 0x40, 0x30, 0x01, 0x40, 0x10, + 0x57, 0x04, 0x03, 0x04, 0x10, 0x00, 0xf0, 0x03, 0x04, 0x01, + 0x00, 0x10, 0x34, 0x03, 0xf0, 0x1c, 0x01, 0x40, 0x30, 0xf4, + 0x00, 0x40, 0x34, 0xc3, 0x00, 0x00, 0x01, 0x00, 0x01, 0x10, + /* 1100 */ 0x3f, 0x03, 0x40, 0x00, 0x10, 0x10, 0x00, 0x40, 0x03, 0x00, + 0x03, 0x04, 0x40, 0x03, 0x00, 0x13, 0x03, 0x00, 0xc0, 0x01, + 0x34, 0x01, 0x00, 0x00, 0x10, 0xf4, 0x00, 0xf0, 0x30, 0x00, + 0x00, 0xc3, 0x1c, 0x41, 0x00, 0x40, 0x30, 0x04, 0x10, 0xc4, + 0x11, 0x03, 0x00, 0x10, 0x04, 0x4f, 0x17, 0xc0, 0x00, 0x30, + 0xcd, 0x3c, 0x40, 0xc4, 0x00, 0xf0, 0x00, 0x00, 0x04, 0x30, + 0x0f, 0x31, 0x34, 0xf0, 0x00, 0x07, 0x0c, 0x34, 0x00, 0x50, + 0x05, 0x03, 0x10, 0x70, 0x00, 0x33, 0x0c, 0x00, 0xc4, 0x54, + 0x07, 0x00) +}; + +START_TEST(test_bliss_keys_priv) +{ + private_key_t *privkey; + + privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_BLISS, + BUILD_BLOB, privkey_chunk[_i], BUILD_END); + if (_i == countof(privkey_chunk) - 1) + { + ck_assert(privkey); + privkey->destroy(privkey); + } + else + { + ck_assert(!privkey); + } +} +END_TEST + +typedef struct privkey_mod_t privkey_mod_t; + +struct privkey_mod_t { + int offset; + char byte; +}; + +static privkey_mod_t privkey_mod[] = { + { 20, 0x80 }, + { 22, 0xc1 }, + { 920, 0x80 }, + { 922, 0x85 }, + { 1052, 0x80 }, + { 1054, 0x8c } +}; + +START_TEST(test_bliss_keys_priv_mod) +{ + private_key_t *privkey; + chunk_t data; + + data = chunk_clone(privkey_chunk[countof(privkey_chunk) - 1]); + data.ptr[privkey_mod[_i].offset] = privkey_mod[_i].byte; + + privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_BLISS, + BUILD_BLOB, data, BUILD_END); + ck_assert(!privkey); + chunk_free(&data); +} +END_TEST + +static chunk_t pubkey_chunk[] = { + {NULL, 0}, + chunk_from_chars(0x30, 0x00), + chunk_from_chars(0x30, 0x01), + chunk_from_chars(0x30, 0x02, 0x30, 0x00), + chunk_from_chars(0x30, 0x05, 0x30, 0x03, 0x06, 0x01, 0x01), + chunk_from_chars(0x30, 0x11, 0x30, 0x0F, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, + 0x01, 0x82, 0xa0, 0x2a, 0x05, 0x01, 0x01, 0x04, 0x00), + chunk_from_chars(0x30, 0x12, 0x30, 0x10, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, + 0x01, 0x82, 0xa0, 0x2a, 0x05, 0x01, 0x01, 0x06, 0x01, 0x01), + chunk_from_chars(0x30, 0x1c, 0x30, 0x1a, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, + 0x01, 0x82, 0xa0, 0x2a, 0x05, 0x01, 0x01, 0x06, 0x0b, 0x2b, + 0x06, 0x01, 0x04, 0x01, 0x82, 0xa0, 0x2a, 0x05, 0x02, 0x06), + chunk_from_chars(0x30, 0x1e, 0x30, 0x1a, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, + 0x01, 0x82, 0xa0, 0x2a, 0x05, 0x01, 0x01, 0x06, 0x0b, 0x2b, + 0x06, 0x01, 0x04, 0x01, 0x82, 0xa0, 0x2a, 0x05, 0x02, 0x05, + 0x03, 0x00) +}; + +START_TEST(test_bliss_keys_pub) +{ + public_key_t *pubkey; + + pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY, + BUILD_BLOB, pubkey_chunk[_i], BUILD_END); + ck_assert(!pubkey); +} +END_TEST + +Suite *bliss_keys_suite_create() +{ + Suite *s; + TCase *tc; + + s = suite_create("bliss_keys"); + + tc = tcase_create("keys_priv"); + tcase_add_loop_test(tc, test_bliss_keys_priv, 0, countof(privkey_chunk)); + suite_add_tcase(s, tc); + + tc = tcase_create("keys_priv_mod"); + tcase_add_loop_test(tc, test_bliss_keys_priv_mod, 0, countof(privkey_mod)); + suite_add_tcase(s, tc); + + tc = tcase_create("keys_pub"); + tcase_add_loop_test(tc, test_bliss_keys_pub, 0, countof(pubkey_chunk)); + suite_add_tcase(s, tc); + + return s; +} diff --git a/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sampler.c b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sampler.c new file mode 100644 index 000000000..1bd1266ad --- /dev/null +++ b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sampler.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "test_suite.h" + +#include <bliss_sampler.h> + +static u_int key_size[] = { 1, 3, 4}; + +START_TEST(test_bliss_sampler_gaussian) +{ + bliss_sampler_t *sampler; + bliss_param_set_t *set; + int i, k, count; + uint32_t hist[8], sign[3]; + int32_t z; + hash_algorithm_t alg; + size_t seed_len; + chunk_t seed; + + set = bliss_param_set_get_by_id(key_size[_i]); + alg = HASH_SHA256; + seed_len = 32; + count = 10000000; + + seed = chunk_alloc(seed_len); + memset(seed.ptr, 0xcc, seed_len); + + for (k = 0; k < 3; k++) + { + sign[k] = 0; + } + for (k = 0; k < 8; k++) + { + hist[k] = 0; + } + + sampler = bliss_sampler_create(alg, seed, set); + for (i = 0; i < count; i++) + { + ck_assert(sampler->gaussian(sampler, &z)); + if (z == 0) + { + sign[1]++; + hist[0]++; + } + else if (z > 0) + { + sign[2]++; + hist[z/256]++; + } + else + { + sign[0]++; + hist[(-z)/256]++; + } + } + sampler->destroy(sampler); + free(seed.ptr); + + DBG1(DBG_LIB, "histogram"); + for (k = 0; k < 8; k++) + { + DBG1(DBG_LIB, "%d %7d", k, hist[k]); + } + DBG1(DBG_LIB, "- %7d", sign[0]); + DBG1(DBG_LIB, "0 %7d", sign[1]); + DBG1(DBG_LIB, "+ %7d", sign[2]); +} +END_TEST + +Suite *bliss_sampler_suite_create() +{ + Suite *s; + TCase *tc; + + s = suite_create("bliss_sampler"); + + tc = tcase_create("sampler_gaussian"); + tcase_set_timeout(tc, 10); + tcase_add_loop_test(tc, test_bliss_sampler_gaussian, 0, countof(key_size)); + suite_add_tcase(s, tc); + + return s; +} diff --git a/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sign.c b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sign.c new file mode 100644 index 000000000..8b4e9cbf0 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_sign.c @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2014-2015 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "test_suite.h" + +#include <bliss_private_key.h> +#include <bliss_public_key.h> + +static u_int key_type[] = { 1, 3, 4 }; +static u_int key_strength[] = { 128, 160, 192 }; + +START_TEST(test_bliss_sign_all) +{ + signature_scheme_t signature_scheme; + private_key_t *privkey, *privkey1; + public_key_t *pubkey, *pubkey1; + chunk_t msg, signature, privkey_blob, pubkey_blob, pubkey_fp, privkey_fp; + int k; + + for (k = 0; k < 4; k++) + { + int verify_count = 1000; + + switch (k) + { + case 1: + signature_scheme = SIGN_BLISS_WITH_SHA256; + break; + case 2: + signature_scheme = SIGN_BLISS_WITH_SHA384; + break; + default: + signature_scheme = SIGN_BLISS_WITH_SHA512; + } + + /* enforce BLISS-B key for k = 2, 3 */ + lib->settings->set_bool(lib->settings, + "%s.plugins.bliss.use_bliss_b", k >= 2, lib->ns); + + msg = chunk_from_str("Hello Dolly!"); + + /* generate private key */ + privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_BLISS, + BUILD_KEY_SIZE, key_type[_i], BUILD_END); + ck_assert(privkey); + + /* generate ASN.1 DER and PEM encoding of private key */ + ck_assert(privkey->get_encoding(privkey, (k % 2) ? + PRIVKEY_ASN1_DER : PRIVKEY_PEM, &privkey_blob)); + + /* extract public key from private key */ + pubkey = privkey->get_public_key(privkey); + ck_assert(pubkey); + + /* generate ASN.1 DER and PEM encodings of public key */ + ck_assert(pubkey->get_encoding(pubkey, (k % 2) ? + PUBKEY_SPKI_ASN1_DER : PUBKEY_PEM, &pubkey_blob)); + + /* compare fingerprints of public and private key */ + ck_assert(pubkey->get_fingerprint(pubkey, (k % 2) ? + KEYID_PUBKEY_INFO_SHA1 : KEYID_PUBKEY_SHA1, &pubkey_fp)); + ck_assert(privkey->get_fingerprint(privkey, (k % 2) ? + KEYID_PUBKEY_INFO_SHA1 : KEYID_PUBKEY_SHA1, &privkey_fp)); + ck_assert(chunk_equals(pubkey_fp, privkey_fp)); + + /* retrieve fingerprints of public and private key from cache */ + ck_assert(pubkey->get_fingerprint(pubkey, (k % 2) ? + KEYID_PUBKEY_INFO_SHA1 : KEYID_PUBKEY_SHA1, &pubkey_fp)); + ck_assert(privkey->get_fingerprint(privkey, (k % 2) ? + KEYID_PUBKEY_INFO_SHA1 : KEYID_PUBKEY_SHA1, &privkey_fp)); + + /* get a reference of the private key and destroy both instances */ + privkey1 = privkey->get_ref(privkey); + ck_assert(privkey1); + ck_assert(privkey1 == privkey); + privkey->destroy(privkey); + privkey1->destroy(privkey1); + + /* get a reference of the public key and destroy both instances */ + pubkey1 = pubkey->get_ref(pubkey); + ck_assert(pubkey1); + ck_assert(pubkey1 == pubkey); + pubkey->destroy(pubkey); + pubkey1->destroy(pubkey1); + + /* enforce BLISS-B key for k = 1, 3 */ + lib->settings->set_bool(lib->settings, + "%s.plugins.bliss.use_bliss_b", k % 2, lib->ns); + + /* load private key from ASN.1 blob */ + privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_BLISS, + BUILD_BLOB, privkey_blob, BUILD_END); + ck_assert(privkey); + ck_assert(privkey->get_type(privkey) == KEY_BLISS); + ck_assert(privkey->get_keysize(privkey) == key_strength[_i]); + chunk_free(&privkey_blob); + + /* load public key from ASN.1 blob */ + pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ANY, + BUILD_BLOB, pubkey_blob, BUILD_END); + ck_assert(pubkey); + ck_assert(pubkey->get_type(pubkey) == KEY_BLISS); + ck_assert(pubkey->get_keysize(pubkey) == key_strength[_i]); + chunk_free(&pubkey_blob); + + /* generate and verify 1000 BLISS signatures */ + while (verify_count--) + { + ck_assert(privkey->sign(privkey, signature_scheme, msg, + &signature)); + ck_assert(pubkey->verify(pubkey, signature_scheme, msg, + signature)); + free(signature.ptr); + } + privkey->destroy(privkey); + pubkey->destroy(pubkey); + } +} +END_TEST + +START_TEST(test_bliss_sign_fail) +{ + private_key_t *privkey; + public_key_t *pubkey; + chunk_t msg, signature, encoding, fp; + + /* generate non-supported BLISS-II private key */ + privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_BLISS, + BUILD_KEY_SIZE, BLISS_II, BUILD_END); + ck_assert(!privkey); + + /* generate non-supported BLISS-B-II private key */ + privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_BLISS, + BUILD_KEY_SIZE, BLISS_B_II, BUILD_END); + ck_assert(!privkey); + + /* generate supported BLISS-B-I private key */ + privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_BLISS, + BUILD_KEY_SIZE, BLISS_B_I, BUILD_END); + ck_assert(privkey); + + /* wrong private key encoding format */ + ck_assert(!privkey->get_encoding(privkey, PUBKEY_PEM, &encoding)); + + /* wrong fingerprint encoding format */ + ck_assert(!privkey->get_fingerprint(privkey, KEYID_PGPV4, &fp)); + + /* extract public key */ + pubkey = privkey->get_public_key(privkey); + ck_assert(pubkey); + + /* wrong private key encoding format */ + ck_assert(!pubkey->get_encoding(pubkey, PRIVKEY_PEM, &encoding)); + + /* wrong fingerprint encoding format */ + ck_assert(!pubkey->get_fingerprint(pubkey, KEYID_PGPV4, &fp)); + + /* encryption / decryption operation is not defined for BLISS */ + ck_assert(!pubkey->encrypt(pubkey, ENCRYPT_UNKNOWN, chunk_empty, NULL)); + ck_assert(!privkey->decrypt(privkey, ENCRYPT_UNKNOWN, chunk_empty, NULL)); + + /* sign with invalid signature scheme */ + ck_assert(!privkey->sign(privkey, SIGN_UNKNOWN, msg, &signature)); + + /* generate valid signature */ + msg = chunk_from_str("Hello Dolly!"); + ck_assert(privkey->sign(privkey, SIGN_BLISS_WITH_SHA512, msg, &signature)); + + /* verify with invalid signature scheme */ + ck_assert(!pubkey->verify(pubkey, SIGN_UNKNOWN, msg, signature)); + + /* corrupt signature */ + signature.ptr[signature.len - 1] ^= 0x80; + ck_assert(!pubkey->verify(pubkey, SIGN_BLISS_WITH_SHA512, msg, signature)); + + free(signature.ptr); + privkey->destroy(privkey); + pubkey->destroy(pubkey); +} +END_TEST + +Suite *bliss_sign_suite_create() +{ + Suite *s; + TCase *tc; + + s = suite_create("bliss_sign"); + + tc = tcase_create("sign_all"); + test_case_set_timeout(tc, 30); + tcase_add_loop_test(tc, test_bliss_sign_all, 0, countof(key_type)); + suite_add_tcase(s, tc); + + tc = tcase_create("sign_fail"); + tcase_add_test(tc, test_bliss_sign_fail); + suite_add_tcase(s, tc); + + return s; +} diff --git a/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_signature.c b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_signature.c new file mode 100644 index 000000000..2a2f48c53 --- /dev/null +++ b/src/libstrongswan/plugins/bliss/tests/suites/test_bliss_signature.c @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2015 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "test_suite.h" + +#include <bliss_signature.h> + +static chunk_t data = chunk_from_chars( + 0xC1, 0xA1, 0x96, 0x98, 0x4F, 0x60, 0xF5, 0xCA, 0x89, 0x9E, + 0x78, 0xAF, 0x64, 0xDD, 0x01, 0x76, 0x04, 0x29, 0x11, 0xD0, + 0x21, 0x9E, 0xE4, 0x2D, 0xC5, 0x82, 0x69, 0x19, 0x82, 0x75, + 0x30, 0xAC, 0xB0, 0x64, 0xCB, 0x65, 0x19, 0x22, 0x4A, 0x03, + 0x03, 0x61, 0x4A, 0x37, 0x8E, 0xA3, 0xB6, 0xB3, 0x58, 0x44, + 0xFD, 0x68, 0x38, 0xF1, 0x4B, 0xCF, 0xE8, 0xA2, 0x05, 0x39, + 0x87, 0xE0, 0x5E, 0x7C, 0x45, 0x33, 0x4A, 0xEB, 0x2E, 0xCF, + 0x98, 0x01, 0x3D, 0x28, 0x60, 0xCE, 0x90, 0x45, 0xF0, 0x8E, + 0x36, 0x25, 0x50, 0x8B, 0xA2, 0xC0, 0x6E, 0xDF, 0xC2, 0xA1, + 0x35, 0xC1, 0x16, 0x14, 0xE8, 0x6A, 0xE3, 0x9C, 0x0B, 0x32, + 0x53, 0x55, 0x60, 0x52, 0x43, 0x93, 0xBB, 0x9F, 0x1D, 0x17, + 0xDC, 0x6E, 0x26, 0x99, 0x60, 0x83, 0x12, 0x53, 0xB0, 0x2B, + 0x36, 0xE2, 0x95, 0xA7, 0xBF, 0x9B, 0xC0, 0x0A, 0x63, 0xD6, + 0x32, 0xA9, 0xE2, 0xAD, 0x02, 0x53, 0x10, 0x81, 0x00, 0xD4, + 0x9A, 0xC2, 0x04, 0x1B, 0x48, 0x53, 0x37, 0xF0, 0x95, 0x39, + 0x4B, 0x2E, 0x37, 0x28, 0xE2, 0x70, 0xAD, 0xB5, 0xF1, 0x63, + 0x48, 0x17, 0xEF, 0x45, 0xC0, 0x30, 0xA6, 0xAA, 0x37, 0x9A, + 0x00, 0x8F, 0x8D, 0xAC, 0x66, 0x2C, 0x96, 0x8C, 0xC2, 0x74, + 0x9D, 0x66, 0x16, 0x5D, 0x70, 0x70, 0x1D, 0x2F, 0x11, 0xBD, + 0x11, 0x62, 0x58, 0xC6, 0xB2, 0xA6, 0xFA, 0xB7, 0x8C, 0x10, + 0x6A, 0x13, 0x34, 0x25, 0xB8, 0xF2, 0x46, 0xE3, 0x08, 0xAD, + 0x8D, 0x49, 0x33, 0x24, 0x37, 0xA5, 0x0A, 0xF9, 0x5E, 0x95, + 0xF9, 0x50, 0xDA, 0x2B, 0x80, 0x4F, 0x10, 0x4F, 0xAB, 0xE4, + 0x96, 0xB1, 0xA1, 0x28, 0xCE, 0x6D, 0xB6, 0x17, 0x33, 0x2A, + 0xE0, 0xC3, 0x80, 0xAA, 0x3D, 0x1A, 0x5C, 0x48, 0xA0, 0x48, + 0x60, 0xCC, 0xC7, 0x29, 0x4F, 0xB8, 0x96, 0xDF, 0xC6, 0x6A, + 0xC2, 0x83, 0x5E, 0xFC, 0xD7, 0x4E, 0xCA, 0x14, 0xB4, 0xC6, + 0x30, 0x29, 0xC7, 0xCE, 0x79, 0x42, 0x2D, 0x22, 0x28, 0x99, + 0x59, 0x14, 0xFB, 0x04, 0xAD, 0x79, 0x3C, 0x74, 0x34, 0xC6, + 0x7A, 0x1C, 0x13, 0x07, 0x17, 0xB1, 0x8A, 0x02, 0xA7, 0x70, + 0x3C, 0x5B, 0xBA, 0x88, 0xA2, 0xE6, 0x4B, 0x2A, 0xC1, 0x1E, + 0x42, 0xDD, 0x83, 0x2B, 0x00, 0xCC, 0xF8, 0x80, 0x03, 0x7E, + 0x97, 0xA4, 0x04, 0xE1, 0xB2, 0x0B, 0xE2, 0xF3, 0x91, 0x91, + 0x80, 0xA0, 0xC5, 0x44, 0x67, 0xB1, 0x56, 0xD0, 0x13, 0x58, + 0x7B, 0x6E, 0x12, 0xE7, 0x3A, 0x90, 0xE4, 0x2C, 0x44, 0x17, + 0xA3, 0xBD, 0x21, 0x68, 0x45, 0x61, 0x20, 0x57, 0x8D, 0x4A, + 0xF1, 0xE6, 0xD3, 0x17, 0xC9, 0xB0, 0xF8, 0x3A, 0x87, 0x6A, + 0x7E, 0x25, 0x45, 0xDC, 0x9A, 0x1D, 0xAC, 0x10, 0xB6, 0xF6, + 0x07, 0x4C, 0x50, 0x92, 0xF9, 0xE1, 0x3E, 0xAD, 0x3B, 0x80, + 0x20, 0xA8, 0x34, 0x04, 0xD6, 0x0D, 0x2D, 0x46, 0x69, 0x5E, + 0x8C, 0x4B, 0xB0, 0x1C, 0x37, 0xD8, 0x0D, 0x72, 0x7B, 0xE6, + 0xEE, 0x04, 0x81, 0x98, 0x78, 0x69, 0x88, 0xD8, 0xDF, 0x04, + 0xF0, 0x80, 0xE2, 0x0A, 0xD3, 0x60, 0x94, 0xDF, 0x49, 0xF7, + 0x52, 0x95, 0xA6, 0xAF, 0x8C, 0x13, 0x10, 0x09, 0xAA, 0x03, + 0xAC, 0x2C, 0x89, 0x2D, 0x2C, 0x61, 0x0F, 0xBE, 0x5C, 0x29, + 0x01, 0x7C, 0x9E, 0xD2, 0xFF, 0x34, 0xA1, 0x9E, 0xEE, 0xBF, + 0x28, 0x18, 0x3A, 0x17, 0xA6, 0x40, 0x94, 0xD5, 0xC4, 0xEC, + 0x27, 0x0A, 0x40, 0x1C, 0xC4, 0x16, 0x80, 0x4E, 0x6F, 0xDD, + 0xA5, 0x6A, 0x03, 0xE8, 0xBA, 0xB2, 0xAA, 0x7A, 0x7F, 0x4B, + 0x30, 0x11, 0x11, 0x12, 0x4A, 0xFE, 0xB2, 0x99, 0xC6, 0x12, + 0x1A, 0x98, 0xC0, 0x15, 0x41, 0xE1, 0x55, 0x35, 0x54, 0xF2, + 0x1C, 0xE2, 0x78, 0x85, 0x66, 0xD3, 0x9C, 0x8A, 0x88, 0x7C, + 0x86, 0x7F, 0x48, 0xBE, 0xB7, 0x1C, 0xE4, 0xCF, 0x35, 0xEE, + 0x24, 0xA6, 0x62, 0xD6, 0x36, 0x1F, 0x66, 0x10, 0x5D, 0xEF, + 0x07, 0x64, 0xA8, 0xD0, 0xAD, 0x2F, 0x47, 0x02, 0xA2, 0x0F, + 0x73, 0x96, 0x2A, 0x21, 0x20, 0x36, 0x01, 0xA3, 0x2F, 0x5E, + 0xC8, 0x80, 0x3A, 0x54, 0xA6, 0xB5, 0xD0, 0x19, 0xBF, 0xC4, + 0x35, 0x01, 0x0B, 0x2A, 0x8E, 0x61, 0x4A, 0xDD, 0xB2, 0x4A, + 0xE1, 0x0C, 0x15, 0x94, 0x9C, 0xD2, 0x54, 0x93, 0x85, 0x16, + 0x49, 0x69, 0xA0, 0x41, 0x34, 0x16, 0x69, 0x28, 0x74, 0x11, + 0x88, 0x44, 0xC8, 0x46, 0x5E, 0x62, 0xFF, 0x6E, 0xC5, 0xA8, + 0xE8, 0x8A, 0x8A, 0xFA, 0x2D, 0x94, 0x14, 0xD4, 0x51, 0x16, + 0xB0, 0x40, 0xDC, 0xF3, 0xAA, 0x97, 0x39, 0x1A, 0xDA, 0x7F, + 0x41, 0x61, 0x25, 0x1E, 0xDF, 0x46, 0x29, 0x44, 0x80, 0xEA, + 0x10, 0xE4, 0x0F, 0x94, 0xA6, 0x52, 0x20, 0x06, 0x9C, 0x69, + 0x48, 0x1F, 0x45, 0x30, 0x4B, 0x21, 0x02, 0xE6, 0xF3, 0x44, + 0x35, 0xC1, 0xC8, 0xC9, 0x68, 0x6C, 0x43, 0xA4, 0x56, 0x07, + 0x36, 0x11, 0xFB, 0x6D, 0x8E, 0xF0, 0x62, 0x5A, 0x3C, 0x8B, + 0x23, 0xF1, 0x46, 0xE2, 0x76, 0x2A, 0x6F, 0xBB, 0x09, 0x24, + 0x18, 0x64, 0xE6, 0x5C, 0xD0, 0x85, 0x69, 0xF0, 0x4F, 0x66, + 0x97, 0x40, 0x01, 0x27, 0xD1, 0x41, 0xCC, 0xEB, 0x4D, 0xB7, + 0x04, 0xC4, 0x91, 0xE0, 0x95, 0x8A, 0x43, 0x26, 0x2D, 0x1F, + 0x88, 0xA0, 0xD8 +); + +START_TEST(test_bliss_signature_fail) +{ + bliss_param_set_t set2 = { .id = BLISS_B_II }; + bliss_param_set_t *set; + bliss_signature_t *signature; + chunk_t encoding; + int k; + + signature = bliss_signature_create(&set2); + ck_assert(signature); + encoding = signature->get_encoding(signature); + ck_assert(encoding.len == 0); + signature->destroy(signature); + + signature = bliss_signature_create_from_data(&set2, data); + ck_assert(!signature); + + set = bliss_param_set_get_by_id(BLISS_B_I); + ck_assert(set); + + for (k = 0; k < data.len - 2; k++) + { + chunk_t fragment = { data.ptr, k }; + + signature = bliss_signature_create_from_data(set, fragment); + ck_assert(!signature); + } + signature = bliss_signature_create_from_data(set, data); + ck_assert(signature); + signature->destroy(signature); +} +END_TEST + +Suite *bliss_signature_suite_create() +{ + Suite *s; + TCase *tc; + + s = suite_create("bliss_signature"); + + tc = tcase_create("signature_fail"); + tcase_add_test(tc, test_bliss_signature_fail); + suite_add_tcase(s, tc); + + return s; +} diff --git a/src/libstrongswan/plugins/blowfish/Makefile.in b/src/libstrongswan/plugins/blowfish/Makefile.in index 33e5958ed..f19616552 100644 --- a/src/libstrongswan/plugins/blowfish/Makefile.in +++ b/src/libstrongswan/plugins/blowfish/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/ccm/Makefile.in b/src/libstrongswan/plugins/ccm/Makefile.in index 43bdf1fc5..ca7cadbe4 100644 --- a/src/libstrongswan/plugins/ccm/Makefile.in +++ b/src/libstrongswan/plugins/ccm/Makefile.in @@ -226,6 +226,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/cmac/Makefile.in b/src/libstrongswan/plugins/cmac/Makefile.in index 7c5674045..9e249399b 100644 --- a/src/libstrongswan/plugins/cmac/Makefile.in +++ b/src/libstrongswan/plugins/cmac/Makefile.in @@ -226,6 +226,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/cmac/cmac.c b/src/libstrongswan/plugins/cmac/cmac.c index c8cb7fbf2..4f222ff4e 100644 --- a/src/libstrongswan/plugins/cmac/cmac.c +++ b/src/libstrongswan/plugins/cmac/cmac.c @@ -247,6 +247,9 @@ METHOD(mac_t, set_key, bool, { chunk_t resized, iv, l; + memset(this->t, 0, this->b); + this->remaining_bytes = 0; + /* we support variable keys as defined in RFC 4615 */ if (key.len == this->b) { diff --git a/src/libstrongswan/plugins/constraints/Makefile.in b/src/libstrongswan/plugins/constraints/Makefile.in index 39469368c..2e623ad3b 100644 --- a/src/libstrongswan/plugins/constraints/Makefile.in +++ b/src/libstrongswan/plugins/constraints/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/constraints/constraints_validator.c b/src/libstrongswan/plugins/constraints/constraints_validator.c index 62ccc7108..a0f4a7465 100644 --- a/src/libstrongswan/plugins/constraints/constraints_validator.c +++ b/src/libstrongswan/plugins/constraints/constraints_validator.c @@ -52,16 +52,67 @@ static bool check_pathlen(x509_t *issuer, int pathlen) } /** - * Check if a FQDN/RFC822 constraint matches (suffix match) + * Check if a FQDN constraint matches */ -static bool suffix_matches(identification_t *constraint, identification_t *id) +static bool fqdn_matches(identification_t *constraint, identification_t *id) { - chunk_t c, i; + chunk_t c, i, diff; c = constraint->get_encoding(constraint); i = id->get_encoding(id); - return i.len >= c.len && chunk_equals(c, chunk_skip(i, i.len - c.len)); + if (!c.len || i.len < c.len) + { + return FALSE; + } + diff = chunk_create(i.ptr, i.len - c.len); + if (!chunk_equals(c, chunk_skip(i, diff.len))) + { + return FALSE; + } + if (!diff.len) + { + return TRUE; + } + if (c.ptr[0] == '.' || diff.ptr[diff.len - 1] == '.') + { + return TRUE; + } + return FALSE; +} + +/** + * Check if a RFC822 constraint matches + */ +static bool email_matches(identification_t *constraint, identification_t *id) +{ + chunk_t c, i, diff; + + c = constraint->get_encoding(constraint); + i = id->get_encoding(id); + + if (!c.len || i.len < c.len) + { + return FALSE; + } + if (memchr(c.ptr, '@', c.len)) + { /* constraint is a full email address */ + return chunk_equals(c, i); + } + diff = chunk_create(i.ptr, i.len - c.len); + if (!diff.len || !chunk_equals(c, chunk_skip(i, diff.len))) + { + return FALSE; + } + if (c.ptr[0] == '.') + { /* constraint is domain, suffix match */ + return TRUE; + } + if (diff.ptr[diff.len - 1] == '@') + { /* constraint is host specific, only username can be appended */ + return TRUE; + } + return FALSE; } /** @@ -121,8 +172,10 @@ static bool name_constraint_matches(identification_t *constraint, switch (type) { case ID_FQDN: + matches = fqdn_matches(constraint, id); + break; case ID_RFC822_ADDR: - matches = suffix_matches(constraint, id); + matches = email_matches(constraint, id); break; case ID_DER_ASN1_DN: matches = dn_matches(constraint, id); @@ -151,7 +204,7 @@ static bool name_constraint_inherited(identification_t *constraint, x509_t *x509, bool permitted) { enumerator_t *enumerator; - identification_t *id; + identification_t *id, *a, *b; bool inherited = FALSE; id_type_t type; @@ -166,28 +219,26 @@ static bool name_constraint_inherited(identification_t *constraint, { if (id->get_type(id) == type) { + if (permitted) + { /* permitted constraint can be narrowed */ + a = constraint; + b = id; + } + else + { /* excluded constraint can be widened */ + a = id; + b = constraint; + } switch (type) { case ID_FQDN: + inherited = fqdn_matches(a, b); + break; case ID_RFC822_ADDR: - if (permitted) - { /* permitted constraint can be narrowed */ - inherited = suffix_matches(constraint, id); - } - else - { /* excluded constraint can be widened */ - inherited = suffix_matches(id, constraint); - } + inherited = email_matches(a, b); break; case ID_DER_ASN1_DN: - if (permitted) - { - inherited = dn_matches(constraint, id); - } - else - { - inherited = dn_matches(id, constraint); - } + inherited = dn_matches(a, b); break; default: DBG1(DBG_CFG, "%N NameConstraint matching not implemented", @@ -298,8 +349,7 @@ static bool has_policy(x509_t *issuer, chunk_t oid) /** * Check certificatePolicies. */ -static bool check_policy(x509_t *subject, x509_t *issuer, bool check, - auth_cfg_t *auth) +static bool check_policy(x509_t *subject, x509_t *issuer) { certificate_t *cert = (certificate_t*)subject; x509_policy_mapping_t *mapping; @@ -323,33 +373,85 @@ static bool check_policy(x509_t *subject, x509_t *issuer, bool check, } enumerator->destroy(enumerator); - if (check) + enumerator = subject->create_cert_policy_enumerator(subject); + while (enumerator->enumerate(enumerator, &policy)) + { + if (!has_policy(issuer, policy->oid)) + { + oid = asn1_oid_to_string(policy->oid); + DBG1(DBG_CFG, "policy %s missing in issuing certificate '%Y'", + oid, cert->get_issuer(cert)); + free(oid); + enumerator->destroy(enumerator); + return FALSE; + } + } + enumerator->destroy(enumerator); + + return TRUE; +} + +/** + * Check if a given policy is valid under a trustchain + */ +static bool is_policy_valid(linked_list_t *chain, chunk_t oid) +{ + x509_policy_mapping_t *mapping; + x509_cert_policy_t *policy; + x509_t *issuer; + enumerator_t *issuers, *policies, *mappings; + bool found = TRUE; + + issuers = chain->create_enumerator(chain); + while (issuers->enumerate(issuers, &issuer)) { - enumerator = subject->create_cert_policy_enumerator(subject); - while (enumerator->enumerate(enumerator, &policy)) + int maxmap = 8; + + while (found) { - if (!has_policy(issuer, policy->oid)) + found = FALSE; + + policies = issuer->create_cert_policy_enumerator(issuer); + while (policies->enumerate(policies, &policy)) { - oid = asn1_oid_to_string(policy->oid); - DBG1(DBG_CFG, "policy %s missing in issuing certificate '%Y'", - oid, cert->get_issuer(cert)); - free(oid); - enumerator->destroy(enumerator); - return FALSE; + if (chunk_equals(oid, policy->oid) || + chunk_equals(any_policy, policy->oid)) + { + found = TRUE; + break; + } } - if (auth) + policies->destroy(policies); + if (found) { - oid = asn1_oid_to_string(policy->oid); - if (oid) + break; + } + /* fall back to a mapped policy */ + mappings = issuer->create_policy_mapping_enumerator(issuer); + while (mappings->enumerate(mappings, &mapping)) + { + if (chunk_equals(mapping->subject, oid)) { - auth->add(auth, AUTH_RULE_CERT_POLICY, oid); + oid = mapping->issuer; + found = TRUE; + break; } } + mappings->destroy(mappings); + if (--maxmap == 0) + { + found = FALSE; + break; + } + } + if (!found) + { + break; } - enumerator->destroy(enumerator); } + issuers->destroy(issuers); - return TRUE; + return found; } /** @@ -364,7 +466,7 @@ static bool has_policy_chain(linked_list_t *chain, x509_t *subject, int len) enumerator = chain->create_enumerator(chain); while (len-- > 0 && enumerator->enumerate(enumerator, &issuer)) { - if (!check_policy(subject, issuer, TRUE, NULL)) + if (!check_policy(subject, issuer)) { valid = FALSE; break; @@ -450,6 +552,7 @@ static bool check_policy_constraints(x509_t *issuer, u_int pathlen, { if (subject->get_type(subject) == CERT_X509) { + x509_cert_policy_t *policy; enumerator_t *enumerator; linked_list_t *chain; certificate_t *cert; @@ -457,6 +560,7 @@ static bool check_policy_constraints(x509_t *issuer, u_int pathlen, x509_t *x509; int len = 0; u_int expl, inh; + char *oid; /* prepare trustchain to validate */ chain = linked_list_create(); @@ -517,6 +621,31 @@ static bool check_policy_constraints(x509_t *issuer, u_int pathlen, } enumerator->destroy(enumerator); + if (valid) + { + x509 = (x509_t*)subject; + + enumerator = x509->create_cert_policy_enumerator(x509); + while (enumerator->enumerate(enumerator, &policy)) + { + oid = asn1_oid_to_string(policy->oid); + if (oid) + { + if (is_policy_valid(chain, policy->oid)) + { + auth->add(auth, AUTH_RULE_CERT_POLICY, oid); + } + else + { + DBG1(DBG_CFG, "certificate policy %s for '%Y' " + "not allowed by trustchain, ignored", + oid, subject->get_subject(subject)); + free(oid); + } + } + } + enumerator->destroy(enumerator); + } chain->destroy(chain); } } @@ -543,12 +672,6 @@ METHOD(cert_validator_t, validate, bool, subject); return FALSE; } - if (!check_policy((x509_t*)subject, (x509_t*)issuer, !pathlen, auth)) - { - lib->credmgr->call_hook(lib->credmgr, CRED_HOOK_POLICY_VIOLATION, - subject); - return FALSE; - } if (anchor) { if (!check_policy_constraints((x509_t*)issuer, pathlen, auth)) diff --git a/src/libstrongswan/plugins/ctr/Makefile.in b/src/libstrongswan/plugins/ctr/Makefile.in index 4b397e85d..7b7231b85 100644 --- a/src/libstrongswan/plugins/ctr/Makefile.in +++ b/src/libstrongswan/plugins/ctr/Makefile.in @@ -226,6 +226,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/curl/Makefile.in b/src/libstrongswan/plugins/curl/Makefile.in index 2e221c8b4..d525eac02 100644 --- a/src/libstrongswan/plugins/curl/Makefile.in +++ b/src/libstrongswan/plugins/curl/Makefile.in @@ -226,6 +226,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/des/Makefile.in b/src/libstrongswan/plugins/des/Makefile.in index 0025a2b20..96b2f6055 100644 --- a/src/libstrongswan/plugins/des/Makefile.in +++ b/src/libstrongswan/plugins/des/Makefile.in @@ -226,6 +226,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/dnskey/Makefile.in b/src/libstrongswan/plugins/dnskey/Makefile.in index 0b30923a5..910289906 100644 --- a/src/libstrongswan/plugins/dnskey/Makefile.in +++ b/src/libstrongswan/plugins/dnskey/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/files/Makefile.am b/src/libstrongswan/plugins/files/Makefile.am new file mode 100644 index 000000000..67767495c --- /dev/null +++ b/src/libstrongswan/plugins/files/Makefile.am @@ -0,0 +1,16 @@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/libstrongswan + +AM_CFLAGS = \ + $(PLUGIN_CFLAGS) + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-files.la +else +plugin_LTLIBRARIES = libstrongswan-files.la +endif + +libstrongswan_files_la_SOURCES = \ + files_plugin.h files_plugin.c files_fetcher.c files_fetcher.h + +libstrongswan_files_la_LDFLAGS = -module -avoid-version diff --git a/src/libstrongswan/plugins/files/Makefile.in b/src/libstrongswan/plugins/files/Makefile.in new file mode 100644 index 000000000..31dc4a3ac --- /dev/null +++ b/src/libstrongswan/plugins/files/Makefile.in @@ -0,0 +1,775 @@ +# Makefile.in generated by automake 1.14.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/libstrongswan/plugins/files +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ + $(top_srcdir)/m4/config/ltoptions.m4 \ + $(top_srcdir)/m4/config/ltsugar.m4 \ + $(top_srcdir)/m4/config/ltversion.m4 \ + $(top_srcdir)/m4/config/lt~obsolete.m4 \ + $(top_srcdir)/m4/macros/split-package-version.m4 \ + $(top_srcdir)/m4/macros/with.m4 \ + $(top_srcdir)/m4/macros/enable-disable.m4 \ + $(top_srcdir)/m4/macros/add-plugin.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(plugindir)" +LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) +libstrongswan_files_la_LIBADD = +am_libstrongswan_files_la_OBJECTS = files_plugin.lo files_fetcher.lo +libstrongswan_files_la_OBJECTS = $(am_libstrongswan_files_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libstrongswan_files_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libstrongswan_files_la_LDFLAGS) \ + $(LDFLAGS) -o $@ +@MONOLITHIC_FALSE@am_libstrongswan_files_la_rpath = -rpath \ +@MONOLITHIC_FALSE@ $(plugindir) +@MONOLITHIC_TRUE@am_libstrongswan_files_la_rpath = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libstrongswan_files_la_SOURCES) +DIST_SOURCES = $(libstrongswan_files_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ALLOCA = @ALLOCA@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BFDLIB = @BFDLIB@ +BTLIB = @BTLIB@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +COVERAGE_CFLAGS = @COVERAGE_CFLAGS@ +COVERAGE_LDFLAGS = @COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLIB = @DLLIB@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GEM = @GEM@ +GENHTML = @GENHTML@ +GPERF = @GPERF@ +GPRBUILD = @GPRBUILD@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +MYSQLCFLAG = @MYSQLCFLAG@ +MYSQLCONFIG = @MYSQLCONFIG@ +MYSQLLIB = @MYSQLLIB@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPENSSL_LIB = @OPENSSL_LIB@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@ +PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@ +PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@ +PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ +PTHREADLIB = @PTHREADLIB@ +PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ +PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ +PYTHON_PLATFORM = @PYTHON_PLATFORM@ +PYTHON_PREFIX = @PYTHON_PREFIX@ +PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ +RANLIB = @RANLIB@ +RTLIB = @RTLIB@ +RUBY = @RUBY@ +RUBYGEMDIR = @RUBYGEMDIR@ +RUBYINCLUDE = @RUBYINCLUDE@ +RUBYLIB = @RUBYLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOCKLIB = @SOCKLIB@ +STRIP = @STRIP@ +UNWINDLIB = @UNWINDLIB@ +VERSION = @VERSION@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +aikgen_plugins = @aikgen_plugins@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +attest_plugins = @attest_plugins@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +c_plugins = @c_plugins@ +charon_natt_port = @charon_natt_port@ +charon_plugins = @charon_plugins@ +charon_udp_port = @charon_udp_port@ +clearsilver_LIBS = @clearsilver_LIBS@ +cmd_plugins = @cmd_plugins@ +datadir = @datadir@ +datarootdir = @datarootdir@ +dbusservicedir = @dbusservicedir@ +dev_headers = @dev_headers@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +fips_mode = @fips_mode@ +gtk_CFLAGS = @gtk_CFLAGS@ +gtk_LIBS = @gtk_LIBS@ +h_plugins = @h_plugins@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +imcvdir = @imcvdir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +ipsec_script = @ipsec_script@ +ipsec_script_upper = @ipsec_script_upper@ +ipsecdir = @ipsecdir@ +ipsecgroup = @ipsecgroup@ +ipseclibdir = @ipseclibdir@ +ipsecuser = @ipsecuser@ +json_CFLAGS = @json_CFLAGS@ +json_LIBS = @json_LIBS@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ +linux_headers = @linux_headers@ +localedir = @localedir@ +localstatedir = @localstatedir@ +maemo_CFLAGS = @maemo_CFLAGS@ +maemo_LIBS = @maemo_LIBS@ +manager_plugins = @manager_plugins@ +mandir = @mandir@ +medsrv_plugins = @medsrv_plugins@ +mkdir_p = @mkdir_p@ +nm_CFLAGS = @nm_CFLAGS@ +nm_LIBS = @nm_LIBS@ +nm_ca_dir = @nm_ca_dir@ +nm_plugins = @nm_plugins@ +oldincludedir = @oldincludedir@ +pcsclite_CFLAGS = @pcsclite_CFLAGS@ +pcsclite_LIBS = @pcsclite_LIBS@ +pdfdir = @pdfdir@ +piddir = @piddir@ +pkgpyexecdir = @pkgpyexecdir@ +pkgpythondir = @pkgpythondir@ +pki_plugins = @pki_plugins@ +plugindir = @plugindir@ +pool_plugins = @pool_plugins@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +pyexecdir = @pyexecdir@ +pythondir = @pythondir@ +random_device = @random_device@ +resolv_conf = @resolv_conf@ +routing_table = @routing_table@ +routing_table_prio = @routing_table_prio@ +s_plugins = @s_plugins@ +sbindir = @sbindir@ +scepclient_plugins = @scepclient_plugins@ +scripts_plugins = @scripts_plugins@ +sharedstatedir = @sharedstatedir@ +soup_CFLAGS = @soup_CFLAGS@ +soup_LIBS = @soup_LIBS@ +srcdir = @srcdir@ +starter_plugins = @starter_plugins@ +strongswan_conf = @strongswan_conf@ +strongswan_options = @strongswan_options@ +swanctldir = @swanctldir@ +sysconfdir = @sysconfdir@ +systemd_daemon_CFLAGS = @systemd_daemon_CFLAGS@ +systemd_daemon_LIBS = @systemd_daemon_LIBS@ +systemd_journal_CFLAGS = @systemd_journal_CFLAGS@ +systemd_journal_LIBS = @systemd_journal_LIBS@ +systemdsystemunitdir = @systemdsystemunitdir@ +t_plugins = @t_plugins@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +urandom_device = @urandom_device@ +xml_CFLAGS = @xml_CFLAGS@ +xml_LIBS = @xml_LIBS@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/libstrongswan + +AM_CFLAGS = \ + $(PLUGIN_CFLAGS) + +@MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-files.la +@MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-files.la +libstrongswan_files_la_SOURCES = \ + files_plugin.h files_plugin.c files_fetcher.c files_fetcher.h + +libstrongswan_files_la_LDFLAGS = -module -avoid-version +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/libstrongswan/plugins/files/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/libstrongswan/plugins/files/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ + } + +uninstall-pluginLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(plugindir)/$$f"; \ + done + +clean-pluginLTLIBRARIES: + -test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES) + @list='$(plugin_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libstrongswan-files.la: $(libstrongswan_files_la_OBJECTS) $(libstrongswan_files_la_DEPENDENCIES) $(EXTRA_libstrongswan_files_la_DEPENDENCIES) + $(AM_V_CCLD)$(libstrongswan_files_la_LINK) $(am_libstrongswan_files_la_rpath) $(libstrongswan_files_la_OBJECTS) $(libstrongswan_files_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/files_fetcher.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/files_plugin.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: + for dir in "$(DESTDIR)$(plugindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + clean-pluginLTLIBRARIES mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-pluginLTLIBRARIES + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-pluginLTLIBRARIES + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pluginLTLIBRARIES install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pluginLTLIBRARIES + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libstrongswan/plugins/files/files_fetcher.c b/src/libstrongswan/plugins/files/files_fetcher.c new file mode 100644 index 000000000..e0b7cbdb6 --- /dev/null +++ b/src/libstrongswan/plugins/files/files_fetcher.c @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2015 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include <errno.h> + +#include <library.h> +#include <utils/debug.h> + +#include "files_fetcher.h" + +typedef struct private_files_fetcher_t private_files_fetcher_t; + +/** + * private data of a files_fetcher_t object. + */ +struct private_files_fetcher_t { + + /** + * Public data + */ + files_fetcher_t public; + + /** + * Callback function + */ + fetcher_callback_t cb; +}; + +METHOD(fetcher_t, fetch, status_t, + private_files_fetcher_t *this, char *uri, void *userdata) +{ + chunk_t *data; + status_t status = FAILED; + + if (this->cb == fetcher_default_callback) + { + *(chunk_t*)userdata = chunk_empty; + } + if (!strpfx(uri, "file://")) + { + return NOT_SUPPORTED; + } + uri = uri + strlen("file://"); + data = chunk_map(uri, FALSE); + if (!data) + { + DBG1(DBG_LIB, " opening '%s' failed: %s", uri, strerror(errno)); + return FAILED; + } + if (this->cb(userdata, *data)) + { + status = SUCCESS; + } + chunk_unmap(data); + return status; +} + +METHOD(fetcher_t, set_option, bool, + private_files_fetcher_t *this, fetcher_option_t option, ...) +{ + bool supported = TRUE; + va_list args; + + va_start(args, option); + switch (option) + { + case FETCH_CALLBACK: + { + this->cb = va_arg(args, fetcher_callback_t); + break; + } + default: + supported = FALSE; + break; + } + va_end(args); + return supported; +} + +METHOD(fetcher_t, destroy, void, + private_files_fetcher_t *this) +{ + free(this); +} + +/* + * Described in header. + */ +files_fetcher_t *files_fetcher_create() +{ + private_files_fetcher_t *this; + + INIT(this, + .public = { + .interface = { + .fetch = _fetch, + .set_option = _set_option, + .destroy = _destroy, + }, + }, + .cb = fetcher_default_callback, + ); + + return &this->public; +} diff --git a/src/libcharon/plugins/unit_tester/tests.h b/src/libstrongswan/plugins/files/files_fetcher.h index 169292e9b..7fc4ec98e 100644 --- a/src/libcharon/plugins/unit_tester/tests.h +++ b/src/libstrongswan/plugins/files/files_fetcher.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Martin Willi + * Copyright (C) 2015 Tobias Brunner * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -14,17 +14,29 @@ */ /** - * @defgroup tests tests - * @{ @ingroup unit_tester + * @defgroup files_fetcher files_fetcher + * @{ @ingroup files_p */ -DEFINE_TEST("auth cfg", test_auth_cfg, FALSE) -DEFINE_TEST("CURL get", test_curl_get, FALSE) -DEFINE_TEST("MySQL operations", test_mysql, FALSE) -DEFINE_TEST("SQLite operations", test_sqlite, FALSE) -DEFINE_TEST("X509 certificate", test_cert_x509, FALSE) -DEFINE_TEST("Mediation database key fetch", test_med_db, FALSE) -DEFINE_TEST("IP pool", test_pool, FALSE) -DEFINE_TEST("SSH agent", test_agent, FALSE) +#ifndef FILES_FETCHER_H_ +#define FILES_FETCHER_H_ -/** @}*/ +typedef struct files_fetcher_t files_fetcher_t; + +/** + * Fetcher implementation loading local files + */ +struct files_fetcher_t { + + /** + * Implements fetcher interface + */ + fetcher_t interface; +}; + +/** + * Create a files_fetcher instance. + */ +files_fetcher_t *files_fetcher_create(); + +#endif /** FILES_FETCHER_H_ @}*/ diff --git a/src/libstrongswan/plugins/files/files_plugin.c b/src/libstrongswan/plugins/files/files_plugin.c new file mode 100644 index 000000000..6ab735dab --- /dev/null +++ b/src/libstrongswan/plugins/files/files_plugin.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2015 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "files_plugin.h" +#include "files_fetcher.h" + +#include <library.h> +#include <utils/debug.h> + +typedef struct private_files_plugin_t private_files_plugin_t; + +/** + * private data of files_plugin + */ +struct private_files_plugin_t { + + /** + * public functions + */ + files_plugin_t public; +}; + +METHOD(plugin_t, get_name, char*, + private_files_plugin_t *this) +{ + return "files"; +} + +METHOD(plugin_t, get_features, int, + private_files_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_REGISTER(FETCHER, files_fetcher_create), + PLUGIN_PROVIDE(FETCHER, "file://"), + }; + *features = f; + return countof(f); +} + +METHOD(plugin_t, destroy, void, + private_files_plugin_t *this) +{ + free(this); +} + +/* + * see header file + */ +plugin_t *files_plugin_create() +{ + private_files_plugin_t *this; + + INIT(this, + .public = { + .plugin = { + .get_name = _get_name, + .get_features = _get_features, + .destroy = _destroy, + }, + }, + ); + + return &this->public.plugin; +} diff --git a/src/libcharon/plugins/unit_tester/unit_tester.h b/src/libstrongswan/plugins/files/files_plugin.h index 08784f6f4..c121b9652 100644 --- a/src/libcharon/plugins/unit_tester/unit_tester.h +++ b/src/libstrongswan/plugins/files/files_plugin.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Martin Willi + * Copyright (C) 2015 Tobias Brunner * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -14,31 +14,29 @@ */ /** - * @defgroup unit_tester unit_tester - * @{ @ingroup cplugins + * @defgroup files_p files + * @ingroup plugins + * + * @defgroup files_plugin files_plugin + * @{ @ingroup files_p */ -#ifndef UNIT_TESTER_H_ -#define UNIT_TESTER_H_ +#ifndef FILES_PLUGIN_H_ +#define FILES_PLUGIN_H_ #include <plugins/plugin.h> -typedef struct unit_tester_t unit_tester_t; +typedef struct files_plugin_t files_plugin_t; /** - * Unit testing plugin. - * - * The unit testing plugin runs tests on plugin initialization. Tests are - * defined in tests.h using the DEFINE_TEST macro. Implementation of the - * tests is done in the tests folder. Each test has uses a function which - * returns TRUE for success or FALSE for failure. + * Plugin implementing fetcher interface loading local files directly. */ -struct unit_tester_t { +struct files_plugin_t { /** - * Implements the plugin interface. + * implements plugin interface */ plugin_t plugin; }; -#endif /** UNIT_TESTER_H_ @}*/ +#endif /** FILES_PLUGIN_H_ @}*/ diff --git a/src/libstrongswan/plugins/fips_prf/Makefile.in b/src/libstrongswan/plugins/fips_prf/Makefile.in index 64ae66559..b7ca1ce97 100644 --- a/src/libstrongswan/plugins/fips_prf/Makefile.in +++ b/src/libstrongswan/plugins/fips_prf/Makefile.in @@ -228,6 +228,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -288,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -365,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/fips_prf/fips_prf.c b/src/libstrongswan/plugins/fips_prf/fips_prf.c index 23825078e..25accf996 100644 --- a/src/libstrongswan/plugins/fips_prf/fips_prf.c +++ b/src/libstrongswan/plugins/fips_prf/fips_prf.c @@ -116,6 +116,12 @@ METHOD(prf_t, get_bytes, bool, u_int8_t *xkey = this->key; u_int8_t one[this->b]; + if (!w) + { + /* append mode is not supported */ + return FALSE; + } + memset(one, 0, this->b); one[this->b - 1] = 0x01; @@ -250,4 +256,3 @@ fips_prf_t *fips_prf_create(pseudo_random_function_t algo) return &this->public; } - diff --git a/src/libstrongswan/plugins/gcm/Makefile.in b/src/libstrongswan/plugins/gcm/Makefile.in index 511bfc365..e125ab884 100644 --- a/src/libstrongswan/plugins/gcm/Makefile.in +++ b/src/libstrongswan/plugins/gcm/Makefile.in @@ -226,6 +226,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/gcrypt/Makefile.in b/src/libstrongswan/plugins/gcrypt/Makefile.in index 0c7d22d71..4ce7438fc 100644 --- a/src/libstrongswan/plugins/gcrypt/Makefile.in +++ b/src/libstrongswan/plugins/gcrypt/Makefile.in @@ -230,6 +230,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -290,10 +291,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -367,6 +370,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c b/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c index f418b941d..744ec0bbf 100644 --- a/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c +++ b/src/libstrongswan/plugins/gcrypt/gcrypt_dh.c @@ -35,7 +35,7 @@ struct private_gcrypt_dh_t { /** * Diffie Hellman group number */ - u_int16_t group; + diffie_hellman_group_t group; /* * Generator value @@ -73,12 +73,17 @@ struct private_gcrypt_dh_t { size_t p_len; }; -METHOD(diffie_hellman_t, set_other_public_value, void, +METHOD(diffie_hellman_t, set_other_public_value, bool, private_gcrypt_dh_t *this, chunk_t value) { gcry_mpi_t p_min_1; gcry_error_t err; + if (!diffie_hellman_verify_value(this->group, value)) + { + return FALSE; + } + if (this->yb) { gcry_mpi_release(this->yb); @@ -88,7 +93,7 @@ METHOD(diffie_hellman_t, set_other_public_value, void, if (err) { DBG1(DBG_LIB, "importing mpi yb failed: %s", gpg_strerror(err)); - return; + return FALSE; } p_min_1 = gcry_mpi_new(this->p_len * 8); @@ -112,6 +117,7 @@ METHOD(diffie_hellman_t, set_other_public_value, void, " y < 2 || y > p - 1 "); } gcry_mpi_release(p_min_1); + return this->zz != NULL; } /** @@ -132,21 +138,22 @@ static chunk_t export_mpi(gcry_mpi_t value, size_t len) return chunk; } -METHOD(diffie_hellman_t, get_my_public_value, void, +METHOD(diffie_hellman_t, get_my_public_value, bool, private_gcrypt_dh_t *this, chunk_t *value) { *value = export_mpi(this->ya, this->p_len); + return TRUE; } -METHOD(diffie_hellman_t, get_shared_secret, status_t, +METHOD(diffie_hellman_t, get_shared_secret, bool, private_gcrypt_dh_t *this, chunk_t *secret) { if (!this->zz) { - return FAILED; + return FALSE; } *secret = export_mpi(this->zz, this->p_len); - return SUCCESS; + return TRUE; } METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, diff --git a/src/libstrongswan/plugins/gmp/Makefile.in b/src/libstrongswan/plugins/gmp/Makefile.in index eab4a0047..788cb931e 100644 --- a/src/libstrongswan/plugins/gmp/Makefile.in +++ b/src/libstrongswan/plugins/gmp/Makefile.in @@ -227,6 +227,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c index b74d35169..4fcb168fa 100644 --- a/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c +++ b/src/libstrongswan/plugins/gmp/gmp_diffie_hellman.c @@ -42,7 +42,7 @@ struct private_gmp_diffie_hellman_t { /** * Diffie Hellman group number. */ - u_int16_t group; + diffie_hellman_group_t group; /* * Generator value. @@ -85,11 +85,16 @@ struct private_gmp_diffie_hellman_t { bool computed; }; -METHOD(diffie_hellman_t, set_other_public_value, void, +METHOD(diffie_hellman_t, set_other_public_value, bool, private_gmp_diffie_hellman_t *this, chunk_t value) { mpz_t p_min_1; + if (!diffie_hellman_verify_value(this->group, value)) + { + return FALSE; + } + mpz_init(p_min_1); mpz_sub_ui(p_min_1, this->p, 1); @@ -142,9 +147,10 @@ METHOD(diffie_hellman_t, set_other_public_value, void, " y < 2 || y > p - 1 "); } mpz_clear(p_min_1); + return this->computed; } -METHOD(diffie_hellman_t, get_my_public_value, void, +METHOD(diffie_hellman_t, get_my_public_value, bool, private_gmp_diffie_hellman_t *this,chunk_t *value) { value->len = this->p_len; @@ -153,22 +159,23 @@ METHOD(diffie_hellman_t, get_my_public_value, void, { value->len = 0; } + return TRUE; } -METHOD(diffie_hellman_t, get_shared_secret, status_t, +METHOD(diffie_hellman_t, get_shared_secret, bool, private_gmp_diffie_hellman_t *this, chunk_t *secret) { if (!this->computed) { - return FAILED; + return FALSE; } secret->len = this->p_len; secret->ptr = mpz_export(NULL, NULL, 1, secret->len, 1, 0, this->zz); if (secret->ptr == NULL) { - return FAILED; + return FALSE; } - return SUCCESS; + return TRUE; } METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, @@ -245,7 +252,7 @@ static gmp_diffie_hellman_t *create_generic(diffie_hellman_group_t group, *random.ptr &= 0x7F; } mpz_import(this->xa, random.len, 1, 1, 1, 0, random.ptr); - chunk_free(&random); + chunk_clear(&random); DBG2(DBG_LIB, "size of DH secret exponent: %u bits", mpz_sizeinbase(this->xa, 2)); diff --git a/src/libstrongswan/plugins/hmac/Makefile.in b/src/libstrongswan/plugins/hmac/Makefile.in index bf34e4c9f..a8c39cbab 100644 --- a/src/libstrongswan/plugins/hmac/Makefile.in +++ b/src/libstrongswan/plugins/hmac/Makefile.in @@ -226,6 +226,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/hmac/hmac.c b/src/libstrongswan/plugins/hmac/hmac.c index 44cb46b4d..96a14aed9 100644 --- a/src/libstrongswan/plugins/hmac/hmac.c +++ b/src/libstrongswan/plugins/hmac/hmac.c @@ -103,7 +103,8 @@ METHOD(mac_t, set_key, bool, if (key.len > this->b) { /* if key is too long, it will be hashed */ - if (!this->h->get_hash(this->h, key, buffer)) + if (!this->h->reset(this->h) || + !this->h->get_hash(this->h, key, buffer)) { return FALSE; } diff --git a/src/libstrongswan/plugins/keychain/Makefile.in b/src/libstrongswan/plugins/keychain/Makefile.in index 17faa569d..8f6a6f54d 100644 --- a/src/libstrongswan/plugins/keychain/Makefile.in +++ b/src/libstrongswan/plugins/keychain/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/ldap/Makefile.in b/src/libstrongswan/plugins/ldap/Makefile.in index 332a587c9..5316323a4 100644 --- a/src/libstrongswan/plugins/ldap/Makefile.in +++ b/src/libstrongswan/plugins/ldap/Makefile.in @@ -226,6 +226,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/md4/Makefile.in b/src/libstrongswan/plugins/md4/Makefile.in index 91fe8c45f..d5f9c6c81 100644 --- a/src/libstrongswan/plugins/md4/Makefile.in +++ b/src/libstrongswan/plugins/md4/Makefile.in @@ -226,6 +226,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/md5/Makefile.in b/src/libstrongswan/plugins/md5/Makefile.in index ba6cb0cf6..1dd3892cd 100644 --- a/src/libstrongswan/plugins/md5/Makefile.in +++ b/src/libstrongswan/plugins/md5/Makefile.in @@ -226,6 +226,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/mysql/Makefile.in b/src/libstrongswan/plugins/mysql/Makefile.in index bca4562d6..e2fb7e720 100644 --- a/src/libstrongswan/plugins/mysql/Makefile.in +++ b/src/libstrongswan/plugins/mysql/Makefile.in @@ -228,6 +228,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -288,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -365,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/nonce/Makefile.in b/src/libstrongswan/plugins/nonce/Makefile.in index 0d15d7c2e..0b51ba5d8 100644 --- a/src/libstrongswan/plugins/nonce/Makefile.in +++ b/src/libstrongswan/plugins/nonce/Makefile.in @@ -227,6 +227,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/ntru/Makefile.am b/src/libstrongswan/plugins/ntru/Makefile.am index b959afa8e..c9fcee982 100644 --- a/src/libstrongswan/plugins/ntru/Makefile.am +++ b/src/libstrongswan/plugins/ntru/Makefile.am @@ -16,7 +16,6 @@ libstrongswan_ntru_la_SOURCES = \ ntru_convert.h ntru_convert.c \ ntru_drbg.h ntru_drbg.c \ ntru_ke.h ntru_ke.c \ - ntru_mgf1.h ntru_mgf1.c \ ntru_param_set.h ntru_param_set.c \ ntru_poly.h ntru_poly.c \ ntru_public_key.h ntru_public_key.c \ diff --git a/src/libstrongswan/plugins/ntru/Makefile.in b/src/libstrongswan/plugins/ntru/Makefile.in index e57a3673e..5636692ab 100644 --- a/src/libstrongswan/plugins/ntru/Makefile.in +++ b/src/libstrongswan/plugins/ntru/Makefile.in @@ -129,9 +129,8 @@ am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) libstrongswan_ntru_la_LIBADD = am_libstrongswan_ntru_la_OBJECTS = ntru_plugin.lo ntru_convert.lo \ - ntru_drbg.lo ntru_ke.lo ntru_mgf1.lo ntru_param_set.lo \ - ntru_poly.lo ntru_public_key.lo ntru_private_key.lo \ - ntru_trits.lo + ntru_drbg.lo ntru_ke.lo ntru_param_set.lo ntru_poly.lo \ + ntru_public_key.lo ntru_private_key.lo ntru_trits.lo libstrongswan_ntru_la_OBJECTS = $(am_libstrongswan_ntru_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -229,6 +228,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ @@ -438,7 +442,6 @@ libstrongswan_ntru_la_SOURCES = \ ntru_convert.h ntru_convert.c \ ntru_drbg.h ntru_drbg.c \ ntru_ke.h ntru_ke.c \ - ntru_mgf1.h ntru_mgf1.c \ ntru_param_set.h ntru_param_set.c \ ntru_poly.h ntru_poly.c \ ntru_public_key.h ntru_public_key.c \ @@ -539,7 +542,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_convert.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_drbg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_ke.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_mgf1.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_param_set.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_plugin.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntru_poly.Plo@am__quote@ diff --git a/src/libstrongswan/plugins/ntru/ntru_ke.c b/src/libstrongswan/plugins/ntru/ntru_ke.c index abaa22336..3b5df81d9 100644 --- a/src/libstrongswan/plugins/ntru/ntru_ke.c +++ b/src/libstrongswan/plugins/ntru/ntru_ke.c @@ -56,7 +56,7 @@ struct private_ntru_ke_t { /** * Diffie Hellman group number. */ - u_int16_t group; + diffie_hellman_group_t group; /** * NTRU Parameter Set @@ -106,10 +106,10 @@ struct private_ntru_ke_t { /** * Deterministic Random Bit Generator */ - ntru_drbg_t *drbg; + ntru_drbg_t *drbg; }; -METHOD(diffie_hellman_t, get_my_public_value, void, +METHOD(diffie_hellman_t, get_my_public_value, bool, private_ntru_ke_t *this, chunk_t *value) { *value = chunk_empty; @@ -130,30 +130,30 @@ METHOD(diffie_hellman_t, get_my_public_value, void, if (!this->privkey) { DBG1(DBG_LIB, "NTRU keypair generation failed"); - return; + return FALSE; } this->pubkey = this->privkey->get_public_key(this->privkey); } *value = chunk_clone(this->pubkey->get_encoding(this->pubkey)); DBG3(DBG_LIB, "NTRU public key: %B", value); } + return TRUE; } -METHOD(diffie_hellman_t, get_shared_secret, status_t, +METHOD(diffie_hellman_t, get_shared_secret, bool, private_ntru_ke_t *this, chunk_t *secret) { if (!this->computed || !this->shared_secret.len) { *secret = chunk_empty; - return FAILED; + return FALSE; } *secret = chunk_clone(this->shared_secret); - return SUCCESS; + return TRUE; } - -METHOD(diffie_hellman_t, set_other_public_value, void, +METHOD(diffie_hellman_t, set_other_public_value, bool, private_ntru_ke_t *this, chunk_t value) { if (this->privkey) @@ -162,15 +162,15 @@ METHOD(diffie_hellman_t, set_other_public_value, void, if (value.len == 0) { DBG1(DBG_LIB, "empty NTRU ciphertext"); - return; + return FALSE; } DBG3(DBG_LIB, "NTRU ciphertext: %B", &value); /* decrypt the shared secret */ - if (!this->privkey->decrypt(this->privkey, value, &this->shared_secret)) + if (!this->privkey->decrypt(this->privkey, value, &this->shared_secret)) { DBG1(DBG_LIB, "NTRU decryption of shared secret failed"); - return; + return FALSE; } this->computed = TRUE; } @@ -185,13 +185,13 @@ METHOD(diffie_hellman_t, set_other_public_value, void, pubkey = ntru_public_key_create_from_data(this->drbg, value); if (!pubkey) { - return; + return FALSE; } if (pubkey->get_id(pubkey) != this->param_set->id) { DBG1(DBG_LIB, "received NTRU public key with wrong OUI"); pubkey->destroy(pubkey); - return; + return FALSE; } this->pubkey = pubkey; @@ -204,7 +204,7 @@ METHOD(diffie_hellman_t, set_other_public_value, void, { DBG1(DBG_LIB, "generation of shared secret failed"); chunk_free(&this->shared_secret); - return; + return FALSE; } this->computed = TRUE; @@ -212,10 +212,11 @@ METHOD(diffie_hellman_t, set_other_public_value, void, if (!pubkey->encrypt(pubkey, this->shared_secret, &this->ciphertext)) { DBG1(DBG_LIB, "NTRU encryption of shared secret failed"); - return; + return FALSE; } DBG3(DBG_LIB, "NTRU ciphertext: %B", &this->ciphertext); } + return this->computed; } METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, @@ -301,10 +302,10 @@ ntru_ke_t *ntru_ke_create(diffie_hellman_group_t group, chunk_t g, chunk_t p) drbg = ntru_drbg_create(strength, chunk_from_str("IKE NTRU-KE"), entropy); if (!drbg) - { + { DBG1(DBG_LIB, "could not instantiate DRBG at %u bit security", strength); entropy->destroy(entropy); - return NULL; + return NULL; } INIT(this, @@ -326,4 +327,3 @@ ntru_ke_t *ntru_ke_create(diffie_hellman_group_t group, chunk_t g, chunk_t p) return &this->public; } - diff --git a/src/libstrongswan/plugins/ntru/ntru_poly.c b/src/libstrongswan/plugins/ntru/ntru_poly.c index 77ab54a5c..cb11601cd 100644 --- a/src/libstrongswan/plugins/ntru/ntru_poly.c +++ b/src/libstrongswan/plugins/ntru/ntru_poly.c @@ -16,8 +16,8 @@ */ #include "ntru_poly.h" -#include "ntru_mgf1.h" +#include <crypto/mgf1/mgf1_bitspender.h> #include <utils/debug.h> #include <utils/test.h> @@ -297,22 +297,17 @@ ntru_poly_t *ntru_poly_create_from_seed(hash_algorithm_t alg, chunk_t seed, bool is_product_form) { private_ntru_poly_t *this; - size_t hash_len, octet_count = 0, i; - uint8_t octets[HASH_SIZE_SHA512], *used, num_left = 0, num_needed; - uint16_t index, limit, left = 0; int n, num_indices, index_i = 0; - ntru_mgf1_t *mgf1; + uint32_t index, limit; + uint8_t *used; + mgf1_bitspender_t *bitspender; - DBG2(DBG_LIB, "MGF1 is seeded with %u bytes", seed.len); - mgf1 = ntru_mgf1_create(alg, seed, TRUE); - if (!mgf1) + bitspender = mgf1_bitspender_create(alg, seed, TRUE); + if (!bitspender) { return NULL; } - i = hash_len = mgf1->get_hash_size(mgf1); - this = ntru_poly_create(N, q, indices_len_p, indices_len_m, is_product_form); - used = malloc(N); limit = N * ((1 << c_bits) / N); @@ -328,43 +323,12 @@ ntru_poly_t *ntru_poly_create_from_seed(hash_algorithm_t alg, chunk_t seed, /* generate a random candidate index with a size of c_bits */ do { - /* use any leftover bits first */ - index = num_left ? left << (c_bits - num_left) : 0; - - /* get the rest of the bits needed from new octets */ - num_needed = c_bits - num_left; - - while (num_needed) + if (!bitspender->get_bits(bitspender, c_bits, &index)) { - if (i == hash_len) - { - /* get another block from MGF1 */ - if (!mgf1->get_mask(mgf1, hash_len, octets)) - { - mgf1->destroy(mgf1); - destroy(this); - free(used); - return NULL; - } - octet_count += hash_len; - i = 0; - } - left = octets[i++]; - - if (num_needed <= 8) - { - /* all bits needed to fill the index are in this octet */ - index |= left >> (8 - num_needed); - num_left = 8 - num_needed; - num_needed = 0; - left &= 0xff >> (8 - num_left); - } - else - { - /* more than one octet will be needed */ - index |= left << (num_needed - 8); - num_needed -= 8; - } + bitspender->destroy(bitspender); + destroy(this); + free(used); + return NULL; } } while (index >= limit); @@ -380,9 +344,7 @@ ntru_poly_t *ntru_poly_create_from_seed(hash_algorithm_t alg, chunk_t seed, } } - DBG2(DBG_LIB, "MGF1 generates %u octets to derive %u indices", - octet_count, this->num_indices); - mgf1->destroy(mgf1); + bitspender->destroy(bitspender); free(used); return &this->public; diff --git a/src/libstrongswan/plugins/ntru/ntru_trits.c b/src/libstrongswan/plugins/ntru/ntru_trits.c index 1abb7671c..57b3532ef 100644 --- a/src/libstrongswan/plugins/ntru/ntru_trits.c +++ b/src/libstrongswan/plugins/ntru/ntru_trits.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Andreas Steffen + * Copyright (C) 2013-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -14,9 +14,9 @@ */ #include "ntru_trits.h" -#include "ntru_mgf1.h" #include "ntru_convert.h" +#include <crypto/mgf1/mgf1_bitspender.h> #include <utils/debug.h> #include <utils/test.h> @@ -70,17 +70,15 @@ METHOD(ntru_trits_t, destroy, void, ntru_trits_t *ntru_trits_create(size_t len, hash_algorithm_t alg, chunk_t seed) { private_ntru_trits_t *this; - uint8_t octets[HASH_SIZE_SHA512], buf[5], *trits; - size_t hash_len, octet_count = 0, trits_needed, i; - ntru_mgf1_t *mgf1; + uint8_t octet, buf[5], *trits; + size_t trits_needed; + mgf1_bitspender_t *bitspender; - DBG2(DBG_LIB, "MGF1 is seeded with %u bytes", seed.len); - mgf1 = ntru_mgf1_create(alg, seed, TRUE); - if (!mgf1) + bitspender = mgf1_bitspender_create(alg, seed, TRUE); + if (!bitspender) { return NULL; } - i = hash_len = mgf1->get_hash_size(mgf1); INIT(this, .public = { @@ -97,21 +95,15 @@ ntru_trits_t *ntru_trits_create(size_t len, hash_algorithm_t alg, chunk_t seed) while (trits_needed > 0) { - if (i == hash_len) + if (!bitspender->get_byte(bitspender, &octet)) { - /* get another block from MGF1 */ - if (!mgf1->get_mask(mgf1, hash_len, octets)) - { - mgf1->destroy(mgf1); - destroy(this); - return NULL; - } - octet_count += hash_len; - i = 0; + bitspender->destroy(bitspender); + destroy(this); + return NULL; } - if (octets[i] < 243) /* 243 = 3^5 */ + if (octet < 243) /* 243 = 3^5 */ { - ntru_octet_2_trits(octets[i], (trits_needed < 5) ? buf : trits); + ntru_octet_2_trits(octet, (trits_needed < 5) ? buf : trits); if (trits_needed < 5) { memcpy(trits, buf, trits_needed); @@ -120,11 +112,8 @@ ntru_trits_t *ntru_trits_create(size_t len, hash_algorithm_t alg, chunk_t seed) trits += 5; trits_needed -= 5; } - i++; } - DBG2(DBG_LIB, "MGF1 generates %u octets to extract %u trits", - octet_count, len); - mgf1->destroy(mgf1); + bitspender->destroy(bitspender); return &this->public; } diff --git a/src/libstrongswan/plugins/openssl/Makefile.in b/src/libstrongswan/plugins/openssl/Makefile.in index ac0db0150..a667ca47e 100644 --- a/src/libstrongswan/plugins/openssl/Makefile.in +++ b/src/libstrongswan/plugins/openssl/Makefile.in @@ -236,6 +236,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -296,10 +297,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -373,6 +376,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/openssl/openssl_crypter.c b/src/libstrongswan/plugins/openssl/openssl_crypter.c index 07b96b320..c2478a4ed 100644 --- a/src/libstrongswan/plugins/openssl/openssl_crypter.c +++ b/src/libstrongswan/plugins/openssl/openssl_crypter.c @@ -135,7 +135,7 @@ METHOD(crypter_t, get_block_size, size_t, METHOD(crypter_t, get_iv_size, size_t, private_openssl_crypter_t *this) { - return this->cipher->block_size; + return this->cipher->iv_len; } METHOD(crypter_t, get_key_size, size_t, diff --git a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c index ff3382473..2615d60a2 100644 --- a/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c +++ b/src/libstrongswan/plugins/openssl/openssl_diffie_hellman.c @@ -38,7 +38,7 @@ struct private_openssl_diffie_hellman_t { /** * Diffie Hellman group number. */ - u_int16_t group; + diffie_hellman_group_t group; /** * Diffie Hellman object @@ -61,36 +61,42 @@ struct private_openssl_diffie_hellman_t { bool computed; }; -METHOD(diffie_hellman_t, get_my_public_value, void, +METHOD(diffie_hellman_t, get_my_public_value, bool, private_openssl_diffie_hellman_t *this, chunk_t *value) { *value = chunk_alloc(DH_size(this->dh)); memset(value->ptr, 0, value->len); BN_bn2bin(this->dh->pub_key, value->ptr + value->len - BN_num_bytes(this->dh->pub_key)); + return TRUE; } -METHOD(diffie_hellman_t, get_shared_secret, status_t, +METHOD(diffie_hellman_t, get_shared_secret, bool, private_openssl_diffie_hellman_t *this, chunk_t *secret) { if (!this->computed) { - return FAILED; + return FALSE; } /* shared secret should requires a len according the DH group */ *secret = chunk_alloc(DH_size(this->dh)); memset(secret->ptr, 0, secret->len); memcpy(secret->ptr + secret->len - this->shared_secret.len, this->shared_secret.ptr, this->shared_secret.len); - return SUCCESS; + return TRUE; } -METHOD(diffie_hellman_t, set_other_public_value, void, +METHOD(diffie_hellman_t, set_other_public_value, bool, private_openssl_diffie_hellman_t *this, chunk_t value) { int len; + if (!diffie_hellman_verify_value(this->group, value)) + { + return FALSE; + } + BN_bin2bn(value.ptr, value.len, this->pub_key); chunk_clear(&this->shared_secret); this->shared_secret.ptr = malloc(DH_size(this->dh)); @@ -99,10 +105,11 @@ METHOD(diffie_hellman_t, set_other_public_value, void, if (len < 0) { DBG1(DBG_LIB, "DH shared secret computation failed"); - return; + return FALSE; } this->shared_secret.len = len; this->computed = TRUE; + return TRUE; } METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, diff --git a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c index b487d59a5..550a5432f 100644 --- a/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c +++ b/src/libstrongswan/plugins/openssl/openssl_ec_diffie_hellman.c @@ -40,7 +40,7 @@ struct private_openssl_ec_diffie_hellman_t { /** * Diffie Hellman group number. */ - u_int16_t group; + diffie_hellman_group_t group; /** * EC private (public) key @@ -216,40 +216,47 @@ error: return ret; } -METHOD(diffie_hellman_t, set_other_public_value, void, +METHOD(diffie_hellman_t, set_other_public_value, bool, private_openssl_ec_diffie_hellman_t *this, chunk_t value) { + if (!diffie_hellman_verify_value(this->group, value)) + { + return FALSE; + } + if (!chunk2ecp(this->ec_group, value, this->pub_key)) { DBG1(DBG_LIB, "ECDH public value is malformed"); - return; + return FALSE; } chunk_clear(&this->shared_secret); if (!compute_shared_key(this, &this->shared_secret)) { DBG1(DBG_LIB, "ECDH shared secret computation failed"); - return; + return FALSE; } this->computed = TRUE; + return TRUE; } -METHOD(diffie_hellman_t, get_my_public_value, void, +METHOD(diffie_hellman_t, get_my_public_value, bool, private_openssl_ec_diffie_hellman_t *this,chunk_t *value) { ecp2chunk(this->ec_group, EC_KEY_get0_public_key(this->key), value, FALSE); + return TRUE; } -METHOD(diffie_hellman_t, get_shared_secret, status_t, +METHOD(diffie_hellman_t, get_shared_secret, bool, private_openssl_ec_diffie_hellman_t *this, chunk_t *secret) { if (!this->computed) { - return FAILED; + return FALSE; } *secret = chunk_clone(this->shared_secret); - return SUCCESS; + return TRUE; } METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, diff --git a/src/libstrongswan/plugins/padlock/Makefile.in b/src/libstrongswan/plugins/padlock/Makefile.in index 4bd958784..44603afb1 100644 --- a/src/libstrongswan/plugins/padlock/Makefile.in +++ b/src/libstrongswan/plugins/padlock/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/pem/Makefile.in b/src/libstrongswan/plugins/pem/Makefile.in index f9c5b9b52..4c982fdf5 100644 --- a/src/libstrongswan/plugins/pem/Makefile.in +++ b/src/libstrongswan/plugins/pem/Makefile.in @@ -227,6 +227,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/pem/pem_builder.c b/src/libstrongswan/plugins/pem/pem_builder.c index 62780c384..f0e508abf 100644 --- a/src/libstrongswan/plugins/pem/pem_builder.c +++ b/src/libstrongswan/plugins/pem/pem_builder.c @@ -365,6 +365,29 @@ static status_t pem_to_bin(chunk_t *blob, bool *pgp) } /** + * Check if a blob looks like an ASN1 SEQUENCE or SET with BER indefinite length + */ +static bool is_ber_indefinite_length(chunk_t blob) +{ + if (blob.len >= 4) + { + switch (blob.ptr[0]) + { + case ASN1_SEQUENCE: + case ASN1_SET: + /* BER indefinite length uses 0x80, and is terminated with + * end-of-content using 0x00,0x00 */ + return blob.ptr[1] == 0x80 && + blob.ptr[blob.len - 2] == 0 && + blob.ptr[blob.len - 1] == 0; + default: + break; + } + } + return FALSE; +} + +/** * load the credential from a blob */ static void *load_from_blob(chunk_t blob, credential_type_t type, int subtype, @@ -374,7 +397,7 @@ static void *load_from_blob(chunk_t blob, credential_type_t type, int subtype, bool pgp = FALSE; blob = chunk_clone(blob); - if (!is_asn1(blob)) + if (!is_ber_indefinite_length(blob) && !is_asn1(blob)) { if (pem_to_bin(&blob, &pgp) != SUCCESS) { diff --git a/src/libstrongswan/plugins/pem/pem_encoder.c b/src/libstrongswan/plugins/pem/pem_encoder.c index df4b77cc3..35ea3e885 100644 --- a/src/libstrongswan/plugins/pem/pem_encoder.c +++ b/src/libstrongswan/plugins/pem/pem_encoder.c @@ -53,6 +53,11 @@ bool pem_encoder_encode(cred_encoding_type_t type, chunk_t *encoding, break; } } + if (cred_encoding_args(args, CRED_PART_BLISS_PUB_ASN1_DER, + &asn1, CRED_PART_END)) + { + break; + } return FALSE; case PRIVKEY_PEM: label ="RSA PRIVATE KEY"; @@ -86,6 +91,12 @@ bool pem_encoder_encode(cred_encoding_type_t type, chunk_t *encoding, label ="EC PRIVATE KEY"; break; } + if (cred_encoding_args(args, CRED_PART_BLISS_PRIV_ASN1_DER, + &asn1, CRED_PART_END)) + { + label ="BLISS PRIVATE KEY"; + break; + } return FALSE; case CERT_PEM: if (cred_encoding_args(args, CRED_PART_X509_ASN1_DER, diff --git a/src/libstrongswan/plugins/pem/pem_plugin.c b/src/libstrongswan/plugins/pem/pem_plugin.c index e7edd7b89..d5bcbb617 100644 --- a/src/libstrongswan/plugins/pem/pem_plugin.c +++ b/src/libstrongswan/plugins/pem/pem_plugin.c @@ -60,6 +60,9 @@ METHOD(plugin_t, get_features, int, PLUGIN_PROVIDE(PRIVKEY, KEY_DSA), PLUGIN_DEPENDS(PRIVKEY, KEY_DSA), PLUGIN_SDEPEND(HASHER, HASH_MD5), + PLUGIN_REGISTER(PRIVKEY, pem_private_key_load, FALSE), + PLUGIN_PROVIDE(PRIVKEY, KEY_BLISS), + PLUGIN_DEPENDS(PRIVKEY, KEY_BLISS), /* public key PEM decoding */ PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE), @@ -74,6 +77,8 @@ METHOD(plugin_t, get_features, int, PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE), PLUGIN_PROVIDE(PUBKEY, KEY_DSA), PLUGIN_DEPENDS(PUBKEY, KEY_DSA), + PLUGIN_REGISTER(PUBKEY, pem_public_key_load, FALSE), + PLUGIN_PROVIDE(PUBKEY, KEY_BLISS), /* certificate PEM decoding */ PLUGIN_REGISTER(CERT_DECODE, pem_certificate_load, FALSE), diff --git a/src/libstrongswan/plugins/pgp/Makefile.in b/src/libstrongswan/plugins/pgp/Makefile.in index 8e351c273..4d4215bfe 100644 --- a/src/libstrongswan/plugins/pgp/Makefile.in +++ b/src/libstrongswan/plugins/pgp/Makefile.in @@ -227,6 +227,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/pkcs1/Makefile.in b/src/libstrongswan/plugins/pkcs1/Makefile.in index 445bc2d24..2a708364a 100644 --- a/src/libstrongswan/plugins/pkcs1/Makefile.in +++ b/src/libstrongswan/plugins/pkcs1/Makefile.in @@ -228,6 +228,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -288,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -365,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c b/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c index c6661fcda..767b3acf2 100644 --- a/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c +++ b/src/libstrongswan/plugins/pkcs1/pkcs1_builder.c @@ -63,11 +63,18 @@ static public_key_t *parse_public_key(chunk_t blob) } else if (oid == OID_EC_PUBLICKEY) { - /* we need the whole subjectPublicKeyInfo for EC public keys */ + /* Need the whole subjectPublicKeyInfo for EC public keys */ key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, KEY_ECDSA, BUILD_BLOB_ASN1_DER, blob, BUILD_END); goto end; } + else if (oid == OID_BLISS_PUBLICKEY) + { + /* Need the whole subjectPublicKeyInfo for BLISS public keys */ + key = lib->creds->create(lib->creds, CRED_PUBLIC_KEY, + KEY_BLISS, BUILD_BLOB_ASN1_DER, blob, BUILD_END); + goto end; + } else { /* key type not supported */ diff --git a/src/libstrongswan/plugins/pkcs11/Makefile.in b/src/libstrongswan/plugins/pkcs11/Makefile.in index 34e8d0caa..de033a3fb 100644 --- a/src/libstrongswan/plugins/pkcs11/Makefile.in +++ b/src/libstrongswan/plugins/pkcs11/Makefile.in @@ -231,6 +231,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c index 36cc284bf..c0033bd8e 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_dh.c @@ -47,7 +47,7 @@ struct private_pkcs11_dh_t { /** * Diffie Hellman group number. */ - u_int16_t group; + diffie_hellman_group_t group; /** * Handle for own private value @@ -81,7 +81,7 @@ struct private_pkcs11_dh_t { * * If this succeeds the shared secret is stored in this->secret. */ -static void derive_secret(private_pkcs11_dh_t *this, chunk_t other) +static bool derive_secret(private_pkcs11_dh_t *this, chunk_t other) { CK_OBJECT_CLASS klass = CKO_SECRET_KEY; CK_KEY_TYPE type = CKK_GENERIC_SECRET; @@ -102,19 +102,25 @@ static void derive_secret(private_pkcs11_dh_t *this, chunk_t other) if (rv != CKR_OK) { DBG1(DBG_CFG, "C_DeriveKey() error: %N", ck_rv_names, rv); - return; + return FALSE; } if (!this->lib->get_ck_attribute(this->lib, this->session, secret, CKA_VALUE, &this->secret)) { chunk_free(&this->secret); - return; + return FALSE; } + return TRUE; } -METHOD(diffie_hellman_t, set_other_public_value, void, +METHOD(diffie_hellman_t, set_other_public_value, bool, private_pkcs11_dh_t *this, chunk_t value) { + if (!diffie_hellman_verify_value(this->group, value)) + { + return FALSE; + } + switch (this->group) { case ECP_192_BIT: @@ -137,7 +143,7 @@ METHOD(diffie_hellman_t, set_other_public_value, void, if (!lib->settings->get_bool(lib->settings, "%s.ecp_x_coordinate_only", TRUE, lib->ns)) { /* we only get the x coordinate back */ - return; + return FALSE; } value = chunk_from_thing(params); break; @@ -145,24 +151,25 @@ METHOD(diffie_hellman_t, set_other_public_value, void, default: break; } - derive_secret(this, value); + return derive_secret(this, value); } -METHOD(diffie_hellman_t, get_my_public_value, void, +METHOD(diffie_hellman_t, get_my_public_value, bool, private_pkcs11_dh_t *this, chunk_t *value) { *value = chunk_clone(this->pub_key); + return TRUE; } -METHOD(diffie_hellman_t, get_shared_secret, status_t, +METHOD(diffie_hellman_t, get_shared_secret, bool, private_pkcs11_dh_t *this, chunk_t *secret) { if (!this->secret.ptr) { - return FAILED; + return FALSE; } *secret = chunk_clone(this->secret); - return SUCCESS; + return TRUE; } METHOD(diffie_hellman_t, get_dh_group, diffie_hellman_group_t, @@ -443,4 +450,3 @@ pkcs11_dh_t *pkcs11_dh_create(diffie_hellman_group_t group, } return NULL; } - diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_library.c b/src/libstrongswan/plugins/pkcs11/pkcs11_library.c index 7661473b1..dc8a1f17a 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_library.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_library.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Tobias Brunner + * Copyright (C) 2011-2015 Tobias Brunner * Hochschule fuer Technik Rapperswil * * Copyright (C) 2010 Martin Willi @@ -21,6 +21,7 @@ #include <dlfcn.h> #include <library.h> +#include <asn1/asn1.h> #include <utils/debug.h> #include <threading/mutex.h> #include <collections/linked_list.h> @@ -641,10 +642,37 @@ static void free_attrs(object_enumerator_t *this) } /** + * CKA_EC_POINT is encodeed as ASN.1 octet string, we can't handle that and + * some tokens actually return them even unwrapped. + * + * Because ASN1_OCTET_STRING is 0x04 and uncompressed EC_POINTs also begin with + * 0x04 (compressed ones with 0x02 or 0x03) there will be an attempt to parse + * unwrapped uncompressed EC_POINTs. This will fail in most cases as the length + * will not be correct, however, there is a small chance that the key's first + * byte denotes the correct length. Checking the first byte of the key should + * further reduce the risk of false positives, though. + * + * The original memory is freed if the value is unwrapped. + */ +static void unwrap_ec_point(chunk_t *data) +{ + chunk_t wrapped, unwrapped; + + wrapped = unwrapped = *data; + if (asn1_unwrap(&unwrapped, &unwrapped) == ASN1_OCTET_STRING && + unwrapped.len && unwrapped.ptr[0] >= 0x02 && unwrapped.ptr[0] <= 0x04) + { + *data = chunk_clone(unwrapped); + free(wrapped.ptr); + } +} + +/** * Get attributes for a given object during enumeration */ static bool get_attributes(object_enumerator_t *this, CK_OBJECT_HANDLE object) { + chunk_t data; CK_RV rv; int i; @@ -677,6 +705,16 @@ static bool get_attributes(object_enumerator_t *this, CK_OBJECT_HANDLE object) DBG1(DBG_CFG, "C_GetAttributeValue() error: %N", ck_rv_names, rv); return FALSE; } + for (i = 0; i < this->count; i++) + { + if (this->attr[i].type == CKA_EC_POINT) + { + data = chunk_create(this->attr[i].pValue, this->attr[i].ulValueLen); + unwrap_ec_point(&data); + this->attr[i].pValue = data.ptr; + this->attr[i].ulValueLen = data.len; + } + } return TRUE; } @@ -887,6 +925,10 @@ METHOD(pkcs11_library_t, get_ck_attribute, bool, chunk_free(data); return FALSE; } + if (attr.type == CKA_EC_POINT) + { + unwrap_ec_point(data); + } return TRUE; } diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c index bb9cc7a21..bfc545972 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Tobias Brunner + * Copyright (C) 2011-2015 Tobias Brunner * Hochschule fuer Technik Rapperswil * * Copyright (C) 2010 Martin Willi @@ -23,6 +23,7 @@ #include "pkcs11_public_key.h" #include <utils/debug.h> +#include <asn1/asn1.h> typedef struct private_pkcs11_private_key_t private_pkcs11_private_key_t; @@ -288,7 +289,23 @@ METHOD(private_key_t, sign, bool, free(buf); return FALSE; } - *signature = chunk_create(buf, len); + switch (scheme) + { + case SIGN_ECDSA_WITH_SHA1_DER: + case SIGN_ECDSA_WITH_SHA256_DER: + case SIGN_ECDSA_WITH_SHA384_DER: + case SIGN_ECDSA_WITH_SHA512_DER: + /* return an ASN.1 encoded sequence of integers r and s */ + len /= 2; + *signature = asn1_wrap(ASN1_SEQUENCE, "mm", + asn1_integer("c", chunk_create(buf, len)), + asn1_integer("c", chunk_create(buf+len, len))); + free(buf); + break; + default: + *signature = chunk_create(buf, len); + break; + } return TRUE; } diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c index 0302c0edd..6d5211657 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_public_key.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Tobias Brunner + * Copyright (C) 2011-2015 Tobias Brunner * Hochschule fuer Technik Rapperswil * * Copyright (C) 2010 Martin Willi @@ -135,6 +135,7 @@ static const asn1Object_t pkinfoObjects[] = { /** * Extract the DER encoded Parameters and ECPoint from the given DER encoded * subjectPublicKeyInfo. + * Memory for ecpoint is allocated. */ static bool parse_ecdsa_public_key(chunk_t blob, chunk_t *ecparams, chunk_t *ecpoint, size_t *keylen) @@ -173,7 +174,9 @@ static bool parse_ecdsa_public_key(chunk_t blob, chunk_t *ecparams, { /* skip initial bit string octet defining 0 unused bits */ object = chunk_skip(object, 1); } - *ecpoint = object; + /* the correct way to encode an EC_POINT in PKCS#11 is as + * ASN.1 octet string */ + *ecpoint = asn1_wrap(ASN1_OCTET_STRING, "c", object); break; } } @@ -205,7 +208,8 @@ METHOD(public_key_t, verify, bool, CK_SESSION_HANDLE session; CK_RV rv; hash_algorithm_t hash_alg; - chunk_t hash = chunk_empty; + chunk_t hash = chunk_empty, parse, r, s; + size_t len; mechanism = pkcs11_signature_scheme_to_mech(scheme, this->type, this->k, &hash_alg); @@ -215,9 +219,37 @@ METHOD(public_key_t, verify, bool, signature_scheme_names, scheme); return FALSE; } - if (sig.len && sig.ptr[0] == 0) - { /* trim leading zero byte in sig */ - sig = chunk_skip(sig, 1); + switch (scheme) + { + case SIGN_ECDSA_WITH_SHA1_DER: + case SIGN_ECDSA_WITH_SHA256_DER: + case SIGN_ECDSA_WITH_SHA384_DER: + case SIGN_ECDSA_WITH_SHA512_DER: + /* PKCS#11 expects the ECDSA signatures as simple concatenation of + * r and s, so unwrap the ASN.1 encoded sequence */ + parse = sig; + if (asn1_unwrap(&parse, &parse) != ASN1_SEQUENCE || + asn1_unwrap(&parse, &r) != ASN1_INTEGER || + asn1_unwrap(&parse, &s) != ASN1_INTEGER) + { + return FALSE; + } + r = chunk_skip_zero(r); + s = chunk_skip_zero(s); + len = (get_keysize(this) + 7) / 8; + if (r.len > len || s.len > len) + { + return FALSE; + } + /* concatenate r and s (forced to the defined length) */ + sig = chunk_alloca(2*len); + memset(sig.ptr, 0, sig.len); + memcpy(sig.ptr + (len - r.len), r.ptr, r.len); + memcpy(sig.ptr + len + (len - s.len), s.ptr, s.len); + break; + default: + sig = chunk_skip_zero(sig); + break; } rv = this->lib->f->C_OpenSession(this->slot, CKF_SERIAL_SESSION, NULL, NULL, &session); @@ -776,11 +808,11 @@ pkcs11_public_key_t *pkcs11_public_key_load(key_type_t type, va_list args) if (parse_ecdsa_public_key(blob, &ecparams, &ecpoint, &keylen)) { this = find_ecdsa_key(ecparams, ecpoint, keylen); - if (this) + if (!this) { - return &this->public; + this = create_ecdsa_key(ecparams, ecpoint, keylen); } - this = create_ecdsa_key(ecparams, ecpoint, keylen); + chunk_free(&ecpoint); if (this) { return &this->public; diff --git a/src/libstrongswan/plugins/pkcs12/Makefile.in b/src/libstrongswan/plugins/pkcs12/Makefile.in index d90cd3532..3fa0a3890 100644 --- a/src/libstrongswan/plugins/pkcs12/Makefile.in +++ b/src/libstrongswan/plugins/pkcs12/Makefile.in @@ -228,6 +228,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -288,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -365,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/pkcs7/Makefile.in b/src/libstrongswan/plugins/pkcs7/Makefile.in index f6534f087..3266e5d5f 100644 --- a/src/libstrongswan/plugins/pkcs7/Makefile.in +++ b/src/libstrongswan/plugins/pkcs7/Makefile.in @@ -230,6 +230,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -290,10 +291,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -367,6 +370,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/pkcs8/Makefile.in b/src/libstrongswan/plugins/pkcs8/Makefile.in index 0756db856..2130c9c93 100644 --- a/src/libstrongswan/plugins/pkcs8/Makefile.in +++ b/src/libstrongswan/plugins/pkcs8/Makefile.in @@ -227,6 +227,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c index 1fec1b3ea..f7ac347d2 100644 --- a/src/libstrongswan/plugins/plugin_loader.c +++ b/src/libstrongswan/plugins/plugin_loader.c @@ -380,7 +380,15 @@ static plugin_entry_t *load_plugin(private_plugin_loader_t *this, char *name, return NULL; } } - handle = dlopen(file, RTLD_LAZY); + handle = dlopen(file, RTLD_LAZY +#ifdef RTLD_NODELETE + /* if supported, do not unload library when unloading a plugin. It really + * doesn't matter in productive systems, but causes many (dependency) + * library reloads during unit tests. Some libraries can't handle that, + * GnuTLS leaks file descriptors in its library load/unload functions. */ + | RTLD_NODELETE +#endif + ); if (handle == NULL) { DBG1(DBG_LIB, "plugin '%s' failed to load: %s", name, dlerror()); @@ -1283,9 +1291,9 @@ METHOD(plugin_loader_t, status, void, if (this->stats.failed) { - dbg(DBG_LIB, level, "unable to load %d plugin feature%s (%d due to " - "unmet dependencies)", this->stats.failed, - this->stats.failed == 1 ? "" : "s", this->stats.depends); + DBG2(DBG_LIB, "unable to load %d plugin feature%s (%d due to unmet " + "dependencies)", this->stats.failed, + this->stats.failed == 1 ? "" : "s", this->stats.depends); } } } diff --git a/src/libstrongswan/plugins/pubkey/Makefile.in b/src/libstrongswan/plugins/pubkey/Makefile.in index fcdbe9450..a9f3dd14c 100644 --- a/src/libstrongswan/plugins/pubkey/Makefile.in +++ b/src/libstrongswan/plugins/pubkey/Makefile.in @@ -228,6 +228,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -288,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -365,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/random/Makefile.in b/src/libstrongswan/plugins/random/Makefile.in index fb6c9ae43..11a13463b 100644 --- a/src/libstrongswan/plugins/random/Makefile.in +++ b/src/libstrongswan/plugins/random/Makefile.in @@ -228,6 +228,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -288,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -365,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/rc2/Makefile.in b/src/libstrongswan/plugins/rc2/Makefile.in index d84b1ba17..b81acef55 100644 --- a/src/libstrongswan/plugins/rc2/Makefile.in +++ b/src/libstrongswan/plugins/rc2/Makefile.in @@ -226,6 +226,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/rdrand/Makefile.in b/src/libstrongswan/plugins/rdrand/Makefile.in index 967e8625d..028464bf3 100644 --- a/src/libstrongswan/plugins/rdrand/Makefile.in +++ b/src/libstrongswan/plugins/rdrand/Makefile.in @@ -228,6 +228,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -288,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -365,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/revocation/Makefile.in b/src/libstrongswan/plugins/revocation/Makefile.in index 127482635..342c544d9 100644 --- a/src/libstrongswan/plugins/revocation/Makefile.in +++ b/src/libstrongswan/plugins/revocation/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/sha1/Makefile.in b/src/libstrongswan/plugins/sha1/Makefile.in index 70a98b006..18771e4f9 100644 --- a/src/libstrongswan/plugins/sha1/Makefile.in +++ b/src/libstrongswan/plugins/sha1/Makefile.in @@ -227,6 +227,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/sha2/Makefile.in b/src/libstrongswan/plugins/sha2/Makefile.in index f7d11beb1..6aaa06b20 100644 --- a/src/libstrongswan/plugins/sha2/Makefile.in +++ b/src/libstrongswan/plugins/sha2/Makefile.in @@ -226,6 +226,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/soup/Makefile.in b/src/libstrongswan/plugins/soup/Makefile.in index ee96f08c2..02290b4a2 100644 --- a/src/libstrongswan/plugins/soup/Makefile.in +++ b/src/libstrongswan/plugins/soup/Makefile.in @@ -227,6 +227,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -287,10 +288,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -364,6 +367,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/sqlite/Makefile.in b/src/libstrongswan/plugins/sqlite/Makefile.in index b9f949bcf..3e234f1ca 100644 --- a/src/libstrongswan/plugins/sqlite/Makefile.in +++ b/src/libstrongswan/plugins/sqlite/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/sshkey/Makefile.in b/src/libstrongswan/plugins/sshkey/Makefile.in index b66302e1a..a8d5a1020 100644 --- a/src/libstrongswan/plugins/sshkey/Makefile.in +++ b/src/libstrongswan/plugins/sshkey/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/test_vectors/Makefile.in b/src/libstrongswan/plugins/test_vectors/Makefile.in index 8d7c667d8..8980ec46c 100644 --- a/src/libstrongswan/plugins/test_vectors/Makefile.in +++ b/src/libstrongswan/plugins/test_vectors/Makefile.in @@ -243,6 +243,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -303,10 +304,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -380,6 +383,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/unbound/Makefile.in b/src/libstrongswan/plugins/unbound/Makefile.in index 02f4ccd8a..c84717bdc 100644 --- a/src/libstrongswan/plugins/unbound/Makefile.in +++ b/src/libstrongswan/plugins/unbound/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/winhttp/Makefile.in b/src/libstrongswan/plugins/winhttp/Makefile.in index fb87917a2..f8db1ffac 100644 --- a/src/libstrongswan/plugins/winhttp/Makefile.in +++ b/src/libstrongswan/plugins/winhttp/Makefile.in @@ -229,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -289,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -366,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/x509/Makefile.in b/src/libstrongswan/plugins/x509/Makefile.in index 23a6b3ba3..b31bfbed1 100644 --- a/src/libstrongswan/plugins/x509/Makefile.in +++ b/src/libstrongswan/plugins/x509/Makefile.in @@ -228,6 +228,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -288,10 +289,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -365,6 +368,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/x509/x509_ac.c b/src/libstrongswan/plugins/x509/x509_ac.c index ed58377a6..bfc200421 100644 --- a/src/libstrongswan/plugins/x509/x509_ac.c +++ b/src/libstrongswan/plugins/x509/x509_ac.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler * Copyright (C) 2003 Martin Berner, Lukas Suter - * Copyright (C) 2002-2009 Andreas Steffen + * Copyright (C) 2002-2014 Andreas Steffen * Copyright (C) 2009 Martin Willi * * HSR Hochschule fuer Technik Rapperswil @@ -557,7 +557,7 @@ static bool parse_certificate(private_x509_ac_t *this) } break; case AC_OBJ_SIGNATURE: - this->signature = object; + this->signature = chunk_skip(object, 1); break; default: break; diff --git a/src/libstrongswan/plugins/x509/x509_cert.c b/src/libstrongswan/plugins/x509/x509_cert.c index bdc8234c9..96280a033 100644 --- a/src/libstrongswan/plugins/x509/x509_cert.c +++ b/src/libstrongswan/plugins/x509/x509_cert.c @@ -1465,7 +1465,7 @@ static bool parse_certificate(private_x509_cert_t *this) } break; case X509_OBJ_SIGNATURE: - this->signature = object; + this->signature = chunk_skip(object, 1); break; default: break; diff --git a/src/libstrongswan/plugins/x509/x509_crl.c b/src/libstrongswan/plugins/x509/x509_crl.c index d6057c30f..4d7e7bd10 100644 --- a/src/libstrongswan/plugins/x509/x509_crl.c +++ b/src/libstrongswan/plugins/x509/x509_crl.c @@ -347,7 +347,7 @@ static bool parse(private_x509_crl_t *this) break; } case CRL_OBJ_SIGNATURE: - this->signature = object; + this->signature = chunk_skip(object, 1); break; default: break; @@ -451,6 +451,7 @@ METHOD(certificate_t, issued_by, bool, signature_scheme_t scheme; bool valid; x509_t *x509 = (x509_t*)issuer; + chunk_t keyid = chunk_empty; /* check if issuer is an X.509 CA certificate */ if (issuer->get_type(issuer) != CERT_X509) @@ -462,21 +463,16 @@ METHOD(certificate_t, issued_by, bool, return FALSE; } - /* get the public key of the issuer */ - key = issuer->get_public_key(issuer); - /* compare keyIdentifiers if available, otherwise use DNs */ - if (this->authKeyIdentifier.ptr && key) + if (this->authKeyIdentifier.ptr) { - chunk_t fingerprint; - - if (!key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &fingerprint) || - !chunk_equals(fingerprint, this->authKeyIdentifier)) + keyid = x509->get_subjectKeyIdentifier(x509); + if (keyid.len && !chunk_equals(keyid, this->authKeyIdentifier)) { return FALSE; } } - else + if (!keyid.len) { if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer))) { @@ -484,10 +480,13 @@ METHOD(certificate_t, issued_by, bool, } } - /* determine signature scheme */ scheme = signature_scheme_from_oid(this->algorithm); - - if (scheme == SIGN_UNKNOWN || key == NULL) + if (scheme == SIGN_UNKNOWN) + { + return FALSE; + } + key = issuer->get_public_key(issuer); + if (!key) { return FALSE; } diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_request.c b/src/libstrongswan/plugins/x509/x509_ocsp_request.c index ff0f0231f..eb5b01986 100644 --- a/src/libstrongswan/plugins/x509/x509_ocsp_request.c +++ b/src/libstrongswan/plugins/x509/x509_ocsp_request.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2008-2009 Martin Willi - * Copyright (C) 2007 Andreas Steffen + * Copyright (C) 2007-2014 Andreas Steffen * Hochschule fuer Technik Rapperswil * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen * @@ -265,6 +265,10 @@ static chunk_t build_optionalSignature(private_x509_ocsp_request_t *this, oid = OID_ECDSA_WITH_SHA1; scheme = SIGN_ECDSA_WITH_SHA1_DER; break; + case KEY_BLISS: + oid = OID_BLISS_WITH_SHA512; + scheme = SIGN_BLISS_WITH_SHA512; + break; default: DBG1(DBG_LIB, "unable to sign OCSP request, %N signature not " "supported", key_type_names, this->key->get_type(this->key)); diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_response.c b/src/libstrongswan/plugins/x509/x509_ocsp_response.c index ad04c7dea..60133fc7f 100644 --- a/src/libstrongswan/plugins/x509/x509_ocsp_response.c +++ b/src/libstrongswan/plugins/x509/x509_ocsp_response.c @@ -1,6 +1,6 @@ /** * Copyright (C) 2008-2009 Martin Willi - * Copyright (C) 2007 Andreas Steffen + * Copyright (C) 2007-2014 Andreas Steffen * Hochschule fuer Technik Rapperswil * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen * @@ -537,7 +537,7 @@ static bool parse_basicOCSPResponse(private_x509_ocsp_response_t *this, parser->get_level(parser)+1, NULL); break; case BASIC_RESPONSE_SIGNATURE: - this->signature = object; + this->signature = chunk_skip(object, 1); break; case BASIC_RESPONSE_CERTIFICATE: { diff --git a/src/libstrongswan/plugins/x509/x509_pkcs10.c b/src/libstrongswan/plugins/x509/x509_pkcs10.c index 024b4dba5..20561f7e2 100644 --- a/src/libstrongswan/plugins/x509/x509_pkcs10.c +++ b/src/libstrongswan/plugins/x509/x509_pkcs10.c @@ -435,7 +435,7 @@ static bool parse_certificate_request(private_x509_pkcs10_t *this) this->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL); break; case PKCS10_SIGNATURE: - this->signature = object; + this->signature = chunk_skip(object, 1); break; default: break; diff --git a/src/libstrongswan/plugins/xcbc/Makefile.in b/src/libstrongswan/plugins/xcbc/Makefile.in index ffcee547c..6c9901e6c 100644 --- a/src/libstrongswan/plugins/xcbc/Makefile.in +++ b/src/libstrongswan/plugins/xcbc/Makefile.in @@ -226,6 +226,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -286,10 +287,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -363,6 +366,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libstrongswan/plugins/xcbc/xcbc.c b/src/libstrongswan/plugins/xcbc/xcbc.c index 802c8a39f..d852a2932 100644 --- a/src/libstrongswan/plugins/xcbc/xcbc.c +++ b/src/libstrongswan/plugins/xcbc/xcbc.c @@ -219,6 +219,10 @@ METHOD(mac_t, set_key, bool, { chunk_t iv, k1, lengthened; + memset(this->e, 0, this->b); + this->remaining_bytes = 0; + this->zero = TRUE; + /* we support variable keys from RFC4434 */ if (key.len == this->b) { diff --git a/src/libstrongswan/processing/processor.h b/src/libstrongswan/processing/processor.h index f96530e54..ee08870fb 100644 --- a/src/libstrongswan/processing/processor.h +++ b/src/libstrongswan/processing/processor.h @@ -23,6 +23,8 @@ #ifndef PROCESSOR_H_ #define PROCESSOR_H_ +#include <utils/utils.h> + typedef struct processor_t processor_t; #include <stdlib.h> diff --git a/src/libstrongswan/processing/scheduler.c b/src/libstrongswan/processing/scheduler.c index 3f1598fc4..d90852561 100644 --- a/src/libstrongswan/processing/scheduler.c +++ b/src/libstrongswan/processing/scheduler.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Tobias Brunner + * Copyright (C) 2008-2015 Tobias Brunner * Copyright (C) 2005-2006 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -300,16 +300,26 @@ METHOD(scheduler_t, schedule_job_ms, void, schedule_job_tv(this, job, tv); } -METHOD(scheduler_t, destroy, void, +METHOD(scheduler_t, flush, void, private_scheduler_t *this) { event_t *event; - this->condvar->destroy(this->condvar); - this->mutex->destroy(this->mutex); + + this->mutex->lock(this->mutex); while ((event = remove_event(this)) != NULL) { event_destroy(event); } + this->condvar->signal(this->condvar); + this->mutex->unlock(this->mutex); +} + +METHOD(scheduler_t, destroy, void, + private_scheduler_t *this) +{ + flush(this); + this->condvar->destroy(this->condvar); + this->mutex->destroy(this->mutex); free(this->heap); free(this); } @@ -328,6 +338,7 @@ scheduler_t * scheduler_create() .schedule_job = _schedule_job, .schedule_job_ms = _schedule_job_ms, .schedule_job_tv = _schedule_job_tv, + .flush = _flush, .destroy = _destroy, }, .heap_size = HEAP_SIZE_DEFAULT, diff --git a/src/libstrongswan/processing/scheduler.h b/src/libstrongswan/processing/scheduler.h index abbf74e2c..7f91fcc59 100644 --- a/src/libstrongswan/processing/scheduler.h +++ b/src/libstrongswan/processing/scheduler.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Tobias Brunner + * Copyright (C) 2009-2015 Tobias Brunner * Copyright (C) 2005-2007 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -115,6 +115,11 @@ struct scheduler_t { u_int (*get_job_load) (scheduler_t *this); /** + * Remove all scheduled jobs. + */ + void (*flush)(scheduler_t *this); + + /** * Destroys a scheduler object. */ void (*destroy) (scheduler_t *this); diff --git a/src/libstrongswan/processing/watcher.c b/src/libstrongswan/processing/watcher.c index d4de2a907..5b94208bf 100644 --- a/src/libstrongswan/processing/watcher.c +++ b/src/libstrongswan/processing/watcher.c @@ -24,9 +24,6 @@ #include <unistd.h> #include <errno.h> -#ifndef WIN32 -#include <sys/select.h> -#endif #include <fcntl.h> typedef struct private_watcher_t private_watcher_t; @@ -121,11 +118,7 @@ static void update(private_watcher_t *this) this->pending = TRUE; if (this->notify[1] != -1) { -#ifdef WIN32 - if (send(this->notify[1], buf, sizeof(buf), 0) == -1) -#else if (write(this->notify[1], buf, sizeof(buf)) == -1) -#endif { DBG1(DBG_JOB, "notifying watcher failed: %s", strerror(errno)); } @@ -245,23 +238,57 @@ static void activate_all(private_watcher_t *this) } /** + * Find flagged revents in a pollfd set by fd + */ +static int find_revents(struct pollfd *pfd, int count, int fd) +{ + int i; + + for (i = 0; i < count; i++) + { + if (pfd[i].fd == fd) + { + return pfd[i].revents; + } + } + return 0; +} + +/** + * Check if entry is waiting for a specific event, and if it got signaled + */ +static bool entry_ready(entry_t *entry, watcher_event_t event, int revents) +{ + if (entry->events & event) + { + switch (event) + { + case WATCHER_READ: + return (revents & (POLLIN | POLLHUP | POLLNVAL)) != 0; + case WATCHER_WRITE: + return (revents & (POLLOUT | POLLHUP | POLLNVAL)) != 0; + case WATCHER_EXCEPT: + return (revents & (POLLERR | POLLHUP | POLLNVAL)) != 0; + } + } + return FALSE; +} + +/** * Dispatching function */ static job_requeue_t watch(private_watcher_t *this) { enumerator_t *enumerator; entry_t *entry; - fd_set rd, wr, ex; - int maxfd = 0, res; + struct pollfd *pfd; + int count = 0, res; bool rebuild = FALSE; - FD_ZERO(&rd); - FD_ZERO(&wr); - FD_ZERO(&ex); - this->mutex->lock(this->mutex); - if (this->fds->get_count(this->fds) == 0) + count = this->fds->get_count(this->fds); + if (count == 0) { this->state = WATCHER_STOPPED; this->mutex->unlock(this->mutex); @@ -272,33 +299,34 @@ static job_requeue_t watch(private_watcher_t *this) this->state = WATCHER_RUNNING; } - if (this->notify[0] != -1) - { - FD_SET(this->notify[0], &rd); - maxfd = this->notify[0]; - } + pfd = alloca(sizeof(*pfd) * (count + 1)); + pfd[0].fd = this->notify[0]; + pfd[0].events = POLLIN; + count = 1; enumerator = this->fds->create_enumerator(this->fds); while (enumerator->enumerate(enumerator, &entry)) { if (!entry->in_callback) { + pfd[count].fd = entry->fd; + pfd[count].events = 0; if (entry->events & WATCHER_READ) { DBG3(DBG_JOB, " watching %d for reading", entry->fd); - FD_SET(entry->fd, &rd); + pfd[count].events |= POLLIN; } if (entry->events & WATCHER_WRITE) { DBG3(DBG_JOB, " watching %d for writing", entry->fd); - FD_SET(entry->fd, &wr); + pfd[count].events |= POLLOUT; } if (entry->events & WATCHER_EXCEPT) { DBG3(DBG_JOB, " watching %d for exceptions", entry->fd); - FD_SET(entry->fd, &ex); + pfd[count].events |= POLLERR; } - maxfd = max(maxfd, entry->fd); + count++; } } enumerator->destroy(enumerator); @@ -306,30 +334,27 @@ static job_requeue_t watch(private_watcher_t *this) while (!rebuild) { + int revents; char buf[1]; bool old; ssize_t len; job_t *job; - DBG2(DBG_JOB, "watcher going to select()"); + DBG2(DBG_JOB, "watcher going to poll() %d fds", count); thread_cleanup_push((void*)activate_all, this); old = thread_cancelability(TRUE); - res = select(maxfd + 1, &rd, &wr, &ex, NULL); + res = poll(pfd, count, -1); thread_cancelability(old); thread_cleanup_pop(FALSE); if (res > 0) { - if (this->notify[0] != -1 && FD_ISSET(this->notify[0], &rd)) + if (pfd[0].revents & POLLIN) { while (TRUE) { -#ifdef WIN32 - len = recv(this->notify[0], buf, sizeof(buf), 0); -#else len = read(this->notify[0], buf, sizeof(buf)); -#endif if (len == -1) { if (errno != EAGAIN && errno != EWOULDBLOCK) @@ -354,21 +379,25 @@ static job_requeue_t watch(private_watcher_t *this) rebuild = TRUE; break; } - if (FD_ISSET(entry->fd, &rd) && (entry->events & WATCHER_READ)) - { - DBG2(DBG_JOB, "watched FD %d ready to read", entry->fd); - notify(this, entry, WATCHER_READ); - } - if (FD_ISSET(entry->fd, &wr) && (entry->events & WATCHER_WRITE)) - { - DBG2(DBG_JOB, "watched FD %d ready to write", entry->fd); - notify(this, entry, WATCHER_WRITE); - } - if (FD_ISSET(entry->fd, &ex) && (entry->events & WATCHER_EXCEPT)) + revents = find_revents(pfd, count, entry->fd); + if (entry_ready(entry, WATCHER_EXCEPT, revents)) { DBG2(DBG_JOB, "watched FD %d has exception", entry->fd); notify(this, entry, WATCHER_EXCEPT); } + else + { + if (entry_ready(entry, WATCHER_READ, revents)) + { + DBG2(DBG_JOB, "watched FD %d ready to read", entry->fd); + notify(this, entry, WATCHER_READ); + } + if (entry_ready(entry, WATCHER_WRITE, revents)) + { + DBG2(DBG_JOB, "watched FD %d ready to write", entry->fd); + notify(this, entry, WATCHER_WRITE); + } + } } enumerator->destroy(enumerator); this->mutex->unlock(this->mutex); @@ -388,7 +417,7 @@ static job_requeue_t watch(private_watcher_t *this) { if (!this->pending && errno != EINTR) { /* complain only if no pending updates */ - DBG1(DBG_JOB, "watcher select() error: %s", strerror(errno)); + DBG1(DBG_JOB, "watcher poll() error: %s", strerror(errno)); } return JOB_REQUEUE_DIRECT; } diff --git a/src/libstrongswan/selectors/traffic_selector.c b/src/libstrongswan/selectors/traffic_selector.c index 94b77467a..3b7f8c5a0 100644 --- a/src/libstrongswan/selectors/traffic_selector.c +++ b/src/libstrongswan/selectors/traffic_selector.c @@ -449,41 +449,9 @@ METHOD(traffic_selector_t, get_subset, traffic_selector_t*, } METHOD(traffic_selector_t, equals, bool, - private_traffic_selector_t *this, traffic_selector_t *other_public) + private_traffic_selector_t *this, traffic_selector_t *other) { - private_traffic_selector_t *other; - - other = (private_traffic_selector_t*)other_public; - if (this->type != other->type) - { - return FALSE; - } - if (!(this->from_port == other->from_port && - this->to_port == other->to_port && - this->protocol == other->protocol)) - { - return FALSE; - } - switch (this->type) - { - case TS_IPV4_ADDR_RANGE: - if (memeq(this->from4, other->from4, sizeof(this->from4)) && - memeq(this->to4, other->to4, sizeof(this->to4))) - { - return TRUE; - } - break; - case TS_IPV6_ADDR_RANGE: - if (memeq(this->from6, other->from6, sizeof(this->from6)) && - memeq(this->to6, other->to6, sizeof(this->to6))) - { - return TRUE; - } - break; - default: - break; - } - return FALSE; + return traffic_selector_cmp(&this->public, other, NULL) == 0; } METHOD(traffic_selector_t, get_from_address, chunk_t, @@ -717,12 +685,96 @@ METHOD(traffic_selector_t, clone_, traffic_selector_t*, } } +METHOD(traffic_selector_t, hash, u_int, + private_traffic_selector_t *this, u_int hash) +{ + return chunk_hash_inc(get_from_address(this), + chunk_hash_inc(get_to_address(this), + chunk_hash_inc(chunk_from_thing(this->from_port), + chunk_hash_inc(chunk_from_thing(this->to_port), + chunk_hash_inc(chunk_from_thing(this->protocol), + hash))))); +} + METHOD(traffic_selector_t, destroy, void, private_traffic_selector_t *this) { free(this); } +/** + * Compare two integers + */ +static int compare_int(int a, int b) +{ + return a - b; +} + +/* + * See header + */ +int traffic_selector_cmp(traffic_selector_t *a_pub, traffic_selector_t *b_pub, + void *opts) +{ + private_traffic_selector_t *a, *b; + int res; + + a = (private_traffic_selector_t*)a_pub; + b = (private_traffic_selector_t*)b_pub; + + /* IPv4 before IPv6 */ + res = compare_int(a->type, b->type); + if (res) + { + return res; + } + switch (a->type) + { + case TS_IPV4_ADDR_RANGE: + /* lower starting subnets first */ + res = memcmp(a->from4, b->from4, sizeof(a->from4)); + if (res) + { + return res; + } + /* larger subnets first */ + res = memcmp(b->to4, a->to4, sizeof(a->to4)); + if (res) + { + return res; + } + break; + case TS_IPV6_ADDR_RANGE: + res = memcmp(a->from6, b->from6, sizeof(a->from6)); + if (res) + { + return res; + } + res = memcmp(b->to6, a->to6, sizeof(a->to6)); + if (res) + { + return res; + } + break; + default: + return 1; + } + /* lower protocols first */ + res = compare_int(a->protocol, b->protocol); + if (res) + { + return res; + } + /* lower starting ports first */ + res = compare_int(a->from_port, b->from_port); + if (res) + { + return res; + } + /* larger port ranges first */ + return compare_int(b->to_port, a->to_port); +} + /* * see header */ @@ -933,6 +985,7 @@ static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol, .set_address = _set_address, .to_subnet = _to_subnet, .clone = _clone_, + .hash = _hash, .destroy = _destroy, }, .from_port = from_port, diff --git a/src/libstrongswan/selectors/traffic_selector.h b/src/libstrongswan/selectors/traffic_selector.h index ab6813acc..cf9a2861b 100644 --- a/src/libstrongswan/selectors/traffic_selector.h +++ b/src/libstrongswan/selectors/traffic_selector.h @@ -221,6 +221,14 @@ struct traffic_selector_t { bool (*to_subnet) (traffic_selector_t *this, host_t **net, u_int8_t *mask); /** + * Create a hash value for the traffic selector. + * + * @param inc optional value for incremental hashing + * @return calculated hash value for the traffic selector + */ + u_int (*hash)(traffic_selector_t *this, u_int inc); + + /** * Destroys the ts object */ void (*destroy) (traffic_selector_t *this); @@ -249,6 +257,17 @@ static inline u_int8_t traffic_selector_icmp_code(u_int16_t port) } /** + * Compare two traffic selectors, usable as sort function + * + * @param a first selector to compare + * @param b second selector to compare + * @param opts optional sort options, currently unused + * @return > 0 if a > b, 0 if a == b, < 0 if a < b + */ +int traffic_selector_cmp(traffic_selector_t *a, traffic_selector_t *b, + void *opts); + +/** * Create a new traffic selector using human readable params. * * If protocol is ICMP or ICMPv6 the ports are interpreted as follows: If they diff --git a/src/libstrongswan/settings/settings_lexer.c b/src/libstrongswan/settings/settings_lexer.c index 76433012a..0d71a1d01 100644 --- a/src/libstrongswan/settings/settings_lexer.c +++ b/src/libstrongswan/settings/settings_lexer.c @@ -456,8 +456,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); yyg->yy_c_buf_p = yy_cp; /* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */ -#define YY_NUM_RULES 25 -#define YY_END_OF_BUFFER 26 +#define YY_NUM_RULES 26 +#define YY_END_OF_BUFFER 27 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -465,31 +465,32 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[50] = +static yyconst flex_int16_t yy_accept[52] = { 0, - 0, 0, 0, 0, 0, 0, 26, 9, 2, 3, + 0, 0, 0, 0, 0, 0, 27, 9, 2, 3, 8, 1, 6, 9, 4, 5, 14, 10, 11, 12, - 24, 16, 15, 17, 9, 2, 1, 1, 3, 9, - 14, 13, 24, 23, 21, 22, 18, 19, 20, 1, - 9, 9, 9, 9, 9, 0, 7, 7, 0 + 25, 16, 15, 17, 9, 2, 1, 1, 3, 9, + 14, 13, 25, 24, 23, 24, 21, 22, 18, 19, + 20, 1, 9, 9, 9, 9, 9, 0, 7, 7, + 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 5, 1, 6, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 4, 1, 5, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 8, 1, 1, 1, 1, 1, 9, 10, 11, + 1, 9, 1, 1, 1, 1, 1, 10, 11, 12, - 12, 13, 1, 1, 14, 1, 1, 15, 1, 16, - 1, 1, 1, 17, 1, 18, 19, 1, 1, 1, - 1, 1, 20, 1, 21, 1, 1, 1, 1, 1, + 13, 14, 1, 1, 15, 1, 1, 16, 1, 17, + 1, 1, 1, 18, 1, 19, 20, 1, 1, 1, + 1, 1, 21, 1, 22, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -506,88 +507,92 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[22] = +static yyconst flex_int32_t yy_meta[23] = { 0, - 1, 2, 3, 4, 5, 4, 6, 7, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, - 4 + 1, 2, 3, 1, 4, 5, 4, 6, 7, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 8, 4 } ; -static yyconst flex_int16_t yy_base[60] = +static yyconst flex_int16_t yy_base[62] = { 0, - 0, 0, 20, 40, 24, 28, 63, 0, 33, 145, - 145, 57, 145, 43, 145, 145, 0, 145, 145, 0, - 0, 145, 145, 53, 0, 45, 0, 55, 145, 47, - 0, 145, 0, 145, 145, 145, 145, 145, 145, 0, - 41, 35, 23, 18, 36, 48, 145, 51, 145, 71, - 79, 87, 94, 102, 107, 112, 120, 128, 136 + 0, 0, 21, 42, 26, 28, 63, 0, 31, 155, + 155, 59, 155, 44, 155, 155, 0, 155, 155, 0, + 0, 155, 155, 62, 0, 48, 0, 57, 155, 47, + 0, 155, 0, 155, 155, 49, 155, 155, 155, 155, + 155, 0, 30, 21, 28, 12, 37, 52, 155, 54, + 155, 81, 89, 97, 104, 112, 117, 122, 130, 138, + 146 } ; -static yyconst flex_int16_t yy_def[60] = +static yyconst flex_int16_t yy_def[62] = { 0, - 49, 1, 50, 50, 51, 51, 49, 52, 49, 49, - 49, 53, 49, 52, 49, 49, 54, 49, 49, 55, - 56, 49, 49, 57, 52, 49, 58, 53, 49, 52, - 54, 49, 56, 49, 49, 49, 49, 49, 49, 58, - 52, 52, 52, 52, 52, 59, 49, 59, 0, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49 + 51, 1, 52, 52, 53, 53, 51, 54, 51, 51, + 51, 55, 51, 54, 51, 51, 56, 51, 51, 57, + 58, 51, 51, 59, 54, 51, 60, 55, 51, 54, + 56, 51, 58, 51, 51, 51, 51, 51, 51, 51, + 51, 60, 54, 54, 54, 54, 54, 61, 51, 61, + 0, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51 } ; -static yyconst flex_int16_t yy_nxt[167] = +static yyconst flex_int16_t yy_nxt[178] = { 0, - 8, 9, 10, 9, 11, 12, 13, 8, 8, 8, - 8, 8, 8, 14, 8, 8, 8, 8, 8, 15, - 16, 18, 18, 18, 19, 18, 22, 20, 23, 45, - 22, 24, 23, 44, 26, 24, 26, 46, 27, 46, - 18, 18, 18, 18, 19, 18, 26, 20, 26, 48, - 27, 48, 48, 43, 48, 42, 41, 29, 30, 29, - 18, 35, 49, 49, 49, 36, 49, 49, 37, 38, - 39, 17, 17, 17, 17, 17, 17, 17, 17, 21, - 21, 21, 21, 21, 21, 21, 21, 25, 49, 49, - 49, 49, 49, 25, 28, 28, 28, 28, 28, 28, - - 28, 28, 31, 49, 49, 49, 49, 31, 49, 31, - 32, 32, 33, 33, 49, 33, 49, 33, 49, 33, - 34, 34, 34, 34, 34, 34, 34, 34, 40, 40, - 49, 40, 40, 40, 40, 40, 47, 47, 47, 47, - 47, 49, 47, 47, 7, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49 + 8, 9, 10, 8, 9, 11, 12, 13, 8, 8, + 8, 8, 8, 8, 14, 8, 8, 8, 8, 8, + 15, 16, 18, 18, 47, 18, 19, 18, 22, 20, + 22, 23, 26, 23, 24, 26, 24, 27, 48, 46, + 45, 48, 18, 18, 18, 44, 18, 19, 18, 26, + 20, 35, 26, 50, 27, 50, 50, 43, 50, 29, + 30, 29, 51, 18, 35, 36, 51, 51, 51, 51, + 51, 37, 51, 51, 51, 38, 51, 51, 39, 40, + 41, 17, 17, 17, 17, 17, 17, 17, 17, 21, + 21, 21, 21, 21, 21, 21, 21, 25, 51, 51, + + 51, 51, 51, 25, 28, 28, 28, 28, 28, 28, + 28, 28, 31, 51, 51, 51, 51, 31, 51, 31, + 32, 32, 33, 33, 51, 33, 51, 33, 51, 33, + 34, 34, 34, 34, 34, 34, 34, 34, 42, 42, + 51, 42, 42, 42, 42, 42, 49, 49, 49, 49, + 49, 51, 49, 49, 7, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51 } ; -static yyconst flex_int16_t yy_chk[167] = +static yyconst flex_int16_t yy_chk[178] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 3, 3, 3, 3, 3, 5, 3, 5, 44, - 6, 5, 6, 43, 9, 6, 9, 45, 9, 45, - 3, 4, 4, 4, 4, 4, 26, 4, 26, 46, - 26, 46, 48, 42, 48, 41, 30, 28, 14, 12, - 4, 24, 7, 0, 0, 24, 0, 0, 24, 24, - 24, 50, 50, 50, 50, 50, 50, 50, 50, 51, - 51, 51, 51, 51, 51, 51, 51, 52, 0, 0, - 0, 0, 0, 52, 53, 53, 53, 53, 53, 53, - - 53, 53, 54, 0, 0, 0, 0, 54, 0, 54, - 55, 55, 56, 56, 0, 56, 0, 56, 0, 56, - 57, 57, 57, 57, 57, 57, 57, 57, 58, 58, - 0, 58, 58, 58, 58, 58, 59, 59, 59, 59, - 59, 0, 59, 59, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49 + 1, 1, 3, 3, 46, 3, 3, 3, 5, 3, + 6, 5, 9, 6, 5, 9, 6, 9, 47, 45, + 44, 47, 3, 4, 4, 43, 4, 4, 4, 26, + 4, 36, 26, 48, 26, 50, 48, 30, 50, 28, + 14, 12, 7, 4, 24, 24, 0, 0, 0, 0, + 0, 24, 0, 0, 0, 24, 0, 0, 24, 24, + 24, 52, 52, 52, 52, 52, 52, 52, 52, 53, + 53, 53, 53, 53, 53, 53, 53, 54, 0, 0, + + 0, 0, 0, 54, 55, 55, 55, 55, 55, 55, + 55, 55, 56, 0, 0, 0, 0, 56, 0, 56, + 57, 57, 58, 58, 0, 58, 0, 58, 0, 58, + 59, 59, 59, 59, 59, 59, 59, 59, 60, 60, + 0, 60, 60, 60, 60, 60, 61, 61, 61, 61, + 61, 0, 61, 61, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51 } ; /* Table of booleans, true if rule could match eol. */ -static yyconst flex_int32_t yy_rule_can_match_eol[26] = +static yyconst flex_int32_t yy_rule_can_match_eol[27] = { 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, - 0, 0, 0, 1, 0, 0, }; + 0, 0, 0, 1, 0, 0, 0, }; -static yyconst flex_int16_t yy_rule_linenum[25] = +static yyconst flex_int16_t yy_rule_linenum[26] = { 0, 59, 60, 61, 63, 64, 65, 67, 72, 77, 85, 105, 108, 111, 114, 120, 122, 123, 146, 147, 148, - 149, 150, 151, 154 + 149, 150, 151, 152, 153 } ; /* The intent behind this definition is that it'll catch @@ -635,7 +640,7 @@ static void include_files(parser_helper_t *ctx); /* state used to scan quoted strings */ -#line 639 "settings/settings_lexer.c" +#line 644 "settings/settings_lexer.c" #define INITIAL 0 #define inc 1 @@ -947,7 +952,7 @@ YY_DECL #line 57 "settings/settings_lexer.l" -#line 951 "settings/settings_lexer.c" +#line 956 "settings/settings_lexer.c" yylval = yylval_param; @@ -1012,13 +1017,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 50 ) + if ( yy_current_state >= 52 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 145 ); + while ( yy_base[yy_current_state] != 155 ); yy_find_action: /* %% [10.0] code to find the action number goes here */ @@ -1053,13 +1058,13 @@ do_action: /* This label is used only to access EOF actions. */ { if ( yy_act == 0 ) fprintf( stderr, "--scanner backing up\n" ); - else if ( yy_act < 25 ) + else if ( yy_act < 26 ) fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n", (long)yy_rule_linenum[yy_act], yytext ); - else if ( yy_act == 25 ) + else if ( yy_act == 26 ) fprintf( stderr, "--accepting default rule (\"%s\")\n", yytext ); - else if ( yy_act == 26 ) + else if ( yy_act == 27 ) fprintf( stderr, "--(end of buffer or a NUL)\n" ); else fprintf( stderr, "--EOF (start condition %d)\n", YY_START ); @@ -1251,20 +1256,23 @@ case 23: /* rule 23 can match eol */ YY_RULE_SETUP #line 151 "settings/settings_lexer.l" -{ - yyextra->string_add(yyextra, yytext+1); - } +/* merge lines that end with EOL characters */ YY_BREAK case 24: YY_RULE_SETUP -#line 154 "settings/settings_lexer.l" +#line 152 "settings/settings_lexer.l" +yyextra->string_add(yyextra, yytext+1); + YY_BREAK +case 25: +YY_RULE_SETUP +#line 153 "settings/settings_lexer.l" { yyextra->string_add(yyextra, yytext); } YY_BREAK case YY_STATE_EOF(INITIAL): -#line 159 "settings/settings_lexer.l" +#line 158 "settings/settings_lexer.l" { settings_parser_pop_buffer_state(yyscanner); if (!settings_parser_open_next_file(yyextra) && !YY_CURRENT_BUFFER) @@ -1273,12 +1281,12 @@ case YY_STATE_EOF(INITIAL): } } YY_BREAK -case 25: +case 26: YY_RULE_SETUP -#line 167 "settings/settings_lexer.l" +#line 166 "settings/settings_lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 1282 "settings/settings_lexer.c" +#line 1290 "settings/settings_lexer.c" case YY_END_OF_BUFFER: { @@ -1591,7 +1599,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 50 ) + if ( yy_current_state >= 52 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1625,11 +1633,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 50 ) + if ( yy_current_state >= 52 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 49); + yy_is_jam = (yy_current_state == 51); return yy_is_jam ? 0 : yy_current_state; } @@ -2646,7 +2654,7 @@ void settings_parser_free (void * ptr , yyscan_t yyscanner) /* %ok-for-header */ -#line 167 "settings/settings_lexer.l" +#line 166 "settings/settings_lexer.l" diff --git a/src/libstrongswan/settings/settings_lexer.l b/src/libstrongswan/settings/settings_lexer.l index c6546f464..176387f1f 100644 --- a/src/libstrongswan/settings/settings_lexer.l +++ b/src/libstrongswan/settings/settings_lexer.l @@ -148,9 +148,8 @@ static void include_files(parser_helper_t *ctx); \\t yyextra->string_add(yyextra, "\t"); \\b yyextra->string_add(yyextra, "\b"); \\f yyextra->string_add(yyextra, "\f"); - \\(.|\n) { - yyextra->string_add(yyextra, yytext+1); - } + \\\r?\n /* merge lines that end with EOL characters */ + \\. yyextra->string_add(yyextra, yytext+1); [^\\\n"]+ { yyextra->string_add(yyextra, yytext); } diff --git a/src/libstrongswan/tests/Makefile.am b/src/libstrongswan/tests/Makefile.am index 7ecba19da..8c081c673 100644 --- a/src/libstrongswan/tests/Makefile.am +++ b/src/libstrongswan/tests/Makefile.am @@ -29,6 +29,7 @@ tests_SOURCES = tests.h tests.c \ suites/test_enum.c \ suites/test_hashtable.c \ suites/test_identification.c \ + suites/test_traffic_selector.c \ suites/test_threading.c \ suites/test_process.c \ suites/test_watcher.c \ @@ -40,6 +41,8 @@ tests_SOURCES = tests.h tests.c \ suites/test_array.c \ suites/test_ecdsa.c \ suites/test_rsa.c \ + suites/test_certpolicy.c \ + suites/test_certnames.c \ suites/test_host.c \ suites/test_hasher.c \ suites/test_crypter.c \ @@ -49,6 +52,7 @@ tests_SOURCES = tests.h tests.c \ suites/test_asn1_parser.c \ suites/test_printf.c \ suites/test_test_rng.c \ + suites/test_mgf1.c \ suites/test_ntru.c tests_CFLAGS = \ diff --git a/src/libstrongswan/tests/Makefile.in b/src/libstrongswan/tests/Makefile.in index 3268b5488..97e24bdb7 100644 --- a/src/libstrongswan/tests/Makefile.in +++ b/src/libstrongswan/tests/Makefile.in @@ -125,6 +125,7 @@ am_tests_OBJECTS = tests-tests.$(OBJEXT) \ suites/tests-test_enum.$(OBJEXT) \ suites/tests-test_hashtable.$(OBJEXT) \ suites/tests-test_identification.$(OBJEXT) \ + suites/tests-test_traffic_selector.$(OBJEXT) \ suites/tests-test_threading.$(OBJEXT) \ suites/tests-test_process.$(OBJEXT) \ suites/tests-test_watcher.$(OBJEXT) \ @@ -136,6 +137,8 @@ am_tests_OBJECTS = tests-tests.$(OBJEXT) \ suites/tests-test_array.$(OBJEXT) \ suites/tests-test_ecdsa.$(OBJEXT) \ suites/tests-test_rsa.$(OBJEXT) \ + suites/tests-test_certpolicy.$(OBJEXT) \ + suites/tests-test_certnames.$(OBJEXT) \ suites/tests-test_host.$(OBJEXT) \ suites/tests-test_hasher.$(OBJEXT) \ suites/tests-test_crypter.$(OBJEXT) \ @@ -145,6 +148,7 @@ am_tests_OBJECTS = tests-tests.$(OBJEXT) \ suites/tests-test_asn1_parser.$(OBJEXT) \ suites/tests-test_printf.$(OBJEXT) \ suites/tests-test_test_rng.$(OBJEXT) \ + suites/tests-test_mgf1.$(OBJEXT) \ suites/tests-test_ntru.$(OBJEXT) tests_OBJECTS = $(am_tests_OBJECTS) tests_DEPENDENCIES = \ @@ -260,6 +264,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -320,10 +325,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -397,6 +404,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ @@ -480,6 +489,7 @@ tests_SOURCES = tests.h tests.c \ suites/test_enum.c \ suites/test_hashtable.c \ suites/test_identification.c \ + suites/test_traffic_selector.c \ suites/test_threading.c \ suites/test_process.c \ suites/test_watcher.c \ @@ -491,6 +501,8 @@ tests_SOURCES = tests.h tests.c \ suites/test_array.c \ suites/test_ecdsa.c \ suites/test_rsa.c \ + suites/test_certpolicy.c \ + suites/test_certnames.c \ suites/test_host.c \ suites/test_hasher.c \ suites/test_crypter.c \ @@ -500,6 +512,7 @@ tests_SOURCES = tests.h tests.c \ suites/test_asn1_parser.c \ suites/test_printf.c \ suites/test_test_rng.c \ + suites/test_mgf1.c \ suites/test_ntru.c tests_CFLAGS = \ @@ -603,6 +616,8 @@ suites/tests-test_hashtable.$(OBJEXT): suites/$(am__dirstamp) \ suites/$(DEPDIR)/$(am__dirstamp) suites/tests-test_identification.$(OBJEXT): suites/$(am__dirstamp) \ suites/$(DEPDIR)/$(am__dirstamp) +suites/tests-test_traffic_selector.$(OBJEXT): suites/$(am__dirstamp) \ + suites/$(DEPDIR)/$(am__dirstamp) suites/tests-test_threading.$(OBJEXT): suites/$(am__dirstamp) \ suites/$(DEPDIR)/$(am__dirstamp) suites/tests-test_process.$(OBJEXT): suites/$(am__dirstamp) \ @@ -625,6 +640,10 @@ suites/tests-test_ecdsa.$(OBJEXT): suites/$(am__dirstamp) \ suites/$(DEPDIR)/$(am__dirstamp) suites/tests-test_rsa.$(OBJEXT): suites/$(am__dirstamp) \ suites/$(DEPDIR)/$(am__dirstamp) +suites/tests-test_certpolicy.$(OBJEXT): suites/$(am__dirstamp) \ + suites/$(DEPDIR)/$(am__dirstamp) +suites/tests-test_certnames.$(OBJEXT): suites/$(am__dirstamp) \ + suites/$(DEPDIR)/$(am__dirstamp) suites/tests-test_host.$(OBJEXT): suites/$(am__dirstamp) \ suites/$(DEPDIR)/$(am__dirstamp) suites/tests-test_hasher.$(OBJEXT): suites/$(am__dirstamp) \ @@ -643,6 +662,8 @@ suites/tests-test_printf.$(OBJEXT): suites/$(am__dirstamp) \ suites/$(DEPDIR)/$(am__dirstamp) suites/tests-test_test_rng.$(OBJEXT): suites/$(am__dirstamp) \ suites/$(DEPDIR)/$(am__dirstamp) +suites/tests-test_mgf1.$(OBJEXT): suites/$(am__dirstamp) \ + suites/$(DEPDIR)/$(am__dirstamp) suites/tests-test_ntru.$(OBJEXT): suites/$(am__dirstamp) \ suites/$(DEPDIR)/$(am__dirstamp) @@ -667,6 +688,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_asn1_parser.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_bio_reader.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_bio_writer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_certnames.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_certpolicy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_chunk.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_crypter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_crypto_factory.Po@am__quote@ @@ -680,6 +703,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_identification.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_linked_list.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_linked_list_enumerator.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_mgf1.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_ntru.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_pen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_printf.Po@am__quote@ @@ -689,6 +713,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_stream.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_test_rng.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_threading.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_traffic_selector.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_utils.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_vectors.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_watcher.Po@am__quote@ @@ -879,6 +904,20 @@ suites/tests-test_identification.obj: suites/test_identification.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_identification.obj `if test -f 'suites/test_identification.c'; then $(CYGPATH_W) 'suites/test_identification.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_identification.c'; fi` +suites/tests-test_traffic_selector.o: suites/test_traffic_selector.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_traffic_selector.o -MD -MP -MF suites/$(DEPDIR)/tests-test_traffic_selector.Tpo -c -o suites/tests-test_traffic_selector.o `test -f 'suites/test_traffic_selector.c' || echo '$(srcdir)/'`suites/test_traffic_selector.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_traffic_selector.Tpo suites/$(DEPDIR)/tests-test_traffic_selector.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_traffic_selector.c' object='suites/tests-test_traffic_selector.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_traffic_selector.o `test -f 'suites/test_traffic_selector.c' || echo '$(srcdir)/'`suites/test_traffic_selector.c + +suites/tests-test_traffic_selector.obj: suites/test_traffic_selector.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_traffic_selector.obj -MD -MP -MF suites/$(DEPDIR)/tests-test_traffic_selector.Tpo -c -o suites/tests-test_traffic_selector.obj `if test -f 'suites/test_traffic_selector.c'; then $(CYGPATH_W) 'suites/test_traffic_selector.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_traffic_selector.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_traffic_selector.Tpo suites/$(DEPDIR)/tests-test_traffic_selector.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_traffic_selector.c' object='suites/tests-test_traffic_selector.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_traffic_selector.obj `if test -f 'suites/test_traffic_selector.c'; then $(CYGPATH_W) 'suites/test_traffic_selector.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_traffic_selector.c'; fi` + suites/tests-test_threading.o: suites/test_threading.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_threading.o -MD -MP -MF suites/$(DEPDIR)/tests-test_threading.Tpo -c -o suites/tests-test_threading.o `test -f 'suites/test_threading.c' || echo '$(srcdir)/'`suites/test_threading.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_threading.Tpo suites/$(DEPDIR)/tests-test_threading.Po @@ -1033,6 +1072,34 @@ suites/tests-test_rsa.obj: suites/test_rsa.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_rsa.obj `if test -f 'suites/test_rsa.c'; then $(CYGPATH_W) 'suites/test_rsa.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_rsa.c'; fi` +suites/tests-test_certpolicy.o: suites/test_certpolicy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_certpolicy.o -MD -MP -MF suites/$(DEPDIR)/tests-test_certpolicy.Tpo -c -o suites/tests-test_certpolicy.o `test -f 'suites/test_certpolicy.c' || echo '$(srcdir)/'`suites/test_certpolicy.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_certpolicy.Tpo suites/$(DEPDIR)/tests-test_certpolicy.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_certpolicy.c' object='suites/tests-test_certpolicy.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_certpolicy.o `test -f 'suites/test_certpolicy.c' || echo '$(srcdir)/'`suites/test_certpolicy.c + +suites/tests-test_certpolicy.obj: suites/test_certpolicy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_certpolicy.obj -MD -MP -MF suites/$(DEPDIR)/tests-test_certpolicy.Tpo -c -o suites/tests-test_certpolicy.obj `if test -f 'suites/test_certpolicy.c'; then $(CYGPATH_W) 'suites/test_certpolicy.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_certpolicy.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_certpolicy.Tpo suites/$(DEPDIR)/tests-test_certpolicy.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_certpolicy.c' object='suites/tests-test_certpolicy.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_certpolicy.obj `if test -f 'suites/test_certpolicy.c'; then $(CYGPATH_W) 'suites/test_certpolicy.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_certpolicy.c'; fi` + +suites/tests-test_certnames.o: suites/test_certnames.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_certnames.o -MD -MP -MF suites/$(DEPDIR)/tests-test_certnames.Tpo -c -o suites/tests-test_certnames.o `test -f 'suites/test_certnames.c' || echo '$(srcdir)/'`suites/test_certnames.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_certnames.Tpo suites/$(DEPDIR)/tests-test_certnames.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_certnames.c' object='suites/tests-test_certnames.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_certnames.o `test -f 'suites/test_certnames.c' || echo '$(srcdir)/'`suites/test_certnames.c + +suites/tests-test_certnames.obj: suites/test_certnames.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_certnames.obj -MD -MP -MF suites/$(DEPDIR)/tests-test_certnames.Tpo -c -o suites/tests-test_certnames.obj `if test -f 'suites/test_certnames.c'; then $(CYGPATH_W) 'suites/test_certnames.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_certnames.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_certnames.Tpo suites/$(DEPDIR)/tests-test_certnames.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_certnames.c' object='suites/tests-test_certnames.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_certnames.obj `if test -f 'suites/test_certnames.c'; then $(CYGPATH_W) 'suites/test_certnames.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_certnames.c'; fi` + suites/tests-test_host.o: suites/test_host.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_host.o -MD -MP -MF suites/$(DEPDIR)/tests-test_host.Tpo -c -o suites/tests-test_host.o `test -f 'suites/test_host.c' || echo '$(srcdir)/'`suites/test_host.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_host.Tpo suites/$(DEPDIR)/tests-test_host.Po @@ -1159,6 +1226,20 @@ suites/tests-test_test_rng.obj: suites/test_test_rng.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_test_rng.obj `if test -f 'suites/test_test_rng.c'; then $(CYGPATH_W) 'suites/test_test_rng.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_test_rng.c'; fi` +suites/tests-test_mgf1.o: suites/test_mgf1.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_mgf1.o -MD -MP -MF suites/$(DEPDIR)/tests-test_mgf1.Tpo -c -o suites/tests-test_mgf1.o `test -f 'suites/test_mgf1.c' || echo '$(srcdir)/'`suites/test_mgf1.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_mgf1.Tpo suites/$(DEPDIR)/tests-test_mgf1.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_mgf1.c' object='suites/tests-test_mgf1.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_mgf1.o `test -f 'suites/test_mgf1.c' || echo '$(srcdir)/'`suites/test_mgf1.c + +suites/tests-test_mgf1.obj: suites/test_mgf1.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_mgf1.obj -MD -MP -MF suites/$(DEPDIR)/tests-test_mgf1.Tpo -c -o suites/tests-test_mgf1.obj `if test -f 'suites/test_mgf1.c'; then $(CYGPATH_W) 'suites/test_mgf1.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_mgf1.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_mgf1.Tpo suites/$(DEPDIR)/tests-test_mgf1.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_mgf1.c' object='suites/tests-test_mgf1.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_mgf1.obj `if test -f 'suites/test_mgf1.c'; then $(CYGPATH_W) 'suites/test_mgf1.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_mgf1.c'; fi` + suites/tests-test_ntru.o: suites/test_ntru.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_ntru.o -MD -MP -MF suites/$(DEPDIR)/tests-test_ntru.Tpo -c -o suites/tests-test_ntru.o `test -f 'suites/test_ntru.c' || echo '$(srcdir)/'`suites/test_ntru.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_ntru.Tpo suites/$(DEPDIR)/tests-test_ntru.Po diff --git a/src/libstrongswan/tests/suites/test_certnames.c b/src/libstrongswan/tests/suites/test_certnames.c new file mode 100644 index 000000000..e30702864 --- /dev/null +++ b/src/libstrongswan/tests/suites/test_certnames.c @@ -0,0 +1,398 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "test_suite.h" + +#include <asn1/asn1.h> +#include <credentials/sets/mem_cred.h> +#include <credentials/certificates/x509.h> + +/** + * RSA private key, so we don't have to generate one + */ +static char keydata[] = { + 0x30,0x82,0x02,0x5e,0x02,0x01,0x00,0x02,0x81,0x81,0x00,0xb1,0x9b,0xd4,0x51,0x24, + 0xfc,0x56,0x1d,0x3d,0xfb,0xa2,0xea,0x37,0x02,0x70,0x72,0x87,0x84,0x2f,0x3b,0x2d, + 0x6e,0x22,0xef,0x3f,0x37,0x04,0xb2,0x6f,0xb7,0xe7,0xd8,0x58,0x05,0xde,0x34,0xbf, + 0x99,0xe6,0x40,0x7a,0x56,0xa7,0x73,0xf5,0x98,0xcb,0xb0,0x37,0x90,0x5e,0xd1,0x3f, + 0xf4,0x73,0x50,0x7f,0x53,0x8e,0xf1,0x04,0x25,0xb4,0x77,0x22,0x4e,0x8a,0x9d,0x27, + 0x8f,0x6f,0xaf,0x59,0xbd,0xb0,0x0f,0xf0,0xaa,0x11,0x94,0x66,0x16,0x10,0x58,0xad, + 0x77,0xa1,0xac,0x58,0xb4,0xd0,0x0d,0xbc,0x11,0xe0,0xc0,0xe9,0x29,0xdc,0x42,0x63, + 0x01,0x23,0x4f,0x28,0x41,0x6d,0x34,0x9e,0x0c,0x4a,0xc8,0x62,0x83,0xb5,0x71,0x71, + 0x0b,0x51,0xc0,0x4c,0x37,0xd4,0x68,0x19,0x52,0x9a,0x8b,0x02,0x03,0x01,0x00,0x01, + 0x02,0x81,0x81,0x00,0x82,0xca,0x33,0x16,0xb2,0x3a,0xd4,0x1b,0x62,0x9a,0x9c,0xc5, + 0x07,0x4f,0x57,0x89,0x2f,0x7c,0x4a,0xdf,0xb4,0x3b,0xc7,0xa4,0x11,0x14,0x2d,0xf4, + 0x4c,0xca,0xcc,0x03,0x88,0x06,0x82,0x34,0xab,0xe7,0xe4,0x24,0x15,0x33,0x1c,0xcb, + 0x0a,0xcf,0xc3,0x27,0x78,0x33,0x6b,0x6f,0x82,0x3e,0x3c,0x70,0xc9,0xe2,0xb9,0x7f, + 0x88,0xc3,0x4f,0x59,0xb5,0x8e,0xa3,0x81,0xd9,0x88,0x1f,0xc0,0x38,0xbc,0xc8,0x93, + 0x40,0x0f,0x43,0xd8,0x72,0x12,0xb4,0xcc,0x6d,0x76,0x0a,0x6f,0x01,0x05,0xa8,0x88, + 0xf4,0x57,0x44,0xd2,0x05,0xc4,0x77,0xf5,0xfb,0x1b,0xf3,0xb2,0x0d,0x90,0xb8,0xb4, + 0x63,0x62,0x70,0x2c,0xe4,0x28,0xd8,0x20,0x10,0x85,0x4a,0x5e,0x63,0xa9,0xb0,0xdd, + 0xba,0xd0,0x32,0x49,0x02,0x41,0x00,0xdb,0x77,0xf1,0xdd,0x1a,0x12,0xc5,0xfb,0x2b, + 0x5b,0xb2,0xcd,0xb6,0xd0,0x4c,0xc4,0xe5,0x93,0xd6,0xf8,0x88,0xfc,0x18,0x40,0x21, + 0x9c,0xf7,0x2d,0x60,0x6f,0x91,0xf5,0x73,0x3c,0xf7,0x7f,0x67,0x1d,0x5b,0xb5,0xee, + 0x29,0xc1,0xd4,0xc6,0xdb,0x44,0x4c,0x40,0x05,0x63,0xaa,0x71,0x95,0x18,0x14,0xa7, + 0x23,0x9f,0x7a,0xee,0x7f,0xb5,0xc7,0x02,0x41,0x00,0xcf,0x2c,0x24,0x50,0x65,0xf4, + 0x94,0x7b,0xe9,0xf3,0x13,0x77,0xea,0x27,0x3c,0x6f,0x03,0x84,0xa7,0x7d,0xa2,0x54, + 0x40,0x97,0x82,0x0e,0xd9,0x09,0x9f,0x4a,0xa6,0x75,0xe5,0x66,0xe4,0x9c,0x59,0xd9, + 0x3a,0xe6,0xf7,0xd8,0x8b,0x68,0xb0,0x21,0x52,0x31,0xb3,0x4a,0xa0,0x2c,0x41,0xd7, + 0x1f,0x7b,0xe2,0x0f,0x15,0xc9,0x6e,0xc0,0xe5,0x1d,0x02,0x41,0x00,0x9c,0x1a,0x61, + 0x9f,0x89,0xc7,0x26,0xa9,0x33,0xba,0xe2,0xa0,0x6d,0xd3,0x15,0x77,0xcb,0x6f,0xef, + 0xad,0x12,0x0a,0x75,0xd9,0x4f,0xcf,0x4d,0x05,0x2a,0x9d,0xd1,0x2c,0xcb,0xcd,0xe6, + 0xa0,0xe9,0x20,0x39,0xb6,0x5a,0xf3,0xba,0x99,0xf4,0xe3,0xcb,0x5d,0x8d,0x00,0x08, + 0x57,0x18,0xb9,0x1a,0xca,0xbd,0xe3,0x99,0xb1,0x1f,0xe9,0x18,0xcb,0x02,0x40,0x65, + 0x35,0x1b,0x48,0x6b,0x86,0x60,0x43,0x68,0xb6,0xe6,0xfb,0xdd,0xd7,0xed,0x1e,0x0e, + 0x89,0xef,0x88,0xe0,0x94,0x68,0x39,0x9b,0xbf,0xc5,0x27,0x7e,0x39,0xe9,0xb8,0x0e, + 0xa9,0x85,0x65,0x1c,0x3f,0x93,0x16,0xe2,0x5d,0x57,0x3d,0x7d,0x4d,0xc9,0xe9,0x9d, + 0xbd,0x07,0x22,0x97,0xc7,0x90,0x09,0xe5,0x15,0x99,0x7f,0x1e,0x2b,0xfd,0xc1,0x02, + 0x41,0x00,0x92,0x78,0xfe,0x04,0xa0,0x53,0xed,0x36,0x97,0xbd,0x16,0xce,0x91,0x9b, + 0xbe,0x1f,0x8e,0x40,0x00,0x99,0x0c,0x49,0x15,0xca,0x59,0xd3,0xe3,0xd4,0xeb,0x71, + 0xcf,0xda,0xd7,0xc8,0x99,0x74,0xfc,0x6b,0xe8,0xfd,0xe5,0xe0,0x49,0x61,0xcb,0xda, + 0xe3,0xe7,0x8b,0x72,0xb5,0x69,0x73,0x2b,0x8b,0x54,0xcb,0xd9,0x48,0x6d,0x61,0x02, + 0x49,0xe8, +}; + +/** + * Issue a certificate with permitted/excluded name constraints + */ +static certificate_t* create_cert(certificate_t *ca, char *subject, char *san, + x509_flag_t flags, identification_t *permitted, + identification_t *excluded) +{ + private_key_t *privkey; + public_key_t *pubkey; + certificate_t *cert; + identification_t *id; + linked_list_t *plist, *elist, *sans; + + privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, + BUILD_BLOB_ASN1_DER, chunk_from_thing(keydata), + BUILD_END); + ck_assert(privkey); + pubkey = privkey->get_public_key(privkey); + ck_assert(pubkey); + plist = linked_list_create(); + if (permitted) + { + plist->insert_last(plist, permitted); + } + elist = linked_list_create(); + if (excluded) + { + elist->insert_last(elist, excluded); + } + sans = linked_list_create(); + if (san) + { + id = identification_create_from_string(san); + sans->insert_last(sans, id); + } + id = identification_create_from_string(subject); + cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, + BUILD_SIGNING_KEY, privkey, + BUILD_PUBLIC_KEY, pubkey, + BUILD_SUBJECT, id, + BUILD_X509_FLAG, flags, + BUILD_SIGNING_CERT, ca, + BUILD_SUBJECT_ALTNAMES, sans, + BUILD_PERMITTED_NAME_CONSTRAINTS, plist, + BUILD_EXCLUDED_NAME_CONSTRAINTS, elist, + BUILD_END); + ck_assert(cert); + id->destroy(id); + sans->destroy_offset(sans, offsetof(identification_t, destroy)); + plist->destroy_offset(plist, offsetof(identification_t, destroy)); + elist->destroy_offset(elist, offsetof(identification_t, destroy)); + privkey->destroy(privkey); + pubkey->destroy(pubkey); + + return cert; +} + +/** + * Check if a certificate with given subject has a valid trustchain + */ +static bool check_trust(identification_t *subject) +{ + enumerator_t *certs; + certificate_t *cert; + bool trusted; + + certs = lib->credmgr->create_trusted_enumerator(lib->credmgr, KEY_ANY, + subject, FALSE); + trusted = certs->enumerate(certs, &cert, NULL); + certs->destroy(certs); + + return trusted; +} + +static mem_cred_t *creds; + +START_SETUP(setup) +{ + creds = mem_cred_create(); + lib->credmgr->add_set(lib->credmgr, &creds->set); +} +END_SETUP + +START_TEARDOWN(teardown) +{ + lib->credmgr->remove_set(lib->credmgr, &creds->set); + creds->destroy(creds); + lib->credmgr->flush_cache(lib->credmgr, CERT_ANY); +} +END_TEARDOWN + +static struct { + char *constraint; + char *subject; + bool good; +} permitted_dn[] = { + { "C=CH, O=strongSwan", "C=CH, O=strongSwan, CN=tester", TRUE }, + { "C=CH, O=strongSwan", "C=CH, O=strong", FALSE }, + { "C=CH, O=strongSwan", "C=CH, O=strong, CN=tester", FALSE }, + { "C=CH, O=strongSwan", "C=CH, O=another, CN=tester", FALSE }, + { "C=CH, O=strongSwan", "C=CH, CN=tester, O=strongSwan", FALSE }, +}; + +START_TEST(test_permitted_dn) +{ + certificate_t *ca, *im, *sj; + identification_t *id; + + id = identification_create_from_string(permitted_dn[_i].constraint); + ca = create_cert(NULL, "C=CH, O=strongSwan, CN=CA", NULL, X509_CA, id, NULL); + id = identification_create_from_string(permitted_dn[_i].constraint); + im = create_cert(ca, "C=CH, O=strongSwan, CN=IM", NULL, X509_CA, id, NULL); + sj = create_cert(im, permitted_dn[_i].subject, NULL, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_trust(sj->get_subject(sj)) == permitted_dn[_i].good); +} +END_TEST + +static struct { + id_type_t ctype; + char *cdata; + char *subject; + bool good; +} permitted_san[] = { + { ID_FQDN, ".strongswan.org", "test.strongswan.org", TRUE }, + { ID_FQDN, "strongswan.org", "test.strongswan.org", TRUE }, + { ID_FQDN, "a.b.c.strongswan.org", "d.a.b.c.strongswan.org", TRUE }, + { ID_FQDN, "a.b.c.strongswan.org", "a.b.c.d.strongswan.org", FALSE }, + { ID_FQDN, "strongswan.org", "strongswan.org.com", FALSE }, + { ID_FQDN, ".strongswan.org", "strongswan.org", FALSE }, + { ID_FQDN, "strongswan.org", "nostrongswan.org", FALSE }, + { ID_FQDN, "strongswan.org", "swan.org", FALSE }, + { ID_FQDN, "strongswan.org", "swan.org", FALSE }, + { ID_RFC822_ADDR, "tester@strongswan.org", "tester@strongswan.org", TRUE }, + { ID_RFC822_ADDR, "tester@strongswan.org", "atester@strongswan.org", FALSE }, + { ID_RFC822_ADDR, "strongswan.org", "tester@strongswan.org", TRUE }, + { ID_RFC822_ADDR, "strongswan.org", "tester@test.strongswan.org", FALSE }, + { ID_RFC822_ADDR, ".strongswan.org", "tester@test.strongswan.org", TRUE }, + { ID_RFC822_ADDR, ".strongswan.org", "tester@strongswan.org", FALSE }, +}; + +START_TEST(test_permitted_san) +{ + certificate_t *ca, *sj; + identification_t *id; + + id = identification_create_from_encoding(permitted_san[_i].ctype, + chunk_from_str(permitted_san[_i].cdata)); + ca = create_cert(NULL, "CN=CA", NULL, X509_CA, id, NULL); + sj = create_cert(ca, "CN=SJ", permitted_san[_i].subject, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_trust(sj->get_subject(sj)) == permitted_san[_i].good); +} +END_TEST + +static struct { + char *constraint; + char *subject; + bool good; +} excluded_dn[] = { + { "C=CH, O=another", "C=CH, O=strongSwan, CN=tester", TRUE }, + { "C=CH, O=another", "C=CH, O=anot", TRUE }, + { "C=CH, O=another", "C=CH, O=anot, CN=tester", TRUE }, + { "C=CH, O=another", "C=CH, O=another, CN=tester", FALSE }, + { "C=CH, O=another", "C=CH, CN=tester, O=another", TRUE }, +}; + +START_TEST(test_excluded_dn) +{ + certificate_t *ca, *im, *sj; + identification_t *id; + + id = identification_create_from_string(excluded_dn[_i].constraint); + ca = create_cert(NULL, "C=CH, O=strongSwan, CN=CA", NULL, X509_CA, NULL, id); + id = identification_create_from_string(excluded_dn[_i].constraint); + im = create_cert(ca, "C=CH, O=strongSwan, CN=IM", NULL, X509_CA, NULL, id); + sj = create_cert(im, excluded_dn[_i].subject, NULL, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_trust(sj->get_subject(sj)) == excluded_dn[_i].good); +} +END_TEST + +static struct { + id_type_t ctype; + char *cdata; + char *subject; + bool good; +} excluded_san[] = { + { ID_FQDN, ".strongswan.org", "test.strongswan.org", FALSE }, + { ID_FQDN, "strongswan.org", "test.strongswan.org", FALSE }, + { ID_FQDN, "a.b.c.strongswan.org", "d.a.b.c.strongswan.org", FALSE }, + { ID_FQDN, "a.b.c.strongswan.org", "a.b.c.d.strongswan.org", TRUE }, + { ID_FQDN, "strongswan.org", "strongswan.org.com", TRUE }, + { ID_FQDN, ".strongswan.org", "strongswan.org", TRUE }, + { ID_FQDN, "strongswan.org", "nostrongswan.org", TRUE }, + { ID_FQDN, "strongswan.org", "swan.org", TRUE }, + { ID_FQDN, "strongswan.org", "swan.org", TRUE }, + { ID_RFC822_ADDR, "tester@strongswan.org", "tester@strongswan.org", FALSE }, + { ID_RFC822_ADDR, "tester@strongswan.org", "atester@strongswan.org", TRUE }, + { ID_RFC822_ADDR, "strongswan.org", "tester@strongswan.org", FALSE }, + { ID_RFC822_ADDR, "strongswan.org", "tester@test.strongswan.org", TRUE }, + { ID_RFC822_ADDR, ".strongswan.org", "tester@test.strongswan.org", FALSE }, + { ID_RFC822_ADDR, ".strongswan.org", "tester@strongswan.org", TRUE }, +}; + +START_TEST(test_excluded_san) +{ + certificate_t *ca, *sj; + identification_t *id; + + id = identification_create_from_encoding(excluded_san[_i].ctype, + chunk_from_str(excluded_san[_i].cdata)); + ca = create_cert(NULL, "CN=CA", NULL, X509_CA, NULL, id); + sj = create_cert(ca, "CN=SJ", excluded_san[_i].subject, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_trust(sj->get_subject(sj)) == excluded_san[_i].good); +} +END_TEST + +static struct { + char *caconst; + char *imconst; + char *subject; + bool good; +} permitted_dninh[] = { + { "C=CH", "C=CH, O=strongSwan", "C=CH, O=strongSwan, CN=tester", TRUE }, + { "C=CH", "C=DE, O=strongSwan", "C=CH, O=strongSwan, CN=tester", FALSE }, + { "C=CH, O=strongSwan", "C=CH", "C=CH", FALSE }, +}; + +START_TEST(test_permitted_dninh) +{ + certificate_t *ca, *im, *sj; + identification_t *id; + + id = identification_create_from_string(permitted_dninh[_i].caconst); + ca = create_cert(NULL, "C=CH, O=strongSwan, CN=CA", NULL, X509_CA, id, NULL); + id = identification_create_from_string(permitted_dninh[_i].imconst); + im = create_cert(ca, "C=CH, O=strongSwan, CN=IM", NULL, X509_CA, id, NULL); + sj = create_cert(im, permitted_dninh[_i].subject, NULL, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_trust(sj->get_subject(sj)) == permitted_dninh[_i].good); +} +END_TEST + +static struct { + char *caconst; + char *imconst; + char *subject; + bool good; +} excluded_dninh[] = { + { "C=CH, O=strongSwan", "C=CH", "C=DE", TRUE }, + { "C=CH, O=strongSwan", "C=DE", "C=CH", FALSE }, + { "C=CH", "C=CH, O=strongSwan", "C=CH, O=strongSwan, CN=tester", FALSE }, +}; + +START_TEST(test_excluded_dninh) +{ + certificate_t *ca, *im, *sj; + identification_t *id; + + id = identification_create_from_string(excluded_dninh[_i].caconst); + ca = create_cert(NULL, "C=CH, O=strongSwan, CN=CA", NULL, X509_CA, NULL, id); + id = identification_create_from_string(excluded_dninh[_i].imconst); + im = create_cert(ca, "C=DE, CN=IM", NULL, X509_CA, NULL, id); + sj = create_cert(im, excluded_dninh[_i].subject, NULL, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_trust(sj->get_subject(sj)) == excluded_dninh[_i].good); +} +END_TEST + +Suite *certnames_suite_create() +{ + Suite *s; + TCase *tc; + + s = suite_create("certnames"); + + tc = tcase_create("permitted DN name constraints"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_loop_test(tc, test_permitted_dn, 0, countof(permitted_dn)); + suite_add_tcase(s, tc); + + tc = tcase_create("permitted subjectAltName constraints"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_loop_test(tc, test_permitted_san, 0, countof(permitted_san)); + suite_add_tcase(s, tc); + + tc = tcase_create("excluded DN constraints"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_loop_test(tc, test_excluded_dn, 0, countof(excluded_dn)); + suite_add_tcase(s, tc); + + tc = tcase_create("excluded subjectAltName constraints"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_loop_test(tc, test_excluded_san, 0, countof(excluded_san)); + suite_add_tcase(s, tc); + + tc = tcase_create("permitted DN name constraint inherit"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_loop_test(tc, test_permitted_dninh, 0, countof(permitted_dninh)); + suite_add_tcase(s, tc); + + tc = tcase_create("excluded DN name constraint inherit"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_loop_test(tc, test_excluded_dninh, 0, countof(excluded_dninh)); + suite_add_tcase(s, tc); + + return s; +} diff --git a/src/libstrongswan/tests/suites/test_certpolicy.c b/src/libstrongswan/tests/suites/test_certpolicy.c new file mode 100644 index 000000000..7501e1a8b --- /dev/null +++ b/src/libstrongswan/tests/suites/test_certpolicy.c @@ -0,0 +1,637 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "test_suite.h" + +#include <asn1/asn1.h> +#include <credentials/sets/mem_cred.h> +#include <credentials/certificates/x509.h> + +/** + * RSA private key, so we don't have to generate one + */ +static char keydata[] = { + 0x30,0x82,0x02,0x5e,0x02,0x01,0x00,0x02,0x81,0x81,0x00,0xb1,0x9b,0xd4,0x51,0x24, + 0xfc,0x56,0x1d,0x3d,0xfb,0xa2,0xea,0x37,0x02,0x70,0x72,0x87,0x84,0x2f,0x3b,0x2d, + 0x6e,0x22,0xef,0x3f,0x37,0x04,0xb2,0x6f,0xb7,0xe7,0xd8,0x58,0x05,0xde,0x34,0xbf, + 0x99,0xe6,0x40,0x7a,0x56,0xa7,0x73,0xf5,0x98,0xcb,0xb0,0x37,0x90,0x5e,0xd1,0x3f, + 0xf4,0x73,0x50,0x7f,0x53,0x8e,0xf1,0x04,0x25,0xb4,0x77,0x22,0x4e,0x8a,0x9d,0x27, + 0x8f,0x6f,0xaf,0x59,0xbd,0xb0,0x0f,0xf0,0xaa,0x11,0x94,0x66,0x16,0x10,0x58,0xad, + 0x77,0xa1,0xac,0x58,0xb4,0xd0,0x0d,0xbc,0x11,0xe0,0xc0,0xe9,0x29,0xdc,0x42,0x63, + 0x01,0x23,0x4f,0x28,0x41,0x6d,0x34,0x9e,0x0c,0x4a,0xc8,0x62,0x83,0xb5,0x71,0x71, + 0x0b,0x51,0xc0,0x4c,0x37,0xd4,0x68,0x19,0x52,0x9a,0x8b,0x02,0x03,0x01,0x00,0x01, + 0x02,0x81,0x81,0x00,0x82,0xca,0x33,0x16,0xb2,0x3a,0xd4,0x1b,0x62,0x9a,0x9c,0xc5, + 0x07,0x4f,0x57,0x89,0x2f,0x7c,0x4a,0xdf,0xb4,0x3b,0xc7,0xa4,0x11,0x14,0x2d,0xf4, + 0x4c,0xca,0xcc,0x03,0x88,0x06,0x82,0x34,0xab,0xe7,0xe4,0x24,0x15,0x33,0x1c,0xcb, + 0x0a,0xcf,0xc3,0x27,0x78,0x33,0x6b,0x6f,0x82,0x3e,0x3c,0x70,0xc9,0xe2,0xb9,0x7f, + 0x88,0xc3,0x4f,0x59,0xb5,0x8e,0xa3,0x81,0xd9,0x88,0x1f,0xc0,0x38,0xbc,0xc8,0x93, + 0x40,0x0f,0x43,0xd8,0x72,0x12,0xb4,0xcc,0x6d,0x76,0x0a,0x6f,0x01,0x05,0xa8,0x88, + 0xf4,0x57,0x44,0xd2,0x05,0xc4,0x77,0xf5,0xfb,0x1b,0xf3,0xb2,0x0d,0x90,0xb8,0xb4, + 0x63,0x62,0x70,0x2c,0xe4,0x28,0xd8,0x20,0x10,0x85,0x4a,0x5e,0x63,0xa9,0xb0,0xdd, + 0xba,0xd0,0x32,0x49,0x02,0x41,0x00,0xdb,0x77,0xf1,0xdd,0x1a,0x12,0xc5,0xfb,0x2b, + 0x5b,0xb2,0xcd,0xb6,0xd0,0x4c,0xc4,0xe5,0x93,0xd6,0xf8,0x88,0xfc,0x18,0x40,0x21, + 0x9c,0xf7,0x2d,0x60,0x6f,0x91,0xf5,0x73,0x3c,0xf7,0x7f,0x67,0x1d,0x5b,0xb5,0xee, + 0x29,0xc1,0xd4,0xc6,0xdb,0x44,0x4c,0x40,0x05,0x63,0xaa,0x71,0x95,0x18,0x14,0xa7, + 0x23,0x9f,0x7a,0xee,0x7f,0xb5,0xc7,0x02,0x41,0x00,0xcf,0x2c,0x24,0x50,0x65,0xf4, + 0x94,0x7b,0xe9,0xf3,0x13,0x77,0xea,0x27,0x3c,0x6f,0x03,0x84,0xa7,0x7d,0xa2,0x54, + 0x40,0x97,0x82,0x0e,0xd9,0x09,0x9f,0x4a,0xa6,0x75,0xe5,0x66,0xe4,0x9c,0x59,0xd9, + 0x3a,0xe6,0xf7,0xd8,0x8b,0x68,0xb0,0x21,0x52,0x31,0xb3,0x4a,0xa0,0x2c,0x41,0xd7, + 0x1f,0x7b,0xe2,0x0f,0x15,0xc9,0x6e,0xc0,0xe5,0x1d,0x02,0x41,0x00,0x9c,0x1a,0x61, + 0x9f,0x89,0xc7,0x26,0xa9,0x33,0xba,0xe2,0xa0,0x6d,0xd3,0x15,0x77,0xcb,0x6f,0xef, + 0xad,0x12,0x0a,0x75,0xd9,0x4f,0xcf,0x4d,0x05,0x2a,0x9d,0xd1,0x2c,0xcb,0xcd,0xe6, + 0xa0,0xe9,0x20,0x39,0xb6,0x5a,0xf3,0xba,0x99,0xf4,0xe3,0xcb,0x5d,0x8d,0x00,0x08, + 0x57,0x18,0xb9,0x1a,0xca,0xbd,0xe3,0x99,0xb1,0x1f,0xe9,0x18,0xcb,0x02,0x40,0x65, + 0x35,0x1b,0x48,0x6b,0x86,0x60,0x43,0x68,0xb6,0xe6,0xfb,0xdd,0xd7,0xed,0x1e,0x0e, + 0x89,0xef,0x88,0xe0,0x94,0x68,0x39,0x9b,0xbf,0xc5,0x27,0x7e,0x39,0xe9,0xb8,0x0e, + 0xa9,0x85,0x65,0x1c,0x3f,0x93,0x16,0xe2,0x5d,0x57,0x3d,0x7d,0x4d,0xc9,0xe9,0x9d, + 0xbd,0x07,0x22,0x97,0xc7,0x90,0x09,0xe5,0x15,0x99,0x7f,0x1e,0x2b,0xfd,0xc1,0x02, + 0x41,0x00,0x92,0x78,0xfe,0x04,0xa0,0x53,0xed,0x36,0x97,0xbd,0x16,0xce,0x91,0x9b, + 0xbe,0x1f,0x8e,0x40,0x00,0x99,0x0c,0x49,0x15,0xca,0x59,0xd3,0xe3,0xd4,0xeb,0x71, + 0xcf,0xda,0xd7,0xc8,0x99,0x74,0xfc,0x6b,0xe8,0xfd,0xe5,0xe0,0x49,0x61,0xcb,0xda, + 0xe3,0xe7,0x8b,0x72,0xb5,0x69,0x73,0x2b,0x8b,0x54,0xcb,0xd9,0x48,0x6d,0x61,0x02, + 0x49,0xe8, +}; + +/** + * Issue a certificate fr given policy, including extended flags + */ +static certificate_t* create_cert_ext(certificate_t *ca, char *subject, + char *oid, x509_flag_t flags, + char *map_s, char *map_i, + u_int require_explicit, + u_int inhibit_mapping, + u_int inhibit_any) +{ + private_key_t *privkey; + public_key_t *pubkey; + certificate_t *cert; + identification_t *id; + linked_list_t *policies, *maps; + x509_cert_policy_t policy = {}; + x509_policy_mapping_t map = {}; + + privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA, + BUILD_BLOB_ASN1_DER, chunk_from_thing(keydata), + BUILD_END); + ck_assert(privkey); + pubkey = privkey->get_public_key(privkey); + ck_assert(pubkey); + policies = linked_list_create(); + if (oid) + { + policy.oid = asn1_oid_from_string(oid); + ck_assert(policy.oid.ptr); + policies->insert_last(policies, &policy); + } + maps = linked_list_create(); + if (map_s && map_i) + { + map.subject = asn1_oid_from_string(map_s); + ck_assert(map.subject.ptr); + map.issuer = asn1_oid_from_string(map_i); + ck_assert(map.issuer.ptr); + maps->insert_last(maps, &map); + } + id = identification_create_from_string(subject); + cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, + BUILD_SIGNING_KEY, privkey, + BUILD_PUBLIC_KEY, pubkey, + BUILD_SUBJECT, id, + BUILD_X509_FLAG, flags, + BUILD_CERTIFICATE_POLICIES, policies, + BUILD_POLICY_MAPPINGS, maps, + BUILD_SIGNING_CERT, ca, + BUILD_POLICY_REQUIRE_EXPLICIT, require_explicit, + BUILD_POLICY_INHIBIT_MAPPING, inhibit_mapping, + BUILD_POLICY_INHIBIT_ANY, inhibit_any, + BUILD_END); + ck_assert(cert); + id->destroy(id); + policies->destroy(policies); + maps->destroy(maps); + privkey->destroy(privkey); + pubkey->destroy(pubkey); + free(policy.oid.ptr); + free(map.subject.ptr); + free(map.issuer.ptr); + + return cert; +} + +/** + * Issue a certificate with given certificate policy and flags + */ +static certificate_t* create_cert(certificate_t *ca, char *subject, + char *oid, x509_flag_t flags, + char *map_s, char *map_i) +{ + return create_cert_ext(ca, subject, oid, flags, map_s, map_i, + X509_NO_CONSTRAINT, X509_NO_CONSTRAINT, + X509_NO_CONSTRAINT); +} + +/** + * Check if a certificate with given subject has an oid + */ +static bool check_oid(identification_t *subject, char *oid) +{ + enumerator_t *certs, *auths; + certificate_t *cert; + auth_cfg_t *auth; + bool found = FALSE; + auth_rule_t type; + char *current; + + certs = lib->credmgr->create_trusted_enumerator(lib->credmgr, KEY_ANY, + subject, FALSE); + if (!certs->enumerate(certs, &cert, &auth)) + { + certs->destroy(certs); + ck_assert_msg(FALSE, "no trusted certificate found for %Y", subject); + } + auths = auth->create_enumerator(auth); + while (auths->enumerate(auths, &type, ¤t)) + { + if (type == AUTH_RULE_CERT_POLICY) + { + if (streq(current, oid)) + { + found = TRUE; + break; + } + } + } + auths->destroy(auths); + certs->destroy(certs); + + return found; +} + +/** + * Check if a certificate with given subject has a valid trustchain + */ +static bool check_trust(identification_t *subject) +{ + enumerator_t *certs; + certificate_t *cert; + bool trusted; + + certs = lib->credmgr->create_trusted_enumerator(lib->credmgr, KEY_ANY, + subject, FALSE); + trusted = certs->enumerate(certs, &cert, NULL); + certs->destroy(certs); + + return trusted; +} + +static mem_cred_t *creds; + +static char *anyPolicy = "2.5.29.32.0"; +static char *extended = "2.23.140.1.1"; +static char *baseline = "2.23.140.1.2"; + +START_SETUP(setup) +{ + creds = mem_cred_create(); + lib->credmgr->add_set(lib->credmgr, &creds->set); +} +END_SETUP + +START_TEARDOWN(teardown) +{ + lib->credmgr->remove_set(lib->credmgr, &creds->set); + creds->destroy(creds); + lib->credmgr->flush_cache(lib->credmgr, CERT_ANY); +} +END_TEARDOWN + +START_TEST(test_valid_fixed) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", baseline, X509_CA, NULL, NULL); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_valid_any1) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", baseline, X509_CA, NULL, NULL); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_valid_any2) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", anyPolicy, X509_CA, NULL, NULL); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_invalid_missing) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", baseline, X509_CA, NULL, NULL); + sj = create_cert(im, "CN=SJ", NULL, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(!check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_invalid_wrong) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", baseline, X509_CA, NULL, NULL); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(!check_oid(sj->get_subject(sj), extended)); +} +END_TEST + +START_TEST(test_invalid_any1) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", anyPolicy, X509_CA, NULL, NULL); + sj = create_cert(im, "CN=SJ", NULL, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(!check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_invalid_any2) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", anyPolicy, X509_CA, NULL, NULL); + sj = create_cert(im, "CN=SJ", anyPolicy, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(!check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_badchain_wrong) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", extended, X509_CA, NULL, NULL); + sj = create_cert(im, "CN=SJ", extended, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(!check_oid(sj->get_subject(sj), baseline)); + ck_assert(!check_oid(sj->get_subject(sj), extended)); +} +END_TEST + +START_TEST(test_badchain_gap) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", NULL, X509_CA, NULL, NULL); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(!check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_badchain_any) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", anyPolicy, X509_CA, NULL, NULL); + sj = create_cert(im, "CN=SJ", extended, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(!check_oid(sj->get_subject(sj), extended)); +} +END_TEST + +START_TEST(test_valid_mapping) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", extended, X509_CA, baseline, extended); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_valid_mapping_twice) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", "2.23.140.1.3", X509_CA, + extended, "2.23.140.1.3"); + im = create_cert(ca, "CN=IM", extended, X509_CA, baseline, extended); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_invalid_mapping_loop) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", extended, X509_CA, baseline, baseline); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(!check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_invalid_mapping_notallowed) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", extended, X509_CA, baseline, extended); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(!check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_invalid_mapping_nopolicy) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert(NULL, "CN=CA", baseline, X509_CA, NULL, NULL); + im = create_cert(ca, "CN=IM", "2.23.140.1.3", X509_CA, baseline, extended); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(!check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_inhibit_mapping_good) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert_ext(NULL, "CN=CA", extended, X509_CA, NULL, NULL, + X509_NO_CONSTRAINT, 1, X509_NO_CONSTRAINT); + im = create_cert(ca, "CN=IM", extended, X509_CA, baseline, extended); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_inhibit_mapping_bad) +{ + certificate_t *ca, *i1, *i2, *sj; + + ca = create_cert_ext(NULL, "CN=CA", extended, X509_CA, NULL, NULL, + X509_NO_CONSTRAINT, 1, X509_NO_CONSTRAINT); + i1 = create_cert(ca, "CN=IM1", extended, X509_CA, NULL, NULL); + i2 = create_cert(i1, "CN=IM2", extended, X509_CA, baseline, extended); + sj = create_cert(i2, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, i1); + creds->add_cert(creds, FALSE, i2); + creds->add_cert(creds, FALSE, sj); + + /* TODO: we currently reject the certificate completely, but should + * actually just invalidate the policy not mapped properly */ + ck_assert(!check_trust(sj->get_subject(sj))); +} +END_TEST + +START_TEST(test_inhibit_any_good) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert_ext(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL, + X509_NO_CONSTRAINT, X509_NO_CONSTRAINT, 1); + im = create_cert(ca, "CN=IM", anyPolicy, X509_CA, NULL, NULL); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_inhibit_any_bad) +{ + certificate_t *ca, *i1, *i2, *sj; + + ca = create_cert_ext(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL, + X509_NO_CONSTRAINT, X509_NO_CONSTRAINT, 1); + i1 = create_cert(ca, "CN=IM1", anyPolicy, X509_CA, NULL, NULL); + i2 = create_cert(i1, "CN=IM2", anyPolicy, X509_CA, NULL, NULL); + sj = create_cert(i2, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, i1); + creds->add_cert(creds, FALSE, i2); + creds->add_cert(creds, FALSE, sj); + + /* TODO: we currently reject the certificate completely, but should + * actually just invalidate the policy relying on inhibited anyPolicy */ + ck_assert(!check_trust(sj->get_subject(sj))); +} +END_TEST + +START_TEST(test_require_explicit_good) +{ + certificate_t *ca, *im, *sj; + + ca = create_cert_ext(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL, + 1, X509_NO_CONSTRAINT, X509_NO_CONSTRAINT); + im = create_cert(ca, "CN=IM", baseline, X509_CA, NULL, NULL); + sj = create_cert(im, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, im); + creds->add_cert(creds, FALSE, sj); + + ck_assert(check_oid(sj->get_subject(sj), baseline)); +} +END_TEST + +START_TEST(test_require_explicit_bad) +{ + certificate_t *ca, *i1, *i2, *sj; + + ca = create_cert_ext(NULL, "CN=CA", anyPolicy, X509_CA, NULL, NULL, + 1, X509_NO_CONSTRAINT, X509_NO_CONSTRAINT); + i1 = create_cert(ca, "CN=IM1", extended, X509_CA, NULL, NULL); + i2 = create_cert(i1, "CN=IM2", extended, X509_CA, NULL, NULL); + sj = create_cert(i2, "CN=SJ", baseline, 0, NULL, NULL); + + creds->add_cert(creds, TRUE, ca); + creds->add_cert(creds, FALSE, i1); + creds->add_cert(creds, FALSE, i2); + creds->add_cert(creds, FALSE, sj); + + /* TODO: we currently reject the certificate completely, but should + * actually just invalidate the policy violating requireExplicit */ + ck_assert(!check_trust(sj->get_subject(sj))); +} +END_TEST + +Suite *certpolicy_suite_create() +{ + Suite *s; + TCase *tc; + + s = suite_create("certpolicy"); + + tc = tcase_create("policy valid"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_test(tc, test_valid_fixed); + tcase_add_test(tc, test_valid_any1); + tcase_add_test(tc, test_valid_any2); + suite_add_tcase(s, tc); + + tc = tcase_create("policy invalid"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_test(tc, test_invalid_missing); + tcase_add_test(tc, test_invalid_wrong); + tcase_add_test(tc, test_invalid_any1); + tcase_add_test(tc, test_invalid_any2); + suite_add_tcase(s, tc); + + tc = tcase_create("policy badchain"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_test(tc, test_badchain_wrong); + tcase_add_test(tc, test_badchain_gap); + tcase_add_test(tc, test_badchain_any); + suite_add_tcase(s, tc); + + tc = tcase_create("policy valid mapping"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_test(tc, test_valid_mapping); + tcase_add_test(tc, test_valid_mapping_twice); + suite_add_tcase(s, tc); + + tc = tcase_create("policy invalid mapping"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_test(tc, test_invalid_mapping_loop); + tcase_add_test(tc, test_invalid_mapping_notallowed); + tcase_add_test(tc, test_invalid_mapping_nopolicy); + suite_add_tcase(s, tc); + + tc = tcase_create("inhibit policy mapping"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_test(tc, test_inhibit_mapping_good); + tcase_add_test(tc, test_inhibit_mapping_bad); + suite_add_tcase(s, tc); + + tc = tcase_create("inhibit any policy"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_test(tc, test_inhibit_any_good); + tcase_add_test(tc, test_inhibit_any_bad); + suite_add_tcase(s, tc); + + tc = tcase_create("require explicit policy"); + tcase_add_checked_fixture(tc, setup, teardown); + tcase_add_test(tc, test_require_explicit_good); + tcase_add_test(tc, test_require_explicit_bad); + suite_add_tcase(s, tc); + + return s; +} diff --git a/src/libstrongswan/tests/suites/test_chunk.c b/src/libstrongswan/tests/suites/test_chunk.c index d71e010a2..b5d23658d 100644 --- a/src/libstrongswan/tests/suites/test_chunk.c +++ b/src/libstrongswan/tests/suites/test_chunk.c @@ -787,6 +787,11 @@ END_TEST * test for chunk_internet_checksum[_inc]() */ +static inline u_int16_t compensate_alignment(u_int16_t val) +{ + return ((val & 0xff) << 8) | (val >> 8); +} + START_TEST(test_chunk_internet_checksum) { chunk_t chunk; @@ -804,9 +809,9 @@ START_TEST(test_chunk_internet_checksum) /* need to compensate for even/odd alignment */ sum = chunk_internet_checksum(chunk_create(chunk.ptr, 9)); - sum = ntohs(sum); + sum = compensate_alignment(sum); sum = chunk_internet_checksum_inc(chunk_create(chunk.ptr+9, 11), sum); - sum = ntohs(sum); + sum = compensate_alignment(sum); ck_assert_int_eq(0x442e, ntohs(sum)); chunk = chunk_from_chars(0x45,0x00,0x00,0x30,0x44,0x22,0x40,0x00,0x80,0x06, @@ -821,9 +826,9 @@ START_TEST(test_chunk_internet_checksum) /* need to compensate for even/odd alignment */ sum = chunk_internet_checksum(chunk_create(chunk.ptr, 9)); - sum = ntohs(sum); + sum = compensate_alignment(sum); sum = chunk_internet_checksum_inc(chunk_create(chunk.ptr+9, 10), sum); - sum = ntohs(sum); + sum = compensate_alignment(sum); ck_assert_int_eq(0x4459, ntohs(sum)); } END_TEST diff --git a/src/libstrongswan/tests/suites/test_enum.c b/src/libstrongswan/tests/suites/test_enum.c index b48b51c0e..53ebd2931 100644 --- a/src/libstrongswan/tests/suites/test_enum.c +++ b/src/libstrongswan/tests/suites/test_enum.c @@ -58,6 +58,39 @@ ENUM_NEXT(test_enum_split_names, SPLIT5, SPLIT5, SPLIT4, ENUM_END(test_enum_split_names, SPLIT5); /******************************************************************************* + * enum flags + */ +enum { + FLAG1 = (1 << 0), + FLAG2 = (1 << 1), + FLAG3 = (1 << 2), + FLAG4 = (1 << 3), + FLAG5 = (1 << 4), + FLAG6 = (1 << 5), + FLAG7 = (1 << 6), + FLAG8 = (1 << 7), + FLAG9 = (1 << 8), + FLAG10 = (1 << 9), + FLAG11 = (1 << 10), + FLAG12 = (1 << 11), +} test_enum_flags; + +ENUM_FLAGS(test_enum_flags_names, FLAG1, FLAG5, + "FLAG1", "FLAG2", "FLAG3", "FLAG4", "FLAG5"); + +ENUM_FLAGS(test_enum_flags_incomplete_names, FLAG3, FLAG4, + "FLAG3", "FLAG4"); + +ENUM_FLAGS(test_enum_flags_null_names, FLAG1, FLAG4, + "FLAG1", NULL, "FLAG3", NULL); + +ENUM_FLAGS(test_enum_flags_overflow_names, FLAG1, FLAG12, + "OVERFLOWFLAGLONGNAME1", "OVERFLOWFLAGLONGNAME2", "OVERFLOWFLAGLONGNAME3", + "OVERFLOWFLAGLONGNAME4", "OVERFLOWFLAGLONGNAME5", "OVERFLOWFLAGLONGNAME6", + "OVERFLOWFLAGLONGNAME7", "OVERFLOWFLAGLONGNAME8", "OVERFLOWFLAGLONGNAME9", + "OVERFLOWFLAGLONGNAME10", "OVERFLOWFLAGLONGNAME11", "OVERFLOWFLAGLONGNAME12"); + +/******************************************************************************* * enum_to_name */ @@ -198,11 +231,52 @@ static struct { {256, "(256)"}, }; +/******************************************************************************* + * flag_to_name + */ + +static struct { + int val; + char *str; +} printf_tests_flags[] = { + {0, "(unset)"}, + {FLAG1, "FLAG1"}, + {FLAG2, "FLAG2"}, + {FLAG3, "FLAG3"}, + {FLAG4, "FLAG4"}, + {FLAG5, "FLAG5"}, + {FLAG1 | FLAG3, "FLAG1 | FLAG3"}, + {FLAG1 | FLAG3 | 32, "FLAG1 | FLAG3 | (0x20)"}, + {FLAG1 | FLAG3 | 32 | 64, "FLAG1 | FLAG3 | (0x20) | (0x40)"}, + {0x20, "(0x20)"}, + {0x80000000, "(0x80000000)"}, + {0xFFFFF, "FLAG1 | FLAG2 | FLAG3 | FLAG4 | " + "FLAG5 | (0x20) | (0x40) | (0x80) | " + "(0x100) | (0x200) | (0x400) | (0x800) | " + "(0x1000) | (0x2000) | (0x4000) | (0x8000) | " + "(0x10000) | (0x20000) | (0x40000) | (0x80000)"}, +}, printf_tests_flags_incomplete[] = { + {FLAG1, "(0x1)"}, + {FLAG1 | FLAG2 | FLAG3, "(0x1) | (0x2) | FLAG3"}, + {FLAG3 | FLAG4 | FLAG5, "FLAG3 | FLAG4 | (0x10)"}, +}, printf_tests_flags_null[] = { + {FLAG1 | FLAG2 | FLAG3 | FLAG4, "FLAG1 | FLAG3"}, +}, printf_tests_flags_overflow[] = { + {0xFFFFFFFF, "(0xFFFFFFFF)"}, +}, printf_tests_flags_noflagenum[] = { + {-1, "(-1)"}, + {6435, "(6435)"}, +}, enum_flags_to_string_tests[] = { + {-1, NULL}, + {6435, NULL}, +}; + START_TEST(test_enum_printf_hook_cont) { char buf[128]; - snprintf(buf, sizeof(buf), "%N", test_enum_cont_names, printf_tests_cont[_i].val); + snprintf(buf, sizeof(buf), "%N", + test_enum_cont_names, printf_tests_cont[_i].val); ck_assert_str_eq(printf_tests_cont[_i].str, buf); } END_TEST @@ -211,11 +285,89 @@ START_TEST(test_enum_printf_hook_split) { char buf[128]; - snprintf(buf, sizeof(buf), "%N", test_enum_split_names, printf_tests_split[_i].val); + snprintf(buf, sizeof(buf), "%N", + test_enum_split_names, printf_tests_split[_i].val); ck_assert_str_eq(printf_tests_split[_i].str, buf); } END_TEST +START_TEST(test_enum_printf_hook_flags) +{ + char buf[1024]; + + snprintf(buf, sizeof(buf), "%N", test_enum_flags_names, + printf_tests_flags[_i].val); + ck_assert_str_eq(printf_tests_flags[_i].str, buf); +} +END_TEST + +START_TEST(test_enum_printf_hook_flags_incomplete) +{ + char buf[1024]; + + snprintf(buf, sizeof(buf), "%N", test_enum_flags_incomplete_names, + printf_tests_flags_incomplete[_i].val); + ck_assert_str_eq(printf_tests_flags_incomplete[_i].str, buf); +} +END_TEST + +START_TEST(test_enum_printf_hook_flags_null) +{ + char buf[1024]; + + snprintf(buf, sizeof(buf), "%N", test_enum_flags_null_names, + printf_tests_flags_null[_i].val); + ck_assert_str_eq(printf_tests_flags_null[_i].str, buf); +} +END_TEST + +START_TEST(test_enum_printf_hook_flags_overflow) +{ + char buf[1024]; + + snprintf(buf, sizeof(buf), "%N", test_enum_flags_overflow_names, + printf_tests_flags_overflow[_i].val); + ck_assert_str_eq(printf_tests_flags_overflow[_i].str, buf); +} +END_TEST + +START_TEST(test_enum_printf_hook_flags_noflagenum) +{ + char buf[1024]; + + snprintf(buf, sizeof(buf), "%N", test_enum_cont_names, + printf_tests_flags_noflagenum[_i].val); + ck_assert_str_eq(printf_tests_flags_noflagenum[_i].str, buf); +} +END_TEST + +START_TEST(test_enum_flags_to_string) +{ + char buf[1], *str; + + str = enum_flags_to_string(test_enum_flags_names, + enum_flags_to_string_tests[_i].val, buf, sizeof(buf)); + if (str) + { + ck_assert_str_eq(enum_flags_to_string_tests[_i].str, str); + } + else + { + ck_assert(str == enum_flags_to_string_tests[_i].str); + } +} +END_TEST + +START_TEST(test_enum_flags_to_string_noflagenum) +{ + char buf[1024]; + + enum_flags_to_string(test_enum_cont_names, + printf_tests_flags_noflagenum[_i].val, buf, sizeof(buf)); + ck_assert_str_eq(printf_tests_flags_noflagenum[_i].str, buf); +} +END_TEST + START_TEST(test_enum_printf_hook_width) { char buf[128]; @@ -246,9 +398,19 @@ Suite *enum_suite_create() tcase_add_loop_test(tc, test_enum_from_name_split, 0, countof(enum_tests_split)); suite_add_tcase(s, tc); + tc = tcase_create("enum_flags_to_string"); + tcase_add_loop_test(tc, test_enum_flags_to_string, 0, countof(enum_flags_to_string_tests)); + tcase_add_loop_test(tc, test_enum_flags_to_string_noflagenum, 0, countof(printf_tests_flags_noflagenum)); + suite_add_tcase(s, tc); + tc = tcase_create("enum_printf_hook"); tcase_add_loop_test(tc, test_enum_printf_hook_cont, 0, countof(printf_tests_cont)); tcase_add_loop_test(tc, test_enum_printf_hook_split, 0, countof(printf_tests_split)); + tcase_add_loop_test(tc, test_enum_printf_hook_flags, 0, countof(printf_tests_flags)); + tcase_add_loop_test(tc, test_enum_printf_hook_flags_incomplete, 0, countof(printf_tests_flags_incomplete)); + tcase_add_loop_test(tc, test_enum_printf_hook_flags_null, 0, countof(printf_tests_flags_null)); + tcase_add_loop_test(tc, test_enum_printf_hook_flags_overflow, 0, countof(printf_tests_flags_overflow)); + tcase_add_loop_test(tc, test_enum_printf_hook_flags_noflagenum, 0, countof(printf_tests_flags_noflagenum)); tcase_add_test(tc, test_enum_printf_hook_width); suite_add_tcase(s, tc); diff --git a/src/libstrongswan/tests/suites/test_hasher.c b/src/libstrongswan/tests/suites/test_hasher.c index 41a9d64ef..14cc32122 100644 --- a/src/libstrongswan/tests/suites/test_hasher.c +++ b/src/libstrongswan/tests/suites/test_hasher.c @@ -48,6 +48,9 @@ static hasher_oid_t oids[] = { { OID_ECDSA_WITH_SHA256, HASH_SHA256, KEY_ECDSA }, { OID_ECDSA_WITH_SHA384, HASH_SHA384, KEY_ECDSA }, { OID_ECDSA_WITH_SHA512, HASH_SHA512, KEY_ECDSA }, + { OID_BLISS_WITH_SHA256, HASH_SHA256, KEY_BLISS }, + { OID_BLISS_WITH_SHA384, HASH_SHA384, KEY_BLISS }, + { OID_BLISS_WITH_SHA512, HASH_SHA512, KEY_BLISS }, { OID_UNKNOWN, HASH_UNKNOWN, KEY_ECDSA } }; diff --git a/src/libstrongswan/tests/suites/test_host.c b/src/libstrongswan/tests/suites/test_host.c index 63442083a..7161b2c5b 100644 --- a/src/libstrongswan/tests/suites/test_host.c +++ b/src/libstrongswan/tests/suites/test_host.c @@ -237,6 +237,48 @@ START_TEST(test_create_from_string_and_family_other) END_TEST /******************************************************************************* + * host_create_from_dns + */ + +static void test_create_from_dns(int family, chunk_t addr) +{ + host_t *host; + + host = host_create_from_dns("localhost", family, 500); + if (family != AF_INET6) + { + ck_assert(host != NULL); + } + if (host) + { + if (family != AF_UNSPEC) + { + verify_address(host, addr, family, 500); + } + host->destroy(host); + } +} + +START_TEST(test_create_from_dns_any) +{ + test_create_from_dns(AF_UNSPEC, chunk_empty); +} +END_TEST + +START_TEST(test_create_from_dns_v4) +{ + test_create_from_dns(AF_INET, chunk_from_chars(127,0,0,1)); +} +END_TEST + +START_TEST(test_create_from_dns_v6) +{ + test_create_from_dns(AF_INET6, + chunk_from_chars(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1)); +} +END_TEST + +/******************************************************************************* * host_create_from_sockaddr */ @@ -400,6 +442,90 @@ START_TEST(test_create_from_subnet_v6) END_TEST /******************************************************************************* + * host_create_from_range + */ + +static const chunk_t addr_v4_to = chunk_from_chars(0xc0, 0xa8, 0x00, 0x05); +static const chunk_t addr_v6_to = chunk_from_chars(0xfe, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05); + +static void verify_range(char *str, int family, chunk_t from_addr, + chunk_t to_addr) +{ + host_t *from, *to; + + if (!family) + { + ck_assert(!host_create_from_range(str, &from, &to)); + } + else + { + ck_assert(host_create_from_range(str, &from, &to)); + verify_address(from, from_addr, family, 0); + verify_address(to, to_addr, family, 0); + from->destroy(from); + to->destroy(to); + } +} + +START_TEST(test_create_from_range_v4) +{ + host_t *from, *to; + + ck_assert(host_create_from_range("0.0.0.0-0.0.0.0", &from, &to)); + verify_any(from, AF_INET, 0); + verify_any(to, AF_INET, 0); + from->destroy(from); + to->destroy(to); + + verify_range("192.168.0.1-192.168.0.1", AF_INET, addr_v4, addr_v4); + verify_range("192.168.0.1-192.168.0.5", AF_INET, addr_v4, addr_v4_to); + verify_range("192.168.0.1- 192.168.0.5", AF_INET, addr_v4, addr_v4_to); + verify_range("192.168.0.1 -192.168.0.5", AF_INET, addr_v4, addr_v4_to); + verify_range("192.168.0.1 - 192.168.0.5", AF_INET, addr_v4, addr_v4_to); + verify_range("192.168.0.5-192.168.0.1", AF_INET, addr_v4_to, addr_v4); + + verify_range("192.168.0.1", 0, chunk_empty, chunk_empty); + verify_range("192.168.0.1-", 0, chunk_empty, chunk_empty); + verify_range("-192.168.0.1", 0, chunk_empty, chunk_empty); + verify_range("192.168.0.1-192", 0, chunk_empty, chunk_empty); + verify_range("192.168.0.1-192.168", 0, chunk_empty, chunk_empty); + verify_range("192.168.0.1-192.168.0", 0, chunk_empty, chunk_empty); + verify_range("foo.b.a.r", 0, chunk_empty, chunk_empty); + verify_range("foo.b.a.r-b.a.r.f", 0, chunk_empty, chunk_empty); +} +END_TEST + +START_TEST(test_create_from_range_v6) +{ + host_t *from, *to; + + ck_assert(host_create_from_range("::-::", &from, &to)); + verify_any(from, AF_INET6, 0); + verify_any(to, AF_INET6, 0); + from->destroy(from); + to->destroy(to); + + verify_range("fec1::1-fec1::1", AF_INET6, addr_v6, addr_v6); + verify_range("fec1::1-fec1::5", AF_INET6, addr_v6, addr_v6_to); + verify_range("fec1::1- fec1::5", AF_INET6, addr_v6, addr_v6_to); + verify_range("fec1::1 -fec1::5", AF_INET6, addr_v6, addr_v6_to); + verify_range("fec1::1 - fec1::5", AF_INET6, addr_v6, addr_v6_to); + verify_range("fec1::5-fec1::1", AF_INET6, addr_v6_to, addr_v6); + + verify_range("fec1::1", 0, chunk_empty, chunk_empty); + verify_range("fec1::1-", 0, chunk_empty, chunk_empty); + verify_range("-fec1::1", 0, chunk_empty, chunk_empty); + verify_range("fec1::1-fec1", 0, chunk_empty, chunk_empty); + verify_range("foo::bar", 0, chunk_empty, chunk_empty); + verify_range("foo::bar-bar::foo", 0, chunk_empty, chunk_empty); + + verify_range("fec1::1-192.168.0.1", 0, chunk_empty, chunk_empty); + verify_range("192.168.0.1-fec1::1", 0, chunk_empty, chunk_empty); +} +END_TEST + +/******************************************************************************* * host_create_netmask */ @@ -610,6 +736,12 @@ Suite *host_suite_create() tcase_add_test(tc, test_create_from_string_and_family_other); suite_add_tcase(s, tc); + tc = tcase_create("host_create_from_dns"); + tcase_add_test(tc, test_create_from_dns_any); + tcase_add_test(tc, test_create_from_dns_v4); + tcase_add_test(tc, test_create_from_dns_v6); + suite_add_tcase(s, tc); + tc = tcase_create("host_create_from_sockaddr"); tcase_add_test(tc, test_create_from_sockaddr_v4); tcase_add_test(tc, test_create_from_sockaddr_v6); @@ -627,6 +759,11 @@ Suite *host_suite_create() tcase_add_test(tc, test_create_from_subnet_v6); suite_add_tcase(s, tc); + tc = tcase_create("host_create_from_range"); + tcase_add_test(tc, test_create_from_range_v4); + tcase_add_test(tc, test_create_from_range_v6); + suite_add_tcase(s, tc); + tc = tcase_create("host_create_netmask"); tcase_add_test(tc, test_create_netmask_v4); tcase_add_test(tc, test_create_netmask_v6); diff --git a/src/libstrongswan/tests/suites/test_identification.c b/src/libstrongswan/tests/suites/test_identification.c index 5de785710..de00e4afd 100644 --- a/src/libstrongswan/tests/suites/test_identification.c +++ b/src/libstrongswan/tests/suites/test_identification.c @@ -122,58 +122,68 @@ static struct { } data; } result; } string_data[] = { - {NULL, ID_ANY, { .type = ENC_CHUNK }}, - {"", ID_ANY, { .type = ENC_CHUNK }}, - {"%any", ID_ANY, { .type = ENC_CHUNK }}, - {"%any6", ID_ANY, { .type = ENC_CHUNK }}, - {"0.0.0.0", ID_ANY, { .type = ENC_CHUNK }}, - {"0::0", ID_ANY, { .type = ENC_CHUNK }}, - {"::", ID_ANY, { .type = ENC_CHUNK }}, - {"*", ID_ANY, { .type = ENC_CHUNK }}, - {"any", ID_FQDN, { .type = ENC_SIMPLE }}, - {"any6", ID_FQDN, { .type = ENC_SIMPLE }}, - {"0", ID_FQDN, { .type = ENC_SIMPLE }}, - {"**", ID_FQDN, { .type = ENC_SIMPLE }}, - {"192.168.1.1", ID_IPV4_ADDR, { .type = ENC_CHUNK, - .data.c = chunk_from_chars(0xc0, 0xa8, 0x01, 0x01) }}, - {"192.168.",ID_FQDN, { .type = ENC_SIMPLE }}, - {".", ID_FQDN, { .type = ENC_SIMPLE }}, - {"fec0::1", ID_IPV6_ADDR, { .type = ENC_CHUNK, - .data.c = chunk_from_chars(0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01) }}, - {"fec0::", ID_IPV6_ADDR, { .type = ENC_CHUNK, - .data.c = chunk_from_chars(0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00) }}, - {"fec0:", ID_KEY_ID, { .type = ENC_SIMPLE }}, - {":", ID_KEY_ID, { .type = ENC_SIMPLE }}, - {"alice@strongswan.org", ID_RFC822_ADDR, { .type = ENC_SIMPLE }}, - {"alice@strongswan", ID_RFC822_ADDR, { .type = ENC_SIMPLE }}, - {"alice@", ID_RFC822_ADDR, { .type = ENC_SIMPLE }}, - {"alice", ID_FQDN, { .type = ENC_SIMPLE }}, - {"@", ID_FQDN, { .type = ENC_CHUNK }}, - {" @", ID_RFC822_ADDR, { .type = ENC_SIMPLE }}, - {"@strongswan.org", ID_FQDN, { .type = ENC_STRING, - .data.s = "strongswan.org" }}, - {"@#deadbeef", ID_KEY_ID, { .type = ENC_CHUNK, - .data.c = chunk_from_chars(0xde, 0xad, 0xbe, 0xef) }}, - {"@#deadbee", ID_KEY_ID, { .type = ENC_CHUNK, - .data.c = chunk_from_chars(0x0d, 0xea, 0xdb, 0xee) }}, - {"foo=bar", ID_KEY_ID, { .type = ENC_SIMPLE }}, - {"foo=", ID_KEY_ID, { .type = ENC_SIMPLE }}, - {"=bar", ID_KEY_ID, { .type = ENC_SIMPLE }}, - {"C=", ID_DER_ASN1_DN, { .type = ENC_CHUNK, - .data.c = chunk_from_chars(0x30, 0x0b, 0x31, 0x09, 0x30, 0x07, 0x06, - 0x03, 0x55, 0x04, 0x06, 0x13, 0x00)}}, - {"C=CH", ID_DER_ASN1_DN, { .type = ENC_CHUNK, - .data.c = chunk_from_chars(0x30, 0x0d, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48)}}, - {"C=CH,", ID_DER_ASN1_DN, { .type = ENC_CHUNK, - .data.c = chunk_from_chars(0x30, 0x0d, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48)}}, - {"C=CH, ", ID_DER_ASN1_DN, { .type = ENC_CHUNK, - .data.c = chunk_from_chars(0x30, 0x0d, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x48)}}, - {"C=CH, O", ID_KEY_ID, { .type = ENC_SIMPLE }}, + {NULL, ID_ANY, { .type = ENC_CHUNK }}, + {"", ID_ANY, { .type = ENC_CHUNK }}, + {"%any", ID_ANY, { .type = ENC_CHUNK }}, + {"%any6", ID_ANY, { .type = ENC_CHUNK }}, + {"0.0.0.0", ID_ANY, { .type = ENC_CHUNK }}, + {"0::0", ID_ANY, { .type = ENC_CHUNK }}, + {"::", ID_ANY, { .type = ENC_CHUNK }}, + {"*", ID_ANY, { .type = ENC_CHUNK }}, + {"any", ID_FQDN, { .type = ENC_SIMPLE }}, + {"any6", ID_FQDN, { .type = ENC_SIMPLE }}, + {"0", ID_FQDN, { .type = ENC_SIMPLE }}, + {"**", ID_FQDN, { .type = ENC_SIMPLE }}, + {"192.168.1.1", ID_IPV4_ADDR, { .type = ENC_CHUNK, + .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x01) }}, + {"192.168.", ID_FQDN, { .type = ENC_SIMPLE }}, + {".", ID_FQDN, { .type = ENC_SIMPLE }}, + {"fec0::1", ID_IPV6_ADDR, { .type = ENC_CHUNK, + .data.c = chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01) }}, + {"fec0::", ID_IPV6_ADDR, { .type = ENC_CHUNK, + .data.c = chunk_from_chars(0xfe,0xc0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00) }}, + {"fec0:", ID_KEY_ID, { .type = ENC_SIMPLE }}, + {":", ID_KEY_ID, { .type = ENC_SIMPLE }}, + {"alice@strongswan.org", ID_RFC822_ADDR, { .type = ENC_SIMPLE }}, + {"alice@strongswan", ID_RFC822_ADDR, { .type = ENC_SIMPLE }}, + {"alice@", ID_RFC822_ADDR, { .type = ENC_SIMPLE }}, + {"alice", ID_FQDN, { .type = ENC_SIMPLE }}, + {"@", ID_FQDN, { .type = ENC_CHUNK }}, + {" @", ID_RFC822_ADDR, { .type = ENC_SIMPLE }}, + {"@strongswan.org", ID_FQDN, { .type = ENC_STRING, + .data.s = "strongswan.org" }}, + {"@#deadbeef", ID_KEY_ID, { .type = ENC_CHUNK, + .data.c = chunk_from_chars(0xde,0xad,0xbe,0xef) }}, + {"@#deadbee", ID_KEY_ID, { .type = ENC_CHUNK, + .data.c = chunk_from_chars(0x0d,0xea,0xdb,0xee) }}, + {"foo=bar", ID_KEY_ID, { .type = ENC_SIMPLE }}, + {"foo=", ID_KEY_ID, { .type = ENC_SIMPLE }}, + {"=bar", ID_KEY_ID, { .type = ENC_SIMPLE }}, + {"C=", ID_DER_ASN1_DN, { .type = ENC_CHUNK, + .data.c = chunk_from_chars(0x30,0x0b,0x31,0x09,0x30,0x07,0x06, + 0x03,0x55,0x04,0x06,0x13,0x00) }}, + {"C=CH", ID_DER_ASN1_DN, { .type = ENC_CHUNK, + .data.c = chunk_from_chars(0x30,0x0d,0x31,0x0b,0x30,0x09,0x06, + 0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48) }}, + {"C=CH,", ID_DER_ASN1_DN, { .type = ENC_CHUNK, + .data.c = chunk_from_chars(0x30,0x0d,0x31,0x0b,0x30,0x09,0x06, + 0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48) }}, + {"C=CH, ", ID_DER_ASN1_DN, { .type = ENC_CHUNK, + .data.c = chunk_from_chars(0x30,0x0d,0x31,0x0b,0x30,0x09,0x06, + 0x03,0x55,0x04,0x06,0x13,0x02,0x43,0x48) }}, + {"C=CH, O", ID_KEY_ID, { .type = ENC_SIMPLE }}, + {"IPv4:#c0a80101", ID_IPV4_ADDR, { .type = ENC_CHUNK, + .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x01) }}, + { "email:tester", ID_RFC822_ADDR, { .type = ENC_STRING, + .data.s = "tester" }}, + { "{1}:#c0a80101", ID_IPV4_ADDR, { .type = ENC_CHUNK, + .data.c = chunk_from_chars(0xc0,0xa8,0x01,0x01) }}, + { "{0x02}:tester", ID_FQDN, { .type = ENC_STRING, + .data.s = "tester" }}, + { "{99}:somedata", 99, { .type = ENC_STRING, + .data.s = "somedata" }}, }; START_TEST(test_from_string) diff --git a/src/libstrongswan/tests/suites/test_mgf1.c b/src/libstrongswan/tests/suites/test_mgf1.c new file mode 100644 index 000000000..9388b95d4 --- /dev/null +++ b/src/libstrongswan/tests/suites/test_mgf1.c @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "test_suite.h" + +#include <tests/utils/test_rng.h> +#include <utils/test.h> +#include <crypto/mgf1/mgf1.h> +#include <crypto/mgf1/mgf1_bitspender.h> + +typedef struct { + hash_algorithm_t alg; + size_t hash_size; + size_t ml1, ml2, ml3, seed_len; + chunk_t seed; + chunk_t hashed_seed; + chunk_t mask; + uint32_t bits[22]; +} mgf1_test_t; + +/** + * MGF1 Mask Generation Function Test Vectors + */ +mgf1_test_t mgf1_tests[] = { + { HASH_SHA1, 20, 60, 20, 15, 24, + chunk_from_chars( + 0xED, 0xA5, 0xC3, 0xBC, 0xAF, 0xB3, 0x20, 0x7D, + 0x14, 0xA1, 0x54, 0xF7, 0x8B, 0x37, 0xF2, 0x8D, + 0x8C, 0x9B, 0xD5, 0x63, 0x57, 0x38, 0x11, 0xC2, + 0xB5, 0xCA, 0xBF, 0x06, 0x43, 0x45, 0x19, 0xD5, + 0xE7, 0x36, 0xD0, 0x29, 0x21, 0xDA, 0x02, 0x20, + 0x45, 0xF6, 0x5F, 0x0F, 0x10, 0x04, 0x2A, 0xE3, + 0x6A, 0x1D, 0xD5, 0x9F, 0x1D, 0x66, 0x44, 0x8F, + 0xFA, 0xC6, 0xCA, 0xA4, 0x6E, 0x3B, 0x00, 0x66, + 0xA6, 0xC9, 0x80, 0x5C, 0xF5, 0x2D, 0xD7, 0x72, + 0xC6, 0xD4, 0x4F, 0x30, 0x72, 0xA2, 0xAD, 0xE0, + 0x33, 0xE8, 0x55, 0xD5, 0xE6, 0xD6, 0x00, 0x1D, + 0xA8, 0x68, 0xFF, 0x97, 0x36, 0x8A, 0xF4, 0xD6, + 0xF1, 0xB6, 0x7E, 0x1F, 0x06, 0xCB, 0x57, 0xCB, + 0x35, 0x38, 0xF2, 0x2D, 0xF6, 0x20), + chunk_from_chars( + 0xF3, 0x9B, 0x0B, 0xB4, 0x97, 0x50, 0xB5, 0xA7, + 0xE6, 0xBD, 0xDA, 0xD0, 0x9A, 0x52, 0xBE, 0xA0, + 0x21, 0xC4, 0x90, 0xB6), + chunk_from_chars( + 0x10, 0x43, 0x76, 0x72, 0x6C, 0xDE, 0xA0, 0x0E, + 0x77, 0x51, 0xFB, 0x58, 0x39, 0x8A, 0x36, 0xE1, + 0x63, 0x2B, 0xC9, 0x17, 0x56, 0x0C, 0x4B, 0x46, + 0xA4, 0x07, 0xA4, 0x3B, 0x8E, 0x33, 0x4D, 0xD1, + 0x65, 0xF1, 0xAC, 0xC8, 0x59, 0x21, 0x32, 0x16, + 0x44, 0x2B, 0x7F, 0xB2, 0xA8, 0xA7, 0x26, 0x5D, + 0xE8, 0x02, 0xBE, 0x8E, 0xDC, 0x34, 0xEB, 0x10, + 0x76, 0x16, 0x8C, 0xDD, 0x90, 0x92, 0x3D, 0x29, + 0x90, 0x98, 0x46, 0x11, 0x73, 0x53, 0x47, 0xB1, + 0x2C, 0xD4, 0x83, 0x78, 0x9B, 0x93, 0x2F, 0x5B, + 0xFC, 0x26, 0xFF, 0x42, 0x08, 0x1F, 0x70, 0x66, + 0x40, 0x4B, 0xE7, 0x22, 0x3A, 0x56, 0x10, 0x6D, + 0x4D, 0x29, 0x0B, 0xCE, 0xA6, 0x21, 0xB5, 0x5C, + 0x71, 0x66, 0x2F, 0x70, 0x35, 0xD8, 0x8A, 0x92, + 0x33, 0xF0, 0x16, 0xD4, 0x0E, 0x43, 0x8A, 0x14), + { 0, 0, 0, 4, 1, 1, 46, 103, 38, 411, 848, 57, 3540, 4058, 12403, + 0x63, 0x2B, 0xC9, 0x17, 0x56, 669409, 0xA407A43B }, + }, + { HASH_SHA256, 32, 64, 32, 33, 40, + chunk_from_chars( + 0x52, 0xC5, 0xDD, 0x1E, 0xEF, 0x76, 0x1B, 0x53, + 0x08, 0xE4, 0x86, 0x3F, 0x91, 0x12, 0x98, 0x69, + 0xC5, 0x9D, 0xDE, 0xF6, 0xFC, 0xFA, 0x93, 0xCE, + 0x32, 0x52, 0x66, 0xF9, 0xC9, 0x97, 0xF6, 0x42, + 0x00, 0x2C, 0x64, 0xED, 0x1A, 0x6B, 0x14, 0x0A, + 0x4B, 0x04, 0xCF, 0x6D, 0x2D, 0x82, 0x0A, 0x07, + 0xA2, 0x3B, 0xDE, 0xCE, 0x19, 0x8A, 0x39, 0x43, + 0x16, 0x61, 0x29, 0x98, 0x68, 0xEA, 0xE5, 0xCC, + 0x0A, 0xF8, 0xE9, 0x71, 0x26, 0xF1, 0x07, 0x36, + 0x2C, 0x07, 0x1E, 0xEB, 0xE4, 0x28, 0xA2, 0xF4, + 0xA8, 0x12, 0xC0, 0xC8, 0x20, 0x37, 0xF8, 0xF2, + 0x6C, 0xAF, 0xDC, 0x6F, 0x2E, 0xD0, 0x62, 0x58, + 0xD2, 0x37, 0x03, 0x6D, 0xFA, 0x6E, 0x1A, 0xAC, + 0x9F, 0xCA, 0x56, 0xC6, 0xA4, 0x52, 0x41, 0xE8, + 0x0F, 0x1B, 0x0C, 0xB9, 0xE6, 0xBA, 0xDE, 0xE1, + 0x03, 0x5E, 0xC2, 0xE5, 0xF8, 0xF4, 0xF3, 0x46, + 0x3A, 0x12, 0xC0, 0x1F, 0x3A, 0x00, 0xD0, 0x91, + 0x18, 0xDD, 0x53, 0xE4, 0x22, 0xF5, 0x26, 0xA4, + 0x54, 0xEE, 0x20, 0xF0, 0x80), + chunk_from_chars( + 0x76, 0x89, 0x8B, 0x1B, 0x60, 0xEC, 0x10, 0x9D, + 0x8F, 0x13, 0xF2, 0xFE, 0xD9, 0x85, 0xC1, 0xAB, + 0x7E, 0xEE, 0xB1, 0x31, 0xDD, 0xF7, 0x7F, 0x0C, + 0x7D, 0xF9, 0x6B, 0x7B, 0x19, 0x80, 0xBD, 0x28), + chunk_from_chars( + 0xF1, 0x19, 0x02, 0x4F, 0xDA, 0x58, 0x05, 0x9A, + 0x07, 0xDF, 0x61, 0x81, 0x22, 0x0E, 0x15, 0x46, + 0xCB, 0x35, 0x3C, 0xDC, 0xAD, 0x20, 0xD9, 0x3F, + 0x0D, 0xD1, 0xAA, 0x64, 0x66, 0x5C, 0xFA, 0x4A, + 0xFE, 0xD6, 0x8F, 0x55, 0x57, 0x15, 0xB2, 0xA6, + 0xA0, 0xE6, 0xA8, 0xC6, 0xBD, 0x28, 0xB4, 0xD5, + 0x6E, 0x5B, 0x4B, 0xB0, 0x97, 0x09, 0xF5, 0xAC, + 0x57, 0x65, 0x13, 0x97, 0x71, 0x2C, 0x45, 0x13, + 0x3D, 0xEE, 0xFB, 0xBF, 0xFE, 0xAF, 0xBB, 0x4B, + 0x0D, 0x5C, 0x45, 0xD4, 0x2F, 0x17, 0x92, 0x07, + 0x66, 0x11, 0xF5, 0x46, 0xF8, 0x0C, 0x03, 0x92, + 0xF5, 0xF5, 0xFF, 0xA4, 0xF3, 0x52, 0xF4, 0x08, + 0x2C, 0x49, 0x32, 0x1A, 0x93, 0x51, 0x98, 0xB6, + 0x94, 0x83, 0x39, 0xCF, 0x6B, 0x1F, 0x2F, 0xFC, + 0x2B, 0xFF, 0x10, 0x71, 0x7D, 0x35, 0x6C, 0xEA, + 0xC5, 0x66, 0xC7, 0x26, 0x7D, 0x9E, 0xAC, 0xDD, + 0x35, 0xD7, 0x06, 0x3F, 0x40, 0x82, 0xDA, 0xC3, + 0x2B, 0x3C, 0x91, 0x3A, 0x32, 0xF8, 0xB2, 0xC6, + 0x44, 0x4D, 0xCD, 0xB6, 0x54, 0x5F, 0x81, 0x95, + 0x59, 0xA1, 0xE5, 0x4E, 0xA5, 0x0A, 0x4A, 0x42), + { 0, 1, 3, 4, 4, 12, 32, 36, 253, 331, 2, 1640, 503, 6924, 580, + 0xCB, 0x35, 0x3C, 0xDC, 0xAD, 922950, 0x0DD1AA64 } + } +}; + +START_TEST(mgf1_test_mgf1) +{ + mgf1_t *mgf1; + chunk_t mask, mask1, mask2, mask3; + + mask1 = mgf1_tests[_i].mask; + mask2 = chunk_skip(mask1, mgf1_tests[_i].ml1); + mask3 = chunk_skip(mask2, mgf1_tests[_i].ml2); + mask1.len = mgf1_tests[_i].ml1; + mask2.len = mgf1_tests[_i].ml2; + mask3.len = mgf1_tests[_i].ml3; + + mgf1 = mgf1_create(HASH_UNKNOWN, mgf1_tests[_i].seed, TRUE); + ck_assert(mgf1 == NULL); + + mgf1 = mgf1_create(mgf1_tests[_i].alg, chunk_empty, TRUE); + ck_assert(mgf1 == NULL); + + /* return mask in allocated chunk */ + mgf1 = mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].seed, TRUE); + ck_assert(mgf1); + + /* check hash size */ + ck_assert(mgf1->get_hash_size(mgf1) == mgf1_tests[_i].hash_size); + + /* get zero number of octets */ + ck_assert(mgf1->allocate_mask(mgf1, 0, &mask)); + ck_assert(mask.len == 0 && mask.ptr == NULL); + + /* get non-zero number of octets */ + ck_assert(mgf1->allocate_mask(mgf1, mgf1_tests[_i].mask.len, &mask)); + ck_assert(chunk_equals(mask, mgf1_tests[_i].mask)); + mgf1->destroy(mgf1); + + /* copy mask to pre-allocated buffer */ + mgf1 = mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].seed, TRUE); + ck_assert(mgf1); + ck_assert(mgf1->get_mask(mgf1, mgf1_tests[_i].mask.len, mask.ptr)); + ck_assert(chunk_equals(mask, mgf1_tests[_i].mask)); + mgf1->destroy(mgf1); + + /* get mask in batches without hashing the seed */ + mgf1 = mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].hashed_seed, FALSE); + ck_assert(mgf1); + + /* first batch */ + ck_assert(mgf1->get_mask(mgf1, mask1.len, mask.ptr)); + mask.len = mask1.len; + ck_assert(chunk_equals(mask, mask1)); + + /* second batch */ + ck_assert(mgf1->get_mask(mgf1, mask2.len, mask.ptr)); + mask.len = mask2.len; + ck_assert(chunk_equals(mask, mask2)); + + /* third batch */ + ck_assert(mgf1->get_mask(mgf1, mask3.len, mask.ptr)); + mask.len = mask3.len; + ck_assert(chunk_equals(mask, mask3)); + + mgf1->destroy(mgf1); + chunk_free(&mask); +} +END_TEST + +START_TEST(mgf1_test_bitspender) +{ + mgf1_bitspender_t *bitspender; + uint32_t bits; + uint8_t byte; + int j; + + bitspender = mgf1_bitspender_create(HASH_UNKNOWN, + mgf1_tests[_i].hashed_seed, FALSE); + ck_assert(bitspender == NULL); + + bitspender = mgf1_bitspender_create(mgf1_tests[_i].alg, + mgf1_tests[_i].hashed_seed, FALSE); + ck_assert(bitspender); + + for (j = 0; j < 15; j++) + { + ck_assert(bitspender->get_bits(bitspender, j, &bits)); + DBG1(DBG_LIB, "bits[%d] = %u, bits = %u", j, mgf1_tests[_i].bits[j], + bits); + ck_assert(bits == mgf1_tests[_i].bits[j]); + } + ck_assert(!bitspender->get_bits(bitspender, 33, &bits)); + + for (j = 15; j < 20; j++) + { + ck_assert(bitspender->get_byte(bitspender, &byte)); + DBG1(DBG_LIB, "bits[%d] = 0x%02x, byte = 0x%02x", j, + mgf1_tests[_i].bits[j], byte); + ck_assert(byte == mgf1_tests[_i].bits[j]); + } + + j = 20; /* 23 remaining bits */ + ck_assert(bitspender->get_bits(bitspender, 23, &bits)); + DBG1(DBG_LIB, "bits[%d] = %u, bits = %u", j, + mgf1_tests[_i].bits[j], bits); + ck_assert(bits == mgf1_tests[_i].bits[j]); + + j = 21; /* 32 aligned bits */ + ck_assert(bitspender->get_bits(bitspender, 32, &bits)); + DBG1(DBG_LIB, "bits[%d] = 0x%08x, bits = 0x%08x", j, + mgf1_tests[_i].bits[j], bits); + ck_assert(bits == mgf1_tests[_i].bits[j]); + + bitspender->destroy(bitspender); +} +END_TEST + + +Suite *mgf1_suite_create(char *name, int n) +{ + Suite *s; + TCase *tc; + + s = suite_create(name); + + tc = tcase_create("mgf1"); + tcase_add_loop_test(tc, mgf1_test_mgf1, n, n + 1); + suite_add_tcase(s, tc); + + tc = tcase_create("bitspender"); + tcase_add_loop_test(tc, mgf1_test_bitspender, n, n + 1); + suite_add_tcase(s, tc); + + return s; +} + +Suite *mgf1_sha1_suite_create() +{ + return mgf1_suite_create("mgf1-sha1", 0); +} + +Suite *mgf1_sha256_suite_create() +{ + return mgf1_suite_create("mgf1-sha256", 1); +} diff --git a/src/libstrongswan/tests/suites/test_ntru.c b/src/libstrongswan/tests/suites/test_ntru.c index 7c0cb81bf..d209fa2bc 100644 --- a/src/libstrongswan/tests/suites/test_ntru.c +++ b/src/libstrongswan/tests/suites/test_ntru.c @@ -16,20 +16,17 @@ #include "test_suite.h" #include <tests/utils/test_rng.h> +#include <utils/test.h> +#include <crypto/mgf1/mgf1.h> #include <plugins/ntru/ntru_drbg.h> -#include <plugins/ntru/ntru_mgf1.h> #include <plugins/ntru/ntru_trits.h> #include <plugins/ntru/ntru_poly.h> #include <plugins/ntru/ntru_param_set.h> #include <plugins/ntru/ntru_private_key.h> -#include <utils/test.h> IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_drbg_create, ntru_drbg_t*, u_int32_t strength, chunk_t pers_str, rng_t *entropy) -IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_mgf1_create, ntru_mgf1_t*, - hash_algorithm_t alg, chunk_t seed, bool hash_seed) - IMPORT_FUNCTION_FOR_TESTS(ntru, ntru_trits_create, ntru_trits_t*, size_t len, hash_algorithm_t alg, chunk_t seed) @@ -334,13 +331,11 @@ typedef struct { typedef struct { hash_algorithm_t alg; size_t hash_size; - size_t ml1, ml2, ml3, seed_len; + size_t seed_len; chunk_t seed; - chunk_t hashed_seed; - chunk_t mask; chunk_t trits; poly_test_t poly_test[2]; -} mgf1_test_t; +} trits_test_t; uint16_t indices_ees439ep1[] = { 367, 413, 16, 214, 114, 128, 42, 268, 346, 329, 119, 303, 208, 287, 150, @@ -386,10 +381,10 @@ uint16_t indices_ees1171ep1[] = { }; /** - * MGF1 Mask Generation Function Test Vectors + * Trits and Polynomial Test Vectors */ -mgf1_test_t mgf1_tests[] = { - { HASH_SHA1, 20, 60, 20, 15, 24, +static trits_test_t trits_tests[] = { + { HASH_SHA1, 20, 24, chunk_from_chars( 0xED, 0xA5, 0xC3, 0xBC, 0xAF, 0xB3, 0x20, 0x7D, 0x14, 0xA1, 0x54, 0xF7, 0x8B, 0x37, 0xF2, 0x8D, @@ -406,26 +401,6 @@ mgf1_test_t mgf1_tests[] = { 0xF1, 0xB6, 0x7E, 0x1F, 0x06, 0xCB, 0x57, 0xCB, 0x35, 0x38, 0xF2, 0x2D, 0xF6, 0x20), chunk_from_chars( - 0xF3, 0x9B, 0x0B, 0xB4, 0x97, 0x50, 0xB5, 0xA7, - 0xE6, 0xBD, 0xDA, 0xD0, 0x9A, 0x52, 0xBE, 0xA0, - 0x21, 0xC4, 0x90, 0xB6), - chunk_from_chars( - 0x10, 0x43, 0x76, 0x72, 0x6C, 0xDE, 0xA0, 0x0E, - 0x77, 0x51, 0xFB, 0x58, 0x39, 0x8A, 0x36, 0xE1, - 0x63, 0x2B, 0xC9, 0x17, 0x56, 0x0C, 0x4B, 0x46, - 0xA4, 0x07, 0xA4, 0x3B, 0x8E, 0x33, 0x4D, 0xD1, - 0x65, 0xF1, 0xAC, 0xC8, 0x59, 0x21, 0x32, 0x16, - 0x44, 0x2B, 0x7F, 0xB2, 0xA8, 0xA7, 0x26, 0x5D, - 0xE8, 0x02, 0xBE, 0x8E, 0xDC, 0x34, 0xEB, 0x10, - 0x76, 0x16, 0x8C, 0xDD, 0x90, 0x92, 0x3D, 0x29, - 0x90, 0x98, 0x46, 0x11, 0x73, 0x53, 0x47, 0xB1, - 0x2C, 0xD4, 0x83, 0x78, 0x9B, 0x93, 0x2F, 0x5B, - 0xFC, 0x26, 0xFF, 0x42, 0x08, 0x1F, 0x70, 0x66, - 0x40, 0x4B, 0xE7, 0x22, 0x3A, 0x56, 0x10, 0x6D, - 0x4D, 0x29, 0x0B, 0xCE, 0xA6, 0x21, 0xB5, 0x5C, - 0x71, 0x66, 0x2F, 0x70, 0x35, 0xD8, 0x8A, 0x92, - 0x33, 0xF0, 0x16, 0xD4, 0x0E, 0x43, 0x8A, 0x14), - chunk_from_chars( 1, 2, 1, 0, 0, 1, 1, 1, 2, 0, 1, 0, 1, 1, 1, 0, 2, 0, 1, 1, 0, 0, 0, 1, 1, 0, 2, 0, 2, 2, 1, 2, 2, 2, 1, 2, 1, 1, 0, 0, 2, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 2, 0, 0, 1, 0, 1, 0, 2, 0, @@ -457,7 +432,7 @@ mgf1_test_t mgf1_tests[] = { } } }, - { HASH_SHA256, 32, 64, 32, 33, 40, + { HASH_SHA256, 32, 40, chunk_from_chars( 0x52, 0xC5, 0xDD, 0x1E, 0xEF, 0x76, 0x1B, 0x53, 0x08, 0xE4, 0x86, 0x3F, 0x91, 0x12, 0x98, 0x69, @@ -479,32 +454,6 @@ mgf1_test_t mgf1_tests[] = { 0x18, 0xDD, 0x53, 0xE4, 0x22, 0xF5, 0x26, 0xA4, 0x54, 0xEE, 0x20, 0xF0, 0x80), chunk_from_chars( - 0x76, 0x89, 0x8B, 0x1B, 0x60, 0xEC, 0x10, 0x9D, - 0x8F, 0x13, 0xF2, 0xFE, 0xD9, 0x85, 0xC1, 0xAB, - 0x7E, 0xEE, 0xB1, 0x31, 0xDD, 0xF7, 0x7F, 0x0C, - 0x7D, 0xF9, 0x6B, 0x7B, 0x19, 0x80, 0xBD, 0x28), - chunk_from_chars( - 0xF1, 0x19, 0x02, 0x4F, 0xDA, 0x58, 0x05, 0x9A, - 0x07, 0xDF, 0x61, 0x81, 0x22, 0x0E, 0x15, 0x46, - 0xCB, 0x35, 0x3C, 0xDC, 0xAD, 0x20, 0xD9, 0x3F, - 0x0D, 0xD1, 0xAA, 0x64, 0x66, 0x5C, 0xFA, 0x4A, - 0xFE, 0xD6, 0x8F, 0x55, 0x57, 0x15, 0xB2, 0xA6, - 0xA0, 0xE6, 0xA8, 0xC6, 0xBD, 0x28, 0xB4, 0xD5, - 0x6E, 0x5B, 0x4B, 0xB0, 0x97, 0x09, 0xF5, 0xAC, - 0x57, 0x65, 0x13, 0x97, 0x71, 0x2C, 0x45, 0x13, - 0x3D, 0xEE, 0xFB, 0xBF, 0xFE, 0xAF, 0xBB, 0x4B, - 0x0D, 0x5C, 0x45, 0xD4, 0x2F, 0x17, 0x92, 0x07, - 0x66, 0x11, 0xF5, 0x46, 0xF8, 0x0C, 0x03, 0x92, - 0xF5, 0xF5, 0xFF, 0xA4, 0xF3, 0x52, 0xF4, 0x08, - 0x2C, 0x49, 0x32, 0x1A, 0x93, 0x51, 0x98, 0xB6, - 0x94, 0x83, 0x39, 0xCF, 0x6B, 0x1F, 0x2F, 0xFC, - 0x2B, 0xFF, 0x10, 0x71, 0x7D, 0x35, 0x6C, 0xEA, - 0xC5, 0x66, 0xC7, 0x26, 0x7D, 0x9E, 0xAC, 0xDD, - 0x35, 0xD7, 0x06, 0x3F, 0x40, 0x82, 0xDA, 0xC3, - 0x2B, 0x3C, 0x91, 0x3A, 0x32, 0xF8, 0xB2, 0xC6, - 0x44, 0x4D, 0xCD, 0xB6, 0x54, 0x5F, 0x81, 0x95, - 0x59, 0xA1, 0xE5, 0x4E, 0xA5, 0x0A, 0x4A, 0x42), - chunk_from_chars( 1, 2, 2, 2, 2, 1, 2, 2, 0, 0, 2, 0, 0, 0, 0, 1, 2, 2, 2, 0, 2, 0, 0, 2, 2, 1, 2, 0, 0, 1, 2, 1, 0, 0, 0, 1, 0, 2, 2, 1, 1, 2, 0, 0, 0, 1, 2, 0, 2, 2, 1, 2, 1, 0, 1, 0, 1, 2, 1, 1, @@ -546,104 +495,34 @@ mgf1_test_t mgf1_tests[] = { } }; -START_TEST(test_ntru_mgf1) -{ - ntru_mgf1_t *mgf1; - chunk_t mask, mask1, mask2, mask3; - - mask1 = mgf1_tests[_i].mask; - mask2 = chunk_skip(mask1, mgf1_tests[_i].ml1); - mask3 = chunk_skip(mask2, mgf1_tests[_i].ml2); - mask1.len = mgf1_tests[_i].ml1; - mask2.len = mgf1_tests[_i].ml2; - mask3.len = mgf1_tests[_i].ml3; - - mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, HASH_UNKNOWN, - mgf1_tests[_i].seed, TRUE); - ck_assert(mgf1 == NULL); - - mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg, - chunk_empty, TRUE); - ck_assert(mgf1 == NULL); - - /* return mask in allocated chunk */ - mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg, - mgf1_tests[_i].seed, TRUE); - ck_assert(mgf1); - - /* check hash size */ - ck_assert(mgf1->get_hash_size(mgf1) == mgf1_tests[_i].hash_size); - - /* get zero number of octets */ - ck_assert(mgf1->allocate_mask(mgf1, 0, &mask)); - ck_assert(mask.len == 0 && mask.ptr == NULL); - - /* get non-zero number of octets */ - ck_assert(mgf1->allocate_mask(mgf1, mgf1_tests[_i].mask.len, &mask)); - ck_assert(chunk_equals(mask, mgf1_tests[_i].mask)); - mgf1->destroy(mgf1); - - /* copy mask to pre-allocated buffer */ - mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg, - mgf1_tests[_i].seed, TRUE); - ck_assert(mgf1); - ck_assert(mgf1->get_mask(mgf1, mgf1_tests[_i].mask.len, mask.ptr)); - ck_assert(chunk_equals(mask, mgf1_tests[_i].mask)); - mgf1->destroy(mgf1); - - /* get mask in batches without hashing the seed */ - mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg, - mgf1_tests[_i].hashed_seed, FALSE); - ck_assert(mgf1); - - /* first batch */ - ck_assert(mgf1->get_mask(mgf1, mask1.len, mask.ptr)); - mask.len = mask1.len; - ck_assert(chunk_equals(mask, mask1)); - - /* second batch */ - ck_assert(mgf1->get_mask(mgf1, mask2.len, mask.ptr)); - mask.len = mask2.len; - ck_assert(chunk_equals(mask, mask2)); - - /* third batch */ - ck_assert(mgf1->get_mask(mgf1, mask3.len, mask.ptr)); - mask.len = mask3.len; - ck_assert(chunk_equals(mask, mask3)); - - mgf1->destroy(mgf1); - chunk_free(&mask); -} -END_TEST - START_TEST(test_ntru_trits) { ntru_trits_t *mask; chunk_t trits; - mask = TEST_FUNCTION(ntru, ntru_trits_create, mgf1_tests[_i].trits.len, - HASH_UNKNOWN, mgf1_tests[_i].seed); + mask = TEST_FUNCTION(ntru, ntru_trits_create, trits_tests[_i].trits.len, + HASH_UNKNOWN, trits_tests[_i].seed); ck_assert(mask == NULL); - mask = TEST_FUNCTION(ntru, ntru_trits_create, mgf1_tests[_i].trits.len, - mgf1_tests[_i].alg, chunk_empty); + mask = TEST_FUNCTION(ntru, ntru_trits_create, trits_tests[_i].trits.len, + trits_tests[_i].alg, chunk_empty); ck_assert(mask == NULL); - mask = TEST_FUNCTION(ntru, ntru_trits_create, mgf1_tests[_i].trits.len, - mgf1_tests[_i].alg, mgf1_tests[_i].seed); + mask = TEST_FUNCTION(ntru, ntru_trits_create, trits_tests[_i].trits.len, + trits_tests[_i].alg, trits_tests[_i].seed); ck_assert(mask); trits = chunk_create(mask->get_trits(mask), mask->get_size(mask)); - ck_assert(chunk_equals(trits, mgf1_tests[_i].trits)); + ck_assert(chunk_equals(trits, trits_tests[_i].trits)); mask->destroy(mask); /* generate a multiple of 5 trits */ - mask = TEST_FUNCTION(ntru, ntru_trits_create, 10, mgf1_tests[_i].alg, - mgf1_tests[_i].seed); + mask = TEST_FUNCTION(ntru, ntru_trits_create, 10, trits_tests[_i].alg, + trits_tests[_i].seed); ck_assert(mask); trits = chunk_create(mask->get_trits(mask), mask->get_size(mask)); - ck_assert(chunk_equals(trits, chunk_create(mgf1_tests[_i].trits.ptr, 10))); + ck_assert(chunk_equals(trits, chunk_create(trits_tests[_i].trits.ptr, 10))); mask->destroy(mask); } END_TEST @@ -656,10 +535,10 @@ START_TEST(test_ntru_poly) poly_test_t *p; int j, n; - seed = mgf1_tests[_i].seed; - seed.len = mgf1_tests[_i].seed_len; + seed = trits_tests[_i].seed; + seed.len = trits_tests[_i].seed_len; - p = &mgf1_tests[_i].poly_test[0]; + p = &trits_tests[_i].poly_test[0]; poly = TEST_FUNCTION(ntru, ntru_poly_create_from_seed, HASH_UNKNOWN, seed, p->c_bits, p->N, p->q, p->indices_len, p->indices_len, p->is_product_form); @@ -667,9 +546,9 @@ START_TEST(test_ntru_poly) for (n = 0; n < 2; n++) { - p = &mgf1_tests[_i].poly_test[n]; + p = &trits_tests[_i].poly_test[n]; poly = TEST_FUNCTION(ntru, ntru_poly_create_from_seed, - mgf1_tests[_i].alg, seed, p->c_bits, p->N, p->q, + trits_tests[_i].alg, seed, p->c_bits, p->N, p->q, p->indices_len, p->indices_len, p->is_product_form); ck_assert(poly != NULL && poly->get_size(poly) == p->indices_size); @@ -1182,7 +1061,6 @@ START_TEST(test_ntru_ke) diffie_hellman_t *i_ntru, *r_ntru; char buf[10]; int k, n, len; - status_t status; k = (_i) / countof(parameter_sets); n = (_i) % countof(parameter_sets); @@ -1199,23 +1077,21 @@ START_TEST(test_ntru_ke) ck_assert(i_ntru != NULL); ck_assert(i_ntru->get_dh_group(i_ntru) == params[k].group); - i_ntru->get_my_public_value(i_ntru, &pub_key); + ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key)); ck_assert(pub_key.len > 0); r_ntru = lib->crypto->create_dh(lib->crypto, params[k].group); ck_assert(r_ntru != NULL); - r_ntru->set_other_public_value(r_ntru, pub_key); - r_ntru->get_my_public_value(r_ntru, &cipher_text); + ck_assert(r_ntru->set_other_public_value(r_ntru, pub_key)); + ck_assert(r_ntru->get_my_public_value(r_ntru, &cipher_text)); ck_assert(cipher_text.len > 0); - status = r_ntru->get_shared_secret(r_ntru, &r_shared_secret); - ck_assert(status == SUCCESS); + ck_assert(r_ntru->get_shared_secret(r_ntru, &r_shared_secret)); ck_assert(r_shared_secret.len > 0); - i_ntru->set_other_public_value(i_ntru, cipher_text); - status = i_ntru->get_shared_secret(i_ntru, &i_shared_secret); - ck_assert(status == SUCCESS); + ck_assert(i_ntru->set_other_public_value(i_ntru, cipher_text)); + ck_assert(i_ntru->get_shared_secret(i_ntru, &i_shared_secret)); ck_assert(chunk_equals(i_shared_secret, r_shared_secret)); chunk_clear(&i_shared_secret); @@ -1233,8 +1109,8 @@ START_TEST(test_ntru_retransmission) chunk_t pub_key1, pub_key2; i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_256_BIT); - i_ntru->get_my_public_value(i_ntru, &pub_key1); - i_ntru->get_my_public_value(i_ntru, &pub_key2); + ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key1)); + ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key2)); ck_assert(chunk_equals(pub_key1, pub_key2)); chunk_free(&pub_key1); @@ -1260,8 +1136,8 @@ START_TEST(test_ntru_pubkey_oid) chunk_t cipher_text; r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT); - r_ntru->set_other_public_value(r_ntru, oid_tests[_i]); - r_ntru->get_my_public_value(r_ntru, &cipher_text); + ck_assert(!r_ntru->set_other_public_value(r_ntru, oid_tests[_i])); + ck_assert(r_ntru->get_my_public_value(r_ntru, &cipher_text)); ck_assert(cipher_text.len == 0); r_ntru->destroy(r_ntru); } @@ -1276,14 +1152,14 @@ START_TEST(test_ntru_wrong_set) "libstrongswan.plugins.ntru.parameter_set", "x9_98_bandwidth"); i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_112_BIT); - i_ntru->get_my_public_value(i_ntru, &pub_key); + ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key)); lib->settings->set_str(lib->settings, "libstrongswan.plugins.ntru.parameter_set", "optimum"); r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_112_BIT); - r_ntru->set_other_public_value(r_ntru, pub_key); - r_ntru->get_my_public_value(r_ntru, &cipher_text); + ck_assert(!r_ntru->set_other_public_value(r_ntru, pub_key)); + ck_assert(r_ntru->get_my_public_value(r_ntru, &cipher_text)); ck_assert(cipher_text.len == 0); chunk_free(&pub_key); @@ -1314,9 +1190,9 @@ START_TEST(test_ntru_ciphertext) for (i = 0; i < countof(test); i++) { i_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT); - i_ntru->get_my_public_value(i_ntru, &pub_key); - i_ntru->set_other_public_value(i_ntru, test[i]); - ck_assert(i_ntru->get_shared_secret(i_ntru, &shared_secret) != SUCCESS); + ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key)); + ck_assert(!i_ntru->set_other_public_value(i_ntru, test[i])); + ck_assert(!i_ntru->get_shared_secret(i_ntru, &shared_secret)); ck_assert(shared_secret.len == 0); chunk_free(&pub_key); @@ -1334,12 +1210,12 @@ START_TEST(test_ntru_wrong_ciphertext) r_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT); m_ntru = lib->crypto->create_dh(lib->crypto, NTRU_128_BIT); - i_ntru->get_my_public_value(i_ntru, &pub_key_i); - m_ntru->get_my_public_value(m_ntru, &pub_key_m); - r_ntru->set_other_public_value(r_ntru, pub_key_m); - r_ntru->get_my_public_value(r_ntru, &cipher_text); - i_ntru->set_other_public_value(i_ntru, cipher_text); - ck_assert(i_ntru->get_shared_secret(i_ntru, &shared_secret) != SUCCESS); + ck_assert(i_ntru->get_my_public_value(i_ntru, &pub_key_i)); + ck_assert(m_ntru->get_my_public_value(m_ntru, &pub_key_m)); + ck_assert(r_ntru->set_other_public_value(r_ntru, pub_key_m)); + ck_assert(r_ntru->get_my_public_value(r_ntru, &cipher_text)); + ck_assert(!i_ntru->set_other_public_value(i_ntru, cipher_text)); + ck_assert(!i_ntru->get_shared_secret(i_ntru, &shared_secret)); ck_assert(shared_secret.len == 0); chunk_free(&pub_key_i); @@ -1370,16 +1246,12 @@ Suite *ntru_suite_create() tcase_add_test(tc, test_ntru_drbg_reseed); suite_add_tcase(s, tc); - tc = tcase_create("mgf1"); - tcase_add_loop_test(tc, test_ntru_mgf1, 0, countof(mgf1_tests)); - suite_add_tcase(s, tc); - tc = tcase_create("trits"); - tcase_add_loop_test(tc, test_ntru_trits, 0, countof(mgf1_tests)); + tcase_add_loop_test(tc, test_ntru_trits, 0, countof(trits_tests)); suite_add_tcase(s, tc); tc = tcase_create("poly"); - tcase_add_loop_test(tc, test_ntru_poly, 0, countof(mgf1_tests)); + tcase_add_loop_test(tc, test_ntru_poly, 0, countof(trits_tests)); suite_add_tcase(s, tc); tc = tcase_create("ring_mult"); diff --git a/src/libstrongswan/tests/suites/test_settings.c b/src/libstrongswan/tests/suites/test_settings.c index b9d429a24..9601a34a9 100644 --- a/src/libstrongswan/tests/suites/test_settings.c +++ b/src/libstrongswan/tests/suites/test_settings.c @@ -908,7 +908,7 @@ START_SETUP(setup_string_config) "special = \"all { special } characters # can be used.\"\n" "unterminated = \"is fine\n" "but = produces a warning\n" - "newlines = \"can either be encoded\\nor\\\n" + "newlines = \"can either be encoded\\nor \\\n" "escaped\"\n" "quotes = \"\\\"and\\\" slashes \\\\ can \\\\ be\" # escaped too\n" "multiple = \"strings\" are \"combined\"\n" @@ -922,7 +922,7 @@ START_TEST(test_strings) verify_string("all { special } characters # can be used.", "special"); verify_string("is fine", "unterminated"); verify_string("produces a warning", "but"); - verify_string("can either be encoded\nor\nescaped", "newlines"); + verify_string("can either be encoded\nor escaped", "newlines"); verify_string("\"and\" slashes \\ can \\ be", "quotes"); verify_string("strings are combined", "multiple"); } diff --git a/src/libstrongswan/tests/suites/test_threading.c b/src/libstrongswan/tests/suites/test_threading.c index 47e448484..55a4cd797 100644 --- a/src/libstrongswan/tests/suites/test_threading.c +++ b/src/libstrongswan/tests/suites/test_threading.c @@ -553,6 +553,49 @@ START_TEST(test_rwlock) } END_TEST +static void *rwlock_try_run(void *param) +{ + if (rwlock->try_write_lock(rwlock)) + { + rwlock->unlock(rwlock); + return param; + } + return NULL; +} + +START_TEST(test_rwlock_try) +{ + uintptr_t magic = 0xcafebabe; + thread_t *thread; + + rwlock = rwlock_create(RWLOCK_TYPE_DEFAULT); + + thread = thread_create(rwlock_try_run, (void*)magic); + ck_assert_int_eq((uintptr_t)thread->join(thread), magic); + + rwlock->read_lock(rwlock); + thread = thread_create(rwlock_try_run, (void*)magic); + ck_assert(thread->join(thread) == NULL); + rwlock->unlock(rwlock); + + rwlock->read_lock(rwlock); + rwlock->read_lock(rwlock); + rwlock->read_lock(rwlock); + thread = thread_create(rwlock_try_run, (void*)magic); + ck_assert(thread->join(thread) == NULL); + rwlock->unlock(rwlock); + rwlock->unlock(rwlock); + rwlock->unlock(rwlock); + + rwlock->write_lock(rwlock); + thread = thread_create(rwlock_try_run, (void*)magic); + ck_assert(thread->join(thread) == NULL); + rwlock->unlock(rwlock); + + rwlock->destroy(rwlock); +} +END_TEST + /** * Rwlock condvar */ @@ -1132,6 +1175,191 @@ START_TEST(test_cancel_point) } END_TEST +static void close_fd_ptr(void *fd) +{ + close(*(int*)fd); +} + +static void cancellation_recv() +{ + int sv[2]; + char buf[1]; + + ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0); + + thread_cleanup_push(close_fd_ptr, &sv[0]); + thread_cleanup_push(close_fd_ptr, &sv[1]); + + thread_cancelability(TRUE); + while (TRUE) + { + ck_assert(recv(sv[0], buf, sizeof(buf), 0) == 1); + } +} + +static void cancellation_read() +{ + int sv[2]; + char buf[1]; + + ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0); + + thread_cleanup_push(close_fd_ptr, &sv[0]); + thread_cleanup_push(close_fd_ptr, &sv[1]); + + thread_cancelability(TRUE); + while (TRUE) + { + ck_assert(read(sv[0], buf, sizeof(buf)) == 1); + } +} + +static void cancellation_select() +{ + int sv[2]; + fd_set set; + + ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0); + + thread_cleanup_push(close_fd_ptr, &sv[0]); + thread_cleanup_push(close_fd_ptr, &sv[1]); + + FD_ZERO(&set); + FD_SET(sv[0], &set); + thread_cancelability(TRUE); + while (TRUE) + { + ck_assert(select(sv[0] + 1, &set, NULL, NULL, NULL) == 1); + } +} + +static void cancellation_poll() +{ + int sv[2]; + struct pollfd pfd; + + ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0); + + thread_cleanup_push(close_fd_ptr, &sv[0]); + thread_cleanup_push(close_fd_ptr, &sv[1]); + + pfd.fd = sv[0]; + pfd.events = POLLIN; + thread_cancelability(TRUE); + while (TRUE) + { + ck_assert(poll(&pfd, 1, -1) == 1); + } +} + +static void cancellation_accept() +{ + host_t *host; + int fd, c; + + fd = socket(AF_INET, SOCK_STREAM, 0); + ck_assert(fd >= 0); + host = host_create_from_string("127.0.0.1", 0); + ck_assert_msg(bind(fd, host->get_sockaddr(host), + *host->get_sockaddr_len(host)) == 0, "%m"); + host->destroy(host); + ck_assert(listen(fd, 5) == 0); + + thread_cleanup_push(close_fd_ptr, &fd); + + thread_cancelability(TRUE); + while (TRUE) + { + c = accept(fd, NULL, NULL); + ck_assert(c >= 0); + close(c); + } +} + +static void cancellation_cond() +{ + mutex_t *mutex; + condvar_t *cond; + + mutex = mutex_create(MUTEX_TYPE_DEFAULT); + cond = condvar_create(CONDVAR_TYPE_DEFAULT); + mutex->lock(mutex); + + thread_cleanup_push((void*)mutex->destroy, mutex); + thread_cleanup_push((void*)cond->destroy, cond); + + thread_cancelability(TRUE); + while (TRUE) + { + cond->wait(cond, mutex); + } +} + +static void cancellation_rwcond() +{ + rwlock_t *lock; + rwlock_condvar_t *cond; + + lock = rwlock_create(RWLOCK_TYPE_DEFAULT); + cond = rwlock_condvar_create(); + lock->write_lock(lock); + + thread_cleanup_push((void*)lock->destroy, lock); + thread_cleanup_push((void*)cond->destroy, cond); + + thread_cancelability(TRUE); + while (TRUE) + { + cond->wait(cond, lock); + } +} + +static void (*cancellation_points[])() = { + cancellation_read, + cancellation_recv, + cancellation_select, + cancellation_poll, + cancellation_accept, + cancellation_cond, + cancellation_rwcond, +}; + +static void* run_cancellation_point(void (*fn)()) +{ + fn(); + return NULL; +} + +static void* run_cancellation_point_pre(void (*fn)()) +{ + usleep(5000); + fn(); + return NULL; +} + +START_TEST(test_cancellation_point) +{ + thread_t *thread; + + thread = thread_create((void*)run_cancellation_point, + cancellation_points[_i]); + usleep(5000); + thread->cancel(thread); + thread->join(thread); +} +END_TEST + +START_TEST(test_cancellation_point_pre) +{ + thread_t *thread; + + thread = thread_create((void*)run_cancellation_point_pre, + cancellation_points[_i]); + thread->cancel(thread); + thread->join(thread); +} +END_TEST + static void cleanup1(void *data) { uintptr_t *value = (uintptr_t*)data; @@ -1423,6 +1651,7 @@ Suite *threading_suite_create() tc = tcase_create("rwlock"); tcase_add_test(tc, test_rwlock); + tcase_add_test(tc, test_rwlock_try); suite_add_tcase(s, tc); tc = tcase_create("rwlock condvar"); @@ -1456,6 +1685,13 @@ Suite *threading_suite_create() tcase_add_test(tc, test_cancel_point); suite_add_tcase(s, tc); + tc = tcase_create("thread cancellation point"); + tcase_add_loop_test(tc, test_cancellation_point, + 0, countof(cancellation_points)); + tcase_add_loop_test(tc, test_cancellation_point_pre, + 0, countof(cancellation_points)); + suite_add_tcase(s, tc); + tc = tcase_create("thread cleanup"); tcase_add_test(tc, test_cleanup); tcase_add_test(tc, test_cleanup_exit); diff --git a/src/libstrongswan/tests/suites/test_traffic_selector.c b/src/libstrongswan/tests/suites/test_traffic_selector.c new file mode 100644 index 000000000..4312c6ce1 --- /dev/null +++ b/src/libstrongswan/tests/suites/test_traffic_selector.c @@ -0,0 +1,284 @@ +/* + * Copyright (C) 2015 Martin Willi + * Copyright (C) 2015 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "test_suite.h" + +#include <selectors/traffic_selector.h> + + +static void verify(const char *str, const char *alt, traffic_selector_t *ts) +{ + char buf[512]; + + ck_assert(ts != NULL); + snprintf(buf, sizeof(buf), "%R", ts); + ts->destroy(ts); + if (!streq(buf, str) && !streq(buf, alt)) + { + fail("%s != %s or %s", buf, str, alt); + } +} + +START_TEST(test_create_from_string) +{ + verify("10.1.0.0/16[tcp/http]", "10.1.0.0/16[6/80]", + traffic_selector_create_from_string(IPPROTO_TCP, TS_IPV4_ADDR_RANGE, + "10.1.0.0", 80, "10.1.255.255", 80)); + verify("10.1.0.1..10.1.0.99[udp/1234-1235]", + "10.1.0.1..10.1.0.99[17/1234-1235]", + traffic_selector_create_from_string(IPPROTO_UDP, TS_IPV4_ADDR_RANGE, + "10.1.0.1", 1234, "10.1.0.99", 1235)); + verify("fec1::/64", NULL, + traffic_selector_create_from_string(0, TS_IPV6_ADDR_RANGE, + "fec1::", 0, "fec1::ffff:ffff:ffff:ffff", 65535)); +} +END_TEST + +START_TEST(test_create_from_cidr) +{ + verify("10.1.0.0/16", NULL, + traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535)); + verify("10.1.0.1/32[udp/1234-1235]", "10.1.0.1/32[17/1234-1235]", + traffic_selector_create_from_cidr("10.1.0.1/32", IPPROTO_UDP, + 1234, 1235)); +} +END_TEST + +START_TEST(test_create_from_bytes) +{ + verify("10.1.0.0/16", NULL, + traffic_selector_create_from_bytes(0, TS_IPV4_ADDR_RANGE, + chunk_from_chars(0x0a,0x01,0x00,0x00), 0, + chunk_from_chars(0x0a,0x01,0xff,0xff), 65535)); +} +END_TEST + +START_TEST(test_create_from_subnet) +{ + verify("10.1.0.0/16", NULL, + traffic_selector_create_from_subnet( + host_create_from_string("10.1.0.0", 0), 16, 0, 0, 65535)); +} +END_TEST + + +START_TEST(test_subset) +{ + traffic_selector_t *a, *b; + + a = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535); + b = traffic_selector_create_from_cidr("10.1.5.0/24", 0, 0, 65535); + verify("10.1.5.0/24", NULL, a->get_subset(a, b)); + a->destroy(a); + b->destroy(b); +} +END_TEST + +START_TEST(test_subset_port) +{ + traffic_selector_t *a, *b; + + a = traffic_selector_create_from_cidr("10.0.0.0/8", IPPROTO_TCP, 55, 60); + b = traffic_selector_create_from_cidr("10.2.7.16/30", 0, 0, 65535); + verify("10.2.7.16/30[tcp/55-60]", "10.2.7.16/30[6/55-60]", + a->get_subset(a, b)); + a->destroy(a); + b->destroy(b); +} +END_TEST + +START_TEST(test_subset_equal) +{ + traffic_selector_t *a, *b; + + a = traffic_selector_create_from_cidr("10.1.0.0/16", IPPROTO_TCP, 80, 80); + b = traffic_selector_create_from_cidr("10.1.0.0/16", IPPROTO_TCP, 80, 80); + verify("10.1.0.0/16[tcp/http]", "10.1.0.0/16[6/80]", a->get_subset(a, b)); + a->destroy(a); + b->destroy(b); +} +END_TEST + +START_TEST(test_subset_nonet) +{ + traffic_selector_t *a, *b; + + a = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 65535); + b = traffic_selector_create_from_cidr("10.2.0.0/16", 0, 0, 65535); + ck_assert(a->get_subset(a, b) == NULL); + a->destroy(a); + b->destroy(b); +} +END_TEST + +START_TEST(test_subset_noport) +{ + traffic_selector_t *a, *b; + + a = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 0, 9999); + b = traffic_selector_create_from_cidr("10.1.0.0/16", 0, 10000, 65535); + ck_assert(a->get_subset(a, b) == NULL); + a->destroy(a); + b->destroy(b); +} +END_TEST + +START_TEST(test_subset_noproto) +{ + traffic_selector_t *a, *b; + + a = traffic_selector_create_from_cidr("10.1.0.0/16", IPPROTO_TCP, 0, 65535); + b = traffic_selector_create_from_cidr("10.1.0.0/16", IPPROTO_UDP, 0, 65535); + ck_assert(a->get_subset(a, b) == NULL); + a->destroy(a); + b->destroy(b); +} +END_TEST + +START_TEST(test_subset_nofamily) +{ + traffic_selector_t *a, *b; + + a = traffic_selector_create_from_cidr("0.0.0.0/0", 0, 0, 65535); + b = traffic_selector_create_from_cidr("::/0", 0, 0, 65535); + ck_assert(a->get_subset(a, b) == NULL); + a->destroy(a); + b->destroy(b); +} +END_TEST + +struct { + char *net; + char *host; + bool inc; +} include_tests[] = { + { "0.0.0.0/0", "192.168.1.2", TRUE }, + { "::/0", "fec2::1", TRUE }, + { "fec2::/64", "fec2::afaf", TRUE }, + { "10.1.0.0/16", "10.1.0.1", TRUE }, + { "10.5.6.7/32", "10.5.6.7", TRUE }, + { "0.0.0.0/0", "fec2::1", FALSE }, + { "::/0", "1.2.3.4", FALSE }, + { "10.0.0.0/16", "10.1.0.0", FALSE }, + { "fec2::/64", "fec2:0:0:1::afaf", FALSE }, +}; + +START_TEST(test_includes) +{ + traffic_selector_t *ts; + host_t *h; + + ts = traffic_selector_create_from_cidr(include_tests[_i].net, 0, 0, 65535); + h = host_create_from_string(include_tests[_i].host, 0); + ck_assert(ts->includes(ts, h) == include_tests[_i].inc); + ts->destroy(ts); + h->destroy(h); +} +END_TEST + +struct { + int res; + struct { + char *net; + u_int8_t proto; + u_int16_t from_port; + u_int16_t to_port; + } a, b; +} cmp_tests[] = { + { 0, { "10.0.0.0/8", 0, 0, 65535 }, { "10.0.0.0/8", 0, 0, 65535 }, }, + { 0, { "10.0.0.0/8", 17, 123, 456 }, { "10.0.0.0/8", 17, 123, 456 }, }, + { 0, { "fec2::/64", 0, 0, 65535 }, { "fec2::/64", 0, 0, 65535 }, }, + { 0, { "fec2::/64", 4, 0, 65535 }, { "fec2::/64", 4, 0, 65535 }, }, + + { -1, { "1.0.0.0/8", 0, 0, 65535 }, { "2.0.0.0/8", 0, 0, 65535 }, }, + { 1, { "2.0.0.0/8", 0, 0, 65535 }, { "1.0.0.0/8", 0, 0, 65535 }, }, + { -1, { "1.0.0.0/8", 0, 0, 65535 }, { "1.0.0.0/16", 0, 0, 65535 }, }, + { 1, { "1.0.0.0/16", 0, 0, 65535 }, { "1.0.0.0/8", 0, 0, 65535 }, }, + + { -1, { "10.0.0.0/8", 0, 0, 65535 }, { "fec2::/64", 0, 0, 65535 }, }, + { 1, { "fec2::/64", 0, 0, 65535 }, { "10.0.0.0/8", 0, 0, 65535 }, }, + + { -1, { "10.0.0.0/8", 16, 123, 456 }, { "10.0.0.0/8", 17, 123, 456 }, }, + { 1, { "fec2::/64", 5, 0, 65535 }, { "fec2::/64", 4, 0, 65535 }, }, + + { -1, { "10.0.0.0/8", 17, 111, 456 }, { "10.0.0.0/8", 17, 222, 456 }, }, + { 1, { "fec2::/64", 17, 555, 65535 }, { "fec2::/64", 17, 444, 65535 },}, + + { -1, { "10.0.0.0/8", 17, 55, 65535 }, { "10.0.0.0/8", 17, 55, 666 }, }, + { 1, { "fec2::/64", 17, 55, 111 }, { "fec2::/64", 17, 55, 4567 }, }, + +}; + +START_TEST(test_cmp) +{ + traffic_selector_t *a, *b; + + a = traffic_selector_create_from_cidr( + cmp_tests[_i].a.net, cmp_tests[_i].a.proto, + cmp_tests[_i].a.from_port, cmp_tests[_i].a.to_port); + b = traffic_selector_create_from_cidr( + cmp_tests[_i].b.net, cmp_tests[_i].b.proto, + cmp_tests[_i].b.from_port, cmp_tests[_i].b.to_port); + switch (cmp_tests[_i].res) + { + case 0: + ck_assert(traffic_selector_cmp(a, b, NULL) == 0); + break; + case 1: + ck_assert(traffic_selector_cmp(a, b, NULL) > 0); + break; + case -1: + ck_assert(traffic_selector_cmp(a, b, NULL) < 0); + break; + } + a->destroy(a); + b->destroy(b); +} +END_TEST + +Suite *traffic_selector_suite_create() +{ + Suite *s; + TCase *tc; + + s = suite_create("traffic selector"); + + tc = tcase_create("create"); + tcase_add_test(tc, test_create_from_string); + tcase_add_test(tc, test_create_from_cidr); + tcase_add_test(tc, test_create_from_bytes); + tcase_add_test(tc, test_create_from_subnet); + suite_add_tcase(s, tc); + + tc = tcase_create("subset"); + tcase_add_test(tc, test_subset); + tcase_add_test(tc, test_subset_port); + tcase_add_test(tc, test_subset_equal); + tcase_add_test(tc, test_subset_nonet); + tcase_add_test(tc, test_subset_noport); + tcase_add_test(tc, test_subset_noproto); + tcase_add_test(tc, test_subset_nofamily); + suite_add_tcase(s, tc); + + tc = tcase_create("includes"); + tcase_add_loop_test(tc, test_includes, 0, countof(include_tests)); + suite_add_tcase(s, tc); + + tc = tcase_create("cmp"); + tcase_add_loop_test(tc, test_cmp, 0, countof(cmp_tests)); + suite_add_tcase(s, tc); + + return s; +} diff --git a/src/libstrongswan/tests/suites/test_utils.c b/src/libstrongswan/tests/suites/test_utils.c index abca4620e..85a854456 100644 --- a/src/libstrongswan/tests/suites/test_utils.c +++ b/src/libstrongswan/tests/suites/test_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Tobias Brunner + * Copyright (C) 2013-2015 Tobias Brunner * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -18,6 +18,7 @@ #include <library.h> #include <utils/utils.h> #include <ipsec/ipsec_types.h> +#include <credentials/keys/public_key.h> #include <time.h> @@ -695,6 +696,44 @@ START_TEST(test_mark_from_string) } END_TEST +/******************************************************************************* + * signature_schemes_for_key + */ + +static struct { + key_type_t type; + int size; + signature_scheme_t expected[4]; +} scheme_data[] = { + {KEY_RSA, 1024, { SIGN_RSA_EMSA_PKCS1_SHA256, SIGN_RSA_EMSA_PKCS1_SHA384, SIGN_RSA_EMSA_PKCS1_SHA512, SIGN_UNKNOWN }}, + {KEY_RSA, 2048, { SIGN_RSA_EMSA_PKCS1_SHA256, SIGN_RSA_EMSA_PKCS1_SHA384, SIGN_RSA_EMSA_PKCS1_SHA512, SIGN_UNKNOWN }}, + {KEY_RSA, 4096, { SIGN_RSA_EMSA_PKCS1_SHA384, SIGN_RSA_EMSA_PKCS1_SHA512, SIGN_UNKNOWN }}, + {KEY_RSA, 8192, { SIGN_RSA_EMSA_PKCS1_SHA512, SIGN_UNKNOWN }}, + {KEY_ECDSA, 256, { SIGN_ECDSA_WITH_SHA256_DER, SIGN_ECDSA_WITH_SHA384_DER, SIGN_ECDSA_WITH_SHA512_DER, SIGN_UNKNOWN }}, + {KEY_ECDSA, 384, { SIGN_ECDSA_WITH_SHA384_DER, SIGN_ECDSA_WITH_SHA512_DER, SIGN_UNKNOWN }}, + {KEY_ECDSA, 512, { SIGN_ECDSA_WITH_SHA512_DER, SIGN_UNKNOWN }}, + {KEY_BLISS, 128, { SIGN_BLISS_WITH_SHA256, SIGN_BLISS_WITH_SHA384, SIGN_BLISS_WITH_SHA512, SIGN_UNKNOWN }}, + {KEY_BLISS, 192, { SIGN_BLISS_WITH_SHA384, SIGN_BLISS_WITH_SHA512, SIGN_UNKNOWN }}, + {KEY_BLISS, 256, { SIGN_BLISS_WITH_SHA512, SIGN_UNKNOWN }}, +}; + +START_TEST(test_signature_schemes_for_key) +{ + enumerator_t *enumerator; + signature_scheme_t scheme; + int i; + + enumerator = signature_schemes_for_key(scheme_data[_i].type, scheme_data[_i].size); + for (i = 0; scheme_data[_i].expected[i] != SIGN_UNKNOWN; i++) + { + ck_assert(enumerator->enumerate(enumerator, &scheme)); + ck_assert_int_eq(scheme_data[_i].expected[i], scheme); + } + ck_assert(!enumerator->enumerate(enumerator, &scheme)); + enumerator->destroy(enumerator); +} +END_TEST + Suite *utils_suite_create() { Suite *s; @@ -777,5 +816,9 @@ Suite *utils_suite_create() tcase_add_loop_test(tc, test_mark_from_string, 0, countof(mark_data)); suite_add_tcase(s, tc); + tc = tcase_create("signature_schemes_for_key"); + tcase_add_loop_test(tc, test_signature_schemes_for_key, 0, countof(scheme_data)); + suite_add_tcase(s, tc); + return s; } diff --git a/src/libstrongswan/tests/tests.h b/src/libstrongswan/tests/tests.h index 586227800..e1d8ca4ba 100644 --- a/src/libstrongswan/tests/tests.h +++ b/src/libstrongswan/tests/tests.h @@ -23,6 +23,7 @@ TEST_SUITE(linked_list_enumerator_suite_create) TEST_SUITE(hashtable_suite_create) TEST_SUITE(array_suite_create) TEST_SUITE(identification_suite_create) +TEST_SUITE(traffic_selector_suite_create) TEST_SUITE(threading_suite_create) TEST_SUITE(process_suite_create) TEST_SUITE(watcher_suite_create) @@ -32,6 +33,8 @@ TEST_SUITE(settings_suite_create) TEST_SUITE(vectors_suite_create) TEST_SUITE_DEPEND(ecdsa_suite_create, PRIVKEY_GEN, KEY_ECDSA) TEST_SUITE_DEPEND(rsa_suite_create, PRIVKEY_GEN, KEY_RSA) +TEST_SUITE_DEPEND(certpolicy_suite_create, CERT_ENCODE, CERT_X509) +TEST_SUITE_DEPEND(certnames_suite_create, CERT_ENCODE, CERT_X509) TEST_SUITE(host_suite_create) TEST_SUITE(printf_suite_create) TEST_SUITE(hasher_suite_create) @@ -41,5 +44,7 @@ TEST_SUITE(pen_suite_create) TEST_SUITE(asn1_suite_create) TEST_SUITE(asn1_parser_suite_create) TEST_SUITE(test_rng_suite_create) +TEST_SUITE_DEPEND(mgf1_sha1_suite_create, HASHER, HASH_SHA1) +TEST_SUITE_DEPEND(mgf1_sha256_suite_create, HASHER, HASH_SHA256) TEST_SUITE_DEPEND(ntru_suite_create, DH, NTRU_112_BIT) TEST_SUITE_DEPEND(fetch_http_suite_create, FETCHER, "http://") diff --git a/src/libstrongswan/threading/semaphore.h b/src/libstrongswan/threading/semaphore.h index 34d814971..d3ab0f3d9 100644 --- a/src/libstrongswan/threading/semaphore.h +++ b/src/libstrongswan/threading/semaphore.h @@ -21,10 +21,7 @@ #ifndef THREADING_SEMAPHORE_H_ #define THREADING_SEMAPHORE_H_ -#ifdef __APPLE__ -/* Mach uses a semaphore_create() call, use a different name for ours */ -#define semaphore_create(x) strongswan_semaphore_create(x) -#endif /* __APPLE__ */ +#include <utils/utils.h> typedef struct semaphore_t semaphore_t; @@ -87,4 +84,3 @@ struct semaphore_t { semaphore_t *semaphore_create(u_int value); #endif /** THREADING_SEMAPHORE_H_ @} */ - diff --git a/src/libstrongswan/threading/thread.h b/src/libstrongswan/threading/thread.h index 6abb83411..38275541e 100644 --- a/src/libstrongswan/threading/thread.h +++ b/src/libstrongswan/threading/thread.h @@ -21,40 +21,9 @@ #ifndef THREADING_THREAD_H_ #define THREADING_THREAD_H_ -typedef struct thread_t thread_t; - -#ifdef __APPLE__ -/* thread_create is a syscall used to create Mach kernel threads and although - * there are no errors or warnings during compilation or linkage the dynamic - * linker does not use our implementation, therefore we rename it here - */ -#define thread_create(main, arg) strongswan_thread_create(main, arg) +#include <utils/utils.h> -/* on Mac OS X 10.5 several system calls we use are no cancellation points. - * fortunately, select isn't one of them, so we wrap some of the others with - * calls to select(2). - */ -#include <sys/socket.h> -#include <sys/select.h> - -#define WRAP_WITH_SELECT(func, socket, ...)\ - fd_set rfds; FD_ZERO(&rfds); FD_SET(socket, &rfds);\ - if (select(socket + 1, &rfds, NULL, NULL, NULL) <= 0) { return -1; }\ - return func(socket, __VA_ARGS__) - -static inline int cancellable_accept(int socket, struct sockaddr *address, - socklen_t *address_len) -{ - WRAP_WITH_SELECT(accept, socket, address, address_len); -} -#define accept cancellable_accept -static inline int cancellable_recvfrom(int socket, void *buffer, size_t length, - int flags, struct sockaddr *address, socklen_t *address_len) -{ - WRAP_WITH_SELECT(recvfrom, socket, buffer, length, flags, address, address_len); -} -#define recvfrom cancellable_recvfrom -#endif /* __APPLE__ */ +typedef struct thread_t thread_t; /** * Main function of a thread. @@ -189,32 +158,4 @@ void threads_init(); */ void threads_deinit(); - -#ifdef __APPLE__ - -/* - * While select() is a cancellation point, it seems that OS X does not honor - * pending cancellation points when entering the function. We manually test for - * and honor pending cancellation requests, but this obviously can't prevent - * some race conditions where the the cancellation happens after the check, - * but before the select. - */ -static inline int precancellable_select(int nfds, fd_set *restrict readfds, - fd_set *restrict writefds, fd_set *restrict errorfds, - struct timeval *restrict timeout) -{ - if (thread_cancelability(TRUE)) - { - thread_cancellation_point(); - } - else - { - thread_cancelability(FALSE); - } - return select(nfds, readfds, writefds, errorfds, timeout); -} -#define select precancellable_select - -#endif /* __APPLE__ */ - #endif /** THREADING_THREAD_H_ @} */ diff --git a/src/libstrongswan/threading/windows/rwlock.c b/src/libstrongswan/threading/windows/rwlock.c index 0de57f713..fc0d6d864 100644 --- a/src/libstrongswan/threading/windows/rwlock.c +++ b/src/libstrongswan/threading/windows/rwlock.c @@ -85,8 +85,6 @@ METHOD(rwlock_t, write_lock, void, METHOD(rwlock_t, try_write_lock, bool, private_rwlock_t *this) { - /* TODO: causes random failures and segfaults. Bug? */ - return FALSE; return TryAcquireSRWLockExclusive(&this->srw); } diff --git a/src/libstrongswan/utils/chunk.c b/src/libstrongswan/utils/chunk.c index 4b24b37c2..c4471be70 100644 --- a/src/libstrongswan/utils/chunk.c +++ b/src/libstrongswan/utils/chunk.c @@ -992,7 +992,7 @@ u_int32_t chunk_hash_static(chunk_t chunk) */ u_int16_t chunk_internet_checksum_inc(chunk_t data, u_int16_t checksum) { - u_int32_t sum = ntohs(~checksum); + u_int32_t sum = ntohs((u_int16_t)~checksum); while (data.len > 1) { diff --git a/src/libstrongswan/utils/compat/apple.h b/src/libstrongswan/utils/compat/apple.h new file mode 100644 index 000000000..61afb9d9e --- /dev/null +++ b/src/libstrongswan/utils/compat/apple.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2014 Martin Willi + * Copyright (C) 2014 revosec AG + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup apple apple + * @{ @ingroup compat + */ + +#ifndef APPLE_H_ +#define APPLE_H_ + +#include <poll.h> +#include <sys/socket.h> +#include <sys/select.h> + +/* thread_create is a syscall used to create Mach kernel threads and although + * there are no errors or warnings during compilation or linkage the dynamic + * linker does not use our implementation, therefore we rename it here + */ +#define thread_create(main, arg) strongswan_thread_create(main, arg) + +/* Mach uses a semaphore_create() call, use a different name for ours */ +#define semaphore_create(x) strongswan_semaphore_create(x) + +/* Since OS X 10.10 XPC includes some additional conflicting Mach types */ +#define host_t strongswan_host_t +#define processor_t strongswan_processor_t +#define task_t strongswan_task_t +#define thread_t strongswan_thread_t + +/* forward declaration, see below */ +static inline int precancellable_poll(struct pollfd fds[], nfds_t nfds, + int timeout); + +/* on Mac OS X 10.5 several system calls we use are no cancellation points. + * fortunately, select isn't one of them, so we wrap some of the others with + * calls to select(2). + */ + +#define WRAP_WITH_POLL(func, socket, ...) \ + struct pollfd pfd = { \ + .fd = socket, \ + .events = POLLIN, \ + }; \ + if (precancellable_poll(&pfd, 1, -1) <= 0) \ + {\ + return -1; \ + }\ + return func(socket, __VA_ARGS__) + +static inline int cancellable_accept(int socket, struct sockaddr *address, + socklen_t *address_len) +{ + WRAP_WITH_POLL(accept, socket, address, address_len); +} +#define accept cancellable_accept +static inline int cancellable_recvfrom(int socket, void *buffer, size_t length, + int flags, struct sockaddr *address, socklen_t *address_len) +{ + WRAP_WITH_POLL(recvfrom, socket, buffer, length, flags, address, address_len); +} +#define recvfrom cancellable_recvfrom + +#include <threading/thread.h> + +/* + * While select() is a cancellation point, it seems that OS X does not honor + * pending cancellation points when entering the function. We manually test for + * and honor pending cancellation requests, but this obviously can't prevent + * some race conditions where the the cancellation happens after the check, + * but before the select. + */ +static inline int precancellable_select(int nfds, fd_set *restrict readfds, + fd_set *restrict writefds, fd_set *restrict errorfds, + struct timeval *restrict timeout) +{ + if (thread_cancelability(TRUE)) + { + thread_cancellation_point(); + } + else + { + thread_cancelability(FALSE); + } + return select(nfds, readfds, writefds, errorfds, timeout); +} +#define select precancellable_select + +/* + * The same as to select(2) applies to poll(2) + */ +static inline int precancellable_poll(struct pollfd fds[], nfds_t nfds, + int timeout) +{ + if (thread_cancelability(TRUE)) + { + thread_cancellation_point(); + } + else + { + thread_cancelability(FALSE); + } + return poll(fds, nfds, timeout); +} +#define poll precancellable_poll + +#endif /** APPLE_H_ @}*/ diff --git a/src/libstrongswan/utils/windows.c b/src/libstrongswan/utils/compat/windows.c index 8820287b1..1f22ffa02 100644 --- a/src/libstrongswan/utils/windows.c +++ b/src/libstrongswan/utils/compat/windows.c @@ -13,7 +13,10 @@ * for more details. */ -#include "utils.h" +/* WSAPoll() */ +#define _WIN32_WINNT 0x0600 + +#include <utils/utils.h> #include <errno.h> @@ -639,3 +642,43 @@ ssize_t windows_sendto(int sockfd, const void *buf, size_t len, int flags, } return outlen; } + +/** + * See header + */ +#undef read +ssize_t windows_read(int fd, void *buf, size_t count) +{ + ssize_t ret; + + ret = wserr(recv(fd, buf, count, 0)); + if (ret == -1 && errno == ENOTSOCK) + { + ret = read(fd, buf, count); + } + return ret; +} + +/** + * See header + */ +#undef write +ssize_t windows_write(int fd, void *buf, size_t count) +{ + ssize_t ret; + + ret = wserr(send(fd, buf, count, 0)); + if (ret == -1 && errno == ENOTSOCK) + { + ret = write(fd, buf, count); + } + return ret; +} + +/** + * See header + */ +int poll(struct pollfd *fds, int nfds, int timeout) +{ + return wserr(WSAPoll(fds, nfds, timeout)); +} diff --git a/src/libstrongswan/utils/windows.h b/src/libstrongswan/utils/compat/windows.h index 3761e10ab..fd4f1f196 100644 --- a/src/libstrongswan/utils/windows.h +++ b/src/libstrongswan/utils/compat/windows.h @@ -15,7 +15,7 @@ /** * @defgroup windows windows - * @{ @ingroup utils + * @{ @ingroup compat */ #ifndef WINDOWS_H_ @@ -363,6 +363,49 @@ ssize_t windows_sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen); /** + * read(2) working on files and sockets, cancellable on sockets only + * + * On Windows, there does not seem to be a way how a cancellable read can + * be implemented on Low level I/O functions for files, _pipe()s or stdio. + */ +#define read windows_read +ssize_t windows_read(int fd, void *buf, size_t count); + +/** + * write(2) working on files and sockets + */ +#define write windows_write +ssize_t windows_write(int fd, void *buf, size_t count); + +#if _WIN32_WINNT < 0x0600 +/** + * Define pollfd and flags on our own if not specified + */ +struct pollfd { + SOCKET fd; + short events; + short revents; +}; +enum { + POLLERR = 0x0001, + POLLHUP = 0x0002, + POLLNVAL = 0x0004, + POLLWRNORM = 0x0010, + POLLWRBAND = 0x0020, + POLLPRI = 0x0400, + POLLRDNORM = 0x0100, + POLLRDBAND = 0x0200, + POLLIN = POLLRDNORM | POLLRDBAND, + POLLOUT = POLLWRNORM, +}; +#endif /* _WIN32_WINNT < 0x0600 */ + +/** + * poll(2), implemented using Winsock2 WSAPoll() + */ +int poll(struct pollfd *fds, int nfds, int timeout); + +/** * Declaration missing on older WinGW */ _CRTIMP errno_t strerror_s(char *buf, size_t size, int errnum); diff --git a/src/libstrongswan/utils/enum.c b/src/libstrongswan/utils/enum.c index f96fe2989..089bebb79 100644 --- a/src/libstrongswan/utils/enum.c +++ b/src/libstrongswan/utils/enum.c @@ -60,20 +60,103 @@ bool enum_from_name_as_int(enum_name_t *e, const char *name, int *val) } /** + * Get the position of a flag name using offset calculation + */ +static int find_flag_pos(u_int val, u_int first) +{ + int offset = 0; + + while (val != 0x01) + { + val = val >> 1; + offset++; + } + return first - offset; +} + +/** * Described in header. */ +char *enum_flags_to_string(enum_name_t *e, u_int val, char *buf, size_t len) +{ + char *pos = buf, *delim = ""; + int i, wr; + + if (e->next != ENUM_FLAG_MAGIC) + { + if (snprintf(buf, len, "(%d)", (int)val) >= len) + { + return NULL; + } + return buf; + } + + if (snprintf(buf, len, "(unset)") >= len) + { + return NULL; + } + + for (i = 0; val; i++) + { + u_int flag = 1 << i; + + if (val & flag) + { + char *name = NULL, hex[32]; + + if (flag >= (u_int)e->first && flag <= (u_int)e->last) + { + name = e->names[find_flag_pos(e->first, i)]; + } + else + { + snprintf(hex, sizeof(hex), "(0x%X)", flag); + name = hex; + } + if (name) + { + wr = snprintf(pos, len, "%s%s", delim, name); + if (wr >= len) + { + return NULL; + } + len -= wr; + pos += wr; + delim = " | "; + } + val &= ~flag; + } + } + return buf; +} + +/** + * See header. + */ int enum_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, const void *const *args) { enum_name_t *ed = *((enum_name_t**)(args[0])); int val = *((int*)(args[1])); - char *name, buf[32]; + char *name, buf[512]; - name = enum_to_name(ed, val); - if (name == NULL) + if (ed->next == ENUM_FLAG_MAGIC) + { + name = enum_flags_to_string(ed, val, buf, sizeof(buf)); + if (name == NULL) + { + snprintf(buf, sizeof(buf), "(0x%X)", val); + name = buf; + } + } + else { - snprintf(buf, sizeof(buf), "(%d)", val); - name = buf; + name = enum_to_name(ed, val); + if (name == NULL) + { + snprintf(buf, sizeof(buf), "(%d)", val); + name = buf; + } } if (spec->minus) { diff --git a/src/libstrongswan/utils/enum.h b/src/libstrongswan/utils/enum.h index 3c03c2a7b..928f4079a 100644 --- a/src/libstrongswan/utils/enum.h +++ b/src/libstrongswan/utils/enum.h @@ -27,6 +27,11 @@ typedef struct enum_name_t enum_name_t; /** + * Magic enum_name_t pointer indicating this is an enum name for flags + */ +#define ENUM_FLAG_MAGIC ((enum_name_t*)~(uintptr_t)0) + +/** * Struct to store names for enums. * * To print the string representation of enumeration values, the strings @@ -58,7 +63,7 @@ struct enum_name_t { int first; /** value of the last enum string */ int last; - /** next enum_name_t in list */ + /** next enum_name_t in list, or ENUM_FLAG_MAGIC */ enum_name_t *next; /** array of strings containing names from first to last */ char *names[]; @@ -107,6 +112,23 @@ struct enum_name_t { #define ENUM(name, first, last, ...) ENUM_BEGIN(name, first, last, __VA_ARGS__); ENUM_END(name, last) /** + * Define a enum name with only one range for flags. + * + * Using an enum list for flags would be overkill. Hence we use a single + * range with all values in range. The next pointer is abused to mark + * that the enum name is for flags only. Use NULL if a particular flag + * is not meant to be printed. + * + * @param name name of the enum_name list + * @param first enum value of the first enum string + * @param last enum value of the last enum string + * @param ... a list of strings + */ +#define ENUM_FLAGS(name, first, last, ...) \ + static enum_name_t name##last = {first, last, ENUM_FLAG_MAGIC, { __VA_ARGS__ }}; \ + ENUM_END(name, last) + +/** * Convert a enum value to its string representation. * * @param e enum names for this enum value @@ -146,6 +168,17 @@ char *enum_to_name(enum_name_t *e, int val); bool enum_from_name_as_int(enum_name_t *e, const char *name, int *val); /** + * Convert a enum value containing flags to its string representation. + * + * @param e enum names for this enum value suitable for flags + * @param val enum value to get string for + * @param buf buffer to write flag string to + * @param len buffer size + * @return buf, NULL if buffer too small + */ +char *enum_flags_to_string(enum_name_t *e, u_int val, char *buf, size_t len); + +/** * printf hook function for enum_names_t. * * Arguments are: diff --git a/src/libstrongswan/utils/identification.c b/src/libstrongswan/utils/identification.c index 46ac7e890..b69adf399 100644 --- a/src/libstrongswan/utils/identification.c +++ b/src/libstrongswan/utils/identification.c @@ -17,6 +17,7 @@ #include <string.h> #include <stdio.h> +#include <errno.h> #include "identification.h" @@ -927,6 +928,82 @@ static private_identification_t *identification_create(id_type_t type) return this; } +/** + * Create an identity for a specific type, determined by prefix + */ +static private_identification_t* create_from_string_with_prefix_type(char *str) +{ + struct { + const char *str; + id_type_t type; + } prefixes[] = { + { "ipv4:", ID_IPV4_ADDR }, + { "ipv6:", ID_IPV6_ADDR }, + { "rfc822:", ID_RFC822_ADDR }, + { "email:", ID_RFC822_ADDR }, + { "userfqdn:", ID_USER_FQDN }, + { "fqdn:", ID_FQDN }, + { "dns:", ID_FQDN }, + { "asn1dn:", ID_DER_ASN1_DN }, + { "asn1gn:", ID_DER_ASN1_GN }, + { "keyid:", ID_KEY_ID }, + }; + private_identification_t *this; + int i; + + for (i = 0; i < countof(prefixes); i++) + { + if (strcasepfx(str, prefixes[i].str)) + { + this = identification_create(prefixes[i].type); + str += strlen(prefixes[i].str); + if (*str == '#') + { + this->encoded = chunk_from_hex(chunk_from_str(str + 1), NULL); + } + else + { + this->encoded = chunk_clone(chunk_from_str(str)); + } + return this; + } + } + return NULL; +} + +/** + * Create an identity for a specific type, determined by a numerical prefix + * + * The prefix is of the form "{x}:", where x denotes the numerical identity + * type. + */ +static private_identification_t* create_from_string_with_num_type(char *str) +{ + private_identification_t *this; + u_long type; + + if (*str++ != '{') + { + return NULL; + } + errno = 0; + type = strtoul(str, &str, 0); + if (errno || *str++ != '}' || *str++ != ':') + { + return NULL; + } + this = identification_create(type); + if (*str == '#') + { + this->encoded = chunk_from_hex(chunk_from_str(str + 1), NULL); + } + else + { + this->encoded = chunk_clone(chunk_from_str(str)); + } + return this; +} + /* * Described in header. */ @@ -939,6 +1016,16 @@ identification_t *identification_create_from_string(char *string) { string = "%any"; } + this = create_from_string_with_prefix_type(string); + if (this) + { + return &this->public; + } + this = create_from_string_with_num_type(string); + if (this) + { + return &this->public; + } if (strchr(string, '=') != NULL) { /* we interpret this as an ASCII X.501 ID_DER_ASN1_DN. diff --git a/src/libstrongswan/utils/identification.h b/src/libstrongswan/utils/identification.h index e62446879..e6a9fe1c6 100644 --- a/src/libstrongswan/utils/identification.h +++ b/src/libstrongswan/utils/identification.h @@ -302,6 +302,15 @@ struct identification_t { * N, G, I, dnQualifier, ID, EN, EmployeeNumber, E, Email, emailAddress, UN, * unstructuredName, TCGID. * + * To skip automatic type detection the following prefixes may be used to + * enforce a specific type: ipv4:, ipv6:, rfc822:, email:, userfqdn:, fqdn:, + * dns:, asn1dn:, asn1gn: and keyid:. If a # follows the :, the remaining data + * is interpreted as hex encoded binary data for that ID, otherwise the raw + * string following the prefix is used as identity data, without conversion. + * To specify a non-standard ID type, the numerical type may be prefixed + * between curly backets, building a prefix. For instance the "{1}:" prefix + * defines an ID_IPV4_ADDR type. + * * This constructor never returns NULL. If it does not find a suitable * conversion function, it will copy the string to an ID_KEY_ID. * diff --git a/src/libstrongswan/utils/utils.h b/src/libstrongswan/utils/utils.h index da253cc35..7c48d949f 100644 --- a/src/libstrongswan/utils/utils.h +++ b/src/libstrongswan/utils/utils.h @@ -29,7 +29,7 @@ #include <string.h> #ifdef WIN32 -# include "windows.h" +# include "compat/windows.h" #else # define _GNU_SOURCE # include <arpa/inet.h> @@ -37,6 +37,7 @@ # include <netdb.h> # include <netinet/in.h> # include <sched.h> +# include <poll.h> #endif /** @@ -96,6 +97,9 @@ #include "enum.h" #include "utils/strerror.h" +#ifdef __APPLE__ +# include "compat/apple.h" +#endif /** * Directory separator character in paths on this platform diff --git a/src/libtls/Makefile.in b/src/libtls/Makefile.in index 426d8bcb3..e6c23d970 100644 --- a/src/libtls/Makefile.in +++ b/src/libtls/Makefile.in @@ -278,6 +278,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -338,10 +339,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -415,6 +418,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libtls/tests/Makefile.in b/src/libtls/tests/Makefile.in index 2e44fb4a5..7d5b3771c 100644 --- a/src/libtls/tests/Makefile.in +++ b/src/libtls/tests/Makefile.in @@ -223,6 +223,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -283,10 +284,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -360,6 +363,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libtls/tls.c b/src/libtls/tls.c index 6a8d5030c..08a06f5ef 100644 --- a/src/libtls/tls.c +++ b/src/libtls/tls.c @@ -415,6 +415,12 @@ METHOD(tls_t, get_eap_msk, chunk_t, return this->crypto->get_eap_msk(this->crypto); } +METHOD(tls_t, get_auth, auth_cfg_t*, + private_tls_t *this) +{ + return this->handshake->get_auth(this->handshake); +} + METHOD(tls_t, destroy, void, private_tls_t *this) { @@ -465,6 +471,7 @@ tls_t *tls_create(bool is_server, identification_t *server, .get_purpose = _get_purpose, .is_complete = _is_complete, .get_eap_msk = _get_eap_msk, + .get_auth = _get_auth, .destroy = _destroy, }, .is_server = is_server, @@ -487,7 +494,7 @@ tls_t *tls_create(bool is_server, identification_t *server, this->alert, peer, server)->handshake; } this->fragmentation = tls_fragmentation_create(this->handshake, this->alert, - this->application); + this->application, purpose); this->compression = tls_compression_create(this->fragmentation, this->alert); this->protection = tls_protection_create(this->compression, this->alert); this->crypto->set_protection(this->crypto, this->protection); diff --git a/src/libtls/tls.h b/src/libtls/tls.h index fc1d9b9fd..f3dc198cf 100644 --- a/src/libtls/tls.h +++ b/src/libtls/tls.h @@ -252,6 +252,13 @@ struct tls_t { chunk_t (*get_eap_msk)(tls_t *this); /** + * Get the authentication details after completing the handshake. + * + * @return authentication details, internal data + */ + auth_cfg_t* (*get_auth)(tls_t *this); + + /** * Destroy a tls_t. */ void (*destroy)(tls_t *this); diff --git a/src/libtls/tls_eap.c b/src/libtls/tls_eap.c index ebe5bc3a8..12d5aed53 100644 --- a/src/libtls/tls_eap.c +++ b/src/libtls/tls_eap.c @@ -426,6 +426,12 @@ METHOD(tls_eap_t, set_identifier, void, this->identifier = identifier; } +METHOD(tls_eap_t, get_auth, auth_cfg_t*, + private_tls_eap_t *this) +{ + return this->tls->get_auth(this->tls); +} + METHOD(tls_eap_t, destroy, void, private_tls_eap_t *this) { @@ -453,6 +459,7 @@ tls_eap_t *tls_eap_create(eap_type_t type, tls_t *tls, size_t frag_size, .get_msk = _get_msk, .get_identifier = _get_identifier, .set_identifier = _set_identifier, + .get_auth = _get_auth, .destroy = _destroy, }, .type = type, diff --git a/src/libtls/tls_eap.h b/src/libtls/tls_eap.h index f3fbba078..df41fc4d7 100644 --- a/src/libtls/tls_eap.h +++ b/src/libtls/tls_eap.h @@ -77,6 +77,13 @@ struct tls_eap_t { void (*set_identifier) (tls_eap_t *this, uint8_t identifier); /** + * Get the authentication details after completing the handshake. + * + * @return authentication details, internal data + */ + auth_cfg_t* (*get_auth)(tls_eap_t *this); + + /** * Destroy a tls_eap_t. */ void (*destroy)(tls_eap_t *this); diff --git a/src/libtls/tls_fragmentation.c b/src/libtls/tls_fragmentation.c index 6e4347e3c..a97ca1eaa 100644 --- a/src/libtls/tls_fragmentation.c +++ b/src/libtls/tls_fragmentation.c @@ -96,9 +96,32 @@ struct private_tls_fragmentation_t { * Upper layer application data protocol */ tls_application_t *application; + + /** + * Type of context this TLS instance runs in + */ + tls_purpose_t purpose; }; /** + * Check if we should send a close notify once the application finishes + */ +static bool send_close_notify(private_tls_fragmentation_t *this) +{ + switch (this->purpose) + { + case TLS_PURPOSE_EAP_TLS: + case TLS_PURPOSE_EAP_TTLS: + case TLS_PURPOSE_EAP_PEAP: + /* not for TLS-in-EAP, as we indicate completion with EAP-SUCCCESS. + * Windows does not like close notifies, and hangs/disconnects. */ + return FALSE; + default: + return TRUE; + } +} + +/** * Process a TLS alert */ static status_t process_alert(private_tls_fragmentation_t *this, @@ -223,6 +246,10 @@ static status_t process_application(private_tls_fragmentation_t *this, continue; case SUCCESS: this->application_finished = TRUE; + if (!send_close_notify(this)) + { + return SUCCESS; + } /* FALL */ case FAILED: default: @@ -368,6 +395,10 @@ static status_t build_application(private_tls_fragmentation_t *this) break; case SUCCESS: this->application_finished = TRUE; + if (!send_close_notify(this)) + { + break; + } /* FALL */ case FAILED: default: @@ -463,7 +494,8 @@ METHOD(tls_fragmentation_t, destroy, void, * See header */ tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake, - tls_alert_t *alert, tls_application_t *application) + tls_alert_t *alert, tls_application_t *application, + tls_purpose_t purpose) { private_tls_fragmentation_t *this; @@ -478,6 +510,7 @@ tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake, .alert = alert, .state = ALERT_NONE, .application = application, + .purpose = purpose, ); return &this->public; diff --git a/src/libtls/tls_fragmentation.h b/src/libtls/tls_fragmentation.h index f650e7be8..a49f27b20 100644 --- a/src/libtls/tls_fragmentation.h +++ b/src/libtls/tls_fragmentation.h @@ -80,9 +80,11 @@ struct tls_fragmentation_t { * @param handshake upper layer handshake protocol * @param alert TLS alert handler * @param application upper layer application data or NULL + * @param purpose type of context this TLS stack is running in * @return TLS fragmentation layer */ tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake, - tls_alert_t *alert, tls_application_t *application); + tls_alert_t *alert, tls_application_t *application, + tls_purpose_t purpose); #endif /** TLS_FRAGMENTATION_H_ @}*/ diff --git a/src/libtls/tls_handshake.h b/src/libtls/tls_handshake.h index 7fa660c58..7edb49ba0 100644 --- a/src/libtls/tls_handshake.h +++ b/src/libtls/tls_handshake.h @@ -98,6 +98,13 @@ struct tls_handshake_t { identification_t* (*get_server_id)(tls_handshake_t *this); /** + * Get the peers authentication information after completing the handshake. + * + * @return authentication data, internal data + */ + auth_cfg_t* (*get_auth)(tls_handshake_t *this); + + /** * Destroy a tls_handshake_t. */ void (*destroy)(tls_handshake_t *this); diff --git a/src/libtls/tls_peer.c b/src/libtls/tls_peer.c index a95b40f55..e6be36b7b 100644 --- a/src/libtls/tls_peer.c +++ b/src/libtls/tls_peer.c @@ -312,7 +312,7 @@ static status_t process_certificate(private_tls_peer_t *this, static public_key_t *find_public_key(private_tls_peer_t *this) { public_key_t *public = NULL, *current; - certificate_t *cert; + certificate_t *cert, *found; enumerator_t *enumerator; auth_cfg_t *auth; @@ -323,8 +323,13 @@ static public_key_t *find_public_key(private_tls_peer_t *this) KEY_ANY, cert->get_subject(cert), this->server_auth); while (enumerator->enumerate(enumerator, ¤t, &auth)) { - public = current->get_ref(current); - break; + found = auth->get(auth, AUTH_RULE_SUBJECT_CERT); + if (found && cert->equals(cert, found)) + { + public = current->get_ref(current); + this->server_auth->merge(this->server_auth, auth, FALSE); + break; + } } enumerator->destroy(enumerator); } @@ -379,7 +384,12 @@ static status_t process_modp_key_exchange(private_tls_peer_t *this, this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); return NEED_MORE; } - this->dh->set_other_public_value(this->dh, pub); + if (!this->dh->set_other_public_value(this->dh, pub)) + { + DBG1(DBG_TLS, "applying DH public value failed"); + this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); + return NEED_MORE; + } this->state = STATE_KEY_EXCHANGE_RECEIVED; return NEED_MORE; @@ -489,7 +499,12 @@ static status_t process_ec_key_exchange(private_tls_peer_t *this, this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); return NEED_MORE; } - this->dh->set_other_public_value(this->dh, chunk_skip(pub, 1)); + if (!this->dh->set_other_public_value(this->dh, chunk_skip(pub, 1))) + { + DBG1(DBG_TLS, "applying DH public value failed"); + this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); + return NEED_MORE; + } this->state = STATE_KEY_EXCHANGE_RECEIVED; return NEED_MORE; @@ -968,7 +983,7 @@ static status_t send_key_exchange_dhe(private_tls_peer_t *this, { chunk_t premaster, pub; - if (this->dh->get_shared_secret(this->dh, &premaster) != SUCCESS) + if (!this->dh->get_shared_secret(this->dh, &premaster)) { DBG1(DBG_TLS, "calculating premaster from DH failed"); this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); @@ -985,7 +1000,11 @@ static status_t send_key_exchange_dhe(private_tls_peer_t *this, } chunk_clear(&premaster); - this->dh->get_my_public_value(this->dh, &pub); + if (!this->dh->get_my_public_value(this->dh, &pub)) + { + this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); + return NEED_MORE; + } if (this->dh->get_dh_group(this->dh) == MODP_CUSTOM) { writer->write_data16(writer, pub); @@ -1153,6 +1172,12 @@ METHOD(tls_handshake_t, get_server_id, identification_t*, return this->server; } +METHOD(tls_handshake_t, get_auth, auth_cfg_t*, + private_tls_peer_t *this) +{ + return this->server_auth; +} + METHOD(tls_handshake_t, destroy, void, private_tls_peer_t *this) { @@ -1186,6 +1211,7 @@ tls_peer_t *tls_peer_create(tls_t *tls, tls_crypto_t *crypto, tls_alert_t *alert .finished = _finished, .get_peer_id = _get_peer_id, .get_server_id = _get_server_id, + .get_auth = _get_auth, .destroy = _destroy, }, }, diff --git a/src/libtls/tls_protection.c b/src/libtls/tls_protection.c index b016db21f..e73fedc5d 100644 --- a/src/libtls/tls_protection.c +++ b/src/libtls/tls_protection.c @@ -101,14 +101,13 @@ METHOD(tls_protection_t, build, status_t, status_t status; status = this->compression->build(this->compression, type, data); - if (*type == TLS_CHANGE_CIPHER_SPEC) - { - this->seq_out = 0; - return status; - } - if (status == NEED_MORE) { + if (*type == TLS_CHANGE_CIPHER_SPEC) + { + this->seq_out = 0; + return status; + } if (this->aead_out) { if (!this->aead_out->encrypt(this->aead_out, this->version, diff --git a/src/libtls/tls_server.c b/src/libtls/tls_server.c index aeb5a714f..b1a214f7f 100644 --- a/src/libtls/tls_server.c +++ b/src/libtls/tls_server.c @@ -494,8 +494,13 @@ static status_t process_key_exchange_dhe(private_tls_server_t *this, } pub = chunk_skip(pub, 1); } - this->dh->set_other_public_value(this->dh, pub); - if (this->dh->get_shared_secret(this->dh, &premaster) != SUCCESS) + if (!this->dh->set_other_public_value(this->dh, pub)) + { + DBG1(DBG_TLS, "applying DH public value failed"); + this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); + return NEED_MORE; + } + if (!this->dh->get_shared_secret(this->dh, &premaster)) { DBG1(DBG_TLS, "calculating premaster from DH failed"); this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); @@ -551,6 +556,7 @@ static status_t process_cert_verify(private_tls_server_t *this, sig->destroy(sig); if (verified) { + this->peer_auth->merge(this->peer_auth, auth, FALSE); break; } DBG1(DBG_TLS, "signature verification failed, trying another key"); @@ -914,7 +920,11 @@ static status_t send_server_key_exchange(private_tls_server_t *this, this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); return NEED_MORE; } - this->dh->get_my_public_value(this->dh, &chunk); + if (!this->dh->get_my_public_value(this->dh, &chunk)) + { + this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); + return NEED_MORE; + } if (params) { writer->write_data16(writer, chunk); @@ -1073,6 +1083,12 @@ METHOD(tls_handshake_t, get_server_id, identification_t*, return this->server; } +METHOD(tls_handshake_t, get_auth, auth_cfg_t*, + private_tls_server_t *this) +{ + return this->peer_auth; +} + METHOD(tls_handshake_t, destroy, void, private_tls_server_t *this) { @@ -1107,6 +1123,7 @@ tls_server_t *tls_server_create(tls_t *tls, .finished = _finished, .get_peer_id = _get_peer_id, .get_server_id = _get_server_id, + .get_auth = _get_auth, .destroy = _destroy, }, }, diff --git a/src/libtls/tls_socket.c b/src/libtls/tls_socket.c index 648771e75..2ccd97571 100644 --- a/src/libtls/tls_socket.c +++ b/src/libtls/tls_socket.c @@ -291,25 +291,24 @@ METHOD(tls_socket_t, splice, bool, private_tls_socket_t *this, int rfd, int wfd) { char buf[PLAIN_BUF_SIZE], *pos; - fd_set set; ssize_t in, out; bool old, plain_eof = FALSE, crypto_eof = FALSE; + struct pollfd pfd[] = { + { .fd = this->fd, .events = POLLIN, }, + { .fd = rfd, .events = POLLIN, }, + }; while (!plain_eof && !crypto_eof) { - FD_ZERO(&set); - FD_SET(rfd, &set); - FD_SET(this->fd, &set); - old = thread_cancelability(TRUE); - in = select(max(rfd, this->fd) + 1, &set, NULL, NULL, NULL); + in = poll(pfd, countof(pfd), -1); thread_cancelability(old); if (in == -1) { DBG1(DBG_TLS, "TLS select error: %s", strerror(errno)); return FALSE; } - while (!plain_eof && FD_ISSET(this->fd, &set)) + while (!plain_eof && pfd[0].revents & (POLLIN | POLLHUP | POLLNVAL)) { in = read_(this, buf, sizeof(buf), FALSE); switch (in) @@ -342,7 +341,7 @@ METHOD(tls_socket_t, splice, bool, } break; } - if (!crypto_eof && FD_ISSET(rfd, &set)) + if (!crypto_eof && pfd[1].revents & (POLLIN | POLLHUP | POLLNVAL)) { in = read(rfd, buf, sizeof(buf)); switch (in) diff --git a/src/libtnccs/Android.mk b/src/libtnccs/Android.mk index 68f85c252..e37973202 100644 --- a/src/libtnccs/Android.mk +++ b/src/libtnccs/Android.mk @@ -22,7 +22,7 @@ endif LOCAL_SRC_FILES += $(call add_plugin, tnc-tnccs) LOCAL_SRC_FILES += $(call add_plugin, tnccs-20) -LOCAL_SRC_FILES += $(call add_plugin_subdirs, tnccs-20, batch messages messages/ietf messages/tcg state_machine) +LOCAL_SRC_FILES += $(call add_plugin_subdirs, tnccs-20, batch messages messages/ietf messages/ita messages/tcg state_machine) ifneq ($(call plugin_enabled, tnccs-20),) LOCAL_C_INCLUDES += $(LOCAL_PATH)/plugins/tnccs_20/ endif diff --git a/src/libtnccs/Makefile.in b/src/libtnccs/Makefile.in index b0bfdf20d..dc8c1b8cc 100644 --- a/src/libtnccs/Makefile.in +++ b/src/libtnccs/Makefile.in @@ -283,6 +283,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -343,10 +344,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -420,6 +423,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libtnccs/plugins/tnc_imc/Makefile.in b/src/libtnccs/plugins/tnc_imc/Makefile.in index 2b76aabe6..3641bdf5b 100644 --- a/src/libtnccs/plugins/tnc_imc/Makefile.in +++ b/src/libtnccs/plugins/tnc_imc/Makefile.in @@ -231,6 +231,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.c b/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.c index 859dded79..ce5b48133 100644 --- a/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.c +++ b/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.c @@ -44,6 +44,7 @@ METHOD(plugin_t, get_features, int, PLUGIN_CALLBACK(tnc_manager_register, tnc_imc_manager_create), PLUGIN_PROVIDE(CUSTOM, "imc-manager"), PLUGIN_DEPENDS(CUSTOM, "tnccs-manager"), + PLUGIN_SDEPEND(CUSTOM, "imv-manager"), PLUGIN_SDEPEND(CERT_DECODE, CERT_X509), PLUGIN_SDEPEND(CERT_DECODE, CERT_TRUSTED_PUBKEY), }; diff --git a/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.h b/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.h index 8c5521cb2..8cbc70367 100644 --- a/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.h +++ b/src/libtnccs/plugins/tnc_imc/tnc_imc_plugin.h @@ -15,7 +15,7 @@ /** * @defgroup tnc_imc tnc_imc - * @ingroup cplugins + * @ingroup tplugins * * @defgroup tnc_imc_plugin tnc_imc_plugin * @{ @ingroup tnc_imc diff --git a/src/libtnccs/plugins/tnc_imv/Makefile.in b/src/libtnccs/plugins/tnc_imv/Makefile.in index 06e7b0480..c4b1bee23 100644 --- a/src/libtnccs/plugins/tnc_imv/Makefile.in +++ b/src/libtnccs/plugins/tnc_imv/Makefile.in @@ -232,6 +232,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -292,10 +293,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -369,6 +372,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libtnccs/plugins/tnc_imv/tnc_imv_plugin.h b/src/libtnccs/plugins/tnc_imv/tnc_imv_plugin.h index afeee2ea2..5786bbaab 100644 --- a/src/libtnccs/plugins/tnc_imv/tnc_imv_plugin.h +++ b/src/libtnccs/plugins/tnc_imv/tnc_imv_plugin.h @@ -15,7 +15,7 @@ /** * @defgroup tnc_imv tnc_imv - * @ingroup cplugins + * @ingroup tplugins * * @defgroup tnc_imv_plugin tnc_imv_plugin * @{ @ingroup tnc_imv diff --git a/src/libtnccs/plugins/tnc_tnccs/Makefile.in b/src/libtnccs/plugins/tnc_tnccs/Makefile.in index 8910fe761..5b01e317a 100644 --- a/src/libtnccs/plugins/tnc_tnccs/Makefile.in +++ b/src/libtnccs/plugins/tnc_tnccs/Makefile.in @@ -231,6 +231,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_manager.c b/src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_manager.c index b8683f78c..30e505246 100644 --- a/src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_manager.c +++ b/src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_manager.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2013 Andreas Steffen + * Copyright (C) 2010-2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -169,8 +169,8 @@ METHOD(tnccs_manager_t, remove_method, void, METHOD(tnccs_manager_t, create_instance, tnccs_t*, private_tnc_tnccs_manager_t *this, tnccs_type_t type, bool is_server, - identification_t *server, identification_t *peer, tnc_ift_type_t transport, - tnccs_cb_t cb) + identification_t *server_id, identification_t *peer_id, host_t *server_ip, + host_t *peer_ip, tnc_ift_type_t transport, tnccs_cb_t cb) { enumerator_t *enumerator; tnccs_entry_t *entry; @@ -182,7 +182,8 @@ METHOD(tnccs_manager_t, create_instance, tnccs_t*, { if (type == entry->type) { - protocol = entry->constructor(is_server, server, peer, transport, cb); + protocol = entry->constructor(is_server, server_id, peer_id, + server_ip, peer_ip, transport, cb); if (protocol) { break; @@ -716,7 +717,8 @@ METHOD(tnccs_manager_t, get_attribute, TNC_Result, case TNC_ATTRIBUTEID_AR_IDENTITIES: { linked_list_t *list; - identification_t *peer; + identification_t *peer_id; + host_t *peer_ip; tnccs_t *tnccs; tncif_identity_t *tnc_id; u_int32_t id_type, subject_type; @@ -726,10 +728,11 @@ METHOD(tnccs_manager_t, get_attribute, TNC_Result, list = linked_list_create(); tnccs = entry->tnccs; - peer = tnccs->tls.get_peer_id(&tnccs->tls); - if (peer) + + peer_id = tnccs->tls.get_peer_id(&tnccs->tls); + if (peer_id) { - switch (peer->get_type(peer)) + switch (peer_id->get_type(peer_id)) { case ID_IPV4_ADDR: id_type = TNC_ID_IPV4_ADDR; @@ -756,7 +759,7 @@ METHOD(tnccs_manager_t, get_attribute, TNC_Result, subject_type = TNC_SUBJECT_UNKNOWN; } if (id_type != TNC_ID_UNKNOWN && - asprintf(&id_str, "%Y", peer) >= 0) + asprintf(&id_str, "%Y", peer_id) >= 0) { id_value = chunk_from_str(id_str); tnc_id = tncif_identity_create( @@ -767,6 +770,33 @@ METHOD(tnccs_manager_t, get_attribute, TNC_Result, list->insert_last(list, tnc_id); } } + + peer_ip = tnccs->get_peer_ip(tnccs); + if (peer_ip) + { + switch (peer_ip->get_family(peer_ip)) + { + case AF_INET: + id_type = TNC_ID_IPV4_ADDR; + break; + case AF_INET6: + id_type = TNC_ID_IPV6_ADDR; + break; + default: + id_type = TNC_ID_UNKNOWN; + } + + if (id_type != TNC_ID_UNKNOWN && + asprintf(&id_str, "%H", peer_ip) >= 0) + { + id_value = chunk_from_str(id_str); + tnc_id = tncif_identity_create( + pen_type_create(PEN_TCG, id_type), id_value, + pen_type_create(PEN_TCG, TNC_SUBJECT_MACHINE), + pen_type_create(PEN_TCG, TNC_AUTH_UNKNOWN)); + list->insert_last(list, tnc_id); + } + } result = identity_attribute(buffer_len, buffer, value_len, list); list->destroy_offset(list, offsetof(tncif_identity_t, destroy)); return result; diff --git a/src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_plugin.h b/src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_plugin.h index f935fa462..c99d5e7c8 100644 --- a/src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_plugin.h +++ b/src/libtnccs/plugins/tnc_tnccs/tnc_tnccs_plugin.h @@ -15,7 +15,7 @@ /** * @defgroup tnc_tnccs tnc_tnccs - * @ingroup cplugins + * @ingroup tplugins * * @defgroup tnc_tnccs_plugin tnc_tnccs_plugin * @{ @ingroup tnc_tnccs diff --git a/src/libtnccs/plugins/tnccs_11/Makefile.in b/src/libtnccs/plugins/tnccs_11/Makefile.in index ea6ac5546..e0c039af9 100644 --- a/src/libtnccs/plugins/tnccs_11/Makefile.in +++ b/src/libtnccs/plugins/tnccs_11/Makefile.in @@ -241,6 +241,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -301,10 +302,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -378,6 +381,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libtnccs/plugins/tnccs_11/tnccs_11.c b/src/libtnccs/plugins/tnccs_11/tnccs_11.c index 28c5e52b7..0918a2bad 100644 --- a/src/libtnccs/plugins/tnccs_11/tnccs_11.c +++ b/src/libtnccs/plugins/tnccs_11/tnccs_11.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2013 Andreas Steffen + * Copyright (C) 2010-2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -54,12 +54,22 @@ struct private_tnccs_11_t { /** * Server identity */ - identification_t *server; + identification_t *server_id; /** * Client identity */ - identification_t *peer; + identification_t *peer_id; + + /** + * Server IP address + */ + host_t *server_ip; + + /** + * Client IP address + */ + host_t *peer_ip; /** * Underlying TNC IF-T transport protocol @@ -527,20 +537,20 @@ METHOD(tls_t, is_server, bool, METHOD(tls_t, get_server_id, identification_t*, private_tnccs_11_t *this) { - return this->server; + return this->server_id; } METHOD(tls_t, set_peer_id, void, private_tnccs_11_t *this, identification_t *id) { - DESTROY_IF(this->peer); - this->peer = id->clone(id); + DESTROY_IF(this->peer_id); + this->peer_id = id->clone(id); } METHOD(tls_t, get_peer_id, identification_t*, private_tnccs_11_t *this) { - return this->peer; + return this->peer_id; } METHOD(tls_t, get_purpose, tls_purpose_t, @@ -578,14 +588,28 @@ METHOD(tls_t, destroy, void, { tnc->tnccs->remove_connection(tnc->tnccs, this->connection_id, this->is_server); - this->server->destroy(this->server); - this->peer->destroy(this->peer); + this->server_id->destroy(this->server_id); + this->peer_id->destroy(this->peer_id); + this->server_ip->destroy(this->server_ip); + this->peer_ip->destroy(this->peer_ip); this->mutex->destroy(this->mutex); DESTROY_IF(this->batch); free(this); } } +METHOD(tnccs_t, get_server_ip, host_t*, + private_tnccs_11_t *this) +{ + return this->server_ip; +} + +METHOD(tnccs_t, get_peer_ip, host_t*, + private_tnccs_11_t *this) +{ + return this->peer_ip; +} + METHOD(tnccs_t, get_transport, tnc_ift_type_t, private_tnccs_11_t *this) { @@ -628,9 +652,10 @@ METHOD(tnccs_t, get_ref, tnccs_t*, /** * See header */ -tnccs_t* tnccs_11_create(bool is_server, - identification_t *server, identification_t *peer, - tnc_ift_type_t transport, tnccs_cb_t cb) +tnccs_t* tnccs_11_create(bool is_server, identification_t *server_id, + identification_t *peer_id, host_t *server_ip, + host_t *peer_ip, tnc_ift_type_t transport, + tnccs_cb_t cb) { private_tnccs_11_t *this; @@ -648,6 +673,8 @@ tnccs_t* tnccs_11_create(bool is_server, .get_eap_msk = _get_eap_msk, .destroy = _destroy, }, + .get_server_ip = _get_server_ip, + .get_peer_ip = _get_peer_ip, .get_transport = _get_transport, .set_transport = _set_transport, .get_auth_type = _get_auth_type, @@ -656,8 +683,10 @@ tnccs_t* tnccs_11_create(bool is_server, .get_ref = _get_ref, }, .is_server = is_server, - .server = server->clone(server), - .peer = peer->clone(peer), + .server_id = server_id->clone(server_id), + .peer_id = peer_id->clone(peer_id), + .server_ip = server_ip->clone(server_ip), + .peer_ip = peer_ip->clone(peer_ip), .transport = transport, .callback = cb, .mutex = mutex_create(MUTEX_TYPE_DEFAULT), diff --git a/src/libtnccs/plugins/tnccs_11/tnccs_11.h b/src/libtnccs/plugins/tnccs_11/tnccs_11.h index e805df8bb..60d5518bc 100644 --- a/src/libtnccs/plugins/tnccs_11/tnccs_11.h +++ b/src/libtnccs/plugins/tnccs_11/tnccs_11.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2013 Andreas Steffen + * Copyright (C) 2010-2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -29,14 +29,17 @@ * Create an instance of the TNC IF-TNCCS 1.1 protocol handler. * * @param is_server TRUE to act as TNC Server, FALSE for TNC Client - * @param server Server identity - * @param peer Client identity + * @param server_id Server identity + * @param peer_id Client identity + * @param server_ip Server IP address + * @param peer_ip Client IP address * @param transport Underlying IF-T transport protocol * @param cb Callback function if TNC Server, NULL if TNC Client * @return TNC_IF_TNCCS 1.1 protocol stack */ -tnccs_t* tnccs_11_create(bool is_server, - identification_t *server, identification_t *peer, - tnc_ift_type_t transport, tnccs_cb_t cb); +tnccs_t* tnccs_11_create(bool is_server, identification_t *server_id, + identification_t *peer_id, host_t *server_ip, + host_t *peer_ip, tnc_ift_type_t transport, + tnccs_cb_t cb); #endif /** TNCCS_11_H_ @}*/ diff --git a/src/libtnccs/plugins/tnccs_11/tnccs_11_plugin.h b/src/libtnccs/plugins/tnccs_11/tnccs_11_plugin.h index 619a073ad..73ea5759b 100644 --- a/src/libtnccs/plugins/tnccs_11/tnccs_11_plugin.h +++ b/src/libtnccs/plugins/tnccs_11/tnccs_11_plugin.h @@ -15,7 +15,7 @@ /** * @defgroup tnccs_11 tnccs_11 - * @ingroup cplugins + * @ingroup tplugins * * @defgroup tnccs_11_plugin tnccs_11_plugin * @{ @ingroup tnccs_11 diff --git a/src/libtnccs/plugins/tnccs_20/Makefile.am b/src/libtnccs/plugins/tnccs_20/Makefile.am index 2aefecd26..7d1cdded1 100644 --- a/src/libtnccs/plugins/tnccs_20/Makefile.am +++ b/src/libtnccs/plugins/tnccs_20/Makefile.am @@ -18,6 +18,8 @@ endif libstrongswan_tnccs_20_la_SOURCES = \ tnccs_20_plugin.h tnccs_20_plugin.c tnccs_20.h tnccs_20.c \ + tnccs_20_handler.h \ + tnccs_20_server.h tnccs_20_server.c tnccs_20_client.h tnccs_20_client.c \ batch/pb_tnc_batch.h batch/pb_tnc_batch.c \ messages/pb_tnc_msg.h messages/pb_tnc_msg.c \ messages/ietf/pb_experimental_msg.h messages/ietf/pb_experimental_msg.c \ @@ -28,6 +30,8 @@ libstrongswan_tnccs_20_la_SOURCES = \ messages/ietf/pb_language_preference_msg.h messages/ietf/pb_language_preference_msg.c \ messages/ietf/pb_reason_string_msg.h messages/ietf/pb_reason_string_msg.c \ messages/ietf/pb_remediation_parameters_msg.h messages/ietf/pb_remediation_parameters_msg.c \ + messages/ita/pb_mutual_capability_msg.h messages/ita/pb_mutual_capability_msg.c \ + messages/ita/pb_noskip_test_msg.h messages/ita/pb_noskip_test_msg.c \ messages/tcg/pb_pdp_referral_msg.h messages/tcg/pb_pdp_referral_msg.c \ state_machine/pb_tnc_state_machine.h state_machine/pb_tnc_state_machine.c diff --git a/src/libtnccs/plugins/tnccs_20/Makefile.in b/src/libtnccs/plugins/tnccs_20/Makefile.in index 90c804710..17d997f76 100644 --- a/src/libtnccs/plugins/tnccs_20/Makefile.in +++ b/src/libtnccs/plugins/tnccs_20/Makefile.in @@ -132,8 +132,8 @@ LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) @MONOLITHIC_FALSE@ $(top_builddir)/src/libtnccs/libtnccs.la am__dirstamp = $(am__leading_dot)dirstamp am_libstrongswan_tnccs_20_la_OBJECTS = tnccs_20_plugin.lo tnccs_20.lo \ - batch/pb_tnc_batch.lo messages/pb_tnc_msg.lo \ - messages/ietf/pb_experimental_msg.lo \ + tnccs_20_server.lo tnccs_20_client.lo batch/pb_tnc_batch.lo \ + messages/pb_tnc_msg.lo messages/ietf/pb_experimental_msg.lo \ messages/ietf/pb_pa_msg.lo \ messages/ietf/pb_assessment_result_msg.lo \ messages/ietf/pb_access_recommendation_msg.lo \ @@ -141,6 +141,8 @@ am_libstrongswan_tnccs_20_la_OBJECTS = tnccs_20_plugin.lo tnccs_20.lo \ messages/ietf/pb_language_preference_msg.lo \ messages/ietf/pb_reason_string_msg.lo \ messages/ietf/pb_remediation_parameters_msg.lo \ + messages/ita/pb_mutual_capability_msg.lo \ + messages/ita/pb_noskip_test_msg.lo \ messages/tcg/pb_pdp_referral_msg.lo \ state_machine/pb_tnc_state_machine.lo libstrongswan_tnccs_20_la_OBJECTS = \ @@ -242,6 +244,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -302,10 +305,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -379,6 +384,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ @@ -454,6 +461,8 @@ AM_CFLAGS = \ libstrongswan_tnccs_20_la_SOURCES = \ tnccs_20_plugin.h tnccs_20_plugin.c tnccs_20.h tnccs_20.c \ + tnccs_20_handler.h \ + tnccs_20_server.h tnccs_20_server.c tnccs_20_client.h tnccs_20_client.c \ batch/pb_tnc_batch.h batch/pb_tnc_batch.c \ messages/pb_tnc_msg.h messages/pb_tnc_msg.c \ messages/ietf/pb_experimental_msg.h messages/ietf/pb_experimental_msg.c \ @@ -464,6 +473,8 @@ libstrongswan_tnccs_20_la_SOURCES = \ messages/ietf/pb_language_preference_msg.h messages/ietf/pb_language_preference_msg.c \ messages/ietf/pb_reason_string_msg.h messages/ietf/pb_reason_string_msg.c \ messages/ietf/pb_remediation_parameters_msg.h messages/ietf/pb_remediation_parameters_msg.c \ + messages/ita/pb_mutual_capability_msg.h messages/ita/pb_mutual_capability_msg.c \ + messages/ita/pb_noskip_test_msg.h messages/ita/pb_noskip_test_msg.c \ messages/tcg/pb_pdp_referral_msg.h messages/tcg/pb_pdp_referral_msg.c \ state_machine/pb_tnc_state_machine.h state_machine/pb_tnc_state_machine.c @@ -590,6 +601,17 @@ messages/ietf/pb_reason_string_msg.lo: messages/ietf/$(am__dirstamp) \ messages/ietf/pb_remediation_parameters_msg.lo: \ messages/ietf/$(am__dirstamp) \ messages/ietf/$(DEPDIR)/$(am__dirstamp) +messages/ita/$(am__dirstamp): + @$(MKDIR_P) messages/ita + @: > messages/ita/$(am__dirstamp) +messages/ita/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) messages/ita/$(DEPDIR) + @: > messages/ita/$(DEPDIR)/$(am__dirstamp) +messages/ita/pb_mutual_capability_msg.lo: \ + messages/ita/$(am__dirstamp) \ + messages/ita/$(DEPDIR)/$(am__dirstamp) +messages/ita/pb_noskip_test_msg.lo: messages/ita/$(am__dirstamp) \ + messages/ita/$(DEPDIR)/$(am__dirstamp) messages/tcg/$(am__dirstamp): @$(MKDIR_P) messages/tcg @: > messages/tcg/$(am__dirstamp) @@ -618,6 +640,8 @@ mostlyclean-compile: -rm -f messages/*.lo -rm -f messages/ietf/*.$(OBJEXT) -rm -f messages/ietf/*.lo + -rm -f messages/ita/*.$(OBJEXT) + -rm -f messages/ita/*.lo -rm -f messages/tcg/*.$(OBJEXT) -rm -f messages/tcg/*.lo -rm -f state_machine/*.$(OBJEXT) @@ -627,7 +651,9 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_20.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_20_client.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_20_plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_20_server.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@batch/$(DEPDIR)/pb_tnc_batch.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@messages/$(DEPDIR)/pb_tnc_msg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@messages/ietf/$(DEPDIR)/pb_access_recommendation_msg.Plo@am__quote@ @@ -638,6 +664,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@messages/ietf/$(DEPDIR)/pb_pa_msg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@messages/ietf/$(DEPDIR)/pb_reason_string_msg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@messages/ietf/$(DEPDIR)/pb_remediation_parameters_msg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@messages/ita/$(DEPDIR)/pb_mutual_capability_msg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@messages/ita/$(DEPDIR)/pb_noskip_test_msg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@messages/tcg/$(DEPDIR)/pb_pdp_referral_msg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@state_machine/$(DEPDIR)/pb_tnc_state_machine.Plo@am__quote@ @@ -673,6 +701,7 @@ clean-libtool: -rm -rf batch/.libs batch/_libs -rm -rf messages/.libs messages/_libs -rm -rf messages/ietf/.libs messages/ietf/_libs + -rm -rf messages/ita/.libs messages/ita/_libs -rm -rf messages/tcg/.libs messages/tcg/_libs -rm -rf state_machine/.libs state_machine/_libs @@ -797,6 +826,8 @@ distclean-generic: -rm -f messages/$(am__dirstamp) -rm -f messages/ietf/$(DEPDIR)/$(am__dirstamp) -rm -f messages/ietf/$(am__dirstamp) + -rm -f messages/ita/$(DEPDIR)/$(am__dirstamp) + -rm -f messages/ita/$(am__dirstamp) -rm -f messages/tcg/$(DEPDIR)/$(am__dirstamp) -rm -f messages/tcg/$(am__dirstamp) -rm -f state_machine/$(DEPDIR)/$(am__dirstamp) @@ -811,7 +842,7 @@ clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ clean-pluginLTLIBRARIES mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) batch/$(DEPDIR) messages/$(DEPDIR) messages/ietf/$(DEPDIR) messages/tcg/$(DEPDIR) state_machine/$(DEPDIR) + -rm -rf ./$(DEPDIR) batch/$(DEPDIR) messages/$(DEPDIR) messages/ietf/$(DEPDIR) messages/ita/$(DEPDIR) messages/tcg/$(DEPDIR) state_machine/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -857,7 +888,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) batch/$(DEPDIR) messages/$(DEPDIR) messages/ietf/$(DEPDIR) messages/tcg/$(DEPDIR) state_machine/$(DEPDIR) + -rm -rf ./$(DEPDIR) batch/$(DEPDIR) messages/$(DEPDIR) messages/ietf/$(DEPDIR) messages/ita/$(DEPDIR) messages/tcg/$(DEPDIR) state_machine/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic diff --git a/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.c b/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.c index 228c08255..faad02b9b 100644 --- a/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.c +++ b/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2010 Sansar Choinyanbuu - * Copyright (C) 2010-2012 Andreas Steffen + * Copyright (C) 2010-2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -85,7 +85,7 @@ struct private_pb_tnc_batch_t { pb_tnc_batch_t public; /** - * TNCC if TRUE, TNCS if FALSE + * from TNC server if TRUE, from TNC client if FALSE */ bool is_server; @@ -166,6 +166,9 @@ METHOD(pb_tnc_batch_t, add_msg, bool, case PEN_TCG: msg_type_names = pb_tnc_tcg_msg_type_names; break; + case PEN_ITA: + msg_type_names = pb_tnc_ita_msg_type_names; + break; } DBG2(DBG_TNC, "adding %N/%N message", pen_names, msg_type.vendor_id, msg_type_names, msg_type.type); @@ -176,6 +179,7 @@ METHOD(pb_tnc_batch_t, add_msg, bool, METHOD(pb_tnc_batch_t, build, void, private_pb_tnc_batch_t *this) { + u_int8_t version; u_int32_t msg_len; chunk_t msg_value; enumerator_t *enumerator; @@ -184,9 +188,14 @@ METHOD(pb_tnc_batch_t, build, void, pb_tnc_msg_info_t *msg_infos; bio_writer_t *writer; + /* Set wrong PB-TNC version for testing purposes to force a PB-TNC error */ + version = lib->settings->get_int(lib->settings, + "%s.plugins.tnccs-20.tests.pb_tnc_version", + PB_TNC_VERSION, lib->ns); + /* build PB-TNC batch header */ writer = bio_writer_create(this->batch_len); - writer->write_uint8 (writer, PB_TNC_VERSION); + writer->write_uint8 (writer, version); writer->write_uint8 (writer, this->is_server ? PB_TNC_BATCH_FLAG_D : PB_TNC_BATCH_FLAG_NONE); writer->write_uint16(writer, this->type); @@ -211,6 +220,9 @@ METHOD(pb_tnc_batch_t, build, void, case PEN_TCG: msg_infos = pb_tnc_tcg_msg_infos; break; + case PEN_ITA: + msg_infos = pb_tnc_ita_msg_infos; + break; } if (msg_infos[msg_type.type].has_noskip_flag) { @@ -228,15 +240,15 @@ METHOD(pb_tnc_batch_t, build, void, writer->destroy(writer); } -static status_t process_batch_header(private_pb_tnc_batch_t *this, - pb_tnc_state_machine_t *state_machine) +METHOD(pb_tnc_batch_t, process_header, status_t, + private_pb_tnc_batch_t *this, bool directionality, bool is_server, + bool *from_server) { bio_reader_t *reader; pb_tnc_msg_t *msg; pb_error_msg_t *err_msg; u_int8_t version, flags, reserved, type; u_int32_t batch_len; - bool directionality; if (this->encoding.len < PB_TNC_BATCH_HEADER_SIZE) { @@ -267,13 +279,14 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this, } /* Directionality */ - directionality = (flags & PB_TNC_BATCH_FLAG_D) != PB_TNC_BATCH_FLAG_NONE; - if (directionality == this->is_server) + *from_server = (flags & PB_TNC_BATCH_FLAG_D) != PB_TNC_BATCH_FLAG_NONE; + + if (directionality & (*from_server == is_server)) { DBG1(DBG_TNC, "wrong Directionality: batch is from a PB %s", - directionality ? "server" : "client"); + is_server ? "server" : "client"); msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF, - PB_ERROR_INVALID_PARAMETER, 1); + PB_ERROR_INVALID_PARAMETER, 1); goto fatal; } @@ -287,17 +300,6 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this, goto fatal; } - if (!state_machine->receive_batch(state_machine, this->type)) - { - DBG1(DBG_TNC, "unexpected PB-TNC batch type: %N", - pb_tnc_batch_type_names, this->type); - msg = pb_error_msg_create(TRUE, PEN_IETF, - PB_ERROR_UNEXPECTED_BATCH_TYPE); - goto fatal; - } - DBG1(DBG_TNC, "processing PB-TNC %N batch", pb_tnc_batch_type_names, - this->type); - /* Batch Length */ if (this->encoding.len != batch_len) { @@ -310,12 +312,6 @@ static status_t process_batch_header(private_pb_tnc_batch_t *this, this->offset = PB_TNC_BATCH_HEADER_SIZE; - /* Register an empty CDATA batch with the state machine */ - if (this->type == PB_BATCH_CDATA) - { - state_machine->set_empty_cdata(state_machine, - this->offset == this->encoding.len); - } return SUCCESS; fatal: @@ -395,11 +391,18 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this) msg_type_names = pb_tnc_msg_type_names; msg_infos = pb_tnc_msg_infos; } - else if (vendor_id == PEN_TCG && msg_type <= PB_TCG_MSG_ROOF) + else if (vendor_id == PEN_TCG && msg_type <= PB_TCG_MSG_ROOF && + msg_type > PB_TCG_MSG_RESERVED) { msg_type_names = pb_tnc_tcg_msg_type_names; msg_infos = pb_tnc_tcg_msg_infos; } + else if (vendor_id == PEN_ITA && msg_type <= PB_ITA_MSG_ROOF && + msg_type > PB_ITA_MSG_NOSKIP_TEST) + { + msg_type_names = pb_tnc_ita_msg_type_names; + msg_infos = pb_tnc_ita_msg_infos; + } else { if (msg_len < PB_TNC_MSG_HEADER_SIZE) @@ -413,7 +416,7 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this) if (noskip_flag) { - DBG1(DBG_TNC, "reject PB-TNC message 0x%06x/0x%08x)", + DBG1(DBG_TNC, "reject PB-TNC message (0x%06x/0x%08x)", vendor_id, msg_type); msg = pb_error_msg_create_with_offset(TRUE, PEN_IETF, PB_ERROR_UNSUPPORTED_MANDATORY_MSG, this->offset); @@ -421,7 +424,7 @@ static status_t process_tnc_msg(private_pb_tnc_batch_t *this) } else { - DBG1(DBG_TNC, "ignore PB-TNC message 0x%06x/0x%08x)", + DBG1(DBG_TNC, "ignore PB-TNC message (0x%06x/0x%08x)", vendor_id, msg_type); this->offset += msg_len; return SUCCESS; @@ -502,14 +505,26 @@ fatal: METHOD(pb_tnc_batch_t, process, status_t, private_pb_tnc_batch_t *this, pb_tnc_state_machine_t *state_machine) { - status_t status; + pb_tnc_msg_t *msg; + status_t status = SUCCESS; - status = process_batch_header(this, state_machine); - if (status != SUCCESS) + if (!state_machine->receive_batch(state_machine, this->type)) { + DBG1(DBG_TNC, "unexpected PB-TNC batch type: %N", + pb_tnc_batch_type_names, this->type); + msg = pb_error_msg_create(TRUE, PEN_IETF, + PB_ERROR_UNEXPECTED_BATCH_TYPE); + this->errors->insert_last(this->errors, msg); return FAILED; } + /* Register an empty CDATA batch with the state machine */ + if (this->type == PB_BATCH_CDATA) + { + state_machine->set_empty_cdata(state_machine, + this->offset == this->encoding.len); + } + while (this->offset < this->encoding.len) { switch (process_tnc_msg(this)) @@ -585,7 +600,7 @@ pb_tnc_batch_t* pb_tnc_batch_create(bool is_server, pb_tnc_batch_type_t type, /** * See header */ -pb_tnc_batch_t* pb_tnc_batch_create_from_data(bool is_server, chunk_t data) +pb_tnc_batch_t* pb_tnc_batch_create_from_data(chunk_t data) { private_pb_tnc_batch_t *this; @@ -595,12 +610,12 @@ pb_tnc_batch_t* pb_tnc_batch_create_from_data(bool is_server, chunk_t data) .get_encoding = _get_encoding, .add_msg = _add_msg, .build = _build, + .process_header = _process_header, .process = _process, .create_msg_enumerator = _create_msg_enumerator, .create_error_enumerator = _create_error_enumerator, .destroy = _destroy, }, - .is_server = is_server, .messages = linked_list_create(), .errors = linked_list_create(), .encoding = chunk_clone(data), diff --git a/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.h b/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.h index 106c5578c..6089c7d2e 100644 --- a/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.h +++ b/src/libtnccs/plugins/tnccs_20/batch/pb_tnc_batch.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2012 Andreas Steffen + * Copyright (C) 2010-2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -84,10 +84,21 @@ struct pb_tnc_batch_t { void (*build)(pb_tnc_batch_t *this); /** + * Process the PB-TNC Batch header + * + * @param directionality TRUE if no mutual TNC measurements + * @param is_server TRUE if called by TNC server + * @param from_server TRUE if sent by TNC server + * @return return processing status + */ + status_t (*process_header)(pb_tnc_batch_t *this, bool directionality, + bool is_server, bool *from_server); + + /** * Process the PB-TNC Batch * - * @param PB-TNC state machine - * @return return processing status + * @param state_machine PB-TNC state machine + * @return return processing status */ status_t (*process)(pb_tnc_batch_t *this, pb_tnc_state_machine_t *state_machine); @@ -95,14 +106,14 @@ struct pb_tnc_batch_t { /** * Enumerates over all PB-TNC Messages * - * @return return message enumerator + * @return return message enumerator */ enumerator_t* (*create_msg_enumerator)(pb_tnc_batch_t *this); /** * Enumerates over all parsing errors * - * @return return error enumerator + * @return return error enumerator */ enumerator_t* (*create_error_enumerator)(pb_tnc_batch_t *this); @@ -115,9 +126,9 @@ struct pb_tnc_batch_t { /** * Create an empty PB-TNC Batch of a given type * - * @param is_server TRUE if server, FALSE if client - * @param type PB-TNC batch type - * @param max_batch_len maximum size the PB-TNC batch + * @param is_server TRUE if server, FALSE if client + * @param type PB-TNC batch type + * @param max_batch_len maximum size the PB-TNC batch */ pb_tnc_batch_t* pb_tnc_batch_create(bool is_server, pb_tnc_batch_type_t type, size_t max_batch_len); @@ -125,9 +136,8 @@ pb_tnc_batch_t* pb_tnc_batch_create(bool is_server, pb_tnc_batch_type_t type, /** * Create an unprocessed PB-TNC Batch from data * - * @param is_server TRUE if server, FALSE if client * @param data encoded PB-TNC batch */ -pb_tnc_batch_t* pb_tnc_batch_create_from_data(bool is_server, chunk_t data); +pb_tnc_batch_t* pb_tnc_batch_create_from_data(chunk_t data); #endif /** PB_TNC_BATCH_H_ @}*/ diff --git a/src/libtnccs/plugins/tnccs_20/messages/ita/pb_mutual_capability_msg.c b/src/libtnccs/plugins/tnccs_20/messages/ita/pb_mutual_capability_msg.c new file mode 100644 index 000000000..1f35cae6b --- /dev/null +++ b/src/libtnccs/plugins/tnccs_20/messages/ita/pb_mutual_capability_msg.c @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2015 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "pb_mutual_capability_msg.h" + +#include <bio/bio_writer.h> +#include <bio/bio_reader.h> +#include <utils/debug.h> + +ENUM(pb_tnc_mutual_protocol_type_names, PB_MUTUAL_HALF_DUPLEX, + PB_MUTUAL_FULL_DUPLEX, + "half duplex", + "full duplex" +); + +typedef struct private_pb_mutual_capability_msg_t private_pb_mutual_capability_msg_t; + +/** + * PB-Mutual-Capability message + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |H|F| Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +# define MUTUAL_CAPABILITY_HEADER_SIZE 4 + +/** + * Private data of a pb_mutual_capability_msg_t object. + * + */ +struct private_pb_mutual_capability_msg_t { + /** + * Public pb_mutual_capability_msg_t interface. + */ + pb_mutual_capability_msg_t public; + + /** + * PB-TNC message type + */ + pen_type_t type; + + /** + * PB-TNC mutual protocols + */ + uint32_t protocols; + + /** + * Encoded message + */ + chunk_t encoding; +}; + +METHOD(pb_tnc_msg_t, get_type, pen_type_t, + private_pb_mutual_capability_msg_t *this) +{ + return this->type; +} + +METHOD(pb_tnc_msg_t, get_encoding, chunk_t, + private_pb_mutual_capability_msg_t *this) +{ + return this->encoding; +} + +METHOD(pb_tnc_msg_t, build, void, + private_pb_mutual_capability_msg_t *this) +{ + bio_writer_t *writer; + + if (this->encoding.ptr) + { + return; + } + writer = bio_writer_create(MUTUAL_CAPABILITY_HEADER_SIZE); + writer->write_uint32(writer, this->protocols); + + this->encoding = writer->get_buf(writer); + this->encoding = chunk_clone(this->encoding); + writer->destroy(writer); +} + +METHOD(pb_tnc_msg_t, process, status_t, + private_pb_mutual_capability_msg_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + + *offset = 0; + + /* process message */ + reader = bio_reader_create(this->encoding); + reader->read_uint32(reader, &this->protocols); + reader->destroy(reader); + + return SUCCESS; +} + +METHOD(pb_tnc_msg_t, destroy, void, + private_pb_mutual_capability_msg_t *this) +{ + free(this->encoding.ptr); + free(this); +} + +METHOD(pb_mutual_capability_msg_t, get_protocols, uint32_t, + private_pb_mutual_capability_msg_t *this) +{ + return this->protocols; +} + +/** + * See header + */ +pb_tnc_msg_t* pb_mutual_capability_msg_create(uint32_t protocols) +{ + private_pb_mutual_capability_msg_t *this; + + INIT(this, + .public = { + .pb_interface = { + .get_type = _get_type, + .get_encoding = _get_encoding, + .build = _build, + .process = _process, + .destroy = _destroy, + }, + .get_protocols = _get_protocols, + }, + .type = { PEN_ITA, PB_ITA_MSG_MUTUAL_CAPABILITY }, + .protocols = protocols, + ); + + return &this->public.pb_interface; +} + +/** + * See header + */ +pb_tnc_msg_t *pb_mutual_capability_msg_create_from_data(chunk_t data) +{ + private_pb_mutual_capability_msg_t *this; + + INIT(this, + .public = { + .pb_interface = { + .get_type = _get_type, + .get_encoding = _get_encoding, + .build = _build, + .process = _process, + .destroy = _destroy, + }, + .get_protocols = _get_protocols, + }, + .type = { PEN_ITA, PB_ITA_MSG_MUTUAL_CAPABILITY }, + .encoding = chunk_clone(data), + ); + + return &this->public.pb_interface; +} + diff --git a/src/libtnccs/plugins/tnccs_20/messages/ita/pb_mutual_capability_msg.h b/src/libtnccs/plugins/tnccs_20/messages/ita/pb_mutual_capability_msg.h new file mode 100644 index 000000000..db810a012 --- /dev/null +++ b/src/libtnccs/plugins/tnccs_20/messages/ita/pb_mutual_capability_msg.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2015 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup pb_mutual_capability_msg pb_mutual_capability_msg + * @{ @ingroup tnccs_20 + */ + +#ifndef PB_MUTUAL_CAPABILITY_MSG_H_ +#define PB_MUTUAL_CAPABILITY_MSG_H_ + +typedef enum pb_tnc_mutual_protocol_type_t pb_tnc_mutual_protocol_type_t; +typedef struct pb_mutual_capability_msg_t pb_mutual_capability_msg_t; + +#include "messages/pb_tnc_msg.h" + +/** + * PB-TNC mutual protocol types + */ +enum pb_tnc_mutual_protocol_type_t { + PB_MUTUAL_HALF_DUPLEX = (1 << 31), + PB_MUTUAL_FULL_DUPLEX = (1 << 30) +}; + +/** + * enum name for pb_mutual_protocol_type_t. + */ +extern enum_name_t *pb_tnc_mutual_protocol_type_names; + +/** + * Class representing the PB-Mutual-Capabilities message type. + */ +struct pb_mutual_capability_msg_t { + + /** + * PB-TNC Message interface + */ + pb_tnc_msg_t pb_interface; + + /** + * Get the PB-TNC mutual protocol types + * + * @return PB-TNC mutual protocol types + */ + uint32_t(*get_protocols)(pb_mutual_capability_msg_t *this); + +}; + +/** + * Create a PB-Mutual-Capability message + * + * @param protocols Supported PB-TNC mutual protocols + */ +pb_tnc_msg_t* pb_mutual_capability_msg_create(uint32_t protocols); + +/** + * Create an unprocessed PB-Mutual-Capability message from raw data + * + * @param data PB-Mutual-Capability message data + */ +pb_tnc_msg_t* pb_mutual_capability_msg_create_from_data(chunk_t data); + +#endif /** PB_MUTUAL_CAPABILITY_MSG_ @}*/ diff --git a/src/libtnccs/plugins/tnccs_20/messages/ita/pb_noskip_test_msg.c b/src/libtnccs/plugins/tnccs_20/messages/ita/pb_noskip_test_msg.c new file mode 100644 index 000000000..c95222e3a --- /dev/null +++ b/src/libtnccs/plugins/tnccs_20/messages/ita/pb_noskip_test_msg.c @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2015 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "pb_noskip_test_msg.h" + +typedef struct private_pb_noskip_test_msg_t private_pb_noskip_test_msg_t; + +/** + * Private data of a pb_noskip_test_msg_t object. + * + */ +struct private_pb_noskip_test_msg_t { + /** + * Public pb_noskip_test_msg_t interface. + */ + pb_noskip_test_msg_t public; + + /** + * PB-TNC message type + */ + pen_type_t type; + + /** + * Encoded message + */ + chunk_t encoding; +}; + +METHOD(pb_tnc_msg_t, get_type, pen_type_t, + private_pb_noskip_test_msg_t *this) +{ + return this->type; +} + +METHOD(pb_tnc_msg_t, get_encoding, chunk_t, + private_pb_noskip_test_msg_t *this) +{ + return this->encoding; +} + +METHOD(pb_tnc_msg_t, build, void, + private_pb_noskip_test_msg_t *this) +{ + /* nothing to do since the message is empty */ +} + +METHOD(pb_tnc_msg_t, process, status_t, + private_pb_noskip_test_msg_t *this, u_int32_t *offset) +{ + return SUCCESS; +} + +METHOD(pb_tnc_msg_t, destroy, void, + private_pb_noskip_test_msg_t *this) +{ + free(this); +} + +/** + * See header + */ +pb_tnc_msg_t *pb_noskip_test_msg_create(void) +{ + private_pb_noskip_test_msg_t *this; + + INIT(this, + .public = { + .pb_interface = { + .get_type = _get_type, + .get_encoding = _get_encoding, + .build = _build, + .process = _process, + .destroy = _destroy, + }, + }, + .type = { PEN_ITA, PB_ITA_MSG_NOSKIP_TEST }, + ); + + return &this->public.pb_interface; +} diff --git a/src/libtnccs/plugins/tnccs_20/messages/ita/pb_noskip_test_msg.h b/src/libtnccs/plugins/tnccs_20/messages/ita/pb_noskip_test_msg.h new file mode 100644 index 000000000..6325582da --- /dev/null +++ b/src/libtnccs/plugins/tnccs_20/messages/ita/pb_noskip_test_msg.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2015 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup pb_noskip_test_msg pb_noskip_test_msg + * @{ @ingroup tnccs_20 + */ + +#ifndef PB_NOSKIP_TEST_MSG_H_ +#define PB_NOSKIP_TEST_MSG_H_ + +typedef struct pb_noskip_test_msg_t pb_noskip_test_msg_t; + +#include "messages/pb_tnc_msg.h" + +/** + * Class representing the PB-Noskip-Test message type. + */ +struct pb_noskip_test_msg_t { + + /** + * PB-TNC Message interface + */ + pb_tnc_msg_t pb_interface; +}; + +/** + * Create a PB-Noskip-Test message from parameters + */ +pb_tnc_msg_t* pb_noskip_test_msg_create(void); + +#endif /** PB_NOSKIP_TEST_MSG_H_ @}*/ diff --git a/src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.c b/src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.c index ec43490f4..b46c776e4 100644 --- a/src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.c +++ b/src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.c @@ -22,6 +22,7 @@ #include "ietf/pb_access_recommendation_msg.h" #include "ietf/pb_remediation_parameters_msg.h" #include "ietf/pb_reason_string_msg.h" +#include "ita/pb_mutual_capability_msg.h" #include "tcg/pb_pdp_referral_msg.h" #include <library.h> @@ -37,10 +38,17 @@ ENUM(pb_tnc_msg_type_names, PB_MSG_EXPERIMENTAL, PB_MSG_REASON_STRING, "PB-Reason-String" ); -ENUM(pb_tnc_tcg_msg_type_names, PB_TCG_MSG_PDP_REFERRAL, PB_TCG_MSG_PDP_REFERRAL, +ENUM(pb_tnc_tcg_msg_type_names, PB_TCG_MSG_PDP_REFERRAL, + PB_TCG_MSG_PDP_REFERRAL, "PB-PDP-Referral" ); +ENUM(pb_tnc_ita_msg_type_names, PB_ITA_MSG_NOSKIP_TEST, + PB_ITA_MSG_MUTUAL_CAPABILITY, + "PB-Noskip-Test", + "PB-Mutual-Capability" +); + pb_tnc_msg_info_t pb_tnc_msg_infos[] = { { 12, FALSE, FALSE, TRUE_OR_FALSE }, { 24, FALSE, FALSE, TRUE }, @@ -57,6 +65,11 @@ pb_tnc_msg_info_t pb_tnc_tcg_msg_infos[] = { { 20, FALSE, FALSE, FALSE }, }; +pb_tnc_msg_info_t pb_tnc_ita_msg_infos[] = { + { 12, TRUE, FALSE, TRUE }, + { 16, FALSE, FALSE, FALSE }, +}; + /** * See header */ @@ -91,5 +104,12 @@ pb_tnc_msg_t* pb_tnc_msg_create_from_data(pen_type_t msg_type, chunk_t value) return pb_pdp_referral_msg_create_from_data(value); } } + else if (msg_type.vendor_id == PEN_ITA) + { + if (msg_type.type == PB_ITA_MSG_MUTUAL_CAPABILITY) + { + return pb_mutual_capability_msg_create_from_data(value); + } + } return NULL; } diff --git a/src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.h b/src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.h index 6eeed5156..35b0b7c26 100644 --- a/src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.h +++ b/src/libtnccs/plugins/tnccs_20/messages/pb_tnc_msg.h @@ -54,6 +54,7 @@ extern enum_name_t *pb_tnc_msg_type_names; * PB-TNC Message Type defined in the TCG namespace */ enum pb_tnc_tcg_msg_type_t { + PB_TCG_MSG_RESERVED = 0, PB_TCG_MSG_PDP_REFERRAL = 1, PB_TCG_MSG_ROOF = 1 }; @@ -64,6 +65,20 @@ enum pb_tnc_tcg_msg_type_t { extern enum_name_t *pb_tnc_tcg_msg_type_names; /** + * PB-TNC Message Type defined in the ITA namespace + */ +enum pb_tnc_ita_msg_type_t { + PB_ITA_MSG_NOSKIP_TEST = 0, + PB_ITA_MSG_MUTUAL_CAPABILITY = 1, + PB_ITA_MSG_ROOF = 1 +}; + +/** + * enum name for pb_tnc_tcg_msg_type_t. + */ +extern enum_name_t *pb_tnc_ita_msg_type_names; + +/** * Information entry describing a PB-TNC Message Type */ struct pb_tnc_msg_info_t { @@ -86,6 +101,11 @@ extern pb_tnc_msg_info_t pb_tnc_msg_infos[]; extern pb_tnc_msg_info_t pb_tnc_tcg_msg_infos[]; /** + * Information on PB-TNC ITA Message Types + */ +extern pb_tnc_msg_info_t pb_tnc_ita_msg_infos[]; + +/** * Generic interface for all PB-TNC message types. * * To handle all messages in a generic way, this interface diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20.c b/src/libtnccs/plugins/tnccs_20/tnccs_20.c index dc4da51c6..a1a95733f 100644 --- a/src/libtnccs/plugins/tnccs_20/tnccs_20.c +++ b/src/libtnccs/plugins/tnccs_20/tnccs_20.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2010 Sansar Choinyanbuu - * Copyright (C) 2010-2013 Andreas Steffen + * Copyright (C) 2010-2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -15,30 +15,17 @@ */ #include "tnccs_20.h" +#include "tnccs_20_handler.h" +#include "tnccs_20_server.h" +#include "tnccs_20_client.h" #include "batch/pb_tnc_batch.h" #include "messages/pb_tnc_msg.h" #include "messages/ietf/pb_pa_msg.h" -#include "messages/ietf/pb_error_msg.h" -#include "messages/ietf/pb_assessment_result_msg.h" -#include "messages/ietf/pb_access_recommendation_msg.h" -#include "messages/ietf/pb_remediation_parameters_msg.h" -#include "messages/ietf/pb_reason_string_msg.h" -#include "messages/ietf/pb_language_preference_msg.h" -#include "messages/tcg/pb_pdp_referral_msg.h" -#include "state_machine/pb_tnc_state_machine.h" #include <tncif_names.h> #include <tncif_pa_subtypes.h> -#include <tnc/tnc.h> -#include <tnc/tnccs/tnccs_manager.h> -#include <tnc/imc/imc_manager.h> -#include <tnc/imv/imv_manager.h> - -#include <threading/mutex.h> #include <utils/debug.h> -#include <collections/linked_list.h> -#include <pen/pen.h> typedef struct private_tnccs_20_t private_tnccs_20_t; @@ -60,77 +47,72 @@ struct private_tnccs_20_t { /** * Server identity */ - identification_t *server; + identification_t *server_id; /** * Client identity */ - identification_t *peer; + identification_t *peer_id; /** - * Underlying TNC IF-T transport protocol + * Server IP address */ - tnc_ift_type_t transport; + host_t *server_ip; /** - * Type of TNC client authentication + * Client IP address */ - u_int32_t auth_type; + host_t *peer_ip; /** - * PB-TNC State Machine + * Underlying TNC IF-T transport protocol */ - pb_tnc_state_machine_t *state_machine; + tnc_ift_type_t transport; /** - * Connection ID assigned to this TNCCS connection + * TNC IF-T transport protocol for EAP methods */ - TNC_ConnectionID connection_id; + bool eap_transport; /** - * PB-TNC messages to be sent + * Type of TNC client authentication */ - linked_list_t *messages; + u_int32_t auth_type; /** - * Type of PB-TNC batch being constructed + * Mutual PB-TNC protocol enabled */ - pb_tnc_batch_type_t batch_type; + bool mutual; /** - * Maximum PB-TNC batch size + * Direction the next batch will go to */ - size_t max_batch_len; + bool to_server; /** - * Maximum PA-TNC message size + * TNC Server */ - size_t max_msg_len; + tnccs_20_handler_t *tnc_server; /** - * Mutex locking the batch in construction + * TNC Client */ - mutex_t *mutex; + tnccs_20_handler_t *tnc_client; /** - * Flag set while processing + * Active TNCSS handler */ - bool fatal_error; + tnccs_20_handler_t *tnccs_handler; /** - * Flag set by IMC/IMV RequestHandshakeRetry() function + * Maximum PB-TNC batch size */ - bool request_handshake_retry; - - /** - * SendMessage() by IMC/IMV only allowed if flag is set - */ - bool send_msg; + size_t max_batch_len; /** - * Set of IMV recommendations (TNC Server only) + * Maximum PA-TNC message size */ - recommendations_t *recs; + size_t max_msg_len; /** * Callback function to communicate recommendation (TNC Server only) @@ -138,69 +120,30 @@ struct private_tnccs_20_t { tnccs_cb_t callback; /** - * Data to pass to callback function (TNC Server only) - */ - void *cb_data; - - /** - * PDP server FQDN - */ - chunk_t pdp_server; - - /** - * PDP server port - */ - u_int16_t pdp_port; - - /** * reference count */ refcount_t ref; }; -/** - * If the batch type changes then delete all accumulated PB-TNC messages - */ -void change_batch_type(private_tnccs_20_t *this, pb_tnc_batch_type_t batch_type) -{ - pb_tnc_msg_t *msg; - - if (batch_type != this->batch_type) - { - if (this->batch_type != PB_BATCH_NONE) - { - DBG1(DBG_TNC, "cancelling PB-TNC %N batch", - pb_tnc_batch_type_names, this->batch_type); - - while (this->messages->remove_last(this->messages, - (void**)&msg) == SUCCESS) - { - msg->destroy(msg); - } - } - this->batch_type = batch_type; - } -} - METHOD(tnccs_t, send_msg, TNC_Result, private_tnccs_20_t* this, TNC_IMCID imc_id, TNC_IMVID imv_id, - TNC_UInt32 msg_flags, + TNC_UInt32 msg_flags, TNC_BufferReference msg, TNC_UInt32 msg_len, - TNC_VendorID msg_vid, - TNC_MessageSubtype msg_subtype) + TNC_VendorID msg_vid, + TNC_MessageSubtype msg_subtype) { pb_tnc_msg_t *pb_tnc_msg; - pb_tnc_batch_type_t batch_type; enum_name_t *pa_subtype_names; bool excl; - if (!this->send_msg) + if (!this->tnccs_handler->get_send_flag(this->tnccs_handler)) { DBG1(DBG_TNC, "%s %u not allowed to call SendMessage()", - this->is_server ? "IMV" : "IMC", - this->is_server ? imv_id : imc_id); + this->to_server ? "IMC" : "IMV", + this->to_server ? imc_id : imv_id); + return TNC_RESULT_ILLEGAL_OPERATION; } excl = (msg_flags & TNC_MESSAGE_FLAGS_EXCLUSIVE) != 0; @@ -220,698 +163,169 @@ METHOD(tnccs_t, send_msg, TNC_Result, DBG2(DBG_TNC, "creating PB-PA message type '%N' 0x%06x/0x%08x", pen_names, msg_vid, msg_vid, msg_subtype); } + this->tnccs_handler->add_msg(this->tnccs_handler, pb_tnc_msg); - /* adding PA message to SDATA or CDATA batch only */ - batch_type = this->is_server ? PB_BATCH_SDATA : PB_BATCH_CDATA; - this->mutex->lock(this->mutex); - if (this->batch_type == PB_BATCH_NONE) - { - this->batch_type = batch_type; - } - if (this->batch_type == batch_type) - { - this->messages->insert_last(this->messages, pb_tnc_msg); - } - else - { - pb_tnc_msg->destroy(pb_tnc_msg); - } - this->mutex->unlock(this->mutex); return TNC_RESULT_SUCCESS; } -/** - * Handle a single PB-TNC IETF standard message according to its type - */ -static void handle_ietf_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg) -{ - pen_type_t msg_type = msg->get_type(msg); - - switch (msg_type.type) - { - case PB_MSG_EXPERIMENTAL: - /* nothing to do */ - break; - case PB_MSG_PA: - { - pb_pa_msg_t *pa_msg; - pen_type_t msg_subtype; - u_int16_t imc_id, imv_id; - chunk_t msg_body; - bool excl; - enum_name_t *pa_subtype_names; - - pa_msg = (pb_pa_msg_t*)msg; - msg_subtype = pa_msg->get_subtype(pa_msg); - msg_body = pa_msg->get_body(pa_msg); - imc_id = pa_msg->get_collector_id(pa_msg); - imv_id = pa_msg->get_validator_id(pa_msg); - excl = pa_msg->get_exclusive_flag(pa_msg); - - pa_subtype_names = get_pa_subtype_names(msg_subtype.vendor_id); - if (pa_subtype_names) - { - DBG2(DBG_TNC, "handling PB-PA message type '%N/%N' 0x%06x/0x%08x", - pen_names, msg_subtype.vendor_id, pa_subtype_names, - msg_subtype.type, msg_subtype.vendor_id, msg_subtype.type); - } - else - { - DBG2(DBG_TNC, "handling PB-PA message type '%N' 0x%06x/0x%08x", - pen_names, msg_subtype.vendor_id, msg_subtype.vendor_id, - msg_subtype.type); - } - - this->send_msg = TRUE; - if (this->is_server) - { - tnc->imvs->receive_message(tnc->imvs, this->connection_id, - excl, msg_body.ptr, msg_body.len, - msg_subtype.vendor_id, - msg_subtype.type, imc_id, imv_id); - } - else - { - tnc->imcs->receive_message(tnc->imcs, this->connection_id, - excl, msg_body.ptr, msg_body.len, - msg_subtype.vendor_id, - msg_subtype.type, imv_id, imc_id); - } - this->send_msg = FALSE; - break; - } - case PB_MSG_ASSESSMENT_RESULT: - { - pb_assessment_result_msg_t *assess_msg; - u_int32_t result; - - assess_msg = (pb_assessment_result_msg_t*)msg; - result = assess_msg->get_assessment_result(assess_msg); - DBG1(DBG_TNC, "PB-TNC assessment result is '%N'", - TNC_IMV_Evaluation_Result_names, result); - break; - } - case PB_MSG_ACCESS_RECOMMENDATION: - { - pb_access_recommendation_msg_t *rec_msg; - pb_access_recommendation_code_t rec; - TNC_ConnectionState state = TNC_CONNECTION_STATE_ACCESS_NONE; - - rec_msg = (pb_access_recommendation_msg_t*)msg; - rec = rec_msg->get_access_recommendation(rec_msg); - DBG1(DBG_TNC, "PB-TNC access recommendation is '%N'", - pb_access_recommendation_code_names, rec); - switch (rec) - { - case PB_REC_ACCESS_ALLOWED: - state = TNC_CONNECTION_STATE_ACCESS_ALLOWED; - break; - case PB_REC_ACCESS_DENIED: - state = TNC_CONNECTION_STATE_ACCESS_NONE; - break; - case PB_REC_QUARANTINED: - state = TNC_CONNECTION_STATE_ACCESS_ISOLATED; - } - tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id, - state); - break; - } - case PB_MSG_REMEDIATION_PARAMETERS: - { - pb_remediation_parameters_msg_t *rem_msg; - pen_type_t parameters_type; - chunk_t parameters, string, lang_code; - - rem_msg = (pb_remediation_parameters_msg_t*)msg; - parameters_type = rem_msg->get_parameters_type(rem_msg); - parameters = rem_msg->get_parameters(rem_msg); - - if (parameters_type.vendor_id == PEN_IETF) - { - switch (parameters_type.type) - { - case PB_REMEDIATION_URI: - DBG1(DBG_TNC, "remediation uri: %.*s", - parameters.len, parameters.ptr); - break; - case PB_REMEDIATION_STRING: - string = rem_msg->get_string(rem_msg, &lang_code); - DBG1(DBG_TNC, "remediation string: [%.*s]\n%.*s", - lang_code.len, lang_code.ptr, - string.len, string.ptr); - break; - default: - DBG1(DBG_TNC, "remediation parameters: %B", ¶meters); - } - } - else - { - DBG1(DBG_TNC, "remediation parameters: %B", ¶meters); - } - break; - } - case PB_MSG_ERROR: - { - pb_error_msg_t *err_msg; - bool fatal; - u_int32_t vendor_id; - u_int16_t error_code; - - err_msg = (pb_error_msg_t*)msg; - fatal = err_msg->get_fatal_flag(err_msg); - vendor_id = err_msg->get_vendor_id(err_msg); - error_code = err_msg->get_error_code(err_msg); - - if (fatal) - { - this->fatal_error = TRUE; - } - - if (vendor_id == PEN_IETF) - { - switch (error_code) - { - case PB_ERROR_INVALID_PARAMETER: - case PB_ERROR_UNSUPPORTED_MANDATORY_MSG: - DBG1(DBG_TNC, "received %s PB-TNC error '%N' " - "(offset %u bytes)", - fatal ? "fatal" : "non-fatal", - pb_tnc_error_code_names, error_code, - err_msg->get_offset(err_msg)); - break; - case PB_ERROR_VERSION_NOT_SUPPORTED: - DBG1(DBG_TNC, "received %s PB-TNC error '%N' " - "caused by bad version 0x%02x", - fatal ? "fatal" : "non-fatal", - pb_tnc_error_code_names, error_code, - err_msg->get_bad_version(err_msg)); - break; - case PB_ERROR_UNEXPECTED_BATCH_TYPE: - case PB_ERROR_LOCAL_ERROR: - default: - DBG1(DBG_TNC, "received %s PB-TNC error '%N'", - fatal ? "fatal" : "non-fatal", - pb_tnc_error_code_names, error_code); - break; - } - } - else - { - DBG1(DBG_TNC, "received %s PB-TNC error (%u) " - "with Vendor ID 0x%06x", - fatal ? "fatal" : "non-fatal", - error_code, vendor_id); - } - break; - } - case PB_MSG_LANGUAGE_PREFERENCE: - { - pb_language_preference_msg_t *lang_msg; - chunk_t lang; - - lang_msg = (pb_language_preference_msg_t*)msg; - lang = lang_msg->get_language_preference(lang_msg); - - if (this->recs) - { - DBG2(DBG_TNC, "setting language preference to '%.*s'", - (int)lang.len, lang.ptr); - this->recs->set_preferred_language(this->recs, lang); - } - break; - } - case PB_MSG_REASON_STRING: - { - pb_reason_string_msg_t *reason_msg; - chunk_t reason_string, language_code; - - reason_msg = (pb_reason_string_msg_t*)msg; - reason_string = reason_msg->get_reason_string(reason_msg); - language_code = reason_msg->get_language_code(reason_msg); - DBG1(DBG_TNC, "reason string is '%.*s' [%.*s]", - (int)reason_string.len, reason_string.ptr, - (int)language_code.len, language_code.ptr); - break; - } - default: - break; - } -} - -/** - * Handle a single PB-TNC TCG standard message according to its type - */ -static void handle_tcg_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg) -{ - pen_type_t msg_type = msg->get_type(msg); - - switch (msg_type.type) - { - case PB_TCG_MSG_PDP_REFERRAL: - { - pb_pdp_referral_msg_t *pdp_msg; - pen_type_t pdp_id_type; - u_int8_t pdp_protocol; - - pdp_msg = (pb_pdp_referral_msg_t*)msg; - pdp_id_type = pdp_msg->get_identifier_type(pdp_msg); - - if (pdp_id_type.vendor_id == PEN_TCG && - pdp_id_type.type == PB_PDP_ID_FQDN) - { - this->pdp_server = chunk_clone(pdp_msg->get_fqdn(pdp_msg, - &pdp_protocol, &this->pdp_port)); - if (pdp_protocol != 0) - { - DBG1(DBG_TNC, "unsupported PDP transport protocol"); - break; - } - DBG1(DBG_TNC, "PDP server '%.*s' is listening on port %u", - this->pdp_server.len, this->pdp_server.ptr, - this->pdp_port); - } - break; - } - default: - break; - } -} - -/** - * Handle a single PB-TNC message according to its type - */ -static void handle_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg) -{ - pen_type_t msg_type = msg->get_type(msg); - - switch (msg_type.vendor_id) - { - case PEN_IETF: - handle_ietf_message(this, msg); - break; - case PEN_TCG: - handle_tcg_message(this, msg); - break; - default: - break; - } -} - -/** - * Build a CRETRY or SRETRY batch - */ -static void build_retry_batch(private_tnccs_20_t *this) -{ - pb_tnc_batch_type_t batch_retry_type; - - batch_retry_type = this->is_server ? PB_BATCH_SRETRY : PB_BATCH_CRETRY; - if (this->batch_type == batch_retry_type) - { - /* retry batch has already been selected */ - return; - } - - change_batch_type(this, batch_retry_type); - - if (this->is_server) - { - this->recs->clear_recommendation(this->recs); - tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id, - TNC_CONNECTION_STATE_HANDSHAKE); - } -} - METHOD(tls_t, process, status_t, private_tnccs_20_t *this, void *buf, size_t buflen) { - chunk_t data; pb_tnc_batch_t *batch; - pb_tnc_msg_t *msg; - enumerator_t *enumerator; - identification_t *pdp_server; - u_int16_t *pdp_port; + bool from_server, fatal_header_error = FALSE; status_t status; + chunk_t data; - if (this->is_server && !this->connection_id) + /* On arrival of first batch from TNC client create TNC server */ + if (this->is_server && !this->tnc_server) { - this->connection_id = tnc->tnccs->create_connection(tnc->tnccs, - TNCCS_2_0, (tnccs_t*)this, _send_msg, - &this->request_handshake_retry, - this->max_msg_len, &this->recs); - if (!this->connection_id) + this->tnc_server = tnccs_20_server_create(&this->public, _send_msg, + this->max_batch_len, this->max_msg_len, + this->eap_transport); + if (!this->tnc_server) { return FAILED; } - tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id, - TNC_CONNECTION_STATE_CREATE); - tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id, - TNC_CONNECTION_STATE_HANDSHAKE); - - /* Send a PB-TNC TCG PDP Referral message if PDP is known */ - pdp_server = (identification_t*)lib->get(lib, "pt-tls-server"); - pdp_port = (u_int16_t*)lib->get(lib, "pt-tls-port"); - - if ((this->transport == TNC_IFT_EAP_1_1 || - this->transport == TNC_IFT_EAP_2_0) && pdp_server && pdp_port) - { - msg = pb_pdp_referral_msg_create_from_fqdn( - pdp_server->get_encoding(pdp_server), *pdp_port); - this->messages->insert_last(this->messages, msg); - } - + this->tnccs_handler = this->tnc_server; + this->tnccs_handler->begin_handshake(this->tnccs_handler, FALSE); } data = chunk_create(buf, buflen); - DBG1(DBG_TNC, "received TNCCS batch (%u bytes) for Connection ID %u", - data.len, this->connection_id); + DBG1(DBG_TNC, "received TNCCS batch (%u bytes)", data.len); DBG3(DBG_TNC, "%B", &data); - batch = pb_tnc_batch_create_from_data(this->is_server, data); - status = batch->process(batch, this->state_machine); - if (status != FAILED) + /* Parse the header of the received PB-TNC batch */ + batch = pb_tnc_batch_create_from_data(data); + status = batch->process_header(batch, !this->mutual, this->is_server, + &from_server); + if (status == FAILED) { - enumerator_t *enumerator; - pb_tnc_msg_t *msg; - pb_tnc_batch_type_t batch_type; - bool empty = TRUE; - - batch_type = batch->get_type(batch); - - if (batch_type == PB_BATCH_CRETRY) - { - /* Send an SRETRY batch in response */ - this->mutex->lock(this->mutex); - build_retry_batch(this); - this->mutex->unlock(this->mutex); - } - else if (batch_type == PB_BATCH_SRETRY) - { - /* Restart the measurements */ - tnc->imcs->notify_connection_change(tnc->imcs, - this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE); - this->send_msg = TRUE; - tnc->imcs->begin_handshake(tnc->imcs, this->connection_id); - this->send_msg = FALSE; - } - - enumerator = batch->create_msg_enumerator(batch); - while (enumerator->enumerate(enumerator, &msg)) - { - handle_message(this, msg); - empty = FALSE; - } - enumerator->destroy(enumerator); + fatal_header_error = TRUE; + status = VERIFY_ERROR; + } + this->to_server = this->mutual ? from_server : !this->is_server; - /* received an empty CLOSE batch from PB-TNC client */ - if (this->is_server && batch_type == PB_BATCH_CLOSE && empty) + /* In the mutual case, first batch from TNC server requires a TNC client */ + if (this->to_server && !this->tnc_client) + { + this->tnc_client = tnccs_20_client_create(&this->public, _send_msg, + this->max_batch_len, this->max_msg_len); + if (!this->tnc_client) { batch->destroy(batch); - if (this->fatal_error) - { - DBG1(DBG_TNC, "a fatal PB-TNC error occurred, " - "terminating connection"); - return FAILED; - } - else - { - return SUCCESS; - } - } - - this->send_msg = TRUE; - if (this->is_server) - { - tnc->imvs->batch_ending(tnc->imvs, this->connection_id); - } - else - { - tnc->imcs->batch_ending(tnc->imcs, this->connection_id); + return FAILED; } - this->send_msg = FALSE; + this->tnccs_handler = this->tnc_client; + this->tnccs_handler->begin_handshake(this->tnccs_handler, this->mutual); } + else + { + /* Set active TNCCS handler for processing */ + this->tnccs_handler = this->to_server ? this->tnc_client : + this->tnc_server; + } + DBG2(DBG_TNC, "TNC %s is handling inbound connection", + this->to_server ? "client" : "server"); - switch (status) + if (status == SUCCESS) { - case FAILED: - this->fatal_error = TRUE; - this->mutex->lock(this->mutex); - change_batch_type(this, PB_BATCH_CLOSE); - this->mutex->unlock(this->mutex); - /* fall through to add error messages to outbound batch */ - case VERIFY_ERROR: - enumerator = batch->create_error_enumerator(batch); - while (enumerator->enumerate(enumerator, &msg)) - { - this->mutex->lock(this->mutex); - this->messages->insert_last(this->messages, msg->get_ref(msg)); - this->mutex->unlock(this->mutex); - } - enumerator->destroy(enumerator); - break; - case SUCCESS: - default: - break; + status = this->tnccs_handler->process(this->tnccs_handler, batch); + } + if (status == VERIFY_ERROR) + { + this->tnccs_handler->handle_errors(this->tnccs_handler, batch, + fatal_header_error); + status = NEED_MORE; } batch->destroy(batch); - return NEED_MORE; -} + /* Has a mutual connection been established? */ + this->mutual = this->is_server ? + this->tnc_server->get_mutual(this->tnc_server) : + this->tnc_client->get_mutual(this->tnc_client); -/** - * Build a RESULT batch if a final recommendation is available - */ -static void check_and_build_recommendation(private_tnccs_20_t *this) -{ - TNC_IMV_Action_Recommendation rec; - TNC_IMV_Evaluation_Result eval; - TNC_ConnectionState state; - TNC_IMVID id; - chunk_t reason, language; - enumerator_t *enumerator; - pb_tnc_msg_t *msg; - pb_access_recommendation_code_t pb_rec; - - if (!this->recs->have_recommendation(this->recs, &rec, &eval)) - { - tnc->imvs->solicit_recommendation(tnc->imvs, this->connection_id); - } - if (this->recs->have_recommendation(this->recs, &rec, &eval)) + if (this->mutual && !this->is_server) { - this->batch_type = PB_BATCH_RESULT; + pb_tnc_state_t client_state, server_state; - msg = pb_assessment_result_msg_create(eval); - this->messages->insert_last(this->messages, msg); + client_state = !this->tnc_client ? PB_STATE_INIT : + this->tnc_client->get_state(this->tnc_client); + server_state = !this->tnc_server ? PB_STATE_INIT : + this->tnc_server->get_state(this->tnc_server); - /** - * Map IMV Action Recommendation codes to PB Access Recommendation codes - * and communicate Access Recommendation to IMVs - */ - switch (rec) + /* In half-duplex mutual mode toggle the direction on the client side */ + if ((!this->to_server && client_state != PB_STATE_DECIDED) || + ( this->to_server && server_state != PB_STATE_END)) { - case TNC_IMV_ACTION_RECOMMENDATION_ALLOW: - state = TNC_CONNECTION_STATE_ACCESS_ALLOWED; - pb_rec = PB_REC_ACCESS_ALLOWED; - break; - case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE: - state = TNC_CONNECTION_STATE_ACCESS_ISOLATED; - pb_rec = PB_REC_QUARANTINED; - break; - case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS: - case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION: - default: - state = TNC_CONNECTION_STATE_ACCESS_NONE; - pb_rec = PB_REC_ACCESS_DENIED; + this->to_server = !this->to_server; + } + else if (client_state == PB_STATE_DECIDED && + server_state == PB_STATE_END) + { + /* Cause the final CLOSE batch to be sent to the TNC server */ + this->to_server = TRUE; } - tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id, - state); - - msg = pb_access_recommendation_msg_create(pb_rec); - this->messages->insert_last(this->messages, msg); - enumerator = this->recs->create_reason_enumerator(this->recs); - while (enumerator->enumerate(enumerator, &id, &reason, &language)) + /* Suppress a successful CLOSE batch coming from the TNC server */ + if (status == SUCCESS) { - msg = pb_reason_string_msg_create(reason, language); - this->messages->insert_last(this->messages, msg); + status = NEED_MORE; } - enumerator->destroy(enumerator); } + + return status; } METHOD(tls_t, build, status_t, private_tnccs_20_t *this, void *buf, size_t *buflen, size_t *msglen) { - status_t status; - pb_tnc_state_t state; - - /* Initialize the connection */ - if (!this->is_server && !this->connection_id) - { - pb_tnc_msg_t *msg; - char *pref_lang; - - this->connection_id = tnc->tnccs->create_connection(tnc->tnccs, - TNCCS_2_0, (tnccs_t*)this, _send_msg, - &this->request_handshake_retry, - this->max_msg_len, NULL); - if (!this->connection_id) - { - return FAILED; - } - - /* Create PB-TNC Language Preference message */ - pref_lang = tnc->imcs->get_preferred_language(tnc->imcs); - msg = pb_language_preference_msg_create(chunk_create(pref_lang, - strlen(pref_lang))); - this->mutex->lock(this->mutex); - this->batch_type = PB_BATCH_CDATA; - this->messages->insert_last(this->messages, msg); - this->mutex->unlock(this->mutex); - - tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id, - TNC_CONNECTION_STATE_CREATE); - tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id, - TNC_CONNECTION_STATE_HANDSHAKE); - this->send_msg = TRUE; - tnc->imcs->begin_handshake(tnc->imcs, this->connection_id); - this->send_msg = FALSE; - } - - state = this->state_machine->get_state(this->state_machine); - - if (this->fatal_error && state == PB_STATE_END) - { - DBG1(DBG_TNC, "a fatal PB-TNC error occurred, terminating connection"); - return FAILED; - } - - /* Do not allow any asynchronous IMCs or IMVs to add additional messages */ - this->mutex->lock(this->mutex); - - if (this->request_handshake_retry) - { - if (state != PB_STATE_INIT) - { - build_retry_batch(this); - } - - /* Reset the flag for the next handshake retry request */ - this->request_handshake_retry = FALSE; - } - - if (this->is_server && state == PB_STATE_SERVER_WORKING && - this->recs->have_recommendation(this->recs, NULL, NULL)) + if (this->to_server) { - check_and_build_recommendation(this); - } + DBG2(DBG_TNC, "TNC client is handling outbound connection"); - if (this->batch_type == PB_BATCH_NONE) - { - if (this->is_server) + /* Before sending the first PB-TNC batch create TNC client */ + if (this->tnc_client) { - if (state == PB_STATE_SERVER_WORKING) - { - if (this->state_machine->get_empty_cdata(this->state_machine)) - { - check_and_build_recommendation(this); - } - else - { - DBG2(DBG_TNC, "no recommendation available yet, " - "sending empty PB-TNC SDATA batch"); - this->batch_type = PB_BATCH_SDATA; - } - } + this->tnccs_handler = this->tnc_client; } else { - switch (state) + this->tnc_client = tnccs_20_client_create(&this->public, _send_msg, + this->max_batch_len, + this->max_msg_len); + if (!this->tnc_client) { - case PB_STATE_CLIENT_WORKING: - DBG2(DBG_TNC, "no client data to send, " - "sending empty PB-TNC CDATA batch"); - this->batch_type = PB_BATCH_CDATA; - break; - case PB_STATE_DECIDED: - /** - * In the DECIDED state and if no CRETRY is under way, - * a PB-TNC client replies with an empty CLOSE batch. - */ - this->batch_type = PB_BATCH_CLOSE; - break; - default: - break; + return FAILED; } + this->tnccs_handler = this->tnc_client; + this->tnccs_handler->begin_handshake(this->tnccs_handler, + this->mutual); } } - - if (this->batch_type != PB_BATCH_NONE) + else { - pb_tnc_batch_t *batch; - pb_tnc_msg_t *msg; - chunk_t data; - int msg_count; - enumerator_t *enumerator; + DBG2(DBG_TNC, "TNC server is handling outbound connection"); - if (this->state_machine->send_batch(this->state_machine, this->batch_type)) + /* Before sending the first PB-TNC batch create TNC server */ + if (this->tnc_server) { - batch = pb_tnc_batch_create(this->is_server, this->batch_type, - min(this->max_batch_len, *buflen)); - - enumerator = this->messages->create_enumerator(this->messages); - while (enumerator->enumerate(enumerator, &msg)) - { - if (batch->add_msg(batch, msg)) - { - this->messages->remove_at(this->messages, enumerator); - } - else - { - break; - } - } - enumerator->destroy(enumerator); - - batch->build(batch); - data = batch->get_encoding(batch); - DBG1(DBG_TNC, "sending PB-TNC %N batch (%d bytes) for Connection ID %u", - pb_tnc_batch_type_names, this->batch_type, data.len, - this->connection_id); - DBG3(DBG_TNC, "%B", &data); - - *buflen = data.len; - *msglen = 0; - memcpy(buf, data.ptr, *buflen); - batch->destroy(batch); - - msg_count = this->messages->get_count(this->messages); - if (msg_count) - { - DBG2(DBG_TNC, "queued %d PB-TNC message%s for next %N batch", - msg_count, (msg_count == 1) ? "" : "s", - pb_tnc_batch_type_names, this->batch_type); - } - else - { - this->batch_type = PB_BATCH_NONE; - } - - status = ALREADY_DONE; + this->tnccs_handler = this->tnc_server; } else { - change_batch_type(this, PB_BATCH_NONE); - status = INVALID_STATE; + this->tnc_server = tnccs_20_server_create(&this->public, _send_msg, + this->max_batch_len, this->max_msg_len, + this->eap_transport); + if (!this->tnc_server) + { + return FAILED; + } + this->tnccs_handler = this->tnc_server; + this->tnccs_handler->begin_handshake(this->tnccs_handler, + this->mutual); } } - else - { - DBG1(DBG_TNC, "no PB-TNC batch to send"); - status = INVALID_STATE; - } - this->mutex->unlock(this->mutex); - - return status; + return this->tnccs_handler->build(this->tnccs_handler, buf, buflen, msglen); } METHOD(tls_t, is_server, bool, @@ -923,20 +337,20 @@ METHOD(tls_t, is_server, bool, METHOD(tls_t, get_server_id, identification_t*, private_tnccs_20_t *this) { - return this->server; + return this->server_id; } METHOD(tls_t, set_peer_id, void, private_tnccs_20_t *this, identification_t *id) { - DESTROY_IF(this->peer); - this->peer = id->clone(id); + DESTROY_IF(this->peer_id); + this->peer_id = id->clone(id); } METHOD(tls_t, get_peer_id, identification_t*, private_tnccs_20_t *this) { - return this->peer; + return this->peer_id; } METHOD(tls_t, get_purpose, tls_purpose_t, @@ -951,14 +365,17 @@ METHOD(tls_t, is_complete, bool, TNC_IMV_Action_Recommendation rec; TNC_IMV_Evaluation_Result eval; - if (this->recs && this->recs->have_recommendation(this->recs, &rec, &eval)) + if (this->tnc_server) { - return this->callback ? this->callback(rec, eval) : TRUE; - } - else - { - return FALSE; + tnccs_20_server_t *tnc_server; + + tnc_server = (tnccs_20_server_t*)this->tnc_server; + if (tnc_server->have_recommendation(tnc_server, &rec, &eval)) + { + return this->callback ? this->callback(rec, eval) : TRUE; + } } + return FALSE; } METHOD(tls_t, get_eap_msk, chunk_t, @@ -972,19 +389,28 @@ METHOD(tls_t, destroy, void, { if (ref_put(&this->ref)) { - tnc->tnccs->remove_connection(tnc->tnccs, this->connection_id, - this->is_server); - this->server->destroy(this->server); - this->peer->destroy(this->peer); - this->state_machine->destroy(this->state_machine); - this->mutex->destroy(this->mutex); - this->messages->destroy_offset(this->messages, - offsetof(pb_tnc_msg_t, destroy)); - free(this->pdp_server.ptr); + DESTROY_IF(this->tnc_server); + DESTROY_IF(this->tnc_client); + this->server_id->destroy(this->server_id); + this->peer_id->destroy(this->peer_id); + this->server_ip->destroy(this->server_ip); + this->peer_ip->destroy(this->peer_ip); free(this); } } +METHOD(tnccs_t, get_server_ip, host_t*, + private_tnccs_20_t *this) +{ + return this->server_ip; +} + +METHOD(tnccs_t, get_peer_ip, host_t*, + private_tnccs_20_t *this) +{ + return this->peer_ip; +} + METHOD(tnccs_t, get_transport, tnc_ift_type_t, private_tnccs_20_t *this) { @@ -1012,9 +438,19 @@ METHOD(tnccs_t, set_auth_type, void, METHOD(tnccs_t, get_pdp_server, chunk_t, private_tnccs_20_t *this, u_int16_t *port) { - *port = this->pdp_port; + if (this->tnc_client) + { + tnccs_20_client_t *tnc_client; + + tnc_client = (tnccs_20_client_t*)this->tnc_client; - return this->pdp_server; + return tnc_client->get_pdp_server(tnc_client, port); + } + else + { + *port = 0; + return chunk_empty; + } } METHOD(tnccs_t, get_ref, tnccs_t*, @@ -1027,9 +463,10 @@ METHOD(tnccs_t, get_ref, tnccs_t*, /** * See header */ -tnccs_t* tnccs_20_create(bool is_server, - identification_t *server, identification_t *peer, - tnc_ift_type_t transport, tnccs_cb_t cb) +tnccs_t* tnccs_20_create(bool is_server, identification_t *server_id, + identification_t *peer_id, host_t *server_ip, + host_t *peer_ip, tnc_ift_type_t transport, + tnccs_cb_t cb) { private_tnccs_20_t *this; size_t max_batch_size, default_max_batch_size; @@ -1079,6 +516,8 @@ tnccs_t* tnccs_20_create(bool is_server, .get_eap_msk = _get_eap_msk, .destroy = _destroy, }, + .get_server_ip = _get_server_ip, + .get_peer_ip = _get_peer_ip, .get_transport = _get_transport, .set_transport = _set_transport, .get_auth_type = _get_auth_type, @@ -1087,13 +526,15 @@ tnccs_t* tnccs_20_create(bool is_server, .get_ref = _get_ref, }, .is_server = is_server, - .server = server->clone(server), - .peer = peer->clone(peer), + .to_server = !is_server, + .server_id = server_id->clone(server_id), + .peer_id = peer_id->clone(peer_id), + .server_ip = server_ip->clone(server_ip), + .peer_ip = peer_ip->clone(peer_ip), .transport = transport, + .eap_transport = transport == TNC_IFT_EAP_1_1 || + transport == TNC_IFT_EAP_2_0, .callback = cb, - .state_machine = pb_tnc_state_machine_create(is_server), - .mutex = mutex_create(MUTEX_TYPE_DEFAULT), - .messages = linked_list_create(), .max_batch_len = max_batch_size, .max_msg_len = max_message_size, .ref = 1, diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20.h b/src/libtnccs/plugins/tnccs_20/tnccs_20.h index 2857b1408..010cbecdc 100644 --- a/src/libtnccs/plugins/tnccs_20/tnccs_20.h +++ b/src/libtnccs/plugins/tnccs_20/tnccs_20.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2013 Andreas Steffen + * Copyright (C) 2010-2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -29,14 +29,17 @@ * Create an instance of the TNC IF-TNCCS 2.0 protocol handler. * * @param is_server TRUE to act as TNC Server, FALSE for TNC Client - * @param server Server identity - * @param peer Client identity + * @param server_id Server identity + * @param peer_id Client identity + * @param server_ip Server IP address + * @param peer_ip Client IP address * @param transport Underlying IF-T transport protocol * @param cb Callback function if TNC Server, NULL if TNC Client * @return TNC_IF_TNCCS 2.0 protocol stack */ -tnccs_t* tnccs_20_create(bool is_server, - identification_t *server, identification_t *peer, - tnc_ift_type_t transport, tnccs_cb_t cb); +tnccs_t* tnccs_20_create(bool is_server, identification_t *server_id, + identification_t *peer_id, host_t *server_ip, + host_t *peer_ip, tnc_ift_type_t transport, + tnccs_cb_t cb); #endif /** TNCCS_20_H_ @}*/ diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20_client.c b/src/libtnccs/plugins/tnccs_20/tnccs_20_client.c new file mode 100644 index 000000000..4ba8221d0 --- /dev/null +++ b/src/libtnccs/plugins/tnccs_20/tnccs_20_client.c @@ -0,0 +1,820 @@ +/* + * Copyright (C) 2015 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "tnccs_20_client.h" +#include "messages/pb_tnc_msg.h" +#include "messages/ietf/pb_pa_msg.h" +#include "messages/ietf/pb_error_msg.h" +#include "messages/ietf/pb_assessment_result_msg.h" +#include "messages/ietf/pb_access_recommendation_msg.h" +#include "messages/ietf/pb_remediation_parameters_msg.h" +#include "messages/ietf/pb_reason_string_msg.h" +#include "messages/ietf/pb_language_preference_msg.h" +#include "messages/ita/pb_mutual_capability_msg.h" +#include "messages/ita/pb_noskip_test_msg.h" +#include "messages/tcg/pb_pdp_referral_msg.h" +#include "state_machine/pb_tnc_state_machine.h" + +#include <tncif_names.h> +#include <tncif_pa_subtypes.h> + +#include <tnc/tnc.h> +#include <tnc/tnccs/tnccs_manager.h> +#include <tnc/imc/imc_manager.h> + +#include <threading/mutex.h> +#include <utils/debug.h> +#include <collections/linked_list.h> +#include <pen/pen.h> + +typedef struct private_tnccs_20_client_t private_tnccs_20_client_t; + +/** + * Private data of a tnccs_20_client_t object. + */ +struct private_tnccs_20_client_t { + + /** + * Public tnccs_20_client_t interface. + */ + tnccs_20_client_t public; + + /** + * PB-TNC State Machine + */ + pb_tnc_state_machine_t *state_machine; + + /** + * Connection ID assigned to this TNCCS connection + */ + TNC_ConnectionID connection_id; + + /** + * PB-TNC messages to be sent + */ + linked_list_t *messages; + + /** + * Type of PB-TNC batch being constructed + */ + pb_tnc_batch_type_t batch_type; + + /** + * Maximum PB-TNC batch size + */ + size_t max_batch_len; + + /** + * Mutex locking the batch in construction + */ + mutex_t *mutex; + + /** + * Flag set while processing + */ + bool fatal_error; + + /** + * Flag set by IMC RequestHandshakeRetry() function + */ + bool request_handshake_retry; + + /** + * SendMessage() by IMC only allowed if flag is set + */ + bool send_msg; + + /** + * PDP server FQDN + */ + chunk_t pdp_server; + + /** + * PDP server port + */ + u_int16_t pdp_port; + + /** + * Mutual PB-TNC protocol enabled + */ + bool mutual; + + /** + * Mutual Capability message sent + */ + bool sent_mutual_capability; + +}; + +/** + * The following two functions are shared with the tnccs_20_server class + */ +void tnccs_20_handle_ietf_error_msg(pb_tnc_msg_t *msg, bool *fatal_error) +{ + pb_error_msg_t *err_msg; + u_int32_t vendor_id; + u_int16_t error_code; + bool fatal; + + err_msg = (pb_error_msg_t*)msg; + fatal = err_msg->get_fatal_flag(err_msg); + vendor_id = err_msg->get_vendor_id(err_msg); + error_code = err_msg->get_error_code(err_msg); + + if (fatal) + { + *fatal_error = TRUE; + } + + if (vendor_id == PEN_IETF) + { + switch (error_code) + { + case PB_ERROR_INVALID_PARAMETER: + case PB_ERROR_UNSUPPORTED_MANDATORY_MSG: + DBG1(DBG_TNC, "received %s PB-TNC error '%N' (offset %u bytes)", + fatal ? "fatal" : "non-fatal", + pb_tnc_error_code_names, error_code, + err_msg->get_offset(err_msg)); + break; + case PB_ERROR_VERSION_NOT_SUPPORTED: + DBG1(DBG_TNC, "received %s PB-TNC error '%N' " + "caused by bad version 0x%02x", + fatal ? "fatal" : "non-fatal", + pb_tnc_error_code_names, error_code, + err_msg->get_bad_version(err_msg)); + break; + case PB_ERROR_UNEXPECTED_BATCH_TYPE: + case PB_ERROR_LOCAL_ERROR: + default: + DBG1(DBG_TNC, "received %s PB-TNC error '%N'", + fatal ? "fatal" : "non-fatal", + pb_tnc_error_code_names, error_code); + break; + } + } + else + { + DBG1(DBG_TNC, "received %s PB-TNC error (%u) with Vendor ID 0x%06x", + fatal ? "fatal" : "non-fatal", error_code, vendor_id); + } +} + +bool tnccs_20_handle_ita_mutual_capability_msg(pb_tnc_msg_t *msg) +{ + pb_mutual_capability_msg_t *mutual_msg; + uint32_t protocols; + + if (!lib->settings->get_bool(lib->settings, + "%s.plugins.tnccs-20.mutual", FALSE, lib->ns)) + { + /* PB-TNC mutual capability disabled, ignore message */ + return FALSE; + } + + mutual_msg = (pb_mutual_capability_msg_t*)msg; + protocols = mutual_msg->get_protocols(mutual_msg); + + if (protocols & PB_MUTUAL_HALF_DUPLEX) + { + DBG1(DBG_TNC, "activating mutual PB-TNC %N protocol", + pb_tnc_mutual_protocol_type_names, PB_MUTUAL_HALF_DUPLEX); + return TRUE; + } + + return FALSE; +} + +/** + * If the batch type changes then delete all accumulated PB-TNC messages + */ +static void change_batch_type(private_tnccs_20_client_t *this, + pb_tnc_batch_type_t batch_type) +{ + pb_tnc_msg_t *msg; + + if (batch_type != this->batch_type) + { + if (this->batch_type != PB_BATCH_NONE) + { + DBG1(DBG_TNC, "cancelling PB-TNC %N batch", + pb_tnc_batch_type_names, this->batch_type); + + while (this->messages->remove_last(this->messages, + (void**)&msg) == SUCCESS) + { + msg->destroy(msg); + } + } + this->batch_type = batch_type; + } +} + +/** + * Handle a single PB-TNC IETF standard message according to its type + */ +static void handle_ietf_message(private_tnccs_20_client_t *this, pb_tnc_msg_t *msg) +{ + pen_type_t msg_type = msg->get_type(msg); + + switch (msg_type.type) + { + case PB_MSG_EXPERIMENTAL: + /* nothing to do */ + break; + case PB_MSG_PA: + { + pb_pa_msg_t *pa_msg; + pen_type_t msg_subtype; + u_int16_t imc_id, imv_id; + chunk_t msg_body; + bool excl; + enum_name_t *pa_subtype_names; + + pa_msg = (pb_pa_msg_t*)msg; + msg_subtype = pa_msg->get_subtype(pa_msg); + msg_body = pa_msg->get_body(pa_msg); + imc_id = pa_msg->get_collector_id(pa_msg); + imv_id = pa_msg->get_validator_id(pa_msg); + excl = pa_msg->get_exclusive_flag(pa_msg); + + pa_subtype_names = get_pa_subtype_names(msg_subtype.vendor_id); + if (pa_subtype_names) + { + DBG2(DBG_TNC, "handling PB-PA message type '%N/%N' 0x%06x/0x%08x", + pen_names, msg_subtype.vendor_id, pa_subtype_names, + msg_subtype.type, msg_subtype.vendor_id, msg_subtype.type); + } + else + { + DBG2(DBG_TNC, "handling PB-PA message type '%N' 0x%06x/0x%08x", + pen_names, msg_subtype.vendor_id, msg_subtype.vendor_id, + msg_subtype.type); + } + this->send_msg = TRUE; + tnc->imcs->receive_message(tnc->imcs, this->connection_id, + excl, msg_body.ptr, msg_body.len, + msg_subtype.vendor_id, + msg_subtype.type, imv_id, imc_id); + this->send_msg = FALSE; + break; + } + case PB_MSG_ASSESSMENT_RESULT: + { + pb_assessment_result_msg_t *assess_msg; + u_int32_t result; + + assess_msg = (pb_assessment_result_msg_t*)msg; + result = assess_msg->get_assessment_result(assess_msg); + DBG1(DBG_TNC, "PB-TNC assessment result is '%N'", + TNC_IMV_Evaluation_Result_names, result); + break; + } + case PB_MSG_ACCESS_RECOMMENDATION: + { + pb_access_recommendation_msg_t *rec_msg; + pb_access_recommendation_code_t rec; + TNC_ConnectionState state = TNC_CONNECTION_STATE_ACCESS_NONE; + + rec_msg = (pb_access_recommendation_msg_t*)msg; + rec = rec_msg->get_access_recommendation(rec_msg); + DBG1(DBG_TNC, "PB-TNC access recommendation is '%N'", + pb_access_recommendation_code_names, rec); + switch (rec) + { + case PB_REC_ACCESS_ALLOWED: + state = TNC_CONNECTION_STATE_ACCESS_ALLOWED; + break; + case PB_REC_ACCESS_DENIED: + state = TNC_CONNECTION_STATE_ACCESS_NONE; + break; + case PB_REC_QUARANTINED: + state = TNC_CONNECTION_STATE_ACCESS_ISOLATED; + } + tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id, + state); + break; + } + case PB_MSG_REMEDIATION_PARAMETERS: + { + pb_remediation_parameters_msg_t *rem_msg; + pen_type_t parameters_type; + chunk_t parameters, string, lang_code; + + rem_msg = (pb_remediation_parameters_msg_t*)msg; + parameters_type = rem_msg->get_parameters_type(rem_msg); + parameters = rem_msg->get_parameters(rem_msg); + + if (parameters_type.vendor_id == PEN_IETF) + { + switch (parameters_type.type) + { + case PB_REMEDIATION_URI: + DBG1(DBG_TNC, "remediation uri: %.*s", + parameters.len, parameters.ptr); + break; + case PB_REMEDIATION_STRING: + string = rem_msg->get_string(rem_msg, &lang_code); + DBG1(DBG_TNC, "remediation string: [%.*s]\n%.*s", + lang_code.len, lang_code.ptr, + string.len, string.ptr); + break; + default: + DBG1(DBG_TNC, "remediation parameters: %B", ¶meters); + } + } + else + { + DBG1(DBG_TNC, "remediation parameters: %B", ¶meters); + } + break; + } + case PB_MSG_ERROR: + tnccs_20_handle_ietf_error_msg(msg, &this->fatal_error); + break; + case PB_MSG_REASON_STRING: + { + pb_reason_string_msg_t *reason_msg; + chunk_t reason_string, language_code; + + reason_msg = (pb_reason_string_msg_t*)msg; + reason_string = reason_msg->get_reason_string(reason_msg); + language_code = reason_msg->get_language_code(reason_msg); + DBG1(DBG_TNC, "reason string is '%.*s' [%.*s]", + (int)reason_string.len, reason_string.ptr, + (int)language_code.len, language_code.ptr); + break; + } + default: + break; + } +} + +/** + * Handle a single PB-TNC TCG standard message according to its type + */ +static void handle_tcg_message(private_tnccs_20_client_t *this, pb_tnc_msg_t *msg) +{ + pen_type_t msg_type = msg->get_type(msg); + + switch (msg_type.type) + { + case PB_TCG_MSG_PDP_REFERRAL: + { + pb_pdp_referral_msg_t *pdp_msg; + pen_type_t pdp_id_type; + u_int8_t pdp_protocol; + + pdp_msg = (pb_pdp_referral_msg_t*)msg; + pdp_id_type = pdp_msg->get_identifier_type(pdp_msg); + + if (pdp_id_type.vendor_id == PEN_TCG && + pdp_id_type.type == PB_PDP_ID_FQDN) + { + this->pdp_server = chunk_clone(pdp_msg->get_fqdn(pdp_msg, + &pdp_protocol, &this->pdp_port)); + if (pdp_protocol != 0) + { + DBG1(DBG_TNC, "unsupported PDP transport protocol"); + break; + } + DBG1(DBG_TNC, "PDP server '%.*s' is listening on port %u", + this->pdp_server.len, this->pdp_server.ptr, + this->pdp_port); + } + break; + } + default: + break; + } +} + +/** + * Handle a single PB-TNC ITA standard message according to its type + */ +static void handle_ita_message(private_tnccs_20_client_t *this, pb_tnc_msg_t *msg) +{ + pen_type_t msg_type = msg->get_type(msg); + + switch (msg_type.type) + { + case PB_ITA_MSG_MUTUAL_CAPABILITY: + this->mutual = tnccs_20_handle_ita_mutual_capability_msg(msg); + break; + default: + break; + } +} + +/** + * Handle a single PB-TNC message according to its type + */ +static void handle_message(private_tnccs_20_client_t *this, pb_tnc_msg_t *msg) +{ + pen_type_t msg_type = msg->get_type(msg); + + switch (msg_type.vendor_id) + { + case PEN_IETF: + handle_ietf_message(this, msg); + break; + case PEN_TCG: + handle_tcg_message(this, msg); + break; + case PEN_ITA: + handle_ita_message(this, msg); + break; + default: + break; + } +} + +/** + * Build a CRETRY batch + */ +static void build_retry_batch(private_tnccs_20_client_t *this) +{ + if (this->batch_type == PB_BATCH_CRETRY) + { + /* retry batch has already been selected */ + return; + } + change_batch_type(this, PB_BATCH_CRETRY); +} + +METHOD(tnccs_20_handler_t, process, status_t, + private_tnccs_20_client_t *this, pb_tnc_batch_t *batch) +{ + pb_tnc_batch_type_t batch_type; + status_t status; + + batch_type = batch->get_type(batch); + + DBG1(DBG_TNC, "processing PB-TNC %N batch for Connection ID %d", + pb_tnc_batch_type_names, batch_type, this->connection_id); + + status = batch->process(batch, this->state_machine); + + if (status != FAILED) + { + enumerator_t *enumerator; + pb_tnc_msg_t *msg; + bool empty = TRUE; + + if (batch_type == PB_BATCH_SRETRY) + { + /* Restart the measurements */ + tnc->imcs->notify_connection_change(tnc->imcs, + this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE); + this->send_msg = TRUE; + tnc->imcs->begin_handshake(tnc->imcs, this->connection_id); + this->send_msg = FALSE; + } + + enumerator = batch->create_msg_enumerator(batch); + while (enumerator->enumerate(enumerator, &msg)) + { + handle_message(this, msg); + empty = FALSE; + } + enumerator->destroy(enumerator); + + /* received a CLOSE batch from PB-TNC server */ + if (batch_type == PB_BATCH_CLOSE) + { + return empty ? SUCCESS : FAILED; + } + + this->send_msg = TRUE; + tnc->imcs->batch_ending(tnc->imcs, this->connection_id); + this->send_msg = FALSE; + } + + switch (status) + { + case FAILED: + this->fatal_error = TRUE; + status = VERIFY_ERROR; + break; + case VERIFY_ERROR: + break; + case SUCCESS: + default: + status = NEED_MORE; + break; + } + + return status; +} + +METHOD(tnccs_20_handler_t, build, status_t, + private_tnccs_20_client_t *this, void *buf, size_t *buflen, size_t *msglen) +{ + status_t status; + pb_tnc_state_t state; + + state = this->state_machine->get_state(this->state_machine); + + if (this->fatal_error && state == PB_STATE_END) + { + DBG1(DBG_TNC, "a fatal PB-TNC error occurred, terminating connection"); + return FAILED; + } + + /* Do not allow any asynchronous IMCs to add additional messages */ + this->mutex->lock(this->mutex); + + if (this->request_handshake_retry) + { + if (state != PB_STATE_INIT) + { + build_retry_batch(this); + } + + /* Reset the flag for the next handshake retry request */ + this->request_handshake_retry = FALSE; + } + + if (this->batch_type == PB_BATCH_NONE) + { + switch (state) + { + case PB_STATE_CLIENT_WORKING: + DBG2(DBG_TNC, "no client data to send, " + "sending empty PB-TNC CDATA batch"); + this->batch_type = PB_BATCH_CDATA; + break; + case PB_STATE_DECIDED: + /** + * In the DECIDED state and if no CRETRY is under way, + * a PB-TNC client replies with an empty CLOSE batch. + */ + this->batch_type = PB_BATCH_CLOSE; + break; + default: + break; + } + } + + if (this->batch_type != PB_BATCH_NONE) + { + pb_tnc_batch_t *batch; + pb_tnc_msg_t *msg; + chunk_t data; + int msg_count; + enumerator_t *enumerator; + + if (this->state_machine->send_batch(this->state_machine, this->batch_type)) + { + batch = pb_tnc_batch_create(FALSE, this->batch_type, + min(this->max_batch_len, *buflen)); + + enumerator = this->messages->create_enumerator(this->messages); + while (enumerator->enumerate(enumerator, &msg)) + { + if (batch->add_msg(batch, msg)) + { + this->messages->remove_at(this->messages, enumerator); + } + else + { + break; + } + } + enumerator->destroy(enumerator); + + batch->build(batch); + data = batch->get_encoding(batch); + DBG1(DBG_TNC, "sending PB-TNC %N batch (%d bytes) for Connection ID %u", + pb_tnc_batch_type_names, this->batch_type, data.len, + this->connection_id); + DBG3(DBG_TNC, "%B", &data); + + *buflen = data.len; + *msglen = 0; + memcpy(buf, data.ptr, *buflen); + batch->destroy(batch); + + msg_count = this->messages->get_count(this->messages); + if (msg_count) + { + DBG2(DBG_TNC, "queued %d PB-TNC message%s for next %N batch", + msg_count, (msg_count == 1) ? "" : "s", + pb_tnc_batch_type_names, this->batch_type); + } + else + { + this->batch_type = PB_BATCH_NONE; + } + + status = ALREADY_DONE; + } + else + { + change_batch_type(this, PB_BATCH_NONE); + status = INVALID_STATE; + } + } + else + { + DBG1(DBG_TNC, "no PB-TNC batch to send"); + status = INVALID_STATE; + } + this->mutex->unlock(this->mutex); + + return status; +} + +METHOD(tnccs_20_handler_t, begin_handshake, void, + private_tnccs_20_client_t *this, bool mutual) +{ + pb_tnc_msg_t *msg; + char *pref_lang; + + tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id, + TNC_CONNECTION_STATE_HANDSHAKE); + + /* Announce PB-TNC Mutual Capability if activated */ + this->sent_mutual_capability = mutual; + + if (!mutual && lib->settings->get_bool(lib->settings, + "%s.plugins.tnccs-20.mutual", FALSE, lib->ns)) + { + pb_tnc_mutual_protocol_type_t protocols; + + protocols = PB_MUTUAL_HALF_DUPLEX; + DBG2(DBG_TNC, "proposing PB-TNC mutual %N protocol", + pb_tnc_mutual_protocol_type_names, PB_MUTUAL_HALF_DUPLEX); + msg = pb_mutual_capability_msg_create(protocols); + this->mutex->lock(this->mutex); + this->messages->insert_last(this->messages, msg); + this->mutex->unlock(this->mutex); + this->sent_mutual_capability = TRUE; + } + + /* Create PB-TNC Language Preference message */ + pref_lang = tnc->imcs->get_preferred_language(tnc->imcs); + msg = pb_language_preference_msg_create(chunk_create(pref_lang, + strlen(pref_lang))); + this->mutex->lock(this->mutex); + this->messages->insert_last(this->messages, msg); + this->mutex->unlock(this->mutex); + + this->send_msg = TRUE; + tnc->imcs->begin_handshake(tnc->imcs, this->connection_id); + this->send_msg = FALSE; + + /* Send a PB-Noskip-Test message for testing purposes */ + if (lib->settings->get_bool(lib->settings, + "%s.plugins.tnccs-20.tests.pb_tnc_noskip", FALSE, lib->ns)) + { + msg = pb_noskip_test_msg_create(); + this->mutex->lock(this->mutex); + this->messages->insert_last(this->messages, msg); + this->mutex->unlock(this->mutex); + } +} + +METHOD(tnccs_20_handler_t, get_send_flag, bool, + private_tnccs_20_client_t *this) +{ + return this->send_msg; +} + +METHOD(tnccs_20_handler_t, get_mutual, bool, + private_tnccs_20_client_t *this) +{ + return this->mutual; +} + +METHOD(tnccs_20_handler_t, get_state, pb_tnc_state_t, + private_tnccs_20_client_t *this) +{ + return this->state_machine->get_state(this->state_machine); +} + +METHOD(tnccs_20_handler_t, add_msg, void, + private_tnccs_20_client_t *this, pb_tnc_msg_t *msg) +{ + /* adding PA message to CDATA batch only */ + this->mutex->lock(this->mutex); + if (this->batch_type == PB_BATCH_NONE) + { + this->batch_type = PB_BATCH_CDATA; + } + if (this->batch_type == PB_BATCH_CDATA) + { + this->messages->insert_last(this->messages, msg); + } + else + { + msg->destroy(msg); + } + this->mutex->unlock(this->mutex); +} + +METHOD(tnccs_20_handler_t, handle_errors, void, + private_tnccs_20_client_t *this, pb_tnc_batch_t *batch, + bool fatal_header_error) +{ + pb_tnc_msg_t *msg; + enumerator_t *enumerator; + + if (fatal_header_error || this->fatal_error) + { + this->mutex->lock(this->mutex); + change_batch_type(this, PB_BATCH_CLOSE); + this->mutex->unlock(this->mutex); + } + + enumerator = batch->create_error_enumerator(batch); + while (enumerator->enumerate(enumerator, &msg)) + { + this->mutex->lock(this->mutex); + this->messages->insert_last(this->messages, msg->get_ref(msg)); + this->mutex->unlock(this->mutex); + } + enumerator->destroy(enumerator); +} + +METHOD(tnccs_20_handler_t, destroy, void, + private_tnccs_20_client_t *this) +{ + if (this->connection_id) + { + tnc->tnccs->remove_connection(tnc->tnccs, this->connection_id, FALSE); + } + this->state_machine->destroy(this->state_machine); + this->mutex->destroy(this->mutex); + this->messages->destroy_offset(this->messages, + offsetof(pb_tnc_msg_t, destroy)); + free(this->pdp_server.ptr); + free(this); +} + +METHOD(tnccs_20_client_t, get_pdp_server, chunk_t, + private_tnccs_20_client_t *this, u_int16_t *port) +{ + *port = this->pdp_port; + + return this->pdp_server; +} + +/** + * See header + */ +tnccs_20_handler_t* tnccs_20_client_create(tnccs_t *tnccs, + tnccs_send_message_t send_msg, + size_t max_batch_len, + size_t max_msg_len) +{ + private_tnccs_20_client_t *this; + + INIT(this, + .public = { + .handler = { + .process = _process, + .build = _build, + .begin_handshake = _begin_handshake, + .get_send_flag = _get_send_flag, + .get_mutual = _get_mutual, + .get_state = _get_state, + .add_msg = _add_msg, + .handle_errors = _handle_errors, + .destroy = _destroy, + }, + .get_pdp_server = _get_pdp_server, + }, + .state_machine = pb_tnc_state_machine_create(FALSE), + .mutex = mutex_create(MUTEX_TYPE_DEFAULT), + .messages = linked_list_create(), + .batch_type = PB_BATCH_CDATA, + .max_batch_len = max_batch_len, + ); + + this->connection_id = tnc->tnccs->create_connection(tnc->tnccs, + TNCCS_2_0, tnccs, send_msg, + &this->request_handshake_retry, + max_msg_len, NULL); + if (!this->connection_id) + { + destroy(this); + return NULL; + } + tnc->imcs->notify_connection_change(tnc->imcs, this->connection_id, + TNC_CONNECTION_STATE_CREATE); + + return &this->public.handler; +} diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20_client.h b/src/libtnccs/plugins/tnccs_20/tnccs_20_client.h new file mode 100644 index 000000000..7a5f33ebc --- /dev/null +++ b/src/libtnccs/plugins/tnccs_20/tnccs_20_client.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2015 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup tnccs_20_client_h tnccs_20_client + * @{ @ingroup tnccs_20 + */ + +#ifndef TNCCS_20_CLIENT_H_ +#define TNCCS_20_CLIENT_H_ + +#include <library.h> + +#include <tnc/tnccs/tnccs.h> + +#include "tnccs_20_handler.h" + +typedef struct tnccs_20_client_t tnccs_20_client_t; + +/** + * Interface for a TNC client + */ +struct tnccs_20_client_t { + + /** + * IF-TNCCS 2.0 protocol handler interface + */ + tnccs_20_handler_t handler; + + /** + * Get PDP server information if available + * + * @param port PT-TLS port of the PDP server + * @return FQDN of PDP server + */ + chunk_t (*get_pdp_server)(tnccs_20_client_t *this, u_int16_t *port); + +}; + +/** + * Create an instance of the TNC IF-TNCCS 2.0 client-side protocol handler. + * + * @param tnccs TNC IF-TNCCS 2.0 stack + * @param send_msg TNF IF-TNCCS 2.0 send message callback function + * @param max_batch_len Maximum PB-TNC batch size + * @param max_msg_len Maximum PA-TNC message size + */ +tnccs_20_handler_t* tnccs_20_client_create(tnccs_t *tnccs, + tnccs_send_message_t send_msg, + size_t max_batch_len, + size_t max_msg_len); + +#endif /** TNCCS_20_CLIENT_H_ @}*/ diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20_handler.h b/src/libtnccs/plugins/tnccs_20/tnccs_20_handler.h new file mode 100644 index 000000000..5c4d7a7b4 --- /dev/null +++ b/src/libtnccs/plugins/tnccs_20/tnccs_20_handler.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2015 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup tnccs_20_handler_h tnccs_20_handler + * @{ @ingroup tnccs_20 + */ + +#ifndef TNCCS_20_HANDLER_H_ +#define TNCCS_20_HANDLER_H_ + +#include <library.h> + +#include "batch/pb_tnc_batch.h" +#include "messages/pb_tnc_msg.h" + +typedef struct tnccs_20_handler_t tnccs_20_handler_t; + +/** + * Interface for an IF-TNCCS 2.0 protocol handler + */ +struct tnccs_20_handler_t { + + /** + * Process content of received PB-TNC batch + * + * @param batch PB-TNC batch to be processed + * @return status + */ + status_t (*process)(tnccs_20_handler_t *this, pb_tnc_batch_t *batch); + + /** + * Build PB-TNC batch to be sent + * + * @param buf buffer to write PB-TNC batch to + * @param buflen size of buffer, receives bytes written + * @param msglen receives size of all PB-TNCH batch + * @return status + */ + status_t (*build)(tnccs_20_handler_t *this, void *buf, size_t *buflen, + size_t *msglen); + + /** + * Put the IMCs or IMVs into the handshake state + * + * @param mutual TRUE if PB-TNC mutual mode is already established + */ + void (*begin_handshake)(tnccs_20_handler_t *this, bool mutual); + + /** + * Indicates if IMCs or IMVs are allowed to send PA-TNC messages + * + * @return TRUE if allowed to send + */ + bool (*get_send_flag)(tnccs_20_handler_t *this); + + /** + * Indicates if the PB-TNC mutual protocol has been enabled + * + * @return TRUE if enabled + */ + bool (*get_mutual)(tnccs_20_handler_t *this); + + /** + * Get state of the PB-TNC protocol + * + * @return PB-TNC state + */ + pb_tnc_state_t (*get_state)(tnccs_20_handler_t *this); + + /** + * Add a PB-PA message to the handler's message queue + * + * @param msg PB-PA message to be added + */ + void (*add_msg)(tnccs_20_handler_t *this, pb_tnc_msg_t *msg); + + /** + * Handle errors that occurred during PB-TNC batch header processing + * + * @param batch batch where a fatal error occurred + * @param fatal_header_error TRUE if fatal error in batch header + */ + void (*handle_errors)(tnccs_20_handler_t *this, pb_tnc_batch_t *batch, + bool fatal_header_error); + + /** + * Destroys a tnccs_20_handler_t object. + */ + void (*destroy)(tnccs_20_handler_t *this); +}; + +#endif /** TNCCS_20_HANDLER_H_ @}*/ diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20_plugin.h b/src/libtnccs/plugins/tnccs_20/tnccs_20_plugin.h index 1c4ecf4c9..5073fbe7c 100644 --- a/src/libtnccs/plugins/tnccs_20/tnccs_20_plugin.h +++ b/src/libtnccs/plugins/tnccs_20/tnccs_20_plugin.h @@ -15,7 +15,7 @@ /** * @defgroup tnccs_20 tnccs_20 - * @ingroup cplugins + * @ingroup tplugins * * @defgroup tnccs_20_plugin tnccs_20_plugin * @{ @ingroup tnccs_20 diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20_server.c b/src/libtnccs/plugins/tnccs_20/tnccs_20_server.c new file mode 100644 index 000000000..038fc178b --- /dev/null +++ b/src/libtnccs/plugins/tnccs_20/tnccs_20_server.c @@ -0,0 +1,693 @@ +/* + * Copyright (C) 2015 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include "tnccs_20_server.h" +#include "messages/pb_tnc_msg.h" +#include "messages/ietf/pb_pa_msg.h" +#include "messages/ietf/pb_error_msg.h" +#include "messages/ietf/pb_assessment_result_msg.h" +#include "messages/ietf/pb_access_recommendation_msg.h" +#include "messages/ietf/pb_remediation_parameters_msg.h" +#include "messages/ietf/pb_reason_string_msg.h" +#include "messages/ietf/pb_language_preference_msg.h" +#include "messages/ita/pb_mutual_capability_msg.h" +#include "messages/ita/pb_noskip_test_msg.h" +#include "messages/tcg/pb_pdp_referral_msg.h" +#include "state_machine/pb_tnc_state_machine.h" + +#include <tncif_names.h> +#include <tncif_pa_subtypes.h> + +#include <tnc/tnc.h> +#include <tnc/tnccs/tnccs_manager.h> +#include <tnc/imv/imv_manager.h> + +#include <threading/mutex.h> +#include <utils/debug.h> +#include <collections/linked_list.h> +#include <pen/pen.h> + +typedef struct private_tnccs_20_server_t private_tnccs_20_server_t; + +/** + * Private data of a tnccs_20_server_t object. + */ +struct private_tnccs_20_server_t { + + /** + * Public tnccs_20_server_t interface. + */ + tnccs_20_server_t public; + + /** + * PB-TNC State Machine + */ + pb_tnc_state_machine_t *state_machine; + + /** + * Connection ID assigned to this TNCCS connection + */ + TNC_ConnectionID connection_id; + + /** + * PB-TNC messages to be sent + */ + linked_list_t *messages; + + /** + * Type of PB-TNC batch being constructed + */ + pb_tnc_batch_type_t batch_type; + + /** + * Maximum PB-TNC batch size + */ + size_t max_batch_len; + + /** + * Mutex locking the batch in construction + */ + mutex_t *mutex; + + /** + * Flag set while processing + */ + bool fatal_error; + + /** + * Flag set by IMC/IMV RequestHandshakeRetry() function + */ + bool request_handshake_retry; + + /** + * SendMessage() by IMV only allowed if flag is set + */ + bool send_msg; + + /** + * Set of IMV recommendations + */ + recommendations_t *recs; + + /** + * TNC IF-T transport protocol for EAP methods + */ + bool eap_transport; + + /** + * Mutual PB-TNC protocol enabled + */ + bool mutual; + + /** + * Mutual Capability message sent + */ + bool sent_mutual_capability; + +}; + +/** + * The following two functions are shared with the tnccs_20_server class + */ +extern void tnccs_20_handle_ietf_error_msg(pb_tnc_msg_t *msg, + bool *fatal_error); +extern bool tnccs_20_handle_ita_mutual_capability_msg(pb_tnc_msg_t *msg); + +/** + * If the batch type changes then delete all accumulated PB-TNC messages + */ +static void change_batch_type(private_tnccs_20_server_t *this, + pb_tnc_batch_type_t batch_type) +{ + pb_tnc_msg_t *msg; + + if (batch_type != this->batch_type) + { + if (this->batch_type != PB_BATCH_NONE) + { + DBG1(DBG_TNC, "cancelling PB-TNC %N batch", + pb_tnc_batch_type_names, this->batch_type); + + while (this->messages->remove_last(this->messages, + (void**)&msg) == SUCCESS) + { + msg->destroy(msg); + } + } + this->batch_type = batch_type; + } +} + +/** + * Handle a single PB-TNC IETF standard message according to its type + */ +static void handle_ietf_message(private_tnccs_20_server_t *this, pb_tnc_msg_t *msg) +{ + pen_type_t msg_type = msg->get_type(msg); + + switch (msg_type.type) + { + case PB_MSG_EXPERIMENTAL: + /* nothing to do */ + break; + case PB_MSG_PA: + { + pb_pa_msg_t *pa_msg; + pen_type_t msg_subtype; + u_int16_t imc_id, imv_id; + chunk_t msg_body; + bool excl; + enum_name_t *pa_subtype_names; + + pa_msg = (pb_pa_msg_t*)msg; + msg_subtype = pa_msg->get_subtype(pa_msg); + msg_body = pa_msg->get_body(pa_msg); + imc_id = pa_msg->get_collector_id(pa_msg); + imv_id = pa_msg->get_validator_id(pa_msg); + excl = pa_msg->get_exclusive_flag(pa_msg); + + pa_subtype_names = get_pa_subtype_names(msg_subtype.vendor_id); + if (pa_subtype_names) + { + DBG2(DBG_TNC, "handling PB-PA message type '%N/%N' 0x%06x/0x%08x", + pen_names, msg_subtype.vendor_id, pa_subtype_names, + msg_subtype.type, msg_subtype.vendor_id, msg_subtype.type); + } + else + { + DBG2(DBG_TNC, "handling PB-PA message type '%N' 0x%06x/0x%08x", + pen_names, msg_subtype.vendor_id, msg_subtype.vendor_id, + msg_subtype.type); + } + this->send_msg = TRUE; + tnc->imvs->receive_message(tnc->imvs, this->connection_id, + excl, msg_body.ptr, msg_body.len, + msg_subtype.vendor_id, + msg_subtype.type, imc_id, imv_id); + this->send_msg = FALSE; + break; + } + case PB_MSG_ERROR: + tnccs_20_handle_ietf_error_msg(msg, &this->fatal_error); + break; + case PB_MSG_LANGUAGE_PREFERENCE: + { + pb_language_preference_msg_t *lang_msg; + chunk_t lang; + + lang_msg = (pb_language_preference_msg_t*)msg; + lang = lang_msg->get_language_preference(lang_msg); + DBG2(DBG_TNC, "setting language preference to '%.*s'", + (int)lang.len, lang.ptr); + this->recs->set_preferred_language(this->recs, lang); + break; + } + default: + break; + } +} + +/** + * Handle a single PB-TNC ITA standard message according to its type + */ +static void handle_ita_message(private_tnccs_20_server_t *this, pb_tnc_msg_t *msg) +{ + pen_type_t msg_type = msg->get_type(msg); + + switch (msg_type.type) + { + case PB_ITA_MSG_MUTUAL_CAPABILITY: + this->mutual = tnccs_20_handle_ita_mutual_capability_msg(msg); + + /* Respond with PB-TNC Mutual Capability message if necessary */ + if (this->mutual && !this->sent_mutual_capability) + { + msg = pb_mutual_capability_msg_create(PB_MUTUAL_HALF_DUPLEX); + this->mutex->lock(this->mutex); + this->messages->insert_last(this->messages, msg); + this->mutex->unlock(this->mutex); + this->sent_mutual_capability = TRUE; + } + break; + default: + break; + } +} + +/** + * Handle a single PB-TNC message according to its type + */ +static void handle_message(private_tnccs_20_server_t *this, pb_tnc_msg_t *msg) +{ + pen_type_t msg_type = msg->get_type(msg); + + switch (msg_type.vendor_id) + { + case PEN_IETF: + handle_ietf_message(this, msg); + break; + case PEN_ITA: + handle_ita_message(this, msg); + break; + default: + break; + } +} + +/** + * Build an SRETRY batch + */ +static void build_retry_batch(private_tnccs_20_server_t *this) +{ + if (this->batch_type == PB_BATCH_SRETRY) + { + /* retry batch has already been selected */ + return; + } + change_batch_type(this, PB_BATCH_SRETRY); + + this->recs->clear_recommendation(this->recs); + tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id, + TNC_CONNECTION_STATE_HANDSHAKE); +} + +METHOD(tnccs_20_handler_t, process, status_t, + private_tnccs_20_server_t *this, pb_tnc_batch_t *batch) +{ + pb_tnc_batch_type_t batch_type; + status_t status; + + batch_type = batch->get_type(batch); + + DBG1(DBG_TNC, "processing PB-TNC %N batch for Connection ID %d", + pb_tnc_batch_type_names, batch_type, this->connection_id); + status = batch->process(batch, this->state_machine); + + if (status != FAILED) + { + enumerator_t *enumerator; + pb_tnc_msg_t *msg; + bool empty = TRUE; + + if (batch_type == PB_BATCH_CRETRY) + { + /* Send an SRETRY batch in response */ + this->mutex->lock(this->mutex); + build_retry_batch(this); + this->mutex->unlock(this->mutex); + } + + enumerator = batch->create_msg_enumerator(batch); + while (enumerator->enumerate(enumerator, &msg)) + { + handle_message(this, msg); + empty = FALSE; + } + enumerator->destroy(enumerator); + + /* received a CLOSE batch from PB-TNC client */ + if (batch_type == PB_BATCH_CLOSE) + { + return empty ? SUCCESS : FAILED; + } + + this->send_msg = TRUE; + tnc->imvs->batch_ending(tnc->imvs, this->connection_id); + this->send_msg = FALSE; + } + + switch (status) + { + case FAILED: + this->fatal_error = TRUE; + status = VERIFY_ERROR; + break; + case VERIFY_ERROR: + break; + case SUCCESS: + default: + status = NEED_MORE; + break; + } + + return status; +} + +/** + * Build a RESULT batch if a final recommendation is available + */ +static void check_and_build_recommendation(private_tnccs_20_server_t *this) +{ + TNC_IMV_Action_Recommendation rec; + TNC_IMV_Evaluation_Result eval; + TNC_ConnectionState state; + TNC_IMVID id; + chunk_t reason, language; + enumerator_t *enumerator; + pb_tnc_msg_t *msg; + pb_access_recommendation_code_t pb_rec; + + if (!this->recs->have_recommendation(this->recs, &rec, &eval)) + { + tnc->imvs->solicit_recommendation(tnc->imvs, this->connection_id); + } + if (this->recs->have_recommendation(this->recs, &rec, &eval)) + { + this->batch_type = PB_BATCH_RESULT; + + msg = pb_assessment_result_msg_create(eval); + this->messages->insert_last(this->messages, msg); + + /** + * Map IMV Action Recommendation codes to PB Access Recommendation codes + * and communicate Access Recommendation to IMVs + */ + switch (rec) + { + case TNC_IMV_ACTION_RECOMMENDATION_ALLOW: + state = TNC_CONNECTION_STATE_ACCESS_ALLOWED; + pb_rec = PB_REC_ACCESS_ALLOWED; + break; + case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE: + state = TNC_CONNECTION_STATE_ACCESS_ISOLATED; + pb_rec = PB_REC_QUARANTINED; + break; + case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS: + case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION: + default: + state = TNC_CONNECTION_STATE_ACCESS_NONE; + pb_rec = PB_REC_ACCESS_DENIED; + } + tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id, + state); + + msg = pb_access_recommendation_msg_create(pb_rec); + this->messages->insert_last(this->messages, msg); + + enumerator = this->recs->create_reason_enumerator(this->recs); + while (enumerator->enumerate(enumerator, &id, &reason, &language)) + { + msg = pb_reason_string_msg_create(reason, language); + this->messages->insert_last(this->messages, msg); + } + enumerator->destroy(enumerator); + } +} + +METHOD(tnccs_20_handler_t, build, status_t, + private_tnccs_20_server_t *this, void *buf, size_t *buflen, size_t *msglen) +{ + status_t status; + pb_tnc_state_t state; + + state = this->state_machine->get_state(this->state_machine); + + if (this->fatal_error && state == PB_STATE_END) + { + DBG1(DBG_TNC, "a fatal PB-TNC error occurred, terminating connection"); + return FAILED; + } + + /* Do not allow any asynchronous IMVs to add additional messages */ + this->mutex->lock(this->mutex); + + if (this->request_handshake_retry) + { + if (state != PB_STATE_INIT) + { + build_retry_batch(this); + } + + /* Reset the flag for the next handshake retry request */ + this->request_handshake_retry = FALSE; + } + + if (state == PB_STATE_SERVER_WORKING && + this->recs->have_recommendation(this->recs, NULL, NULL)) + { + check_and_build_recommendation(this); + } + + if (this->batch_type == PB_BATCH_NONE) + { + if (state == PB_STATE_SERVER_WORKING) + { + if (this->state_machine->get_empty_cdata(this->state_machine)) + { + check_and_build_recommendation(this); + } + else + { + DBG2(DBG_TNC, "no recommendation available yet, " + "sending empty PB-TNC SDATA batch"); + this->batch_type = PB_BATCH_SDATA; + } + } + } + + if (this->batch_type != PB_BATCH_NONE) + { + pb_tnc_batch_t *batch; + pb_tnc_msg_t *msg; + chunk_t data; + int msg_count; + enumerator_t *enumerator; + + if (this->state_machine->send_batch(this->state_machine, this->batch_type)) + { + batch = pb_tnc_batch_create(TRUE, this->batch_type, + min(this->max_batch_len, *buflen)); + + enumerator = this->messages->create_enumerator(this->messages); + while (enumerator->enumerate(enumerator, &msg)) + { + if (batch->add_msg(batch, msg)) + { + this->messages->remove_at(this->messages, enumerator); + } + else + { + break; + } + } + enumerator->destroy(enumerator); + + batch->build(batch); + data = batch->get_encoding(batch); + DBG1(DBG_TNC, "sending PB-TNC %N batch (%d bytes) for Connection ID %u", + pb_tnc_batch_type_names, this->batch_type, data.len, + this->connection_id); + DBG3(DBG_TNC, "%B", &data); + + *buflen = data.len; + *msglen = 0; + memcpy(buf, data.ptr, *buflen); + batch->destroy(batch); + + msg_count = this->messages->get_count(this->messages); + if (msg_count) + { + DBG2(DBG_TNC, "queued %d PB-TNC message%s for next %N batch", + msg_count, (msg_count == 1) ? "" : "s", + pb_tnc_batch_type_names, this->batch_type); + } + else + { + this->batch_type = PB_BATCH_NONE; + } + + status = ALREADY_DONE; + } + else + { + change_batch_type(this, PB_BATCH_NONE); + status = INVALID_STATE; + } + } + else + { + DBG1(DBG_TNC, "no PB-TNC batch to send"); + status = INVALID_STATE; + } + this->mutex->unlock(this->mutex); + + return status; +} + +METHOD(tnccs_20_handler_t, begin_handshake, void, + private_tnccs_20_server_t *this, bool mutual) +{ + pb_tnc_msg_t *msg; + identification_t *pdp_server; + u_int16_t *pdp_port; + + tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id, + TNC_CONNECTION_STATE_HANDSHAKE); + + /* Send a PB-TNC TCG PDP Referral message if PDP is known */ + pdp_server = (identification_t*)lib->get(lib, "pt-tls-server"); + pdp_port = (u_int16_t*)lib->get(lib, "pt-tls-port"); + + if (this->eap_transport && pdp_server && pdp_port) + { + msg = pb_pdp_referral_msg_create_from_fqdn( + pdp_server->get_encoding(pdp_server), *pdp_port); + this->mutex->lock(this->mutex); + this->messages->insert_last(this->messages, msg); + this->mutex->unlock(this->mutex); + } + + /* Send a PB-Noskip-Test message for testing purposes */ + if (lib->settings->get_bool(lib->settings, + "%s.plugins.tnccs-20.tests.pb_tnc_noskip", FALSE, lib->ns)) + { + msg = pb_noskip_test_msg_create(); + this->mutex->lock(this->mutex); + this->messages->insert_last(this->messages, msg); + this->mutex->unlock(this->mutex); + } +} + +METHOD(tnccs_20_handler_t, get_send_flag, bool, + private_tnccs_20_server_t *this) +{ + return this->send_msg; +} + +METHOD(tnccs_20_handler_t, get_mutual, bool, + private_tnccs_20_server_t *this) +{ + return this->mutual; +} + +METHOD(tnccs_20_handler_t, get_state, pb_tnc_state_t, + private_tnccs_20_server_t *this) +{ + return this->state_machine->get_state(this->state_machine); +} + +METHOD(tnccs_20_handler_t, add_msg, void, + private_tnccs_20_server_t *this, pb_tnc_msg_t *msg) +{ + /* adding PA message to SDATA batch only */ + this->mutex->lock(this->mutex); + if (this->batch_type == PB_BATCH_NONE) + { + this->batch_type = PB_BATCH_SDATA; + } + if (this->batch_type == PB_BATCH_SDATA) + { + this->messages->insert_last(this->messages, msg); + } + else + { + msg->destroy(msg); + } + this->mutex->unlock(this->mutex); +} + +METHOD(tnccs_20_handler_t, handle_errors, void, + private_tnccs_20_server_t *this, pb_tnc_batch_t *batch, + bool fatal_header_error) +{ + pb_tnc_msg_t *msg; + enumerator_t *enumerator; + + if (fatal_header_error || this->fatal_error) + { + this->mutex->lock(this->mutex); + change_batch_type(this, PB_BATCH_CLOSE); + this->mutex->unlock(this->mutex); + } + + enumerator = batch->create_error_enumerator(batch); + while (enumerator->enumerate(enumerator, &msg)) + { + this->mutex->lock(this->mutex); + this->messages->insert_last(this->messages, msg->get_ref(msg)); + this->mutex->unlock(this->mutex); + } + enumerator->destroy(enumerator); +} + +METHOD(tnccs_20_handler_t, destroy, void, + private_tnccs_20_server_t *this) +{ + if (this->connection_id) + { + tnc->tnccs->remove_connection(tnc->tnccs, this->connection_id, TRUE); + } + this->state_machine->destroy(this->state_machine); + this->mutex->destroy(this->mutex); + this->messages->destroy_offset(this->messages, + offsetof(pb_tnc_msg_t, destroy)); + free(this); +} + +METHOD(tnccs_20_server_t, have_recommendation, bool, + private_tnccs_20_server_t *this, TNC_IMV_Action_Recommendation *rec, + TNC_IMV_Evaluation_Result *eval) +{ + return this->recs->have_recommendation(this->recs, rec, eval); +} + +/** + * See header + */ +tnccs_20_handler_t* tnccs_20_server_create(tnccs_t *tnccs, + tnccs_send_message_t send_msg, + size_t max_batch_len, + size_t max_msg_len, + bool eap_transport) +{ + private_tnccs_20_server_t *this; + + INIT(this, + .public = { + .handler = { + .process = _process, + .build = _build, + .begin_handshake = _begin_handshake, + .get_send_flag = _get_send_flag, + .get_mutual = _get_mutual, + .get_state = _get_state, + .add_msg = _add_msg, + .handle_errors = _handle_errors, + .destroy = _destroy, + }, + .have_recommendation = _have_recommendation, + }, + .state_machine = pb_tnc_state_machine_create(TRUE), + .mutex = mutex_create(MUTEX_TYPE_DEFAULT), + .messages = linked_list_create(), + .batch_type = PB_BATCH_SDATA, + .max_batch_len = max_batch_len, + .eap_transport = eap_transport, + ); + + this->connection_id = tnc->tnccs->create_connection(tnc->tnccs, + TNCCS_2_0, tnccs, send_msg, + &this->request_handshake_retry, + max_msg_len, &this->recs); + if (!this->connection_id) + { + destroy(this); + return NULL; + } + tnc->imvs->notify_connection_change(tnc->imvs, this->connection_id, + TNC_CONNECTION_STATE_CREATE); + + return &this->public.handler; +} diff --git a/src/libtnccs/plugins/tnccs_20/tnccs_20_server.h b/src/libtnccs/plugins/tnccs_20/tnccs_20_server.h new file mode 100644 index 000000000..5833d1132 --- /dev/null +++ b/src/libtnccs/plugins/tnccs_20/tnccs_20_server.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2015 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +/** + * @defgroup tnccs_20_server_h tnccs_20_server + * @{ @ingroup tnccs_20 + */ + +#ifndef TNCCS_20_SERVER_H_ +#define TNCCS_20_SERVER_H_ + +#include <library.h> + +#include <tnc/tnccs/tnccs.h> + +#include "tnccs_20_handler.h" + +typedef struct tnccs_20_server_t tnccs_20_server_t; + +/** + * Interface for a TNC server + */ +struct tnccs_20_server_t { + + /** + * IF-TNCCS 2.0 protocol handler interface + */ + tnccs_20_handler_t handler; + + /** + * Check if an Action Recommendation is already available + * + * @param rec TNC Action Recommendation + * @param eval TNC Evaluation Result + * @return TRUE if Action Recommendation is + */ + bool (*have_recommendation)(tnccs_20_server_t *this, + TNC_IMV_Action_Recommendation *rec, + TNC_IMV_Evaluation_Result *eval); + +}; + +/** + * Create an instance of the TNC IF-TNCCS 2.0 server-side protocol handler. + * + * @param tnccs TNC IF-TNCCS 2.0 stack + * @param send_msg TNF IF-TNCCS 2.0 send message callback function + * @param max_batch_len Maximum PB-TNC batch size + * @param max_msg_len Maximum PA-TNC message size + * @param eap_transport TRUE if IF-T for EAP methods + */ +tnccs_20_handler_t* tnccs_20_server_create(tnccs_t *tnccs, + tnccs_send_message_t send_msg, + size_t max_batch_len, + size_t max_msg_len, + bool eap_transport); + + +#endif /** TNCCS_20_SERVER_H_ @}*/ diff --git a/src/libtnccs/plugins/tnccs_dynamic/Makefile.in b/src/libtnccs/plugins/tnccs_dynamic/Makefile.in index 6a03df994..3f21a22d4 100644 --- a/src/libtnccs/plugins/tnccs_dynamic/Makefile.in +++ b/src/libtnccs/plugins/tnccs_dynamic/Makefile.in @@ -231,6 +231,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -291,10 +292,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -368,6 +371,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.c b/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.c index e08236eb7..44b804fb2 100644 --- a/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.c +++ b/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2013 Andreas Steffen + * Copyright (C) 2011-2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -34,12 +34,22 @@ struct private_tnccs_dynamic_t { /** * Server identity */ - identification_t *server; + identification_t *server_id; /** * Client identity */ - identification_t *peer; + identification_t *peer_id; + + /** + * Server IP address + */ + host_t *server_ip; + + /** + * Client IP address + */ + host_t *peer_ip; /** * Detected TNC IF-TNCCS stack @@ -109,8 +119,8 @@ METHOD(tls_t, process, status_t, DBG1(DBG_TNC, "%N protocol detected dynamically", tnccs_type_names, type); tnccs = tnc->tnccs->create_instance(tnc->tnccs, type, TRUE, - this->server, this->peer, this->transport, - this->callback); + this->server_id, this->peer_id, this->server_ip, + this->peer_ip, this->transport, this->callback); if (!tnccs) { DBG1(DBG_TNC, "N% protocol not supported", tnccs_type_names, type); @@ -137,14 +147,14 @@ METHOD(tls_t, is_server, bool, METHOD(tls_t, get_server_id, identification_t*, private_tnccs_dynamic_t *this) { - return this->server; + return this->server_id; } METHOD(tls_t, set_peer_id, void, private_tnccs_dynamic_t *this, identification_t *id) { - DESTROY_IF(this->peer); - this->peer = id->clone(id); + DESTROY_IF(this->peer_id); + this->peer_id = id->clone(id); if (this->tls) { this->tls->set_peer_id(this->tls, id); @@ -154,7 +164,7 @@ METHOD(tls_t, set_peer_id, void, METHOD(tls_t, get_peer_id, identification_t*, private_tnccs_dynamic_t *this) { - return this->peer; + return this->peer_id; } METHOD(tls_t, get_purpose, tls_purpose_t, @@ -181,12 +191,26 @@ METHOD(tls_t, destroy, void, if (ref_put(&this->ref)) { DESTROY_IF(this->tls); - this->server->destroy(this->server); - this->peer->destroy(this->peer); + this->server_id->destroy(this->server_id); + this->peer_id->destroy(this->peer_id); + this->server_ip->destroy(this->server_ip); + this->peer_ip->destroy(this->peer_ip); free(this); } } +METHOD(tnccs_t, get_server_ip, host_t*, + private_tnccs_dynamic_t *this) +{ + return this->server_ip; +} + +METHOD(tnccs_t, get_peer_ip, host_t*, + private_tnccs_dynamic_t *this) +{ + return this->peer_ip; +} + METHOD(tnccs_t, get_transport, tnc_ift_type_t, private_tnccs_dynamic_t *this) { @@ -229,9 +253,10 @@ METHOD(tnccs_t, get_ref, tnccs_t*, /** * See header */ -tnccs_t* tnccs_dynamic_create(bool is_server, - identification_t *server, identification_t *peer, - tnc_ift_type_t transport, tnccs_cb_t cb) +tnccs_t* tnccs_dynamic_create(bool is_server, identification_t *server_id, + identification_t *peer_id, host_t *server_ip, + host_t *peer_ip, tnc_ift_type_t transport, + tnccs_cb_t cb) { private_tnccs_dynamic_t *this; @@ -249,6 +274,8 @@ tnccs_t* tnccs_dynamic_create(bool is_server, .get_eap_msk = _get_eap_msk, .destroy = _destroy, }, + .get_server_ip = _get_server_ip, + .get_peer_ip = _get_peer_ip, .get_transport = _get_transport, .set_transport = _set_transport, .get_auth_type = _get_auth_type, @@ -256,8 +283,10 @@ tnccs_t* tnccs_dynamic_create(bool is_server, .get_pdp_server = _get_pdp_server, .get_ref = _get_ref, }, - .server = server->clone(server), - .peer = peer->clone(peer), + .server_id = server_id->clone(server_id), + .peer_id = peer_id->clone(peer_id), + .server_ip = server_ip->clone(server_ip), + .peer_ip = peer_ip->clone(peer_ip), .transport = transport, .callback = cb, .ref = 1, diff --git a/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.h b/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.h index cbdc80b83..2e1141780 100644 --- a/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.h +++ b/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2013 Andreas Steffen + * Copyright (C) 2011-2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -29,14 +29,17 @@ * Create an instance of a dynamic TNC IF-TNCCS protocol handler. * * @param is_server TRUE to act as TNC Server, FALSE for TNC Client - * @param server Server identity - * @param peer Client identity + * @param server_id Server identity + * @param peer_id Client identity + * @param server_ip Server IP address + * @param peer_ip Client IP address * @param transport Underlying IF-T transport protocol * @param cb Callback function if TNC Server, NULL if TNC Client * @return dynamic TNC IF-TNCCS protocol stack */ -tnccs_t* tnccs_dynamic_create(bool is_server, - identification_t *server, identification_t *peer, - tnc_ift_type_t transport, tnccs_cb_t cb); +tnccs_t* tnccs_dynamic_create(bool is_server, identification_t *server_id, + identification_t *peer_id, host_t *server_ip, + host_t *peer_ip, tnc_ift_type_t transport, + tnccs_cb_t cb); #endif /** TNCCS_DYNAMIC_H_ @}*/ diff --git a/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic_plugin.h b/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic_plugin.h index b518e1278..97dd0df43 100644 --- a/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic_plugin.h +++ b/src/libtnccs/plugins/tnccs_dynamic/tnccs_dynamic_plugin.h @@ -15,7 +15,7 @@ /** * @defgroup tnccs_dynamic tnccs_dynamic - * @ingroup cplugins + * @ingroup tplugins * * @defgroup tnccs_dynamic_plugin tnccs_dynamic_plugin * @{ @ingroup tnccs_dynamic diff --git a/src/libtnccs/tnc/imc/imc.h b/src/libtnccs/tnc/imc/imc.h index 3ff7d5194..6d13f6bc5 100644 --- a/src/libtnccs/tnc/imc/imc.h +++ b/src/libtnccs/tnc/imc/imc.h @@ -15,7 +15,7 @@ /** * @defgroup imc imc - * @ingroup tnc + * @ingroup libtnccs * * @defgroup imct imc * @{ @ingroup imc diff --git a/src/libtnccs/tnc/imv/imv.h b/src/libtnccs/tnc/imv/imv.h index 3716532d6..fbc26a1e7 100644 --- a/src/libtnccs/tnc/imv/imv.h +++ b/src/libtnccs/tnc/imv/imv.h @@ -15,7 +15,7 @@ /** * @defgroup imv imv - * @ingroup tnc + * @ingroup libtnccs * * @defgroup imvt imv * @{ @ingroup imv diff --git a/src/libtnccs/tnc/tnc.h b/src/libtnccs/tnc/tnc.h index e5a4a2959..7bf8c84b7 100644 --- a/src/libtnccs/tnc/tnc.h +++ b/src/libtnccs/tnc/tnc.h @@ -14,9 +14,12 @@ */ /** - * @defgroup tnc tnc + * @defgroup libtnccs libtnccs * - * @addtogroup tnc + * @defgroup tplugins plugins + * @ingroup libtnccs + * + * @addtogroup libtnccs * @{ */ diff --git a/src/libtnccs/tnc/tnccs/tnccs.h b/src/libtnccs/tnc/tnccs/tnccs.h index eefd5565d..8ff295bcc 100644 --- a/src/libtnccs/tnc/tnccs/tnccs.h +++ b/src/libtnccs/tnc/tnccs/tnccs.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2013 Andreas Steffen + * Copyright (C) 2010-2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -15,7 +15,7 @@ /** * @defgroup tnccs tnccs - * @ingroup tnc + * @ingroup libtnccs * * @defgroup tnccst tnccs * @{ @ingroup tnccs @@ -87,6 +87,20 @@ struct tnccs_t { tls_t tls; /** + * Get server IP address + * + * @return Server IP address + */ + host_t* (*get_server_ip)(tnccs_t *this); + + /** + * Get peer IP address + * + * @return Peer IP address + */ + host_t* (*get_peer_ip)(tnccs_t *this); + + /** * Get underlying TNC IF-T transport protocol * * @return TNC IF-T transport protocol @@ -135,15 +149,19 @@ struct tnccs_t { * Constructor definition for a pluggable TNCCS protocol implementation. * * @param is_server TRUE if TNC Server, FALSE if TNC Client - * @param server Server identity - * @param peer Client identity + * @param server_id Server identity + * @param peer_id Client identity + * @param server_ip Server IP address + * @param peer_ip Client IP address * @param transport Underlying TNC IF-T transport protocol used * @param cb Callback function if TNC Server, NULL if TNC Client * @return implementation of the tnccs_t interface */ typedef tnccs_t *(*tnccs_constructor_t)(bool is_server, - identification_t *server, - identification_t *peer, + identification_t *server_id, + identification_t *peer_id, + host_t *server_ip, + host_t *peer_ip, tnc_ift_type_t transport, tnccs_cb_t cb); diff --git a/src/libtnccs/tnc/tnccs/tnccs_manager.h b/src/libtnccs/tnc/tnccs/tnccs_manager.h index 791336ee1..b5c85f3c0 100644 --- a/src/libtnccs/tnc/tnccs/tnccs_manager.h +++ b/src/libtnccs/tnc/tnccs/tnccs_manager.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2013 Andreas Steffen + * Copyright (C) 2010-2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -56,16 +56,19 @@ struct tnccs_manager_t { * * @param type type of the TNCCS protocol * @param is_server TRUE if TNC Server, FALSE if TNC Client - * @param server Server identity - * @param peer Client identity + * @param server_id Server identity + * @param peer_id Client identity + * @param server_ip Server IP address + * @param peer_ip Client IP address * @param transport Underlying TNC IF-T transport protocol used * @param cb Callback function if TNC Server, NULL if TNC Client * @return TNCCS protocol instance, NULL if no constructor found */ tnccs_t* (*create_instance)(tnccs_manager_t *this, tnccs_type_t type, - bool is_server, identification_t *server, - identification_t *peer, - tnc_ift_type_t transport, tnccs_cb_t cb); + bool is_server, identification_t *server_id, + identification_t *peer_id, host_t *server_ip, + host_t *peer_ip, tnc_ift_type_t transport, + tnccs_cb_t cb); /** * Create a TNCCS connection and assign a unique connection ID as well a diff --git a/src/libtncif/Makefile.in b/src/libtncif/Makefile.in index efa06b927..010fadc42 100644 --- a/src/libtncif/Makefile.in +++ b/src/libtncif/Makefile.in @@ -193,6 +193,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -253,10 +254,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -330,6 +333,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/libtncif/tncif_names.c b/src/libtncif/tncif_names.c index ac948c8ba..b348c548e 100644 --- a/src/libtncif/tncif_names.c +++ b/src/libtncif/tncif_names.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Andreas Steffen + * Copyright (C) 2010-2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -46,6 +46,18 @@ ENUM(TNC_IMV_Evaluation_Result_names, "don't know" ); +ENUM(TNC_Identity_names, + TNC_ID_UNKNOWN, + TNC_ID_X500_DN, + "unknown", + "IPv4 address", + "IPv6 address", + "FQDN", + "email address", + "username", + "X.500 DN" +); + ENUM(TNC_Subject_names, TNC_SUBJECT_UNKNOWN, TNC_SUBJECT_USER, diff --git a/src/libtncif/tncif_names.h b/src/libtncif/tncif_names.h index 75458f960..64dd14fc2 100644 --- a/src/libtncif/tncif_names.h +++ b/src/libtncif/tncif_names.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil + * Copyright (C) 2011-2015 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -30,6 +31,7 @@ extern enum_name_t *TNC_Connection_State_names; extern enum_name_t *TNC_IMV_Action_Recommendation_names; extern enum_name_t *TNC_IMV_Evaluation_Result_names; +extern enum_name_t *TNC_Identity_names; extern enum_name_t *TNC_Subject_names; extern enum_name_t *TNC_Authentication_names; diff --git a/src/manager/Makefile.in b/src/manager/Makefile.in index 79ee9c7b8..500220a3a 100644 --- a/src/manager/Makefile.in +++ b/src/manager/Makefile.in @@ -245,6 +245,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -305,10 +306,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -382,6 +385,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/medsrv/Makefile.in b/src/medsrv/Makefile.in index 3de9153cf..7265457f1 100644 --- a/src/medsrv/Makefile.in +++ b/src/medsrv/Makefile.in @@ -234,6 +234,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -294,10 +295,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -371,6 +374,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/pki/Makefile.am b/src/pki/Makefile.am index 266802cf7..ab407e021 100644 --- a/src/pki/Makefile.am +++ b/src/pki/Makefile.am @@ -13,6 +13,7 @@ pki_SOURCES = pki.c pki.h command.c command.h \ commands/signcrl.c \ commands/acert.c \ commands/pkcs7.c \ + commands/pkcs12.c \ commands/verify.c pki_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la diff --git a/src/pki/Makefile.in b/src/pki/Makefile.in index 5f7a1bc26..4205469fc 100644 --- a/src/pki/Makefile.in +++ b/src/pki/Makefile.in @@ -108,7 +108,7 @@ am_pki_OBJECTS = pki.$(OBJEXT) command.$(OBJEXT) \ commands/req.$(OBJEXT) commands/self.$(OBJEXT) \ commands/print.$(OBJEXT) commands/signcrl.$(OBJEXT) \ commands/acert.$(OBJEXT) commands/pkcs7.$(OBJEXT) \ - commands/verify.$(OBJEXT) + commands/pkcs12.$(OBJEXT) commands/verify.$(OBJEXT) pki_OBJECTS = $(am_pki_OBJECTS) pki_DEPENDENCIES = $(top_builddir)/src/libstrongswan/libstrongswan.la AM_V_lt = $(am__v_lt_@AM_V@) @@ -243,6 +243,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -303,10 +304,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -380,6 +383,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ @@ -450,6 +455,7 @@ pki_SOURCES = pki.c pki.h command.c command.h \ commands/signcrl.c \ commands/acert.c \ commands/pkcs7.c \ + commands/pkcs12.c \ commands/verify.c pki_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la @@ -566,6 +572,8 @@ commands/acert.$(OBJEXT): commands/$(am__dirstamp) \ commands/$(DEPDIR)/$(am__dirstamp) commands/pkcs7.$(OBJEXT): commands/$(am__dirstamp) \ commands/$(DEPDIR)/$(am__dirstamp) +commands/pkcs12.$(OBJEXT): commands/$(am__dirstamp) \ + commands/$(DEPDIR)/$(am__dirstamp) commands/verify.$(OBJEXT): commands/$(am__dirstamp) \ commands/$(DEPDIR)/$(am__dirstamp) @@ -586,6 +594,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/gen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/issue.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/keyid.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/pkcs12.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/pkcs7.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/print.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@commands/$(DEPDIR)/pub.Po@am__quote@ diff --git a/src/pki/command.h b/src/pki/command.h index 9cf036bf2..d49adda09 100644 --- a/src/pki/command.h +++ b/src/pki/command.h @@ -24,7 +24,7 @@ /** * Maximum number of commands (+1). */ -#define MAX_COMMANDS 12 +#define MAX_COMMANDS 13 /** * Maximum number of options in a command (+3) diff --git a/src/pki/commands/acert.c b/src/pki/commands/acert.c index 185aa40b4..7099977f2 100644 --- a/src/pki/commands/acert.c +++ b/src/pki/commands/acert.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2009 Martin Willi - * Hochschule fuer Technik Rapperswil + * Copyright (C) 2015 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -31,7 +32,7 @@ static int acert() { cred_encoding_type_t form = CERT_ASN1_DER; - hash_algorithm_t digest = HASH_SHA1; + hash_algorithm_t digest = HASH_UNKNOWN; certificate_t *ac = NULL, *cert = NULL, *issuer =NULL; private_key_t *private = NULL; public_key_t *public = NULL; @@ -161,6 +162,10 @@ static int acert() error = "loading issuer private key failed"; goto end; } + if (digest == HASH_UNKNOWN) + { + digest = get_default_digest(private); + } if (!private->belongs_to(private, public)) { error = "issuer private key does not match issuer certificate"; @@ -286,7 +291,7 @@ static void __attribute__ ((constructor))reg() {"not-before", 'F', 1, "date/time the validity of the AC starts"}, {"not-after", 'T', 1, "date/time the validity of the AC ends"}, {"dateform", 'D', 1, "strptime(3) input format, default: %d.%m.%y %T"}, - {"digest", 'g', 1, "digest for signature creation, default: sha1"}, + {"digest", 'g', 1, "digest for signature creation, default: key-specific"}, {"outform", 'f', 1, "encoding of generated cert, default: der"}, } }); diff --git a/src/pki/commands/gen.c b/src/pki/commands/gen.c index ce28a0971..8b11854ad 100644 --- a/src/pki/commands/gen.c +++ b/src/pki/commands/gen.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2009 Martin Willi - * Hochschule fuer Technik Rapperswil + * Copyright (C) 2014-2015 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -43,6 +44,10 @@ static int gen() { type = KEY_ECDSA; } + else if (streq(arg, "bliss")) + { + type = KEY_BLISS; + } else { return command_usage("invalid key type"); @@ -96,6 +101,9 @@ static int gen() case KEY_ECDSA: size = 384; break; + case KEY_BLISS: + size = 1; + break; default: break; } @@ -151,12 +159,12 @@ static void __attribute__ ((constructor))reg() { command_register((command_t) { gen, 'g', "gen", "generate a new private key", - {" [--type rsa|ecdsa] [--size bits] [--safe-primes]", + {" [--type rsa|ecdsa|bliss] [--size bits] [--safe-primes]", "[--shares n] [--threshold l] [--outform der|pem]"}, { {"help", 'h', 0, "show usage information"}, {"type", 't', 1, "type of key, default: rsa"}, - {"size", 's', 1, "keylength in bits, default: rsa 2048, ecdsa 384"}, + {"size", 's', 1, "keylength in bits, default: rsa 2048, ecdsa 384, bliss 1"}, {"safe-primes", 'p', 0, "generate rsa safe primes"}, {"shares", 'n', 1, "number of private rsa key shares"}, {"threshold", 'l', 1, "minimum number of participating rsa key shares"}, diff --git a/src/pki/commands/issue.c b/src/pki/commands/issue.c index aaa2c2ff7..6a2d09d78 100644 --- a/src/pki/commands/issue.c +++ b/src/pki/commands/issue.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2009 Martin Willi - * Hochschule fuer Technik Rapperswil + * Copyright (C) 2015 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -59,7 +60,7 @@ static void destroy_cdp(x509_cdp_t *this) static int issue() { cred_encoding_type_t form = CERT_ASN1_DER; - hash_algorithm_t digest = HASH_SHA1; + hash_algorithm_t digest = HASH_UNKNOWN; certificate_t *cert_req = NULL, *cert = NULL, *ca =NULL; private_key_t *private = NULL; public_key_t *public = NULL; @@ -287,6 +288,7 @@ static int issue() } break; } + if (!cacert) { error = "--cacert is required"; @@ -355,6 +357,10 @@ static int issue() error = "loading CA private key failed"; goto end; } + if (digest == HASH_UNKNOWN) + { + digest = get_default_digest(private); + } if (!private->belongs_to(private, public)) { error = "CA private key does not match CA certificate"; @@ -589,7 +595,7 @@ static void __attribute__ ((constructor))reg() {"crl", 'u', 1, "CRL distribution point URI to include"}, {"crlissuer", 'I', 1, "CRL Issuer for CRL at distribution point"}, {"ocsp", 'o', 1, "OCSP AuthorityInfoAccess URI to include"}, - {"digest", 'g', 1, "digest for signature creation, default: sha1"}, + {"digest", 'g', 1, "digest for signature creation, default: key-specific"}, {"outform", 'f', 1, "encoding of generated cert, default: der"}, } }); diff --git a/src/pki/commands/keyid.c b/src/pki/commands/keyid.c index c3ac0c288..3bc62e74d 100644 --- a/src/pki/commands/keyid.c +++ b/src/pki/commands/keyid.c @@ -52,6 +52,11 @@ static int keyid() type = CRED_PRIVATE_KEY; subtype = KEY_ECDSA; } + else if (streq(arg, "bliss-priv")) + { + type = CRED_PRIVATE_KEY; + subtype = KEY_BLISS; + } else if (streq(arg, "pub")) { type = CRED_PUBLIC_KEY; @@ -164,7 +169,7 @@ static void __attribute__ ((constructor))reg() command_register((command_t) { keyid, 'k', "keyid", "calculate key identifiers of a key/certificate", - {"[--in file] [--type rsa-priv|ecdsa-priv|pub|pkcs10|x509]"}, + {"[--in file] [--type rsa-priv|ecdsa-priv|bliss-priv|pub|pkcs10|x509]"}, { {"help", 'h', 0, "show usage information"}, {"in", 'i', 1, "input file, default: stdin"}, diff --git a/src/pki/commands/pkcs12.c b/src/pki/commands/pkcs12.c new file mode 100644 index 000000000..dcd1496ba --- /dev/null +++ b/src/pki/commands/pkcs12.c @@ -0,0 +1,247 @@ +/* + * Copyright (C) 2014 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * This program 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program 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. + */ + +#include <errno.h> + +#include "pki.h" + +#include <credentials/certificates/x509.h> +#include <credentials/containers/pkcs12.h> + +/** + * Show info about PKCS#12 container + */ +static int show(pkcs12_t *pkcs12) +{ + enumerator_t *enumerator; + certificate_t *cert; + private_key_t *key; + int index = 1; + + printf("Certificates:\n"); + enumerator = pkcs12->create_cert_enumerator(pkcs12); + while (enumerator->enumerate(enumerator, &cert)) + { + x509_t *x509 = (x509_t*)cert; + + if (x509->get_flags(x509) & X509_CA) + { + printf("[%2d] \"%Y\" (CA)\n", index++, cert->get_subject(cert)); + } + else + { + printf("[%2d] \"%Y\"\n", index++, cert->get_subject(cert)); + } + } + enumerator->destroy(enumerator); + + printf("Private keys:\n"); + enumerator = pkcs12->create_key_enumerator(pkcs12); + while (enumerator->enumerate(enumerator, &key)) + { + printf("[%2d] %N %d bits\n", index++, key_type_names, + key->get_type(key), key->get_keysize(key)); + } + enumerator->destroy(enumerator); + return 0; +} + +static int export(pkcs12_t *pkcs12, int index, char *outform) +{ + cred_encoding_type_t form; + enumerator_t *enumerator; + certificate_t *cert; + private_key_t *key; + chunk_t encoding; + int i = 1; + + enumerator = pkcs12->create_cert_enumerator(pkcs12); + while (enumerator->enumerate(enumerator, &cert)) + { + if (i++ == index) + { + form = CERT_ASN1_DER; + if (outform && !get_form(outform, &form, CRED_CERTIFICATE)) + { + enumerator->destroy(enumerator); + return command_usage("invalid output format"); + } + if (cert->get_encoding(cert, form, &encoding)) + { + set_file_mode(stdout, form); + if (fwrite(encoding.ptr, encoding.len, 1, stdout) == 1) + { + free(encoding.ptr); + enumerator->destroy(enumerator); + return 0; + } + free(encoding.ptr); + } + fprintf(stderr, "certificate export failed\n"); + enumerator->destroy(enumerator); + return 1; + } + } + enumerator->destroy(enumerator); + + enumerator = pkcs12->create_key_enumerator(pkcs12); + while (enumerator->enumerate(enumerator, &key)) + { + if (i++ == index) + { + form = PRIVKEY_ASN1_DER; + if (outform && !get_form(outform, &form, CRED_PRIVATE_KEY)) + { + enumerator->destroy(enumerator); + return command_usage("invalid output format"); + } + if (key->get_encoding(key, form, &encoding)) + { + set_file_mode(stdout, form); + if (fwrite(encoding.ptr, encoding.len, 1, stdout) == 1) + { + free(encoding.ptr); + enumerator->destroy(enumerator); + return 0; + } + free(encoding.ptr); + } + fprintf(stderr, "private key export failed\n"); + enumerator->destroy(enumerator); + return 0; + } + } + enumerator->destroy(enumerator); + + fprintf(stderr, "invalid index %d\n", index); + return 1; +} + + +/** + * Handle PKCs#12 containers + */ +static int pkcs12() +{ + char *arg, *file = NULL, *outform = NULL; + pkcs12_t *p12 = NULL; + int res = 1, index = 0; + enum { + OP_NONE, + OP_LIST, + OP_EXPORT, + } op = OP_NONE; + + while (TRUE) + { + switch (command_getopt(&arg)) + { + case 'h': + return command_usage(NULL); + case 'i': + file = arg; + continue; + case 'l': + if (op != OP_NONE) + { + goto invalid; + } + op = OP_LIST; + continue; + case 'e': + if (op != OP_NONE) + { + goto invalid; + } + op = OP_EXPORT; + index = atoi(arg); + continue; + case 'f': + outform = arg; + continue; + case EOF: + break; + default: + invalid: + return command_usage("invalid --pkcs12 option"); + } + break; + } + + if (file) + { + p12 = lib->creds->create(lib->creds, CRED_CONTAINER, CONTAINER_PKCS12, + BUILD_FROM_FILE, file, BUILD_END); + } + else + { + chunk_t chunk; + + set_file_mode(stdin, CERT_ASN1_DER); + if (!chunk_from_fd(0, &chunk)) + { + fprintf(stderr, "reading input failed: %s\n", strerror(errno)); + return 1; + } + p12 = lib->creds->create(lib->creds, CRED_CONTAINER, CONTAINER_PKCS12, + BUILD_BLOB, chunk, BUILD_END); + free(chunk.ptr); + } + + if (!p12) + { + fprintf(stderr, "reading input failed!\n"); + goto end; + } + + switch (op) + { + case OP_LIST: + res = show(p12); + break; + case OP_EXPORT: + res = export(p12, index, outform); + break; + default: + p12->container.destroy(&p12->container); + return command_usage(NULL); + } + +end: + if (p12) + { + p12->container.destroy(&p12->container); + } + return res; +} + +/** + * Register the command. + */ +static void __attribute__ ((constructor))reg() +{ + command_register((command_t) { + pkcs12, 'u', "pkcs12", "PKCS#12 functions", + {"--export index|--list [--in file]", + "[--outform der|pem]"}, + { + {"help", 'h', 0, "show usage information"}, + {"in", 'i', 1, "input file, default: stdin"}, + {"list", 'l', 0, "list certificates and keys"}, + {"export", 'e', 1, "export the credential with the given index"}, + {"outform", 'f', 1, "encoding of exported credentials, default: der"}, + } + }); +} diff --git a/src/pki/commands/print.c b/src/pki/commands/print.c index fb07169bf..fa69de133 100644 --- a/src/pki/commands/print.c +++ b/src/pki/commands/print.c @@ -32,9 +32,12 @@ static void print_pubkey(public_key_t *key) { chunk_t chunk; + key_type_t type; + + type = key->get_type(key); + printf("pubkey: %N %d bits%s\n", key_type_names, type, + key->get_keysize(key), (type == KEY_BLISS) ? " strength" : ""); - printf("pubkey: %N %d bits\n", key_type_names, key->get_type(key), - key->get_keysize(key)); if (key->get_fingerprint(key, KEYID_PUBKEY_INFO_SHA1, &chunk)) { printf("keyid: %#B\n", &chunk); @@ -66,6 +69,22 @@ static void print_key(private_key_t *key) } /** + * Get a prefix for a named constraint identity type + */ +static char* get_type_pfx(identification_t *id) +{ + switch (id->get_type(id)) + { + case ID_RFC822_ADDR: + return "email:"; + case ID_FQDN: + return "dns:"; + default: + return ""; + } +} + +/** * Print X509 specific certificate information */ static void print_x509(x509_t *x509) @@ -202,7 +221,7 @@ static void print_x509(x509_t *x509) printf("Permitted NameConstraints:\n"); first = FALSE; } - printf(" %Y\n", id); + printf(" %s%Y\n", get_type_pfx(id), id); } enumerator->destroy(enumerator); first = TRUE; @@ -214,7 +233,7 @@ static void print_x509(x509_t *x509) printf("Excluded NameConstraints:\n"); first = FALSE; } - printf(" %Y\n", id); + printf(" %s%Y\n", get_type_pfx(id), id); } enumerator->destroy(enumerator); @@ -580,6 +599,11 @@ static int print() type = CRED_PRIVATE_KEY; subtype = KEY_ECDSA; } + else if (streq(arg, "bliss-priv")) + { + type = CRED_PRIVATE_KEY; + subtype = KEY_BLISS; + } else { return command_usage( "invalid input type"); @@ -652,7 +676,7 @@ static void __attribute__ ((constructor))reg() command_register((command_t) { print, 'a', "print", "print a credential in a human readable form", - {"[--in file] [--type rsa-priv|ecdsa-priv|pub|x509|crl|ac]"}, + {"[--in file] [--type rsa-priv|ecdsa-priv|bliss-priv|pub|x509|crl|ac]"}, { {"help", 'h', 0, "show usage information"}, {"in", 'i', 1, "input file, default: stdin"}, diff --git a/src/pki/commands/pub.c b/src/pki/commands/pub.c index b8d2f701d..ccc3c4251 100644 --- a/src/pki/commands/pub.c +++ b/src/pki/commands/pub.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2009 Martin Willi - * Hochschule fuer Technik Rapperswil + * Copyright (C) 2015 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -53,6 +54,11 @@ static int pub() type = CRED_PRIVATE_KEY; subtype = KEY_ECDSA; } + else if (streq(arg, "bliss")) + { + type = CRED_PRIVATE_KEY; + subtype = KEY_BLISS; + } else if (streq(arg, "pub")) { type = CRED_PUBLIC_KEY; @@ -183,7 +189,7 @@ static void __attribute__ ((constructor))reg() command_register((command_t) { pub, 'p', "pub", "extract the public key from a private key/certificate", - {"[--in file|--keyid hex] [--type rsa|ecdsa|pub|pkcs10|x509]", + {"[--in file|--keyid hex] [--type rsa|ecdsa|bliss|pub|pkcs10|x509]", "[--outform der|pem|dnskey|sshkey]"}, { {"help", 'h', 0, "show usage information"}, diff --git a/src/pki/commands/req.c b/src/pki/commands/req.c index 023683569..da991b505 100644 --- a/src/pki/commands/req.c +++ b/src/pki/commands/req.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2009 Martin Willi - * Copyright (C) 2009 Andreas Steffen + * Copyright (C) 2009-2015 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil * * HSR Hochschule fuer Technik Rapperswil * @@ -30,7 +31,7 @@ static int req() { cred_encoding_type_t form = CERT_ASN1_DER; key_type_t type = KEY_RSA; - hash_algorithm_t digest = HASH_SHA1; + hash_algorithm_t digest = HASH_UNKNOWN; certificate_t *cert = NULL; private_key_t *private = NULL; char *file = NULL, *dn = NULL, *error = NULL; @@ -57,6 +58,10 @@ static int req() { type = KEY_ECDSA; } + else if (streq(arg, "bliss")) + { + type = KEY_BLISS; + } else { error = "invalid input type"; @@ -134,6 +139,10 @@ static int req() error = "parsing private key failed"; goto end; } + if (digest == HASH_UNKNOWN) + { + digest = get_default_digest(private); + } cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_PKCS10_REQUEST, BUILD_SIGNING_KEY, private, BUILD_SUBJECT, id, @@ -185,7 +194,7 @@ static void __attribute__ ((constructor))reg() command_register((command_t) { req, 'r', "req", "create a PKCS#10 certificate request", - {" [--in file] [--type rsa|ecdsa] --dn distinguished-name", + {" [--in file] [--type rsa|ecdsa|bliss] --dn distinguished-name", "[--san subjectAltName]+ [--password challengePassword]", "[--digest md5|sha1|sha224|sha256|sha384|sha512] [--outform der|pem]"}, { @@ -195,7 +204,7 @@ static void __attribute__ ((constructor))reg() {"dn", 'd', 1, "subject distinguished name"}, {"san", 'a', 1, "subjectAltName to include in cert request"}, {"password",'p', 1, "challengePassword to include in cert request"}, - {"digest", 'g', 1, "digest for signature creation, default: sha1"}, + {"digest", 'g', 1, "digest for signature creation, default: key-specific"}, {"outform", 'f', 1, "encoding of generated request, default: der"}, } }); diff --git a/src/pki/commands/self.c b/src/pki/commands/self.c index daefcdc10..a785c2a0c 100644 --- a/src/pki/commands/self.c +++ b/src/pki/commands/self.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2009 Martin Willi - * Hochschule fuer Technik Rapperswil + * Copyright (C) 2015 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -49,7 +50,7 @@ static int self() { cred_encoding_type_t form = CERT_ASN1_DER; key_type_t type = KEY_RSA; - hash_algorithm_t digest = HASH_SHA1; + hash_algorithm_t digest = HASH_UNKNOWN; certificate_t *cert = NULL; private_key_t *private = NULL; public_key_t *public = NULL; @@ -57,7 +58,8 @@ static int self() identification_t *id = NULL; linked_list_t *san, *ocsp, *permitted, *excluded, *policies, *mappings; int pathlen = X509_NO_CONSTRAINT, inhibit_any = X509_NO_CONSTRAINT; - int inhibit_mapping = X509_NO_CONSTRAINT, require_explicit = X509_NO_CONSTRAINT; + int inhibit_mapping = X509_NO_CONSTRAINT; + int require_explicit = X509_NO_CONSTRAINT; chunk_t serial = chunk_empty; chunk_t encoding = chunk_empty; time_t not_before, not_after, lifetime = 1095 * 24 * 60 * 60; @@ -88,6 +90,10 @@ static int self() { type = KEY_ECDSA; } + else if (streq(arg, "bliss")) + { + type = KEY_BLISS; + } else { error = "invalid input type"; @@ -308,6 +314,10 @@ static int self() error = "loading private key failed"; goto end; } + if (digest == HASH_UNKNOWN) + { + digest = get_default_digest(private); + } public = private->get_public_key(private); if (!public) { @@ -407,7 +417,7 @@ static void __attribute__ ((constructor))reg() command_register((command_t) { self, 's', "self", "create a self signed certificate", - {" [--in file|--keyid hex] [--type rsa|ecdsa]", + {" [--in file|--keyid hex] [--type rsa|ecdsa|bliss]", " --dn distinguished-name [--san subjectAltName]+", "[--lifetime days] [--serial hex] [--ca] [--ocsp uri]+", "[--flag serverAuth|clientAuth|crlSign|ocspSigning|msSmartcardLogon]+", @@ -441,7 +451,7 @@ static void __attribute__ ((constructor))reg() {"policy-any", 'A', 1, "inhibitAnyPolicy constraint"}, {"flag", 'e', 1, "include extendedKeyUsage flag"}, {"ocsp", 'o', 1, "OCSP AuthorityInfoAccess URI to include"}, - {"digest", 'g', 1, "digest for signature creation, default: sha1"}, + {"digest", 'g', 1, "digest for signature creation, default: key-specific"}, {"outform", 'f', 1, "encoding of generated cert, default: der"}, } }); diff --git a/src/pki/commands/signcrl.c b/src/pki/commands/signcrl.c index e5f49efe2..720dfd8a9 100644 --- a/src/pki/commands/signcrl.c +++ b/src/pki/commands/signcrl.c @@ -117,7 +117,7 @@ static int sign_crl() certificate_t *ca = NULL, *crl = NULL; crl_t *lastcrl = NULL; x509_t *x509; - hash_algorithm_t digest = HASH_SHA1; + hash_algorithm_t digest = HASH_UNKNOWN; char *arg, *cacert = NULL, *cakey = NULL, *lastupdate = NULL, *error = NULL; char *basecrl = NULL; char serial[512], *keyid = NULL; @@ -330,6 +330,10 @@ static int sign_crl() error = "loading CA private key failed"; goto error; } + if (digest == HASH_UNKNOWN) + { + digest = get_default_digest(private); + } if (!private->belongs_to(private, public)) { error = "CA private key does not match CA certificate"; @@ -465,7 +469,7 @@ static void __attribute__ ((constructor))reg() {"serial", 's', 1, "hex encoded certificate serial number to revoke"}, {"reason", 'r', 1, "reason for certificate revocation"}, {"date", 'd', 1, "revocation date as unix timestamp, default: now"}, - {"digest", 'g', 1, "digest for signature creation, default: sha1"}, + {"digest", 'g', 1, "digest for signature creation, default: key-specific"}, {"outform", 'f', 1, "encoding of generated crl, default: der"}, } }); diff --git a/src/pki/man/Makefile.in b/src/pki/man/Makefile.in index c288015de..45355bacd 100644 --- a/src/pki/man/Makefile.in +++ b/src/pki/man/Makefile.in @@ -81,10 +81,11 @@ subdir = src/pki/man DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/pki.1.in $(srcdir)/pki---gen.1.in \ $(srcdir)/pki---issue.1.in $(srcdir)/pki---keyid.1.in \ - $(srcdir)/pki---pkcs7.1.in $(srcdir)/pki---print.1.in \ - $(srcdir)/pki---pub.1.in $(srcdir)/pki---req.1.in \ - $(srcdir)/pki---self.1.in $(srcdir)/pki---signcrl.1.in \ - $(srcdir)/pki---acert.1.in $(srcdir)/pki---verify.1.in + $(srcdir)/pki---pkcs7.1.in $(srcdir)/pki---pkcs12.1.in \ + $(srcdir)/pki---print.1.in $(srcdir)/pki---pub.1.in \ + $(srcdir)/pki---req.1.in $(srcdir)/pki---self.1.in \ + $(srcdir)/pki---signcrl.1.in $(srcdir)/pki---acert.1.in \ + $(srcdir)/pki---verify.1.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ $(top_srcdir)/m4/config/ltoptions.m4 \ @@ -101,8 +102,9 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = pki.1 pki---gen.1 pki---issue.1 pki---keyid.1 \ - pki---pkcs7.1 pki---print.1 pki---pub.1 pki---req.1 \ - pki---self.1 pki---signcrl.1 pki---acert.1 pki---verify.1 + pki---pkcs7.1 pki---pkcs12.1 pki---print.1 pki---pub.1 \ + pki---req.1 pki---self.1 pki---signcrl.1 pki---acert.1 \ + pki---verify.1 CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) @@ -181,6 +183,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -241,10 +244,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -318,6 +323,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ @@ -434,6 +441,8 @@ pki---keyid.1: $(top_builddir)/config.status $(srcdir)/pki---keyid.1.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ pki---pkcs7.1: $(top_builddir)/config.status $(srcdir)/pki---pkcs7.1.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +pki---pkcs12.1: $(top_builddir)/config.status $(srcdir)/pki---pkcs12.1.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ pki---print.1: $(top_builddir)/config.status $(srcdir)/pki---print.1.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ pki---pub.1: $(top_builddir)/config.status $(srcdir)/pki---pub.1.in diff --git a/src/pki/man/pki---acert.1.in b/src/pki/man/pki---acert.1.in index ec1d8be6e..d7460fd1f 100644 --- a/src/pki/man/pki---acert.1.in +++ b/src/pki/man/pki---acert.1.in @@ -99,8 +99,8 @@ Serial number in hex. It is randomly allocated by default. .TP .BI "\-g, \-\-digest " digest Digest to use for signature creation. One of \fImd5\fR, \fIsha1\fR, -\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. Defaults to -\fIsha1\fR. +\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. The default is +determined based on the type and size of the signature key. .TP .BI "\-f, \-\-outform " encoding Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or diff --git a/src/pki/man/pki---issue.1.in b/src/pki/man/pki---issue.1.in index 375cb2fe4..3a89059c8 100644 --- a/src/pki/man/pki---issue.1.in +++ b/src/pki/man/pki---issue.1.in @@ -122,8 +122,8 @@ Add extendedKeyUsage flag. One of \fIserverAuth\fR, \fIclientAuth\fR, .TP .BI "\-g, \-\-digest " digest Digest to use for signature creation. One of \fImd5\fR, \fIsha1\fR, -\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. Defaults to -\fIsha1\fR. +\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. The default is +determined based on the type and size of the signature key. .TP .BI "\-f, \-\-outform " encoding Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or @@ -147,10 +147,22 @@ times. Set path length constraint. .TP .BI "\-n, \-\-nc-permitted " name -Add permitted NameConstraint extension to certificate. +Add permitted NameConstraint extension to certificate. For DNS or email +constraints, the identity type is not always detectable by the given name. Use +the +.B dns: +or +.B email: +prefix to force a constraint type. .TP .BI "\-N, \-\-nc-excluded " name -Add excluded NameConstraint extension to certificate. +Add excluded NameConstraint extension to certificate. For DNS or email +constraints, the identity type is not always detectable by the given name. Use +the +.B dns: +or +.B email: +prefix to force a constraint type. .TP .BI "\-M, \-\-policy-mapping " issuer-oid:subject-oid Add policyMapping from issuer to subject OID. diff --git a/src/pki/man/pki---pkcs12.1.in b/src/pki/man/pki---pkcs12.1.in new file mode 100644 index 000000000..470a66389 --- /dev/null +++ b/src/pki/man/pki---pkcs12.1.in @@ -0,0 +1,62 @@ +.TH "PKI \-\-PKCS12" 1 "2014-10-17" "@PACKAGE_VERSION@" "strongSwan" +. +.SH "NAME" +. +pki \-\-pkcs12 \- Provides PKCS#12 functions +. +.SH "SYNOPSIS" +. +.SY pki\ \-\-pkcs12 +.BR \-\-list +.OP \-\-in file +.OP \-\-debug level +.YS +. +.SY pki\ \-\-pkcs12 +.BI \-\-export\~ index +.OP \-\-in file +.OP \-\-outform encoding +.OP \-\-debug level +.YS +. +.SY pki\ \-\-pkcs12 +.BI \-\-options\~ file +.YS +. +.SY "pki \-\-pkcs12" +.B \-h +| +.B \-\-help +.YS +. +.SH "DESCRIPTION" +. +This sub-command of +.BR pki (1) +provides functions to work with PKCS#12 containers. +. +.SH "OPTIONS" +. +.TP +.B "\-h, \-\-help" +Print usage information with a summary of the available options. +.TP +.BI "\-v, \-\-debug " level +Set debug level, default: 1. +.TP +.BI "\-+, \-\-options " file +Read command line options from \fIfile\fR. +.TP +.BI "\-l, \-\-list" +List certificates and keys contained in a PKCS#12 container. +.TP +.BI "\-e, \-\-export " index +Export the credential with the given \fIindex\fR. Use \fI\-\-list\fR to +determine the index of certificates and keys. +.TP +.BI "\-i, \-\-in " file +PKCS#12 input file. If not given the input is read from \fISTDIN\fR. +. +.SH "SEE ALSO" +. +.BR pki (1)
\ No newline at end of file diff --git a/src/pki/man/pki---req.1.in b/src/pki/man/pki---req.1.in index ab144ce2a..a6f6a480a 100644 --- a/src/pki/man/pki---req.1.in +++ b/src/pki/man/pki---req.1.in @@ -62,8 +62,8 @@ The challengePassword to include in the certificate request. .TP .BI "\-g, \-\-digest " digest Digest to use for signature creation. One of \fImd5\fR, \fIsha1\fR, -\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. Defaults to -\fIsha1\fR. +\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. The default is +determined based on the type and size of the signature key. .TP .BI "\-f, \-\-outform " encoding Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or diff --git a/src/pki/man/pki---self.1.in b/src/pki/man/pki---self.1.in index 5e6e78bd0..53f53f816 100644 --- a/src/pki/man/pki---self.1.in +++ b/src/pki/man/pki---self.1.in @@ -109,8 +109,8 @@ Add extendedKeyUsage flag. One of \fIserverAuth\fR, \fIclientAuth\fR, .TP .BI "\-g, \-\-digest " digest Digest to use for signature creation. One of \fImd5\fR, \fIsha1\fR, -\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. Defaults to -\fIsha1\fR. +\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. The default is +determined based on the type and size of the signature key. .TP .BI "\-f, \-\-outform " encoding Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or @@ -127,10 +127,22 @@ times. Set path length constraint. .TP .BI "\-n, \-\-nc-permitted " name -Add permitted NameConstraint extension to certificate. +Add permitted NameConstraint extension to certificate. For DNS or email +constraints, the identity type is not always detectable by the given name. Use +the +.B dns: +or +.B email: +prefix to force a constraint type. .TP .BI "\-N, \-\-nc-excluded " name -Add excluded NameConstraint extension to certificate. +Add excluded NameConstraint extension to certificate. For DNS or email +constraints, the identity type is not always detectable by the given name. Use +the +.B dns: +or +.B email: +prefix to force a constraint type. .TP .BI "\-M, \-\-policy-mapping " issuer-oid:subject-oid Add policyMapping from issuer to subject OID. diff --git a/src/pki/man/pki---signcrl.1.in b/src/pki/man/pki---signcrl.1.in index bd6cba547..b930bfa3c 100644 --- a/src/pki/man/pki---signcrl.1.in +++ b/src/pki/man/pki---signcrl.1.in @@ -98,8 +98,8 @@ Freshest delta CRL URI to include in CRL. Can be used multiple times. .TP .BI "\-g, \-\-digest " digest Digest to use for signature creation. One of \fImd5\fR, \fIsha1\fR, -\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. Defaults to -\fIsha1\fR. +\fIsha224\fR, \fIsha256\fR, \fIsha384\fR, or \fIsha512\fR. The default is +determined based on the type and size of the signature key. .TP .BI "\-f, \-\-outform " encoding Encoding of the created certificate file. Either \fIder\fR (ASN.1 DER) or diff --git a/src/pki/pki.c b/src/pki/pki.c index 434287de6..472704945 100644 --- a/src/pki/pki.c +++ b/src/pki/pki.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2012-2014 Tobias Brunner * Copyright (C) 2009 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -22,6 +23,7 @@ #include <fcntl.h> #include <utils/debug.h> +#include <credentials/sets/mem_cred.h> #include <credentials/sets/callback_cred.h> /** @@ -235,12 +237,40 @@ void set_file_mode(FILE *stream, cred_encoding_type_t enc) #endif } +/* + * Described in header + */ +hash_algorithm_t get_default_digest(private_key_t *private) +{ + enumerator_t *enumerator; + signature_scheme_t scheme; + hash_algorithm_t alg = HASH_UNKNOWN; + + enumerator = signature_schemes_for_key(private->get_type(private), + private->get_keysize(private)); + if (enumerator->enumerate(enumerator, &scheme)) + { + alg = hasher_from_signature_scheme(scheme); + } + enumerator->destroy(enumerator); + + /* default to SHA-256 */ + return alg == HASH_UNKNOWN ? HASH_SHA256 : alg; +} + /** * Callback credential set pki uses */ static callback_cred_t *cb_set; /** + * Credential set to cache entered secrets + */ +static mem_cred_t *cb_creds; + +static shared_key_type_t prompted; + +/** * Callback function to receive credentials */ static shared_key_t* cb(void *data, shared_key_type_t type, @@ -248,7 +278,12 @@ static shared_key_t* cb(void *data, shared_key_type_t type, id_match_t *match_me, id_match_t *match_other) { char buf[64], *label, *secret = NULL; + shared_key_t *shared; + if (prompted == type) + { + return NULL; + } switch (type) { case SHARED_PIN: @@ -266,6 +301,7 @@ static shared_key_t* cb(void *data, shared_key_type_t type, #endif if (secret && strlen(secret)) { + prompted = type; if (match_me) { *match_me = ID_MATCH_PERFECT; @@ -274,8 +310,10 @@ static shared_key_t* cb(void *data, shared_key_type_t type, { *match_other = ID_MATCH_NONE; } - return shared_key_create(type, - chunk_clone(chunk_create(secret, strlen(secret)))); + shared = shared_key_create(type, chunk_clone(chunk_from_str(secret))); + /* cache password in case it is required more than once */ + cb_creds->add_shared(cb_creds, shared, NULL); + return shared->get_ref(shared); } return NULL; } @@ -287,6 +325,8 @@ static void add_callback() { cb_set = callback_cred_create_shared(cb, NULL); lib->credmgr->add_set(lib->credmgr, &cb_set->set); + cb_creds = mem_cred_create(); + lib->credmgr->add_set(lib->credmgr, &cb_creds->set); } /** @@ -294,6 +334,8 @@ static void add_callback() */ static void remove_callback() { + lib->credmgr->remove_set(lib->credmgr, &cb_creds->set); + cb_creds->destroy(cb_creds); lib->credmgr->remove_set(lib->credmgr, &cb_set->set); cb_set->destroy(cb_set); } diff --git a/src/pki/pki.h b/src/pki/pki.h index 1f0827733..017e61df6 100644 --- a/src/pki/pki.h +++ b/src/pki/pki.h @@ -55,4 +55,12 @@ bool calculate_lifetime(char *format, char *nbstr, char *nastr, time_t span, */ void set_file_mode(FILE *stream, cred_encoding_type_t enc); +/** + * Select default digest for signatures with the given key + * + * @param private private key + * @return hash algorithm + */ +hash_algorithm_t get_default_digest(private_key_t *private); + #endif /** PKI_H_ @}*/ diff --git a/src/pool/Makefile.am b/src/pool/Makefile.am index b8d662e57..5ae624b88 100644 --- a/src/pool/Makefile.am +++ b/src/pool/Makefile.am @@ -11,11 +11,13 @@ pool.o : $(top_builddir)/config.status AM_CPPFLAGS = \ -I$(top_srcdir)/src/libstrongswan \ -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon \ -DPLUGINS=\""${pool_plugins}\"" pool_LDADD = \ $(top_builddir)/src/libstrongswan/libstrongswan.la \ - $(top_builddir)/src/libhydra/libhydra.la + $(top_builddir)/src/libhydra/libhydra.la \ + $(top_builddir)/src/libcharon/libcharon.la endif USE_ATTR_SQL diff --git a/src/pool/Makefile.in b/src/pool/Makefile.in index 4f753a0bb..b9557547a 100644 --- a/src/pool/Makefile.in +++ b/src/pool/Makefile.in @@ -109,7 +109,8 @@ am__pool_SOURCES_DIST = pool.c pool_attributes.c pool_attributes.h \ @USE_ATTR_SQL_TRUE@ pool_usage.$(OBJEXT) pool_OBJECTS = $(am_pool_OBJECTS) @USE_ATTR_SQL_TRUE@pool_DEPENDENCIES = $(top_builddir)/src/libstrongswan/libstrongswan.la \ -@USE_ATTR_SQL_TRUE@ $(top_builddir)/src/libhydra/libhydra.la +@USE_ATTR_SQL_TRUE@ $(top_builddir)/src/libhydra/libhydra.la \ +@USE_ATTR_SQL_TRUE@ $(top_builddir)/src/libcharon/libcharon.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent @@ -228,6 +229,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -288,10 +290,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -365,6 +369,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ @@ -430,11 +436,13 @@ xml_LIBS = @xml_LIBS@ @USE_ATTR_SQL_TRUE@AM_CPPFLAGS = \ @USE_ATTR_SQL_TRUE@ -I$(top_srcdir)/src/libstrongswan \ @USE_ATTR_SQL_TRUE@ -I$(top_srcdir)/src/libhydra \ +@USE_ATTR_SQL_TRUE@ -I$(top_srcdir)/src/libcharon \ @USE_ATTR_SQL_TRUE@ -DPLUGINS=\""${pool_plugins}\"" @USE_ATTR_SQL_TRUE@pool_LDADD = \ @USE_ATTR_SQL_TRUE@ $(top_builddir)/src/libstrongswan/libstrongswan.la \ -@USE_ATTR_SQL_TRUE@ $(top_builddir)/src/libhydra/libhydra.la +@USE_ATTR_SQL_TRUE@ $(top_builddir)/src/libhydra/libhydra.la \ +@USE_ATTR_SQL_TRUE@ $(top_builddir)/src/libcharon/libcharon.la templatesdir = $(pkgdatadir)/templates/database/sql dist_templates_DATA = mysql.sql sqlite.sql diff --git a/src/pt-tls-client/Makefile.in b/src/pt-tls-client/Makefile.in index 7ee25c007..a02db98f2 100644 --- a/src/pt-tls-client/Makefile.in +++ b/src/pt-tls-client/Makefile.in @@ -198,6 +198,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -258,10 +259,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -335,6 +338,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/pt-tls-client/pt-tls-client.c b/src/pt-tls-client/pt-tls-client.c index a8d45b54f..3a179af17 100644 --- a/src/pt-tls-client/pt-tls-client.c +++ b/src/pt-tls-client/pt-tls-client.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2010-2013 Martin Willi, revosec AG - * Copyright (C) 2013-2014 Andreas Steffen + * Copyright (C) 2013-2015 Andreas Steffen * HSR Hochschule für Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -54,32 +54,44 @@ static int client(char *address, u_int16_t port, char *identity) { pt_tls_client_t *assessment; tls_t *tnccs; - identification_t *server, *client; - host_t *host; + identification_t *server_id, *client_id; + host_t *server_ip, *client_ip; status_t status; - host = host_create_from_dns(address, AF_UNSPEC, port); - if (!host) + server_ip = host_create_from_dns(address, AF_UNSPEC, port); + if (!server_ip) { return 1; } - server = identification_create_from_string(address); - client = identification_create_from_string(identity); + + client_ip = host_create_any(server_ip->get_family(server_ip)); + if (!client_ip) + { + server_ip->destroy(server_ip); + return 1; + } + server_id = identification_create_from_string(address); + client_id = identification_create_from_string(identity); + tnccs = (tls_t*)tnc->tnccs->create_instance(tnc->tnccs, TNCCS_2_0, FALSE, - server, client, TNC_IFT_TLS_2_0, NULL); + server_id, client_id, server_ip, client_ip, + TNC_IFT_TLS_2_0, NULL); + client_ip->destroy(client_ip); + if (!tnccs) { fprintf(stderr, "loading TNCCS failed: %s\n", PLUGINS); - host->destroy(host); - server->destroy(server); - client->destroy(client); + server_ip->destroy(server_ip); + server_id->destroy(server_id); + client_id->destroy(client_id); return 1; } - assessment = pt_tls_client_create(host, server, client); + assessment = pt_tls_client_create(server_ip, server_id, client_id); status = assessment->run_assessment(assessment, (tnccs_t*)tnccs); assessment->destroy(assessment); tnccs->destroy(tnccs); - return status; + + return (status != SUCCESS); } @@ -258,6 +270,7 @@ int main(int argc, char *argv[]) {"port", required_argument, NULL, 'p' }, {"cert", required_argument, NULL, 'x' }, {"key", required_argument, NULL, 'k' }, + {"mutual", no_argument, NULL, 'm' }, {"quiet", no_argument, NULL, 'q' }, {"debug", required_argument, NULL, 'd' }, {"optionsfrom", required_argument, NULL, '+' }, @@ -299,6 +312,10 @@ int main(int argc, char *argv[]) case 'p': /* --port <port> */ port = atoi(optarg); continue; + case 'm': /* --mutual */ + lib->settings->set_bool(lib->settings, + "%s.plugins.tnccs-20.mutual", TRUE, lib->ns); + continue; case 'q': /* --quiet */ log_to_stderr = FALSE; continue; diff --git a/src/scepclient/Makefile.in b/src/scepclient/Makefile.in index 6a947efa6..bcc70cb1b 100644 --- a/src/scepclient/Makefile.in +++ b/src/scepclient/Makefile.in @@ -225,6 +225,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -285,10 +286,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -362,6 +365,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/starter/Makefile.in b/src/starter/Makefile.in index 88d362f6c..ee68adc21 100644 --- a/src/starter/Makefile.in +++ b/src/starter/Makefile.in @@ -271,6 +271,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -331,10 +332,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -408,6 +411,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/starter/cmp.c b/src/starter/cmp.c index cea864a4a..aee55d94c 100644 --- a/src/starter/cmp.c +++ b/src/starter/cmp.c @@ -45,7 +45,7 @@ bool starter_cmp_conn(starter_conn_t *c1, starter_conn_t *c2) VARCMP(mark_in.value); VARCMP(mark_in.mask); VARCMP(mark_out.value); - VARCMP(mark_in.mask); + VARCMP(mark_out.mask); VARCMP(tfc); VARCMP(sa_keying_tries); diff --git a/src/starter/parser/lexer.c b/src/starter/parser/lexer.c index 157b89c31..cebf5a06c 100644 --- a/src/starter/parser/lexer.c +++ b/src/starter/parser/lexer.c @@ -456,8 +456,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); yyg->yy_c_buf_p = yy_cp; /* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */ -#define YY_NUM_RULES 28 -#define YY_END_OF_BUFFER 29 +#define YY_NUM_RULES 29 +#define YY_END_OF_BUFFER 30 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -465,34 +465,35 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[81] = +static yyconst flex_int16_t yy_accept[83] = { 0, - 0, 0, 0, 0, 0, 0, 29, 12, 3, 5, + 0, 0, 0, 0, 0, 0, 30, 12, 3, 5, 11, 4, 6, 12, 12, 2, 12, 12, 17, 13, - 14, 15, 27, 19, 18, 20, 12, 3, 4, 4, - 0, 12, 2, 0, 9, 12, 12, 17, 16, 27, - 26, 24, 25, 21, 22, 23, 12, 0, 12, 12, - 12, 0, 12, 8, 12, 12, 0, 12, 12, 12, - 0, 12, 12, 12, 0, 0, 12, 0, 0, 0, - 12, 0, 1, 10, 10, 0, 0, 0, 7, 0 + 14, 15, 28, 19, 18, 20, 12, 3, 4, 4, + 0, 12, 2, 0, 9, 12, 12, 17, 16, 28, + 27, 26, 27, 24, 25, 21, 22, 23, 12, 0, + 12, 12, 12, 0, 12, 8, 12, 12, 0, 12, + 12, 12, 0, 12, 12, 12, 0, 0, 12, 0, + 0, 0, 12, 0, 1, 10, 10, 0, 0, 0, + 7, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 5, 1, 6, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 4, 1, 5, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 8, 1, 1, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 7, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 9, 1, 1, 1, 1, 10, 11, 12, 13, + 1, 10, 1, 1, 1, 1, 11, 12, 13, 14, - 14, 15, 16, 1, 17, 1, 1, 18, 1, 19, - 20, 21, 1, 22, 23, 24, 25, 26, 1, 1, - 1, 1, 1, 1, 27, 1, 1, 1, 1, 1, + 15, 16, 17, 1, 18, 1, 1, 19, 1, 20, + 21, 22, 1, 23, 24, 25, 26, 27, 1, 1, + 1, 1, 1, 1, 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -509,106 +510,110 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[28] = +static yyconst flex_int32_t yy_meta[29] = { 0, - 1, 2, 3, 2, 4, 2, 5, 1, 6, 1, + 1, 2, 3, 1, 2, 4, 2, 5, 1, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1 + 1, 1, 1, 1, 1, 1, 1, 1 } ; -static yyconst flex_int16_t yy_base[92] = +static yyconst flex_int16_t yy_base[94] = { 0, - 0, 16, 41, 49, 6, 7, 141, 0, 23, 172, - 172, 0, 172, 134, 120, 30, 20, 120, 0, 172, - 172, 33, 0, 172, 172, 50, 0, 60, 0, 0, - 0, 118, 69, 115, 0, 109, 105, 0, 172, 0, - 172, 172, 172, 172, 172, 172, 76, 71, 16, 69, - 66, 67, 72, 0, 71, 74, 69, 69, 64, 69, - 62, 77, 61, 55, 60, 54, 94, 66, 64, 49, - 100, 46, 172, 172, 74, 24, 16, 5, 172, 172, - 107, 113, 119, 125, 131, 137, 142, 147, 153, 159, - 165 + 0, 17, 43, 52, 7, 26, 102, 0, 9, 189, + 189, 0, 189, 93, 79, 36, 10, 83, 0, 189, + 189, 59, 0, 189, 189, 85, 0, 32, 0, 0, + 0, 83, 65, 80, 0, 74, 70, 0, 189, 0, + 189, 189, 88, 189, 189, 189, 189, 189, 71, 63, + 31, 61, 58, 59, 64, 0, 63, 66, 61, 61, + 56, 60, 53, 64, 41, 10, 40, 32, 109, 66, + 49, 27, 116, 37, 189, 189, 71, 8, 2, 5, + 189, 189, 124, 130, 136, 142, 148, 154, 159, 164, + 170, 176, 182 } ; -static yyconst flex_int16_t yy_def[92] = +static yyconst flex_int16_t yy_def[94] = { 0, - 81, 81, 82, 82, 83, 83, 80, 84, 80, 80, - 80, 85, 80, 84, 84, 80, 84, 84, 86, 80, - 80, 80, 87, 80, 80, 88, 84, 80, 85, 85, - 84, 84, 80, 80, 84, 84, 84, 86, 80, 87, - 80, 80, 80, 80, 80, 80, 84, 80, 84, 84, - 84, 80, 84, 84, 84, 84, 80, 84, 84, 84, - 80, 84, 84, 84, 80, 80, 89, 90, 91, 80, - 89, 91, 80, 80, 90, 80, 80, 80, 80, 0, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80 + 83, 83, 84, 84, 85, 85, 82, 86, 82, 82, + 82, 87, 82, 86, 86, 82, 86, 86, 88, 82, + 82, 82, 89, 82, 82, 90, 86, 82, 87, 87, + 86, 86, 82, 82, 86, 86, 86, 88, 82, 89, + 82, 82, 82, 82, 82, 82, 82, 82, 86, 82, + 86, 86, 86, 82, 86, 86, 86, 86, 82, 86, + 86, 86, 82, 86, 86, 86, 82, 82, 91, 92, + 93, 82, 91, 93, 82, 82, 92, 82, 82, 82, + 82, 0, 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82 } ; -static yyconst flex_int16_t yy_nxt[200] = +static yyconst flex_int16_t yy_nxt[218] = { 0, - 80, 9, 10, 9, 11, 12, 13, 14, 24, 24, - 25, 25, 80, 80, 26, 26, 15, 16, 10, 16, - 11, 12, 13, 14, 28, 79, 28, 17, 29, 35, - 53, 33, 15, 33, 54, 29, 39, 39, 39, 36, - 78, 18, 20, 20, 20, 21, 20, 77, 73, 22, - 20, 20, 20, 21, 20, 34, 68, 22, 68, 39, - 42, 28, 76, 28, 43, 29, 73, 75, 44, 75, - 33, 45, 33, 46, 29, 75, 70, 75, 69, 67, - 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, - 56, 55, 52, 51, 34, 72, 73, 72, 72, 72, - - 72, 72, 73, 72, 72, 72, 72, 8, 8, 8, - 8, 8, 8, 19, 19, 19, 19, 19, 19, 23, - 23, 23, 23, 23, 23, 27, 50, 49, 48, 47, - 27, 30, 30, 37, 30, 30, 30, 38, 32, 31, - 80, 38, 40, 40, 80, 80, 40, 41, 41, 41, - 41, 41, 41, 71, 71, 71, 71, 71, 71, 74, - 74, 74, 74, 80, 74, 72, 72, 72, 72, 72, - 72, 7, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80 - + 82, 9, 10, 82, 9, 11, 12, 13, 14, 24, + 28, 70, 25, 28, 70, 29, 26, 15, 16, 10, + 35, 16, 11, 12, 13, 14, 81, 80, 24, 17, + 36, 25, 79, 28, 15, 26, 28, 33, 29, 75, + 33, 78, 29, 18, 20, 20, 55, 20, 21, 20, + 56, 75, 22, 20, 20, 72, 20, 21, 20, 71, + 69, 22, 34, 39, 39, 39, 33, 77, 68, 33, + 77, 29, 77, 67, 66, 77, 65, 64, 63, 62, + 61, 60, 59, 58, 57, 54, 39, 42, 43, 53, + 42, 34, 52, 51, 50, 49, 44, 37, 32, 31, + + 45, 82, 82, 82, 46, 82, 82, 47, 82, 48, + 74, 75, 82, 74, 74, 74, 74, 74, 75, 82, + 74, 74, 74, 74, 8, 8, 8, 8, 8, 8, + 19, 19, 19, 19, 19, 19, 23, 23, 23, 23, + 23, 23, 27, 82, 82, 82, 82, 27, 30, 30, + 82, 30, 30, 30, 38, 82, 82, 82, 38, 40, + 40, 82, 82, 40, 41, 41, 41, 41, 41, 41, + 73, 73, 73, 73, 73, 73, 76, 76, 76, 76, + 82, 76, 74, 74, 74, 74, 74, 74, 7, 82, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, + + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82 } ; -static yyconst flex_int16_t yy_chk[200] = +static yyconst flex_int16_t yy_chk[218] = { 0, - 0, 1, 1, 1, 1, 1, 1, 1, 5, 6, - 5, 6, 0, 0, 5, 6, 1, 2, 2, 2, - 2, 2, 2, 2, 9, 78, 9, 2, 9, 17, - 49, 16, 2, 16, 49, 16, 22, 22, 22, 17, - 77, 2, 3, 3, 3, 3, 3, 76, 72, 3, - 4, 4, 4, 4, 4, 16, 64, 4, 64, 22, - 26, 28, 70, 28, 26, 28, 69, 68, 26, 68, - 33, 26, 33, 26, 33, 75, 66, 75, 65, 63, - 62, 61, 60, 59, 58, 57, 56, 55, 53, 52, - 51, 50, 48, 47, 33, 67, 67, 67, 67, 67, - - 67, 71, 71, 71, 71, 71, 71, 81, 81, 81, - 81, 81, 81, 82, 82, 82, 82, 82, 82, 83, - 83, 83, 83, 83, 83, 84, 37, 36, 34, 32, - 84, 85, 85, 18, 85, 85, 85, 86, 15, 14, - 7, 86, 87, 87, 0, 0, 87, 88, 88, 88, - 88, 88, 88, 89, 89, 89, 89, 89, 89, 90, - 90, 90, 90, 0, 90, 91, 91, 91, 91, 91, - 91, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80 - + 0, 1, 1, 0, 1, 1, 1, 1, 1, 5, + 9, 66, 5, 9, 66, 9, 5, 1, 2, 2, + 17, 2, 2, 2, 2, 2, 80, 79, 6, 2, + 17, 6, 78, 28, 2, 6, 28, 16, 28, 74, + 16, 72, 16, 2, 3, 3, 51, 3, 3, 3, + 51, 71, 3, 4, 4, 68, 4, 4, 4, 67, + 65, 4, 16, 22, 22, 22, 33, 70, 64, 33, + 70, 33, 77, 63, 62, 77, 61, 60, 59, 58, + 57, 55, 54, 53, 52, 50, 22, 26, 26, 49, + 43, 33, 37, 36, 34, 32, 26, 18, 15, 14, + + 26, 7, 0, 0, 26, 0, 0, 26, 0, 26, + 69, 69, 0, 69, 69, 69, 69, 73, 73, 0, + 73, 73, 73, 73, 83, 83, 83, 83, 83, 83, + 84, 84, 84, 84, 84, 84, 85, 85, 85, 85, + 85, 85, 86, 0, 0, 0, 0, 86, 87, 87, + 0, 87, 87, 87, 88, 0, 0, 0, 88, 89, + 89, 0, 0, 89, 90, 90, 90, 90, 90, 90, + 91, 91, 91, 91, 91, 91, 92, 92, 92, 92, + 0, 92, 93, 93, 93, 93, 93, 93, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, + + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82 } ; /* Table of booleans, true if rule could match eol. */ -static yyconst flex_int32_t yy_rule_can_match_eol[29] = +static yyconst flex_int32_t yy_rule_can_match_eol[30] = { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, - 1, 0, 0, 0, 0, 0, 1, 0, 0, }; + 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, }; -static yyconst flex_int16_t yy_rule_linenum[28] = +static yyconst flex_int16_t yy_rule_linenum[29] = { 0, 60, 61, 62, 63, 65, 67, 68, 69, 70, 72, 77, 82, 90, 109, 112, 115, 118, 124, 126, 127, - 150, 151, 152, 153, 154, 155, 158 + 150, 151, 152, 153, 154, 155, 156, 157 } ; /* The intent behind this definition is that it'll catch @@ -657,7 +662,7 @@ static void include_files(parser_helper_t *ctx); /* state used to scan quoted strings */ -#line 661 "parser/lexer.c" +#line 666 "parser/lexer.c" #define INITIAL 0 #define inc 1 @@ -972,7 +977,7 @@ YY_DECL #line 58 "parser/lexer.l" -#line 976 "parser/lexer.c" +#line 981 "parser/lexer.c" yylval = yylval_param; @@ -1038,13 +1043,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 81 ) + if ( yy_current_state >= 83 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 172 ); + while ( yy_base[yy_current_state] != 189 ); yy_find_action: /* %% [10.0] code to find the action number goes here */ @@ -1079,13 +1084,13 @@ do_action: /* This label is used only to access EOF actions. */ { if ( yy_act == 0 ) fprintf( stderr, "--scanner backing up\n" ); - else if ( yy_act < 28 ) + else if ( yy_act < 29 ) fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n", (long)yy_rule_linenum[yy_act], yytext ); - else if ( yy_act == 28 ) + else if ( yy_act == 29 ) fprintf( stderr, "--accepting default rule (\"%s\")\n", yytext ); - else if ( yy_act == 29 ) + else if ( yy_act == 30 ) fprintf( stderr, "--(end of buffer or a NUL)\n" ); else fprintf( stderr, "--EOF (start condition %d)\n", YY_START ); @@ -1300,20 +1305,23 @@ case 26: /* rule 26 can match eol */ YY_RULE_SETUP #line 155 "parser/lexer.l" -{ - yyextra->string_add(yyextra, yytext+1); - } +/* merge lines that end with EOL characters */ YY_BREAK case 27: YY_RULE_SETUP -#line 158 "parser/lexer.l" +#line 156 "parser/lexer.l" +yyextra->string_add(yyextra, yytext+1); + YY_BREAK +case 28: +YY_RULE_SETUP +#line 157 "parser/lexer.l" { yyextra->string_add(yyextra, yytext); } YY_BREAK case YY_STATE_EOF(INITIAL): -#line 163 "parser/lexer.l" +#line 162 "parser/lexer.l" { conf_parser_pop_buffer_state(yyscanner); if (!conf_parser_open_next_file(yyextra) && !YY_CURRENT_BUFFER) @@ -1322,12 +1330,12 @@ case YY_STATE_EOF(INITIAL): } } YY_BREAK -case 28: +case 29: YY_RULE_SETUP -#line 171 "parser/lexer.l" +#line 170 "parser/lexer.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 1331 "parser/lexer.c" +#line 1339 "parser/lexer.c" case YY_END_OF_BUFFER: { @@ -1641,7 +1649,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 81 ) + if ( yy_current_state >= 83 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1675,11 +1683,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 81 ) + if ( yy_current_state >= 83 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 80); + yy_is_jam = (yy_current_state == 82); return yy_is_jam ? 0 : yy_current_state; } @@ -2697,7 +2705,7 @@ void conf_parser_free (void * ptr , yyscan_t yyscanner) /* %ok-for-header */ -#line 171 "parser/lexer.l" +#line 170 "parser/lexer.l" diff --git a/src/starter/parser/lexer.l b/src/starter/parser/lexer.l index a88cbe809..d967e745b 100644 --- a/src/starter/parser/lexer.l +++ b/src/starter/parser/lexer.l @@ -152,9 +152,8 @@ static void include_files(parser_helper_t *ctx); \\t yyextra->string_add(yyextra, "\t"); \\b yyextra->string_add(yyextra, "\b"); \\f yyextra->string_add(yyextra, "\f"); - \\(.|\n) { - yyextra->string_add(yyextra, yytext+1); - } + \\\r?\n /* merge lines that end with EOL characters */ + \\. yyextra->string_add(yyextra, yytext+1); [^\\\n"]+ { yyextra->string_add(yyextra, yytext); } diff --git a/src/starter/starterstroke.c b/src/starter/starterstroke.c index 1e305db8b..6e1f1605d 100644 --- a/src/starter/starterstroke.c +++ b/src/starter/starterstroke.c @@ -35,10 +35,16 @@ static char* push_string(stroke_msg_t *msg, char *string) { unsigned long string_start = msg->length; - if (string == NULL || msg->length + strlen(string) >= sizeof(stroke_msg_t)) + if (string == NULL) { return NULL; } + else if ((size_t)msg->length + strlen(string) >= sizeof(stroke_msg_t)) + { + /* set invalid length to fail during message send */ + msg->length = ~0; + return NULL; + } else { msg->length += strlen(string) + 1; @@ -53,6 +59,12 @@ static int send_stroke_msg (stroke_msg_t *msg) char *uri, buffer[64]; int count; + if (msg->length > sizeof(stroke_msg_t)) + { + DBG1(DBG_APP, "stroke message exceeds buffer size"); + return -1; + } + /* starter is not called from commandline, and therefore absolutely silent */ msg->output_verbosity = -1; diff --git a/src/starter/tests/Makefile.in b/src/starter/tests/Makefile.in index d42a0d286..b26125501 100644 --- a/src/starter/tests/Makefile.in +++ b/src/starter/tests/Makefile.in @@ -223,6 +223,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -283,10 +284,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -360,6 +363,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/stroke/Makefile.in b/src/stroke/Makefile.in index 9c041dfbf..c32ebf905 100644 --- a/src/stroke/Makefile.in +++ b/src/stroke/Makefile.in @@ -197,6 +197,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -257,10 +258,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -334,6 +337,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ diff --git a/src/stroke/stroke_msg.h b/src/stroke/stroke_msg.h index 60886cf7f..c2b923f6d 100644 --- a/src/stroke/stroke_msg.h +++ b/src/stroke/stroke_msg.h @@ -32,7 +32,7 @@ */ #define STROKE_SOCKET IPSEC_PIDDIR "/charon.ctl" -#define STROKE_BUF_LEN 2048 +#define STROKE_BUF_LEN 4096 typedef enum list_flag_t list_flag_t; diff --git a/src/swanctl/Makefile.am b/src/swanctl/Makefile.am index b84d70587..f4f9fdf7e 100644 --- a/src/swanctl/Makefile.am +++ b/src/swanctl/Makefile.am @@ -65,4 +65,5 @@ install-data-local: swanctl.conf test -e "$(DESTDIR)$(swanctldir)/rsa" || $(INSTALL) -d -m 750 "$(DESTDIR)$(swanctldir)/rsa" || true test -e "$(DESTDIR)$(swanctldir)/ecdsa" || $(INSTALL) -d -m 750 "$(DESTDIR)$(swanctldir)/ecdsa" || true test -e "$(DESTDIR)$(swanctldir)/pkcs8" || $(INSTALL) -d -m 750 "$(DESTDIR)$(swanctldir)/pkcs8" || true + test -e "$(DESTDIR)$(swanctldir)/pkcs12" || $(INSTALL) -d -m 750 "$(DESTDIR)$(swanctldir)/pkcs12" || true test -e "$(DESTDIR)$(swanctldir)/swanctl.conf" || $(INSTALL) -m 640 $(srcdir)/swanctl.conf $(DESTDIR)$(swanctldir)/swanctl.conf || true diff --git a/src/swanctl/Makefile.in b/src/swanctl/Makefile.in index 649e6d8ae..f981bb1f3 100644 --- a/src/swanctl/Makefile.in +++ b/src/swanctl/Makefile.in @@ -238,6 +238,7 @@ DLLIB = @DLLIB@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ +EASY_INSTALL = @EASY_INSTALL@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ @@ -298,10 +299,12 @@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PTHREADLIB = @PTHREADLIB@ PYTHON = @PYTHON@ +PYTHONEGGINSTALLDIR = @PYTHONEGGINSTALLDIR@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_VERSION = @PYTHON_VERSION@ +PY_TEST = @PY_TEST@ RANLIB = @RANLIB@ RTLIB = @RTLIB@ RUBY = @RUBY@ @@ -375,6 +378,8 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libiptc_CFLAGS = @libiptc_CFLAGS@ +libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ localedir = @localedir@ localstatedir = @localstatedir@ @@ -991,6 +996,7 @@ install-data-local: swanctl.conf test -e "$(DESTDIR)$(swanctldir)/rsa" || $(INSTALL) -d -m 750 "$(DESTDIR)$(swanctldir)/rsa" || true test -e "$(DESTDIR)$(swanctldir)/ecdsa" || $(INSTALL) -d -m 750 "$(DESTDIR)$(swanctldir)/ecdsa" || true test -e "$(DESTDIR)$(swanctldir)/pkcs8" || $(INSTALL) -d -m 750 "$(DESTDIR)$(swanctldir)/pkcs8" || true + test -e "$(DESTDIR)$(swanctldir)/pkcs12" || $(INSTALL) -d -m 750 "$(DESTDIR)$(swanctldir)/pkcs12" || true test -e "$(DESTDIR)$(swanctldir)/swanctl.conf" || $(INSTALL) -m 640 $(srcdir)/swanctl.conf $(DESTDIR)$(swanctldir)/swanctl.conf || true # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/src/swanctl/commands/list_conns.c b/src/swanctl/commands/list_conns.c index 31ab9c40a..019c88888 100644 --- a/src/swanctl/commands/list_conns.c +++ b/src/swanctl/commands/list_conns.c @@ -103,7 +103,7 @@ CALLBACK(conn_sn, int, { return vici_parse_cb(res, children_sn, NULL, NULL, NULL); } - if (streq(name, "local") || streq(name, "remote")) + if (strpfx(name, "local") || strpfx(name, "remote")) { hashtable_t *auth; @@ -112,7 +112,8 @@ CALLBACK(conn_sn, int, if (ret == 0) { printf(" %s %s authentication:\n", - name, auth->get(auth, "class") ?: "unspecified"); + strpfx(name, "local") ? "local" : "remote", + auth->get(auth, "class") ?: "unspecified"); if (auth->get(auth, "id")) { printf(" id: %s\n", auth->get(auth, "id")); diff --git a/src/swanctl/commands/list_sas.c b/src/swanctl/commands/list_sas.c index 35e7469a9..81e1b7cca 100644 --- a/src/swanctl/commands/list_sas.c +++ b/src/swanctl/commands/list_sas.c @@ -86,8 +86,8 @@ CALLBACK(child_sas, int, ret = vici_parse_cb(res, NULL, sa_values, sa_list, child); if (ret == 0) { - printf(" %s: #%s, %s, %s%s, %s:", - name, child->get(child, "reqid"), + printf(" %s: #%s, reqid %s, %s, %s%s, %s:", + name, child->get(child, "uniqueid"), child->get(child, "reqid"), child->get(child, "state"), child->get(child, "mode"), child->get(child, "encap") ? "-in-UDP" : "", child->get(child, "protocol")); @@ -122,7 +122,7 @@ CALLBACK(child_sas, int, } if (child->get(child, "esn")) { - printf("/%s", child->get(child, "esn")); + printf("/ESN"); } printf("\n"); diff --git a/src/swanctl/commands/load_conns.c b/src/swanctl/commands/load_conns.c index de30d8eb4..6ee8b8785 100644 --- a/src/swanctl/commands/load_conns.c +++ b/src/swanctl/commands/load_conns.c @@ -93,11 +93,12 @@ static void add_list_key(vici_req_t *req, char *key, char *value) /** * Add a vici list of blobs from a comma separated file list */ -static void add_file_list_key(vici_req_t *req, char *key, char *value) +static bool add_file_list_key(vici_req_t *req, char *key, char *value) { enumerator_t *enumerator; chunk_t *map; char *token, buf[PATH_MAX]; + bool ret = TRUE; vici_begin_list(req, key); enumerator = enumerator_create_token(value, ",", " "); @@ -127,21 +128,26 @@ static void add_file_list_key(vici_req_t *req, char *key, char *value) } else { - fprintf(stderr, "loading certificate '%s' failed: %s\n", - token, strerror(errno)); + fprintf(stderr, "loading %s certificate '%s' failed: %s\n", + key, token, strerror(errno)); + ret = FALSE; + break; } } enumerator->destroy(enumerator); vici_end_list(req); + + return ret; } /** * Translate setting key/values from a section into vici key-values/lists */ -static void add_key_values(vici_req_t *req, settings_t *cfg, char *section) +static bool add_key_values(vici_req_t *req, settings_t *cfg, char *section) { enumerator_t *enumerator; char *key, *value; + bool ret = TRUE; enumerator = cfg->create_key_value_enumerator(cfg, section); while (enumerator->enumerate(enumerator, &key, &value)) @@ -152,34 +158,51 @@ static void add_key_values(vici_req_t *req, settings_t *cfg, char *section) } else if (is_file_list_key(key)) { - add_file_list_key(req, key, value); + ret = add_file_list_key(req, key, value); } else { vici_add_key_valuef(req, key, "%s", value); } + if (!ret) + { + break; + } } enumerator->destroy(enumerator); + + return ret; } /** * Translate a settings section to a vici section */ -static void add_sections(vici_req_t *req, settings_t *cfg, char *section) +static bool add_sections(vici_req_t *req, settings_t *cfg, char *section) { enumerator_t *enumerator; char *name, buf[256]; + bool ret = TRUE; enumerator = cfg->create_section_enumerator(cfg, section); while (enumerator->enumerate(enumerator, &name)) { vici_begin_section(req, name); snprintf(buf, sizeof(buf), "%s.%s", section, name); - add_key_values(req, cfg, buf); - add_sections(req, cfg, buf); + ret = add_key_values(req, cfg, buf); + if (!ret) + { + break; + } + ret = add_sections(req, cfg, buf); + if (!ret) + { + break; + } vici_end_section(req); } enumerator->destroy(enumerator); + + return ret; } /** @@ -198,8 +221,12 @@ static bool load_conn(vici_conn_t *conn, settings_t *cfg, req = vici_begin("load-conn"); vici_begin_section(req, section); - add_key_values(req, cfg, buf); - add_sections(req, cfg, buf); + if (!add_key_values(req, cfg, buf) || + !add_sections(req, cfg, buf)) + { + vici_free_req(req); + return FALSE; + } vici_end_section(req); res = vici_submit(req, conn); diff --git a/src/swanctl/commands/load_creds.c b/src/swanctl/commands/load_creds.c index 86ee3c179..d2ebc22eb 100644 --- a/src/swanctl/commands/load_creds.c +++ b/src/swanctl/commands/load_creds.c @@ -25,6 +25,7 @@ #include <credentials/sets/mem_cred.h> #include <credentials/sets/callback_cred.h> +#include <credentials/containers/pkcs12.h> /** * Load a single certificate over vici @@ -60,7 +61,7 @@ static bool load_cert(vici_conn_t *conn, command_format_options_t format, } else { - printf("loaded %s certificate '%s'\n", type, dir); + printf("loaded %s certificate from '%s'\n", type, dir); } vici_free_res(res); return ret; @@ -113,7 +114,14 @@ static bool load_key(vici_conn_t *conn, command_format_options_t format, req = vici_begin("load-key"); - vici_add_key_valuef(req, "type", "%s", type); + if (streq(type, "pkcs8")) + { /* as used by vici */ + vici_add_key_valuef(req, "type", "any"); + } + else + { + vici_add_key_valuef(req, "type", "%s", type); + } vici_add_key_value(req, "data", data.ptr, data.len); res = vici_submit(req, conn); @@ -135,20 +143,59 @@ static bool load_key(vici_conn_t *conn, command_format_options_t format, } else { - printf("loaded %s key '%s'\n", type, dir); + printf("loaded %s key from '%s'\n", type, dir); } vici_free_res(res); return ret; } /** + * Load a private key of any type to vici + */ +static bool load_key_anytype(vici_conn_t *conn, command_format_options_t format, + char *path, private_key_t *private) +{ + bool loaded = FALSE; + chunk_t encoding; + + if (!private->get_encoding(private, PRIVKEY_ASN1_DER, &encoding)) + { + fprintf(stderr, "encoding private key from '%s' failed\n", path); + return FALSE; + } + switch (private->get_type(private)) + { + case KEY_RSA: + loaded = load_key(conn, format, path, "rsa", encoding); + break; + case KEY_ECDSA: + loaded = load_key(conn, format, path, "ecdsa", encoding); + break; + default: + fprintf(stderr, "unsupported key type in '%s'\n", path); + break; + } + chunk_clear(&encoding); + return loaded; +} + +/** + * Data passed to password callback + */ +typedef struct { + char prompt[128]; + mem_cred_t *cache; +} cb_data_t; + +/** * Callback function to prompt for private key passwords */ CALLBACK(password_cb, shared_key_t*, - char *prompt, shared_key_type_t type, + cb_data_t *data, shared_key_type_t type, identification_t *me, identification_t *other, id_match_t *match_me, id_match_t *match_other) { + shared_key_t *shared; char *pwd = NULL; if (type != SHARED_PRIVATE_KEY_PASS) @@ -156,7 +203,7 @@ CALLBACK(password_cb, shared_key_t*, return NULL; } #ifdef HAVE_GETPASS - pwd = getpass(prompt); + pwd = getpass(data->prompt); #endif if (!pwd || strlen(pwd) == 0) { @@ -170,65 +217,94 @@ CALLBACK(password_cb, shared_key_t*, { *match_other = ID_MATCH_PERFECT; } - return shared_key_create(type, chunk_clone(chunk_from_str(pwd))); + shared = shared_key_create(type, chunk_clone(chunk_from_str(pwd))); + /* cache secret if it is required more than once (PKCS#12) */ + data->cache->add_shared(data->cache, shared, NULL); + return shared->get_ref(shared); } /** - * Try to parse a potentially encrypted private key using password prompt + * Determine credential type and subtype from a type string */ -static private_key_t* decrypt_key(char *name, char *type, chunk_t encoding) +static bool determine_credtype(char *type, credential_type_t *credtype, + int *subtype) { - key_type_t kt = KEY_ANY; - private_key_t *private; - callback_cred_t *cb; - char buf[128]; + struct { + char *type; + credential_type_t credtype; + int subtype; + } map[] = { + { "pkcs8", CRED_PRIVATE_KEY, KEY_ANY, }, + { "rsa", CRED_PRIVATE_KEY, KEY_RSA, }, + { "ecdsa", CRED_PRIVATE_KEY, KEY_ECDSA, }, + { "pkcs12", CRED_CONTAINER, CONTAINER_PKCS12, }, + }; + int i; - if (streq(type, "rsa")) + for (i = 0; i < countof(map); i++) { - kt = KEY_RSA; + if (streq(map[i].type, type)) + { + *credtype = map[i].credtype; + *subtype = map[i].subtype; + return TRUE; + } } - else if (streq(type, "ecdsa")) + return FALSE; +} + +/** + * Try to parse a potentially encrypted credential using password prompt + */ +static void* decrypt(char *name, char *type, chunk_t encoding) +{ + credential_type_t credtype; + int subtype; + void *cred; + callback_cred_t *cb; + cb_data_t data; + + if (!determine_credtype(type, &credtype, &subtype)) { - kt = KEY_ECDSA; + return NULL; } - snprintf(buf, sizeof(buf), "Password for '%s': ", name); + snprintf(data.prompt, sizeof(data.prompt), "Password for %s file '%s': ", + type, name); - cb = callback_cred_create_shared(password_cb, buf); + data.cache = mem_cred_create(); + lib->credmgr->add_set(lib->credmgr, &data.cache->set); + cb = callback_cred_create_shared(password_cb, &data); lib->credmgr->add_set(lib->credmgr, &cb->set); - private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, kt, - BUILD_BLOB_PEM, encoding, BUILD_END); + cred = lib->creds->create(lib->creds, credtype, subtype, + BUILD_BLOB_PEM, encoding, BUILD_END); + lib->credmgr->remove_set(lib->credmgr, &data.cache->set); + data.cache->destroy(data.cache); lib->credmgr->remove_set(lib->credmgr, &cb->set); cb->destroy(cb); - return private; + return cred; } /** - * Try to parse a potentially encrypted private key using configured secret + * Try to parse a potentially encrypted credential using configured secret */ -static private_key_t* decrypt_key_with_config(settings_t *cfg, char *name, - char *type, chunk_t encoding) -{ key_type_t kt = KEY_ANY; +static void* decrypt_with_config(settings_t *cfg, char *name, char *type, + chunk_t encoding) +{ + credential_type_t credtype; + int subtype; enumerator_t *enumerator, *secrets; char *section, *key, *value, *file, buf[128]; shared_key_t *shared; - private_key_t *private = NULL; + void *cred = NULL; mem_cred_t *mem = NULL; - if (streq(type, "rsa")) - { - kt = KEY_RSA; - } - else if (streq(type, "ecdsa")) - { - kt = KEY_ECDSA; - } - else + if (!determine_credtype(type, &credtype, &subtype)) { - type = "pkcs8"; + return NULL; } /* load all secrets for this key type */ @@ -265,12 +341,12 @@ static private_key_t* decrypt_key_with_config(settings_t *cfg, char *name, { lib->credmgr->add_local_set(lib->credmgr, &mem->set, FALSE); - private = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, kt, - BUILD_BLOB_PEM, encoding, BUILD_END); + cred = lib->creds->create(lib->creds, credtype, subtype, + BUILD_BLOB_PEM, encoding, BUILD_END); lib->credmgr->remove_local_set(lib->credmgr, &mem->set); - if (!private) + if (!cred) { fprintf(stderr, "configured decryption secret for '%s' invalid\n", name); @@ -279,7 +355,7 @@ static private_key_t* decrypt_key_with_config(settings_t *cfg, char *name, mem->destroy(mem); } - return private; + return cred; } /** @@ -292,30 +368,15 @@ static bool load_encrypted_key(vici_conn_t *conn, { private_key_t *private; bool loaded = FALSE; - chunk_t encoding; - private = decrypt_key_with_config(cfg, rel, type, data); + private = decrypt_with_config(cfg, rel, type, data); if (!private && !noprompt) { - private = decrypt_key(rel, type, data); + private = decrypt(rel, type, data); } if (private) { - if (private->get_encoding(private, PRIVKEY_ASN1_DER, &encoding)) - { - switch (private->get_type(private)) - { - case KEY_RSA: - loaded = load_key(conn, format, path, "rsa", encoding); - break; - case KEY_ECDSA: - loaded = load_key(conn, format, path, "ecdsa", encoding); - break; - default: - break; - } - chunk_clear(&encoding); - } + loaded = load_key_anytype(conn, format, path, private); private->destroy(private); } return loaded; @@ -361,6 +422,114 @@ static void load_keys(vici_conn_t *conn, command_format_options_t format, } /** + * Load credentials from a PKCS#12 container over vici + */ +static bool load_pkcs12(vici_conn_t *conn, command_format_options_t format, + char *path, pkcs12_t *p12) +{ + enumerator_t *enumerator; + certificate_t *cert; + private_key_t *private; + chunk_t encoding; + bool loaded = TRUE; + + enumerator = p12->create_cert_enumerator(p12); + while (loaded && enumerator->enumerate(enumerator, &cert)) + { + loaded = FALSE; + if (cert->get_encoding(cert, CERT_ASN1_DER, &encoding)) + { + loaded = load_cert(conn, format, path, "x509", encoding); + if (loaded) + { + fprintf(stderr, " %Y\n", cert->get_subject(cert)); + } + free(encoding.ptr); + } + else + { + fprintf(stderr, "encoding certificate from '%s' failed\n", path); + } + } + enumerator->destroy(enumerator); + + enumerator = p12->create_key_enumerator(p12); + while (loaded && enumerator->enumerate(enumerator, &private)) + { + loaded = load_key_anytype(conn, format, path, private); + } + enumerator->destroy(enumerator); + + return loaded; +} + +/** + * Try to decrypt and load credentials from a container + */ +static bool load_encrypted_container(vici_conn_t *conn, + command_format_options_t format, settings_t *cfg, char *rel, + char *path, char *type, bool noprompt, chunk_t data) +{ + container_t *container; + bool loaded = FALSE; + + container = decrypt_with_config(cfg, rel, type, data); + if (!container && !noprompt) + { + container = decrypt(rel, type, data); + } + if (container) + { + switch (container->get_type(container)) + { + case CONTAINER_PKCS12: + loaded = load_pkcs12(conn, format, path, (pkcs12_t*)container); + break; + default: + break; + } + container->destroy(container); + } + return loaded; +} + +/** + * Load credential containers from a directory + */ +static void load_containers(vici_conn_t *conn, command_format_options_t format, + bool noprompt, settings_t *cfg, char *type, char *dir) +{ + enumerator_t *enumerator; + struct stat st; + chunk_t *map; + char *path, *rel; + + enumerator = enumerator_create_directory(dir); + if (enumerator) + { + while (enumerator->enumerate(enumerator, &rel, &path, &st)) + { + if (S_ISREG(st.st_mode)) + { + map = chunk_map(path, FALSE); + if (map) + { + load_encrypted_container(conn, format, cfg, rel, path, + type, noprompt, *map); + chunk_unmap(map); + } + else + { + fprintf(stderr, "mapping '%s' failed: %s, skipped\n", + path, strerror(errno)); + } + } + } + enumerator->destroy(enumerator); + } +} + +/** * Load a single secret over VICI */ static bool load_secret(vici_conn_t *conn, settings_t *cfg, @@ -380,6 +549,7 @@ static bool load_secret(vici_conn_t *conn, settings_t *cfg, "rsa", "ecdsa", "pkcs8", + "pkcs12", }; for (i = 0; i < countof(types); i++) @@ -510,7 +680,9 @@ int load_creds_cfg(vici_conn_t *conn, command_format_options_t format, load_keys(conn, format, noprompt, cfg, "rsa", SWANCTL_RSADIR); load_keys(conn, format, noprompt, cfg, "ecdsa", SWANCTL_ECDSADIR); - load_keys(conn, format, noprompt, cfg, "any", SWANCTL_PKCS8DIR); + load_keys(conn, format, noprompt, cfg, "pkcs8", SWANCTL_PKCS8DIR); + + load_containers(conn, format, noprompt, cfg, "pkcs12", SWANCTL_PKCS12DIR); enumerator = cfg->create_section_enumerator(cfg, "secrets"); while (enumerator->enumerate(enumerator, §ion)) diff --git a/src/swanctl/swanctl.conf b/src/swanctl/swanctl.conf index 0808cf58b..faafecc44 100644 --- a/src/swanctl/swanctl.conf +++ b/src/swanctl/swanctl.conf @@ -286,6 +286,18 @@ # } + # PKCS#12 decryption passphrase for a container in the pkcs12 folder. + # pkcs12<suffix> { + + # File name in the pkcs12 folder for which this passphrase should be + # used. + # file = + + # Value of decryption passphrase for PKCS#12 container. + # secret = + + # } + # } # Section defining named pools. @@ -294,7 +306,7 @@ # Section defining a single pool with a unique name. # <name> { - # Subnet defining addresses allocated in pool. + # Addresses allocated in pool. # addrs = # Comma separated list of additional attributes from type <attr>. diff --git a/src/swanctl/swanctl.conf.5.main b/src/swanctl/swanctl.conf.5.main index 8943b62db..a770b28b1 100644 --- a/src/swanctl/swanctl.conf.5.main +++ b/src/swanctl/swanctl.conf.5.main @@ -251,7 +251,12 @@ performs a reauthentication procedure instead. With the default value IKE rekeying is scheduled every 4 hours, minus the configured .RB "" "rand_time" "." - +If a +.RB "" "reauth_time" "" +is configured, +.RB "" "rekey_time" "" +defaults to zero disabling rekeying; explicitly set both to enforce rekeying and +reauthentication. .TP .BR connections.<conn>.over_time " [10% of rekey_time/reauth_time]" @@ -363,6 +368,37 @@ IKE identity to use for authentication round. When using certificate authentication, the IKE identity must be contained in the certificate, either as subject or as subjectAltName. +The identity can be an IP address, a fully\-qualified domain name, an email +address or a Distinguished Name for which the ID type is determined +automatically and the string is converted to the appropriate encoding. To +enforce a specific identity type, a prefix may be used, followed by a colon (:). +If the number sign (#) follows the colon, the remaining data is interpreted as +hex encoding, otherwise the string is used as\-is as the identification data. +Note that this implies that no conversion is performed for non\-string +identities. For example, +.RI "" "ipv4:10.0.0.1" "" +does not create a valid ID_IPV4_ADDR +IKE identity, as it does not get converted to binary 0x0a000001. Instead, one +could use +.RI "" "ipv4:#0a000001" "" +to get a valid identity, but just using the implicit +type with automatic conversion is usually simpler. The same applies to the ASN1 +encoded types. The following prefixes are known: +.RI "" "ipv4" "," +.RI "" "ipv6" "," +.RI "" "rfc822" "," +.RI "" "email" "," +.RI "" "userfqdn" "," +.RI "" "fqdn" "," +.RI "" "dns" "," +.RI "" "asn1dn" "," +.RI "" "asn1gn" "" +and +.RI "" "keyid" "." +Custom type +prefixes may be specified by surrounding the numerical type value by curly +brackets. + .TP .BR connections.<conn>.local<suffix>.eap_id " [id]" Client EAP\-Identity to use in EAP\-Identity exchange and the EAP method. @@ -397,9 +433,10 @@ omitted. .TP .BR connections.<conn>.remote<suffix>.id " [%any]" -IKE identity to expect for authentication round. When using certificate -authentication, the IKE identity must be contained in the certificate, either as -subject or as subjectAltName. +IKE identity to expect for authentication round. Refer to the +.RI "" "local" "" +.RI "" "id" "" +section for details. .TP .BR connections.<conn>.remote<suffix>.groups " []" @@ -725,9 +762,11 @@ uses dynamic reqids, allocated incrementally. .TP .BR connections.<conn>.children.<child>.mark_in " [0/0x00000000]" -Netfilter mark and mask for input traffic. On Linux Netfilter may apply marks to -each packet coming from a tunnel having that option set. The mark may then be -used by Netfilter to match rules. +Netfilter mark and mask for input traffic. On Linux Netfilter may require marks +on each packet to match an SA having that option set. This allows Netfilter +rules to select specific tunnels for incoming traffic. The special value +.RI "" "%unique" "" +sets a unique mark on each CHILD_SA instance. An additional mask may be appended to the mark, separated by _/_. The default mask if omitted is 0xffffffff. @@ -736,7 +775,9 @@ mask if omitted is 0xffffffff. .BR connections.<conn>.children.<child>.mark_out " [0/0x00000000]" Netfilter mark and mask for output traffic. On Linux Netfilter may require marks on each packet to match a policy having that option set. This allows Netfilter -rules to select specific tunnels for outgoing traffic. +rules to select specific tunnels for outgoing traffic. The special value +.RI "" "%unique" "" +sets a unique mark on each CHILD_SA instance. An additional mask may be appended to the mark, separated by _/_. The default mask if omitted is 0xffffffff. @@ -925,6 +966,23 @@ folder for which this passphrase should be used. Value of decryption passphrase for PKCS#8 key. .TP +.B secrets.pkcs12<suffix> +.br +PKCS#12 decryption passphrase for a container in the +.RI "" "pkcs12" "" +folder. + +.TP +.BR secrets.pkcs12<suffix>.file " []" +File name in the +.RI "" "pkcs12" "" +folder for which this passphrase should be used. + +.TP +.BR secrets.pkcs12<suffix>.secret " []" +Value of decryption passphrase for PKCS#12 container. + +.TP .B pools .br Section defining named pools. Named pools may be referenced by connections with @@ -939,9 +997,9 @@ Section defining a single pool with a unique name. .TP .BR pools.<name>.addrs " []" -Subnet defining addresses allocated in pool. Accepts a single CIDR subnet -defining the pool to allocate addresses from. Pools must be unique and -non\-overlapping. +Subnet or range defining addresses allocated in pool. Accepts a single CIDR +subnet defining the pool to allocate addresses from, or an address range +(<from>\-<to>). Pools must be unique and non\-overlapping. .TP .BR pools.<name>.<attr> " []" diff --git a/src/swanctl/swanctl.h b/src/swanctl/swanctl.h index bd7e00378..cb570cd34 100644 --- a/src/swanctl/swanctl.h +++ b/src/swanctl/swanctl.h @@ -66,4 +66,9 @@ */ #define SWANCTL_PKCS8DIR SWANCTLDIR "/pkcs8" +/** + * Directory for PKCS#12 containers + */ +#define SWANCTL_PKCS12DIR SWANCTLDIR "/pkcs12" + #endif /** SWANCTL_H_ @}*/ diff --git a/src/swanctl/swanctl.opt b/src/swanctl/swanctl.opt index f1e47a9e4..b6ef17546 100644 --- a/src/swanctl/swanctl.opt +++ b/src/swanctl/swanctl.opt @@ -220,7 +220,9 @@ connections.<conn>.rekey_time = 4h IKEv1 performs a reauthentication procedure instead. With the default value IKE rekeying is scheduled every 4 hours, minus the - configured **rand_time**. + configured **rand_time**. If a **reauth_time** is configured, **rekey_time** + defaults to zero disabling rekeying; explicitly set both to enforce + rekeying and reauthentication. connections.<conn>.over_time = 10% of rekey_time/reauth_time Hard IKE_SA lifetime if rekey/reauth does not complete, as time. @@ -303,6 +305,22 @@ connections.<conn>.local<suffix>.id = authentication, the IKE identity must be contained in the certificate, either as subject or as subjectAltName. + The identity can be an IP address, a fully-qualified domain name, an email + address or a Distinguished Name for which the ID type is determined + automatically and the string is converted to the appropriate encoding. To + enforce a specific identity type, a prefix may be used, followed by a colon + (:). If the number sign (#) follows the colon, the remaining data is + interpreted as hex encoding, otherwise the string is used as-is as the + identification data. Note that this implies that no conversion is performed + for non-string identities. For example, _ipv4:10.0.0.1_ does not create a + valid ID_IPV4_ADDR IKE identity, as it does not get converted to binary + 0x0a000001. Instead, one could use _ipv4:#0a000001_ to get a valid identity, + but just using the implicit type with automatic conversion is usually + simpler. The same applies to the ASN1 encoded types. The following prefixes + are known: _ipv4_, _ipv6_, _rfc822_, _email_, _userfqdn_, _fqdn_, _dns_, + _asn1dn_, _asn1gn_ and _keyid_. Custom type prefixes may be specified by + surrounding the numerical type value by curly brackets. + connections.<conn>.local<suffix>.eap_id = id Client EAP-Identity to use in EAP-Identity exchange and the EAP method. @@ -335,9 +353,8 @@ connections.<conn>.remote<suffix> {} connections.<conn>.remote<suffix>.id = %any IKE identity to expect for authentication round. - IKE identity to expect for authentication round. When using certificate - authentication, the IKE identity must be contained in the certificate, - either as subject or as subjectAltName. + IKE identity to expect for authentication round. Refer to the _local_ _id_ + section for details. connections.<conn>.remote<suffix>.groups = Authorization group memberships to require. @@ -607,9 +624,10 @@ connections.<conn>.children.<child>.reqid = 0 connections.<conn>.children.<child>.mark_in = 0/0x00000000 Netfilter mark and mask for input traffic. - Netfilter mark and mask for input traffic. On Linux Netfilter may apply - marks to each packet coming from a tunnel having that option set. The - mark may then be used by Netfilter to match rules. + Netfilter mark and mask for input traffic. On Linux Netfilter may require + marks on each packet to match an SA having that option set. This allows + Netfilter rules to select specific tunnels for incoming traffic. The + special value _%unique_ sets a unique mark on each CHILD_SA instance. An additional mask may be appended to the mark, separated by _/_. The default mask if omitted is 0xffffffff. @@ -619,7 +637,8 @@ connections.<conn>.children.<child>.mark_out = 0/0x00000000 Netfilter mark and mask for output traffic. On Linux Netfilter may require marks on each packet to match a policy having that option set. This allows - Netfilter rules to select specific tunnels for outgoing traffic. + Netfilter rules to select specific tunnels for outgoing traffic. The + special value _%unique_ sets a unique mark on each CHILD_SA instance. An additional mask may be appended to the mark, separated by _/_. The default mask if omitted is 0xffffffff. @@ -756,6 +775,15 @@ secrets.pkcs8<suffix>.file = secrets.pkcs8<suffix>.secret Value of decryption passphrase for PKCS#8 key. +secrets.pkcs12<suffix> { # } + PKCS#12 decryption passphrase for a container in the _pkcs12_ folder. + +secrets.pkcs12<suffix>.file = + File name in the _pkcs12_ folder for which this passphrase should be used. + +secrets.pkcs12<suffix>.secret + Value of decryption passphrase for PKCS#12 container. + pools { # } Section defining named pools. @@ -767,11 +795,11 @@ pools.<name> { # } Section defining a single pool with a unique name. pools.<name>.addrs = - Subnet defining addresses allocated in pool. + Addresses allocated in pool. - Subnet defining addresses allocated in pool. Accepts a single CIDR subnet - defining the pool to allocate addresses from. Pools must be unique and - non-overlapping. + Subnet or range defining addresses allocated in pool. Accepts a single CIDR + subnet defining the pool to allocate addresses from, or an address range + (<from>-<to>). Pools must be unique and non-overlapping. pools.<name>.<attr> = Comma separated list of additional attributes from type <attr>. |