summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS43
-rw-r--r--TODO21
-rwxr-xr-xconfigure378
-rw-r--r--configure.in87
-rw-r--r--src/Makefile.am42
-rw-r--r--src/Makefile.in53
-rw-r--r--src/_updown/Makefile.am1
-rw-r--r--src/_updown/Makefile.in1
-rw-r--r--src/_updown/_updown.in184
-rw-r--r--src/charon/Makefile.am90
-rw-r--r--src/charon/Makefile.in373
-rw-r--r--src/charon/bus/bus.c306
-rw-r--r--src/charon/bus/bus.h52
-rw-r--r--src/charon/config/backends/sqlite_backend.c19
-rw-r--r--src/charon/config/credentials/local_credential_store.c4
-rw-r--r--src/charon/config/peer_cfg.c104
-rw-r--r--src/charon/config/peer_cfg.h53
-rw-r--r--src/charon/control/interface_manager.c656
-rwxr-xr-xsrc/charon/control/interfaces/stroke_interface.c61
-rw-r--r--src/charon/control/interfaces/xml_interface.c273
-rw-r--r--src/charon/daemon.c2
-rw-r--r--src/charon/encoding/payloads/configuration_attribute.c2
-rw-r--r--src/charon/encoding/payloads/eap_payload.c19
-rw-r--r--src/charon/encoding/payloads/eap_payload.h5
-rw-r--r--src/charon/encoding/payloads/endpoint_notify.c29
-rw-r--r--src/charon/encoding/payloads/endpoint_notify.h17
-rw-r--r--src/charon/encoding/payloads/ike_header.c3
-rw-r--r--src/charon/encoding/payloads/notify_payload.c26
-rw-r--r--src/charon/encoding/payloads/notify_payload.h5
-rw-r--r--src/charon/network/socket-raw.c771
-rw-r--r--src/charon/network/socket.c455
-rw-r--r--src/charon/network/socket.h4
-rw-r--r--src/charon/processing/jobs/callback_job.c14
-rw-r--r--src/charon/processing/jobs/initiate_mediation_job.c32
-rw-r--r--src/charon/processing/jobs/mediation_job.c6
-rw-r--r--src/charon/processing/jobs/process_message_job.c7
-rw-r--r--src/charon/processing/scheduler.c8
-rw-r--r--src/charon/sa/authenticators/eap/eap_aka.c1440
-rw-r--r--src/charon/sa/authenticators/eap/eap_aka.h141
-rw-r--r--src/charon/sa/authenticators/eap/eap_md5.c282
-rw-r--r--src/charon/sa/authenticators/eap/eap_md5.h59
-rw-r--r--src/charon/sa/authenticators/eap/eap_method.c42
-rw-r--r--src/charon/sa/authenticators/eap/eap_method.h11
-rw-r--r--src/charon/sa/authenticators/eap/eap_sim.c8
-rw-r--r--src/charon/sa/authenticators/eap_authenticator.c105
-rw-r--r--src/charon/sa/authenticators/eap_authenticator.h9
-rw-r--r--src/charon/sa/child_sa.c2
-rw-r--r--src/charon/sa/connect_manager.c77
-rw-r--r--src/charon/sa/ike_sa.c217
-rw-r--r--src/charon/sa/ike_sa.h45
-rw-r--r--src/charon/sa/mediation_manager.c4
-rw-r--r--src/charon/sa/task_manager.c16
-rw-r--r--src/charon/sa/tasks/ike_auth.c16
-rw-r--r--src/charon/sa/tasks/ike_auth_lifetime.c200
-rw-r--r--src/charon/sa/tasks/ike_auth_lifetime.h61
-rw-r--r--src/charon/sa/tasks/ike_mobike.c8
-rw-r--r--src/charon/sa/tasks/ike_p2p.c97
-rw-r--r--src/charon/sa/tasks/task.c1
-rw-r--r--src/charon/sa/tasks/task.h2
-rwxr-xr-xsrc/ipsec/ipsec.in163
-rw-r--r--src/libstrongswan/crypto/ac.c8
-rw-r--r--src/libstrongswan/crypto/ca.c6
-rwxr-xr-xsrc/libstrongswan/crypto/crl.c6
-rwxr-xr-xsrc/libstrongswan/crypto/x509.c8
-rw-r--r--src/libstrongswan/library.c19
-rw-r--r--src/libstrongswan/printf_hook.c23
-rw-r--r--src/libstrongswan/printf_hook.h3
-rw-r--r--src/libstrongswan/utils/lexparser.c32
-rw-r--r--src/libstrongswan/utils/lexparser.h9
-rw-r--r--src/manager/Makefile.am25
-rw-r--r--src/manager/Makefile.in188
-rw-r--r--src/manager/controller/auth_controller.c2
-rw-r--r--src/manager/controller/config_controller.c214
-rw-r--r--src/manager/controller/config_controller.h (renamed from src/manager/controller/status_controller.h)18
-rw-r--r--src/manager/controller/control_controller.c211
-rw-r--r--src/manager/controller/control_controller.h47
-rw-r--r--src/manager/controller/gateway_controller.c2
-rw-r--r--src/manager/controller/ikesa_controller.c (renamed from src/manager/controller/status_controller.c)38
-rw-r--r--src/manager/controller/ikesa_controller.h47
-rw-r--r--src/manager/gateway.c180
-rw-r--r--src/manager/gateway.h25
-rw-r--r--src/manager/lib/dispatcher.c23
-rw-r--r--src/manager/lib/request.c25
-rw-r--r--src/manager/lib/request.h14
-rw-r--r--src/manager/main.c10
-rw-r--r--src/manager/templates/config/list.cs104
-rw-r--r--src/manager/templates/control/result.cs14
-rw-r--r--src/manager/templates/header.cs4
-rw-r--r--src/manager/templates/ikesa/list.cs (renamed from src/manager/templates/status/ikesalist.cs)26
-rw-r--r--src/manager/templates/static/close.pngbin0 -> 825 bytes
-rw-r--r--src/manager/templates/static/initiate.pngbin0 -> 601 bytes
-rw-r--r--src/manager/templates/static/pipe-thin-green.pngbin0 -> 372 bytes
-rw-r--r--src/manager/templates/static/pipe-thin-left-green.pngbin0 -> 449 bytes
-rw-r--r--src/manager/templates/static/pipe-thin-right-green.pngbin0 -> 460 bytes
-rw-r--r--src/manager/templates/static/script.js5
-rw-r--r--src/manager/templates/static/style.css11
-rw-r--r--src/pluto/Makefile.am12
-rw-r--r--src/pluto/Makefile.in18
-rw-r--r--src/pluto/connections.c3
-rw-r--r--src/pluto/vendor.c6
-rw-r--r--src/pluto/vendor.h4
-rw-r--r--src/starter/confread.c35
-rw-r--r--src/starter/confread.h5
-rw-r--r--src/starter/invokecharon.c9
-rw-r--r--src/starter/ipsec.conf.518
-rw-r--r--src/starter/starter.c36
-rw-r--r--src/starter/starterstroke.c5
-rw-r--r--src/starter/starterwhack.c15
-rw-r--r--src/stroke/stroke.h5
-rw-r--r--testing/INSTALL8
-rwxr-xr-xtesting/do-tests.in13
-rw-r--r--testing/hosts/winnetou/etc/apache2/httpd.conf1103
-rw-r--r--testing/hosts/winnetou/etc/apache2/modules.d/00_mod_mime.conf61
-rw-r--r--testing/hosts/winnetou/etc/apache2/vhosts.d/01_ocsp_vhost.conf21
-rw-r--r--testing/hosts/winnetou/etc/conf.d/apache252
-rwxr-xr-xtesting/hosts/winnetou/etc/init.d/apache2137
-rwxr-xr-xtesting/hosts/winnetou/etc/runlevels/default/apache2137
-rw-r--r--testing/images/a-m-c-w-d-ip6.pngbin0 -> 23726 bytes
-rw-r--r--testing/images/a-m-c-w-ip6.pngbin0 -> 18734 bytes
-rw-r--r--testing/images/a-m-c-w-s-b-med.pngbin0 -> 28066 bytes
-rw-r--r--testing/images/a-m-w-s-b-ip6.pngbin0 -> 23041 bytes
-rw-r--r--testing/images/a-v-m-c-w-med.pngbin0 -> 23462 bytes
-rw-r--r--testing/images/m-w-s-ip6.pngbin0 -> 12067 bytes
-rwxr-xr-xtesting/images/m-w-s.pngbin12340 -> 12508 bytes
-rwxr-xr-xtesting/scripts/build-umlrootfs13
-rwxr-xr-xtesting/testing.conf10
-rw-r--r--testing/tests/ikev1/host2host-transport/evaltest.dat2
-rw-r--r--testing/tests/ikev2/host2host-transport/evaltest.dat3
-rwxr-xr-xtesting/tests/ikev2/host2host-transport/hosts/moon/etc/ipsec.conf1
-rwxr-xr-xtesting/tests/ikev2/host2host-transport/hosts/sun/etc/ipsec.conf1
-rw-r--r--testing/tests/ikev2/reauth-early/description.txt7
-rw-r--r--testing/tests/ikev2/reauth-early/evaltest.dat6
-rwxr-xr-xtesting/tests/ikev2/reauth-early/hosts/carol/etc/ipsec.conf23
-rwxr-xr-xtesting/tests/ikev2/reauth-early/hosts/moon/etc/ipsec.conf22
-rw-r--r--testing/tests/ikev2/reauth-early/posttest.dat4
-rw-r--r--testing/tests/ikev2/reauth-early/pretest.dat7
-rw-r--r--testing/tests/ikev2/reauth-early/test.conf21
-rw-r--r--testing/tests/ikev2/reauth-late/description.txt8
-rw-r--r--testing/tests/ikev2/reauth-late/evaltest.dat7
-rwxr-xr-xtesting/tests/ikev2/reauth-late/hosts/carol/etc/ipsec.conf23
-rwxr-xr-xtesting/tests/ikev2/reauth-late/hosts/moon/etc/ipsec.conf22
-rw-r--r--testing/tests/ikev2/reauth-late/posttest.dat4
-rw-r--r--testing/tests/ikev2/reauth-late/pretest.dat7
-rw-r--r--testing/tests/ikev2/reauth-late/test.conf21
-rw-r--r--testing/tests/ikev2/rw-eap-aka-rsa/description.txt7
-rw-r--r--testing/tests/ikev2/rw-eap-aka-rsa/evaltest.dat10
-rwxr-xr-xtesting/tests/ikev2/rw-eap-aka-rsa/hosts/carol/etc/ipsec.conf23
-rw-r--r--testing/tests/ikev2/rw-eap-aka-rsa/hosts/carol/etc/ipsec.secrets3
-rwxr-xr-xtesting/tests/ikev2/rw-eap-aka-rsa/hosts/moon/etc/ipsec.conf24
-rw-r--r--testing/tests/ikev2/rw-eap-aka-rsa/hosts/moon/etc/ipsec.secrets5
-rw-r--r--testing/tests/ikev2/rw-eap-aka-rsa/posttest.dat4
-rw-r--r--testing/tests/ikev2/rw-eap-aka-rsa/pretest.dat7
-rw-r--r--testing/tests/ikev2/rw-eap-aka-rsa/test.conf21
-rw-r--r--testing/tests/ipv6/host2host-ikev1/description.txt6
-rwxr-xr-xtesting/tests/ipv6/host2host-ikev1/hosts/moon/etc/init.d/iptables100
-rwxr-xr-xtesting/tests/ipv6/host2host-ikev1/hosts/moon/etc/ipsec.conf3
-rwxr-xr-xtesting/tests/ipv6/host2host-ikev1/hosts/sun/etc/init.d/iptables100
-rwxr-xr-xtesting/tests/ipv6/host2host-ikev1/hosts/sun/etc/ipsec.conf2
-rw-r--r--testing/tests/ipv6/host2host-ikev1/posttest.dat2
-rw-r--r--testing/tests/ipv6/host2host-ikev1/pretest.dat2
-rw-r--r--testing/tests/ipv6/host2host-ikev1/test.conf2
-rw-r--r--testing/tests/ipv6/host2host-ikev2/description.txt6
-rwxr-xr-xtesting/tests/ipv6/host2host-ikev2/hosts/moon/etc/init.d/iptables107
-rwxr-xr-xtesting/tests/ipv6/host2host-ikev2/hosts/moon/etc/ipsec.conf3
-rwxr-xr-xtesting/tests/ipv6/host2host-ikev2/hosts/sun/etc/init.d/iptables107
-rwxr-xr-xtesting/tests/ipv6/host2host-ikev2/hosts/sun/etc/ipsec.conf3
-rw-r--r--testing/tests/ipv6/host2host-ikev2/posttest.dat2
-rw-r--r--testing/tests/ipv6/host2host-ikev2/pretest.dat2
-rw-r--r--testing/tests/ipv6/host2host-ikev2/test.conf2
-rw-r--r--testing/tests/ipv6/net2net-ikev1/description.txt6
-rw-r--r--testing/tests/ipv6/net2net-ikev1/evaltest.dat5
-rwxr-xr-xtesting/tests/ipv6/net2net-ikev1/hosts/moon/etc/init.d/iptables100
-rwxr-xr-xtesting/tests/ipv6/net2net-ikev1/hosts/moon/etc/ipsec.conf28
-rwxr-xr-xtesting/tests/ipv6/net2net-ikev1/hosts/sun/etc/init.d/iptables100
-rwxr-xr-xtesting/tests/ipv6/net2net-ikev1/hosts/sun/etc/ipsec.conf27
-rw-r--r--testing/tests/ipv6/net2net-ikev1/posttest.dat8
-rw-r--r--testing/tests/ipv6/net2net-ikev1/pretest.dat10
-rw-r--r--testing/tests/ipv6/net2net-ikev1/test.conf21
-rw-r--r--testing/tests/ipv6/net2net-ikev2/description.txt6
-rw-r--r--testing/tests/ipv6/net2net-ikev2/evaltest.dat5
-rwxr-xr-xtesting/tests/ipv6/net2net-ikev2/hosts/moon/etc/init.d/iptables107
-rwxr-xr-xtesting/tests/ipv6/net2net-ikev2/hosts/moon/etc/ipsec.conf28
-rwxr-xr-xtesting/tests/ipv6/net2net-ikev2/hosts/sun/etc/init.d/iptables107
-rwxr-xr-xtesting/tests/ipv6/net2net-ikev2/hosts/sun/etc/ipsec.conf28
-rw-r--r--testing/tests/ipv6/net2net-ikev2/posttest.dat8
-rw-r--r--testing/tests/ipv6/net2net-ikev2/pretest.dat10
-rw-r--r--testing/tests/ipv6/net2net-ikev2/test.conf21
-rw-r--r--testing/tests/ipv6/rw-ikev1/description.txt7
-rw-r--r--testing/tests/ipv6/rw-ikev1/evaltest.dat5
-rwxr-xr-xtesting/tests/ipv6/rw-ikev1/hosts/carol/etc/init.d/iptables100
-rwxr-xr-xtesting/tests/ipv6/rw-ikev1/hosts/carol/etc/ipsec.conf27
-rwxr-xr-xtesting/tests/ipv6/rw-ikev1/hosts/moon/etc/init.d/iptables100
-rwxr-xr-xtesting/tests/ipv6/rw-ikev1/hosts/moon/etc/ipsec.conf22
-rw-r--r--testing/tests/ipv6/rw-ikev1/posttest.dat6
-rw-r--r--testing/tests/ipv6/rw-ikev1/pretest.dat8
-rw-r--r--testing/tests/ipv6/rw-ikev1/test.conf21
-rw-r--r--testing/tests/ipv6/rw-ikev2/description.txt7
-rw-r--r--testing/tests/ipv6/rw-ikev2/evaltest.dat10
-rwxr-xr-xtesting/tests/ipv6/rw-ikev2/hosts/carol/etc/init.d/iptables107
-rwxr-xr-xtesting/tests/ipv6/rw-ikev2/hosts/carol/etc/ipsec.conf23
-rwxr-xr-xtesting/tests/ipv6/rw-ikev2/hosts/dave/etc/init.d/iptables107
-rwxr-xr-xtesting/tests/ipv6/rw-ikev2/hosts/dave/etc/ipsec.conf23
-rwxr-xr-xtesting/tests/ipv6/rw-ikev2/hosts/moon/etc/init.d/iptables107
-rwxr-xr-xtesting/tests/ipv6/rw-ikev2/hosts/moon/etc/ipsec.conf22
-rw-r--r--testing/tests/ipv6/rw-ikev2/posttest.dat9
-rw-r--r--testing/tests/ipv6/rw-ikev2/pretest.dat12
-rw-r--r--testing/tests/ipv6/rw-ikev2/test.conf21
-rw-r--r--testing/tests/ipv6/rw-psk-ikev1/description.txt5
-rw-r--r--testing/tests/ipv6/rw-psk-ikev1/evaltest.dat5
-rwxr-xr-xtesting/tests/ipv6/rw-psk-ikev1/hosts/carol/etc/init.d/iptables100
-rwxr-xr-xtesting/tests/ipv6/rw-psk-ikev1/hosts/carol/etc/ipsec.conf19
-rw-r--r--testing/tests/ipv6/rw-psk-ikev1/hosts/carol/etc/ipsec.secrets3
-rwxr-xr-xtesting/tests/ipv6/rw-psk-ikev1/hosts/moon/etc/init.d/iptables100
-rwxr-xr-xtesting/tests/ipv6/rw-psk-ikev1/hosts/moon/etc/ipsec.conf19
-rw-r--r--testing/tests/ipv6/rw-psk-ikev1/hosts/moon/etc/ipsec.secrets3
-rw-r--r--testing/tests/ipv6/rw-psk-ikev1/posttest.dat6
-rw-r--r--testing/tests/ipv6/rw-psk-ikev1/pretest.dat10
-rw-r--r--testing/tests/ipv6/rw-psk-ikev1/test.conf21
-rw-r--r--testing/tests/ipv6/rw-psk-ikev2/description.txt7
-rw-r--r--testing/tests/ipv6/rw-psk-ikev2/evaltest.dat10
-rwxr-xr-xtesting/tests/ipv6/rw-psk-ikev2/hosts/carol/etc/init.d/iptables107
-rwxr-xr-xtesting/tests/ipv6/rw-psk-ikev2/hosts/carol/etc/ipsec.conf19
-rw-r--r--testing/tests/ipv6/rw-psk-ikev2/hosts/carol/etc/ipsec.secrets3
-rwxr-xr-xtesting/tests/ipv6/rw-psk-ikev2/hosts/dave/etc/init.d/iptables107
-rwxr-xr-xtesting/tests/ipv6/rw-psk-ikev2/hosts/dave/etc/ipsec.conf20
-rw-r--r--testing/tests/ipv6/rw-psk-ikev2/hosts/dave/etc/ipsec.secrets3
-rwxr-xr-xtesting/tests/ipv6/rw-psk-ikev2/hosts/moon/etc/init.d/iptables107
-rwxr-xr-xtesting/tests/ipv6/rw-psk-ikev2/hosts/moon/etc/ipsec.conf19
-rw-r--r--testing/tests/ipv6/rw-psk-ikev2/hosts/moon/etc/ipsec.secrets5
-rw-r--r--testing/tests/ipv6/rw-psk-ikev2/posttest.dat9
-rw-r--r--testing/tests/ipv6/rw-psk-ikev2/pretest.dat15
-rw-r--r--testing/tests/ipv6/rw-psk-ikev2/test.conf21
-rw-r--r--testing/tests/ipv6/transport-ikev1/description.txt5
-rw-r--r--testing/tests/ipv6/transport-ikev1/evaltest.dat7
-rwxr-xr-xtesting/tests/ipv6/transport-ikev1/hosts/moon/etc/init.d/iptables100
-rwxr-xr-xtesting/tests/ipv6/transport-ikev1/hosts/moon/etc/ipsec.conf23
-rwxr-xr-xtesting/tests/ipv6/transport-ikev1/hosts/sun/etc/init.d/iptables100
-rwxr-xr-xtesting/tests/ipv6/transport-ikev1/hosts/sun/etc/ipsec.conf23
-rw-r--r--testing/tests/ipv6/transport-ikev1/posttest.dat4
-rw-r--r--testing/tests/ipv6/transport-ikev1/pretest.dat6
-rw-r--r--testing/tests/ipv6/transport-ikev1/test.conf21
-rw-r--r--testing/tests/ipv6/transport-ikev2/description.txt5
-rw-r--r--testing/tests/ipv6/transport-ikev2/evaltest.dat8
-rwxr-xr-xtesting/tests/ipv6/transport-ikev2/hosts/moon/etc/init.d/iptables107
-rwxr-xr-xtesting/tests/ipv6/transport-ikev2/hosts/moon/etc/ipsec.conf24
-rwxr-xr-xtesting/tests/ipv6/transport-ikev2/hosts/sun/etc/init.d/iptables107
-rwxr-xr-xtesting/tests/ipv6/transport-ikev2/hosts/sun/etc/ipsec.conf24
-rw-r--r--testing/tests/ipv6/transport-ikev2/posttest.dat4
-rw-r--r--testing/tests/ipv6/transport-ikev2/pretest.dat6
-rw-r--r--testing/tests/ipv6/transport-ikev2/test.conf21
-rw-r--r--testing/tests/p2pnat/behind-same-nat/description.txt6
-rw-r--r--testing/tests/p2pnat/behind-same-nat/evaltest.dat11
-rwxr-xr-xtesting/tests/p2pnat/behind-same-nat/hosts/alice/etc/init.d/iptables78
-rwxr-xr-xtesting/tests/p2pnat/behind-same-nat/hosts/alice/etc/ipsec.conf36
-rw-r--r--testing/tests/p2pnat/behind-same-nat/hosts/alice/etc/ipsec.secrets7
-rwxr-xr-xtesting/tests/p2pnat/behind-same-nat/hosts/carol/etc/init.d/iptables77
-rwxr-xr-xtesting/tests/p2pnat/behind-same-nat/hosts/carol/etc/ipsec.conf25
-rw-r--r--testing/tests/p2pnat/behind-same-nat/hosts/carol/etc/ipsec.secrets11
-rwxr-xr-xtesting/tests/p2pnat/behind-same-nat/hosts/venus/etc/init.d/iptables78
-rwxr-xr-xtesting/tests/p2pnat/behind-same-nat/hosts/venus/etc/ipsec.conf36
-rw-r--r--testing/tests/p2pnat/behind-same-nat/hosts/venus/etc/ipsec.secrets7
-rw-r--r--testing/tests/p2pnat/behind-same-nat/posttest.dat8
-rw-r--r--testing/tests/p2pnat/behind-same-nat/pretest.dat14
-rw-r--r--testing/tests/p2pnat/behind-same-nat/test.conf21
-rw-r--r--testing/tests/p2pnat/medsrv-psk/description.txt7
-rw-r--r--testing/tests/p2pnat/medsrv-psk/evaltest.dat12
-rwxr-xr-xtesting/tests/p2pnat/medsrv-psk/hosts/alice/etc/init.d/iptables74
-rwxr-xr-xtesting/tests/p2pnat/medsrv-psk/hosts/alice/etc/ipsec.conf36
-rw-r--r--testing/tests/p2pnat/medsrv-psk/hosts/alice/etc/ipsec.secrets7
-rwxr-xr-xtesting/tests/p2pnat/medsrv-psk/hosts/bob/etc/ipsec.conf36
-rw-r--r--testing/tests/p2pnat/medsrv-psk/hosts/bob/etc/ipsec.secrets7
-rwxr-xr-xtesting/tests/p2pnat/medsrv-psk/hosts/carol/etc/init.d/iptables77
-rwxr-xr-xtesting/tests/p2pnat/medsrv-psk/hosts/carol/etc/ipsec.conf25
-rw-r--r--testing/tests/p2pnat/medsrv-psk/hosts/carol/etc/ipsec.secrets9
-rw-r--r--testing/tests/p2pnat/medsrv-psk/posttest.dat10
-rw-r--r--testing/tests/p2pnat/medsrv-psk/pretest.dat19
-rw-r--r--testing/tests/p2pnat/medsrv-psk/test.conf21
277 files changed, 11379 insertions, 3110 deletions
diff --git a/NEWS b/NEWS
index 0c3b6e311..37a70e5e2 100644
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,48 @@
+strongswan-4.1.10
+-----------------
+
+- Fixed error in the ordering of the certinfo_t records in the ocsp cache that
+ caused multiple entries of the same serial number to be created.
+
+- Implementation of a simple EAP-MD5 module which provides CHAP
+ authentication. This may be interesting in conjunction with certificate
+ based server authentication, as weak passwords can't be brute forced
+ (in contradiction to traditional IKEv2 PSK).
+
+- A complete software based implementation of EAP-AKA, using algorithms
+ specified in 3GPP2 (S.S0055). This implementation does not use an USIM,
+ but reads the secrets from ipsec.secrets. Make sure to read eap_aka.h
+ before using it.
+
+- Support for vendor specific EAP methods using Expanded EAP types. The
+ interface to EAP modules has been slightly changed, so make sure to
+ check the changes if you're already rolling your own modules.
+
+strongswan-4.1.9
+----------------
+
+- The default _updown script now dynamically inserts and removes ip6tables
+ firewall rules if leftfirewall=yes is set in IPv6 connections. New IPv6
+ net-net and roadwarrior (PSK/RSA) scenarios for both IKEv1 and IKEV2 were
+ added.
+
+- Implemented RFC4478 repeated authentication to force EAP/Virtual-IP clients
+ to reestablish an IKE_SA within a given timeframe.
+
+- strongSwan Manager supports configuration listing, initiation and termination
+ of IKE and CHILD_SAs.
+
+- Fixes and improvements to multithreading code.
+
+- IKEv2 plugins have been renamed to libcharon-* to avoid naming conflicts.
+ Make sure to remove the old plugins in $libexecdir/ipsec, otherwise they get
+ loaded twice.
+
+
strongswan-4.1.8
----------------
-- Removed recursive pthread mutexes since uClib doesn't support them.
+- Removed recursive pthread mutexes since uClibc doesn't support them.
strongswan-4.1.7
diff --git a/TODO b/TODO
index 2ee7713f6..975db468f 100644
--- a/TODO
+++ b/TODO
@@ -7,15 +7,10 @@ migrate IKEv1 into charon. It's hard to say how much effort is needed to
do that, and how much code we can reuse from pluto. But a port IS necessary to
gain hassle-free configuration, version negotiation and maintainability.
-Roadmap 2007
-============
+Roadmap
+=======
- Oct ! - modular credential backends
- ! - enhance manager/XML interface
- !
- Nov ! - Start IKEv1 implementation in charon
- !
- Dec !
+ Dec ! - complete modular credential framework
!
TODO-List
@@ -44,3 +39,13 @@ Misc
----
- Address pool/backend for virtual IP assignement
- replace iterator by enumerator
+
+libstrongswan stuff
+-------------------
+- Header installation support (#include <strongswan/strongswan.h>?)
+- move __constructor__/__destructor__ to a library init function
+- object style for leak detective, include an API
+- Cleanup/Refactor PEM/ASN1 stuff
+- replace file reads through chunk_read
+- rewrite lexparser in object-oriented style
+
diff --git a/configure b/configure
index 575ea96fb..17efdfc15 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for strongSwan 4.1.8.
+# Generated by GNU Autoconf 2.61 for strongSwan 4.1.10.
#
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
@@ -726,8 +726,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='strongSwan'
PACKAGE_TARNAME='strongswan'
-PACKAGE_VERSION='4.1.8'
-PACKAGE_STRING='strongSwan 4.1.8'
+PACKAGE_VERSION='4.1.10'
+PACKAGE_STRING='strongSwan 4.1.10'
PACKAGE_BUGREPORT=''
# Factoring default headers for most tests.
@@ -860,6 +860,8 @@ USE_LIBCURL_TRUE
USE_LIBCURL_FALSE
USE_LIBLDAP_TRUE
USE_LIBLDAP_FALSE
+USE_STROKE_TRUE
+USE_STROKE_FALSE
USE_LIBDBUS_TRUE
USE_LIBDBUS_FALSE
USE_LIBXML_TRUE
@@ -872,8 +874,14 @@ USE_CISCO_QUIRKS_TRUE
USE_CISCO_QUIRKS_FALSE
USE_LEAK_DETECTIVE_TRUE
USE_LEAK_DETECTIVE_FALSE
-BUILD_EAP_SIM_TRUE
-BUILD_EAP_SIM_FALSE
+USE_EAP_SIM_TRUE
+USE_EAP_SIM_FALSE
+USE_EAP_IDENTITY_TRUE
+USE_EAP_IDENTITY_FALSE
+USE_EAP_MD5_TRUE
+USE_EAP_MD5_FALSE
+USE_EAP_AKA_TRUE
+USE_EAP_AKA_FALSE
USE_NAT_TRANSPORT_TRUE
USE_NAT_TRANSPORT_FALSE
USE_VENDORID_TRUE
@@ -890,6 +898,18 @@ USE_INTEGRITY_TEST_TRUE
USE_INTEGRITY_TEST_FALSE
USE_SELF_TEST_TRUE
USE_SELF_TEST_FALSE
+USE_PLUTO_TRUE
+USE_PLUTO_FALSE
+USE_CHARON_TRUE
+USE_CHARON_FALSE
+USE_TOOLS_TRUE
+USE_TOOLS_FALSE
+USE_PLUTO_OR_CHARON_TRUE
+USE_PLUTO_OR_CHARON_FALSE
+USE_LIBSTRONGSWAN_TRUE
+USE_LIBSTRONGSWAN_FALSE
+USE_FILE_CONFIG_TRUE
+USE_FILE_CONFIG_FALSE
build
build_cpu
build_vendor
@@ -1453,7 +1473,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures strongSwan 4.1.8 to adapt to many kinds of systems.
+\`configure' configures strongSwan 4.1.10 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1523,7 +1543,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of strongSwan 4.1.8:";;
+ short | recursive ) echo "Configuration of strongSwan 4.1.10:";;
esac
cat <<\_ACEOF
@@ -1536,6 +1556,8 @@ Optional Features:
over HTTP (default is NO). Requires libcurl.
--enable-ldap enable fetching of CRLs from LDAP (default is NO).
Requires openLDAP.
+ --disable-stroke disable charons stroke (pluto compatibility)
+ configuration backend. (default is NO).
--enable-dbus enable DBUS configuration and control interface
(default is NO). Requires libdbus.
--enable-xml enable XML configuration and control interface
@@ -1548,6 +1570,12 @@ Optional Features:
NO).
--enable-eap-sim build SIM authenication module for EAP (default is
NO).
+ --enable-eap-identity build EAP module providing EAP-Identity helper
+ (default is NO).
+ --enable-eap-md5 build MD5 (CHAP) authenication module for EAP
+ (default is NO).
+ --enable-eap-aka build AKA authentication module for EAP (default is
+ NO).
--enable-nat-transport enable NAT traversal with IPsec transport mode
(default is NO).
--disable-vendor-id disable the sending of the strongSwan vendor ID
@@ -1561,6 +1589,12 @@ Optional Features:
(default is NO).
--disable-self-test disable the self-test of the crypto library (default
is NO).
+ --disable-pluto disable the IKEv1 keying daemon pluto. (default is
+ NO).
+ --disable-charon disable the IKEv2 keying daemon charon. (default is
+ NO).
+ --disable-tools disable additional utilities (openac and
+ scepclient). (default is NO).
--enable-shared[=PKGS] build shared libraries [default=yes]
--enable-static[=PKGS] build static libraries [default=yes]
--enable-fast-install[=PKGS]
@@ -1699,7 +1733,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-strongSwan configure 4.1.8
+strongSwan configure 4.1.10
generated by GNU Autoconf 2.61
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1713,7 +1747,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by strongSwan $as_me 4.1.8, which was
+It was created by strongSwan $as_me 4.1.10, which was
generated by GNU Autoconf 2.61. Invocation command line was
$ $0 $@
@@ -2403,7 +2437,7 @@ fi
# Define the identity of the package.
PACKAGE='strongswan'
- VERSION='4.1.8'
+ VERSION='4.1.10'
cat >>confdefs.h <<_ACEOF
@@ -4868,6 +4902,27 @@ else
fi
+# Check whether --enable-stroke was given.
+if test "${enable_stroke+set}" = set; then
+ enableval=$enable_stroke; if test x$enableval = xyes; then
+ stroke=true
+ else
+ stroke=false
+ fi
+else
+ stroke=true
+
+fi
+
+ if test x$stroke = xtrue; then
+ USE_STROKE_TRUE=
+ USE_STROKE_FALSE='#'
+else
+ USE_STROKE_TRUE='#'
+ USE_STROKE_FALSE=
+fi
+
+
# Check whether --enable-dbus was given.
if test "${enable_dbus+set}" = set; then
enableval=$enable_dbus; if test x$enableval = xyes; then
@@ -4995,11 +5050,62 @@ if test "${enable_eap_sim+set}" = set; then
fi
if test x$eap_sim = xtrue; then
- BUILD_EAP_SIM_TRUE=
- BUILD_EAP_SIM_FALSE='#'
+ USE_EAP_SIM_TRUE=
+ USE_EAP_SIM_FALSE='#'
+else
+ USE_EAP_SIM_TRUE='#'
+ USE_EAP_SIM_FALSE=
+fi
+
+
+# Check whether --enable-eap-identity was given.
+if test "${enable_eap_identity+set}" = set; then
+ enableval=$enable_eap_identity; if test x$enableval = xyes; then
+ eap_identity=true
+ fi
+
+fi
+
+ if test x$eap_identity = xtrue; then
+ USE_EAP_IDENTITY_TRUE=
+ USE_EAP_IDENTITY_FALSE='#'
+else
+ USE_EAP_IDENTITY_TRUE='#'
+ USE_EAP_IDENTITY_FALSE=
+fi
+
+
+# Check whether --enable-eap-md5 was given.
+if test "${enable_eap_md5+set}" = set; then
+ enableval=$enable_eap_md5; if test x$enableval = xyes; then
+ eap_md5=true
+ fi
+
+fi
+
+ if test x$eap_md5 = xtrue; then
+ USE_EAP_MD5_TRUE=
+ USE_EAP_MD5_FALSE='#'
else
- BUILD_EAP_SIM_TRUE='#'
- BUILD_EAP_SIM_FALSE=
+ USE_EAP_MD5_TRUE='#'
+ USE_EAP_MD5_FALSE=
+fi
+
+
+# Check whether --enable-eap-aka was given.
+if test "${enable_eap_aka+set}" = set; then
+ enableval=$enable_eap_aka; if test x$enableval = xyes; then
+ eap_aka=true
+ fi
+
+fi
+
+ if test x$eap_aka = xtrue; then
+ USE_EAP_AKA_TRUE=
+ USE_EAP_AKA_FALSE='#'
+else
+ USE_EAP_AKA_TRUE='#'
+ USE_EAP_AKA_FALSE=
fi
@@ -5163,6 +5269,94 @@ else
fi
+# Check whether --enable-pluto was given.
+if test "${enable_pluto+set}" = set; then
+ enableval=$enable_pluto; if test x$enableval = xyes; then
+ pluto=true
+ else
+ pluto=false
+ fi
+else
+ pluto=true
+
+fi
+
+ if test x$pluto = xtrue; then
+ USE_PLUTO_TRUE=
+ USE_PLUTO_FALSE='#'
+else
+ USE_PLUTO_TRUE='#'
+ USE_PLUTO_FALSE=
+fi
+
+
+# Check whether --enable-charon was given.
+if test "${enable_charon+set}" = set; then
+ enableval=$enable_charon; if test x$enableval = xyes; then
+ charon=true
+ else
+ charon=false
+ fi
+else
+ charon=true
+
+fi
+
+ if test x$charon = xtrue; then
+ USE_CHARON_TRUE=
+ USE_CHARON_FALSE='#'
+else
+ USE_CHARON_TRUE='#'
+ USE_CHARON_FALSE=
+fi
+
+
+# Check whether --enable-tools was given.
+if test "${enable_tools+set}" = set; then
+ enableval=$enable_tools; if test x$enableval = xyes; then
+ tools=true
+ else
+ tools=false
+ fi
+else
+ tools=true
+
+fi
+
+ if test x$tools = xtrue; then
+ USE_TOOLS_TRUE=
+ USE_TOOLS_FALSE='#'
+else
+ USE_TOOLS_TRUE='#'
+ USE_TOOLS_FALSE=
+fi
+
+
+ if test x$pluto = xtrue -o x$charon = xtrue; then
+ USE_PLUTO_OR_CHARON_TRUE=
+ USE_PLUTO_OR_CHARON_FALSE='#'
+else
+ USE_PLUTO_OR_CHARON_TRUE='#'
+ USE_PLUTO_OR_CHARON_FALSE=
+fi
+
+ if test x$charon = xtrue -o x$tools = xtrue; then
+ USE_LIBSTRONGSWAN_TRUE=
+ USE_LIBSTRONGSWAN_FALSE='#'
+else
+ USE_LIBSTRONGSWAN_TRUE='#'
+ USE_LIBSTRONGSWAN_FALSE=
+fi
+
+ if test x$pluto = xtrue -o x$stroke = xtrue; then
+ USE_FILE_CONFIG_TRUE=
+ USE_FILE_CONFIG_FALSE='#'
+else
+ USE_FILE_CONFIG_TRUE='#'
+ USE_FILE_CONFIG_FALSE=
+fi
+
+
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
@@ -5889,7 +6083,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 5892 "configure"' > conftest.$ac_ext
+ echo '#line 6086 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -8210,11 +8404,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:8213: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:8407: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:8217: \$? = $ac_status" >&5
+ echo "$as_me:8411: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -8500,11 +8694,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:8503: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:8697: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:8507: \$? = $ac_status" >&5
+ echo "$as_me:8701: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -8604,11 +8798,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:8607: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:8801: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:8611: \$? = $ac_status" >&5
+ echo "$as_me:8805: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -10962,7 +11156,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 10965 "configure"
+#line 11159 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11062,7 +11256,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 11065 "configure"
+#line 11259 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -13477,11 +13671,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:13480: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:13674: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:13484: \$? = $ac_status" >&5
+ echo "$as_me:13678: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -13581,11 +13775,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:13584: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:13778: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:13588: \$? = $ac_status" >&5
+ echo "$as_me:13782: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -15155,11 +15349,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:15158: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:15352: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:15162: \$? = $ac_status" >&5
+ echo "$as_me:15356: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -15259,11 +15453,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:15262: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:15456: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:15266: \$? = $ac_status" >&5
+ echo "$as_me:15460: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -17454,11 +17648,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:17457: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:17651: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:17461: \$? = $ac_status" >&5
+ echo "$as_me:17655: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -17744,11 +17938,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:17747: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:17941: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:17751: \$? = $ac_status" >&5
+ echo "$as_me:17945: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -17848,11 +18042,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:17851: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:18045: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:17855: \$? = $ac_status" >&5
+ echo "$as_me:18049: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -22888,6 +23082,13 @@ echo "$as_me: error: conditional \"USE_LIBLDAP\" was never defined.
Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; }
fi
+if test -z "${USE_STROKE_TRUE}" && test -z "${USE_STROKE_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"USE_STROKE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"USE_STROKE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
if test -z "${USE_LIBDBUS_TRUE}" && test -z "${USE_LIBDBUS_FALSE}"; then
{ { echo "$as_me:$LINENO: error: conditional \"USE_LIBDBUS\" was never defined.
Usually this means the macro was only invoked conditionally." >&5
@@ -22930,10 +23131,31 @@ echo "$as_me: error: conditional \"USE_LEAK_DETECTIVE\" was never defined.
Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; }
fi
-if test -z "${BUILD_EAP_SIM_TRUE}" && test -z "${BUILD_EAP_SIM_FALSE}"; then
- { { echo "$as_me:$LINENO: error: conditional \"BUILD_EAP_SIM\" was never defined.
+if test -z "${USE_EAP_SIM_TRUE}" && test -z "${USE_EAP_SIM_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"USE_EAP_SIM\" was never defined.
Usually this means the macro was only invoked conditionally." >&5
-echo "$as_me: error: conditional \"BUILD_EAP_SIM\" was never defined.
+echo "$as_me: error: conditional \"USE_EAP_SIM\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${USE_EAP_IDENTITY_TRUE}" && test -z "${USE_EAP_IDENTITY_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"USE_EAP_IDENTITY\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"USE_EAP_IDENTITY\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${USE_EAP_MD5_TRUE}" && test -z "${USE_EAP_MD5_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"USE_EAP_MD5\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"USE_EAP_MD5\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${USE_EAP_AKA_TRUE}" && test -z "${USE_EAP_AKA_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"USE_EAP_AKA\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"USE_EAP_AKA\" was never defined.
Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; }
fi
@@ -22993,6 +23215,48 @@ echo "$as_me: error: conditional \"USE_SELF_TEST\" was never defined.
Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; }
fi
+if test -z "${USE_PLUTO_TRUE}" && test -z "${USE_PLUTO_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"USE_PLUTO\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"USE_PLUTO\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${USE_CHARON_TRUE}" && test -z "${USE_CHARON_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"USE_CHARON\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"USE_CHARON\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${USE_TOOLS_TRUE}" && test -z "${USE_TOOLS_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"USE_TOOLS\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"USE_TOOLS\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${USE_PLUTO_OR_CHARON_TRUE}" && test -z "${USE_PLUTO_OR_CHARON_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"USE_PLUTO_OR_CHARON\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"USE_PLUTO_OR_CHARON\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${USE_LIBSTRONGSWAN_TRUE}" && test -z "${USE_LIBSTRONGSWAN_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"USE_LIBSTRONGSWAN\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"USE_LIBSTRONGSWAN\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${USE_FILE_CONFIG_TRUE}" && test -z "${USE_FILE_CONFIG_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"USE_FILE_CONFIG\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"USE_FILE_CONFIG\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
{ { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined.
Usually this means the macro was only invoked conditionally." >&5
@@ -23307,7 +23571,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by strongSwan $as_me 4.1.8, which was
+This file was extended by strongSwan $as_me 4.1.10, which was
generated by GNU Autoconf 2.61. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -23354,7 +23618,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
-strongSwan config.status 4.1.8
+strongSwan config.status 4.1.10
configured by $0, generated by GNU Autoconf 2.61,
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
@@ -23635,9 +23899,9 @@ USE_LIBCURL_TRUE!$USE_LIBCURL_TRUE$ac_delim
USE_LIBCURL_FALSE!$USE_LIBCURL_FALSE$ac_delim
USE_LIBLDAP_TRUE!$USE_LIBLDAP_TRUE$ac_delim
USE_LIBLDAP_FALSE!$USE_LIBLDAP_FALSE$ac_delim
+USE_STROKE_TRUE!$USE_STROKE_TRUE$ac_delim
+USE_STROKE_FALSE!$USE_STROKE_FALSE$ac_delim
USE_LIBDBUS_TRUE!$USE_LIBDBUS_TRUE$ac_delim
-USE_LIBDBUS_FALSE!$USE_LIBDBUS_FALSE$ac_delim
-USE_LIBXML_TRUE!$USE_LIBXML_TRUE$ac_delim
_ACEOF
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
@@ -23679,6 +23943,8 @@ _ACEOF
ac_delim='%!_!# '
for ac_last_try in false false false false false :; do
cat >conf$$subs.sed <<_ACEOF
+USE_LIBDBUS_FALSE!$USE_LIBDBUS_FALSE$ac_delim
+USE_LIBXML_TRUE!$USE_LIBXML_TRUE$ac_delim
USE_LIBXML_FALSE!$USE_LIBXML_FALSE$ac_delim
USE_LIBSQLITE_TRUE!$USE_LIBSQLITE_TRUE$ac_delim
USE_LIBSQLITE_FALSE!$USE_LIBSQLITE_FALSE$ac_delim
@@ -23688,8 +23954,14 @@ USE_CISCO_QUIRKS_TRUE!$USE_CISCO_QUIRKS_TRUE$ac_delim
USE_CISCO_QUIRKS_FALSE!$USE_CISCO_QUIRKS_FALSE$ac_delim
USE_LEAK_DETECTIVE_TRUE!$USE_LEAK_DETECTIVE_TRUE$ac_delim
USE_LEAK_DETECTIVE_FALSE!$USE_LEAK_DETECTIVE_FALSE$ac_delim
-BUILD_EAP_SIM_TRUE!$BUILD_EAP_SIM_TRUE$ac_delim
-BUILD_EAP_SIM_FALSE!$BUILD_EAP_SIM_FALSE$ac_delim
+USE_EAP_SIM_TRUE!$USE_EAP_SIM_TRUE$ac_delim
+USE_EAP_SIM_FALSE!$USE_EAP_SIM_FALSE$ac_delim
+USE_EAP_IDENTITY_TRUE!$USE_EAP_IDENTITY_TRUE$ac_delim
+USE_EAP_IDENTITY_FALSE!$USE_EAP_IDENTITY_FALSE$ac_delim
+USE_EAP_MD5_TRUE!$USE_EAP_MD5_TRUE$ac_delim
+USE_EAP_MD5_FALSE!$USE_EAP_MD5_FALSE$ac_delim
+USE_EAP_AKA_TRUE!$USE_EAP_AKA_TRUE$ac_delim
+USE_EAP_AKA_FALSE!$USE_EAP_AKA_FALSE$ac_delim
USE_NAT_TRANSPORT_TRUE!$USE_NAT_TRANSPORT_TRUE$ac_delim
USE_NAT_TRANSPORT_FALSE!$USE_NAT_TRANSPORT_FALSE$ac_delim
USE_VENDORID_TRUE!$USE_VENDORID_TRUE$ac_delim
@@ -23706,6 +23978,18 @@ USE_INTEGRITY_TEST_TRUE!$USE_INTEGRITY_TEST_TRUE$ac_delim
USE_INTEGRITY_TEST_FALSE!$USE_INTEGRITY_TEST_FALSE$ac_delim
USE_SELF_TEST_TRUE!$USE_SELF_TEST_TRUE$ac_delim
USE_SELF_TEST_FALSE!$USE_SELF_TEST_FALSE$ac_delim
+USE_PLUTO_TRUE!$USE_PLUTO_TRUE$ac_delim
+USE_PLUTO_FALSE!$USE_PLUTO_FALSE$ac_delim
+USE_CHARON_TRUE!$USE_CHARON_TRUE$ac_delim
+USE_CHARON_FALSE!$USE_CHARON_FALSE$ac_delim
+USE_TOOLS_TRUE!$USE_TOOLS_TRUE$ac_delim
+USE_TOOLS_FALSE!$USE_TOOLS_FALSE$ac_delim
+USE_PLUTO_OR_CHARON_TRUE!$USE_PLUTO_OR_CHARON_TRUE$ac_delim
+USE_PLUTO_OR_CHARON_FALSE!$USE_PLUTO_OR_CHARON_FALSE$ac_delim
+USE_LIBSTRONGSWAN_TRUE!$USE_LIBSTRONGSWAN_TRUE$ac_delim
+USE_LIBSTRONGSWAN_FALSE!$USE_LIBSTRONGSWAN_FALSE$ac_delim
+USE_FILE_CONFIG_TRUE!$USE_FILE_CONFIG_TRUE$ac_delim
+USE_FILE_CONFIG_FALSE!$USE_FILE_CONFIG_FALSE$ac_delim
build!$build$ac_delim
build_cpu!$build_cpu$ac_delim
build_vendor!$build_vendor$ac_delim
@@ -23746,7 +24030,7 @@ LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 65; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 85; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
diff --git a/configure.in b/configure.in
index 751375439..4b0b0ed56 100644
--- a/configure.in
+++ b/configure.in
@@ -16,7 +16,7 @@ dnl ===========================
dnl initialize & set some vars
dnl ===========================
-AC_INIT(strongSwan,4.1.8)
+AC_INIT(strongSwan,4.1.10)
AM_INIT_AUTOMAKE(tar-ustar)
AC_C_BIGENDIAN
AC_SUBST(confdir, '${sysconfdir}')
@@ -156,6 +156,18 @@ AC_ARG_ENABLE(
AM_CONDITIONAL(USE_LIBLDAP, test x$ldap = xtrue)
AC_ARG_ENABLE(
+ [stroke],
+ AS_HELP_STRING([--disable-stroke],[disable charons stroke (pluto compatibility) configuration backend. (default is NO).]),
+ [if test x$enableval = xyes; then
+ stroke=true
+ else
+ stroke=false
+ fi],
+ stroke=true
+)
+AM_CONDITIONAL(USE_STROKE, test x$stroke = xtrue)
+
+AC_ARG_ENABLE(
[dbus],
AS_HELP_STRING([--enable-dbus],[enable DBUS configuration and control interface (default is NO). Requires libdbus.]),
[if test x$enableval = xyes; then
@@ -220,7 +232,34 @@ AC_ARG_ENABLE(
eap_sim=true
fi]
)
-AM_CONDITIONAL(BUILD_EAP_SIM, test x$eap_sim = xtrue)
+AM_CONDITIONAL(USE_EAP_SIM, test x$eap_sim = xtrue)
+
+AC_ARG_ENABLE(
+ [eap-identity],
+ AS_HELP_STRING([--enable-eap-identity],[build EAP module providing EAP-Identity helper (default is NO).]),
+ [if test x$enableval = xyes; then
+ eap_identity=true
+ fi]
+)
+AM_CONDITIONAL(USE_EAP_IDENTITY, test x$eap_identity = xtrue)
+
+AC_ARG_ENABLE(
+ [eap-md5],
+ AS_HELP_STRING([--enable-eap-md5],[build MD5 (CHAP) authenication module for EAP (default is NO).]),
+ [if test x$enableval = xyes; then
+ eap_md5=true
+ fi]
+)
+AM_CONDITIONAL(USE_EAP_MD5, test x$eap_md5 = xtrue)
+
+AC_ARG_ENABLE(
+ [eap-aka],
+ AS_HELP_STRING([--enable-eap-aka],[build AKA authentication module for EAP (default is NO).]),
+ [if test x$enableval = xyes; then
+ eap_aka=true
+ fi]
+)
+AM_CONDITIONAL(USE_EAP_AKA, test x$eap_aka = xtrue)
AC_ARG_ENABLE(
[nat-transport],
@@ -306,6 +345,46 @@ AC_ARG_ENABLE(
)
AM_CONDITIONAL(USE_SELF_TEST, test x$self_test = xtrue)
+AC_ARG_ENABLE(
+ [pluto],
+ AS_HELP_STRING([--disable-pluto],[disable the IKEv1 keying daemon pluto. (default is NO).]),
+ [if test x$enableval = xyes; then
+ pluto=true
+ else
+ pluto=false
+ fi],
+ pluto=true
+)
+AM_CONDITIONAL(USE_PLUTO, test x$pluto = xtrue)
+
+AC_ARG_ENABLE(
+ [charon],
+ AS_HELP_STRING([--disable-charon],[disable the IKEv2 keying daemon charon. (default is NO).]),
+ [if test x$enableval = xyes; then
+ charon=true
+ else
+ charon=false
+ fi],
+ charon=true
+)
+AM_CONDITIONAL(USE_CHARON, test x$charon = xtrue)
+
+AC_ARG_ENABLE(
+ [tools],
+ AS_HELP_STRING([--disable-tools],[disable additional utilities (openac and scepclient). (default is NO).]),
+ [if test x$enableval = xyes; then
+ tools=true
+ else
+ tools=false
+ fi],
+ tools=true
+)
+AM_CONDITIONAL(USE_TOOLS, test x$tools = xtrue)
+
+AM_CONDITIONAL(USE_PLUTO_OR_CHARON, test x$pluto = xtrue -o x$charon = xtrue)
+AM_CONDITIONAL(USE_LIBSTRONGSWAN, test x$charon = xtrue -o x$tools = xtrue)
+AM_CONDITIONAL(USE_FILE_CONFIG, test x$pluto = xtrue -o x$stroke = xtrue)
+
dnl =========================
dnl check required programs
dnl =========================
@@ -335,13 +414,13 @@ if test "$http" = "true"; then
fi
if test "$xml" = "true"; then
- PKG_CHECK_MODULES(xml, libxml-2.0,, AC_MSG_ERROR([No libxml2 package information found]))
+ PKG_CHECK_MODULES(xml, [libxml-2.0],, AC_MSG_ERROR([No libxml2 package information found]))
AC_SUBST(xml_CFLAGS)
AC_SUBST(xml_LIBS)
fi
if test "$dbus" = "true"; then
- PKG_CHECK_MODULES(dbus, dbus-1,, AC_MSG_ERROR([No libdbus package information found]))
+ PKG_CHECK_MODULES(dbus, [dbus-1],, AC_MSG_ERROR([No libdbus package information found]))
AC_SUBST(dbus_CFLAGS)
AC_SUBST(dbus_LIBS)
fi
diff --git a/src/Makefile.am b/src/Makefile.am
index 4d41ea9e5..e01ad84b4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,4 +1,31 @@
-SUBDIRS = include libfreeswan libcrypto libstrongswan pluto whack charon stroke starter openac scepclient ipsec _updown _updown_espmark _copyright
+SUBDIRS = include
+
+if USE_FILE_CONFIG
+ SUBDIRS += libfreeswan starter ipsec _copyright
+endif
+
+if USE_LIBSTRONGSWAN
+ SUBDIRS += libstrongswan
+endif
+
+if USE_PLUTO
+ SUBDIRS += libcrypto pluto whack
+endif
+if USE_CHARON
+ SUBDIRS += charon
+endif
+
+if USE_STROKE
+ SUBDIRS += stroke
+endif
+
+if USE_PLUTO_OR_CHARON
+ SUBDIRS += _updown _updown_espmark
+endif
+
+if USE_TOOLS
+ SUBDIRS += openac scepclient
+endif
if USE_UML
SUBDIRS += dumm
@@ -8,3 +35,16 @@ if USE_MANAGER
SUBDIRS += manager
endif
+if USE_FILE_CONFIG
+install-exec-local :
+ mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d
+ mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/cacerts
+ mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/ocspcerts
+ mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/certs
+ mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/acerts
+ mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/aacerts
+ mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/crls
+ mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/reqs
+ mkdir -p -m 700 $(DESTDIR)$(confdir)/ipsec.d/private
+endif
+
diff --git a/src/Makefile.in b/src/Makefile.in
index aea3c7a2b..f2e6dcefe 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -31,8 +31,15 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-@USE_UML_TRUE@am__append_1 = dumm
-@USE_MANAGER_TRUE@am__append_2 = manager
+@USE_FILE_CONFIG_TRUE@am__append_1 = libfreeswan starter ipsec _copyright
+@USE_LIBSTRONGSWAN_TRUE@am__append_2 = libstrongswan
+@USE_PLUTO_TRUE@am__append_3 = libcrypto pluto whack
+@USE_CHARON_TRUE@am__append_4 = charon
+@USE_STROKE_TRUE@am__append_5 = stroke
+@USE_PLUTO_OR_CHARON_TRUE@am__append_6 = _updown _updown_espmark
+@USE_TOOLS_TRUE@am__append_7 = openac scepclient
+@USE_UML_TRUE@am__append_8 = dumm
+@USE_MANAGER_TRUE@am__append_9 = manager
subdir = src
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -54,9 +61,9 @@ RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
ETAGS = etags
CTAGS = ctags
-DIST_SUBDIRS = include libfreeswan libcrypto libstrongswan pluto whack \
- charon stroke starter openac scepclient ipsec _updown \
- _updown_espmark _copyright dumm manager
+DIST_SUBDIRS = include libfreeswan starter ipsec _copyright \
+ libstrongswan libcrypto pluto whack charon stroke _updown \
+ _updown_espmark openac scepclient dumm manager
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
@@ -188,9 +195,9 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
xml_CFLAGS = @xml_CFLAGS@
xml_LIBS = @xml_LIBS@
-SUBDIRS = include libfreeswan libcrypto libstrongswan pluto whack \
- charon stroke starter openac scepclient ipsec _updown \
- _updown_espmark _copyright $(am__append_1) $(am__append_2)
+SUBDIRS = include $(am__append_1) $(am__append_2) $(am__append_3) \
+ $(am__append_4) $(am__append_5) $(am__append_6) \
+ $(am__append_7) $(am__append_8) $(am__append_9)
all: all-recursive
.SUFFIXES:
@@ -433,6 +440,7 @@ distclean-generic:
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
+@USE_FILE_CONFIG_FALSE@install-exec-local:
clean: clean-recursive
clean-am: clean-generic clean-libtool mostlyclean-am
@@ -455,7 +463,7 @@ install-data-am:
install-dvi: install-dvi-recursive
-install-exec-am:
+install-exec-am: install-exec-local
install-html: install-html-recursive
@@ -496,14 +504,25 @@ uninstall-am:
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 installdirs-am maintainer-clean \
- maintainer-clean-generic mostlyclean mostlyclean-generic \
- mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \
- uninstall uninstall-am
-
+ 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 \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am tags tags-recursive uninstall uninstall-am
+
+
+@USE_FILE_CONFIG_TRUE@install-exec-local :
+@USE_FILE_CONFIG_TRUE@ mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d
+@USE_FILE_CONFIG_TRUE@ mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/cacerts
+@USE_FILE_CONFIG_TRUE@ mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/ocspcerts
+@USE_FILE_CONFIG_TRUE@ mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/certs
+@USE_FILE_CONFIG_TRUE@ mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/acerts
+@USE_FILE_CONFIG_TRUE@ mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/aacerts
+@USE_FILE_CONFIG_TRUE@ mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/crls
+@USE_FILE_CONFIG_TRUE@ mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/reqs
+@USE_FILE_CONFIG_TRUE@ mkdir -p -m 700 $(DESTDIR)$(confdir)/ipsec.d/private
# 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/_updown/Makefile.am b/src/_updown/Makefile.am
index d0b7a27a4..9fd592797 100644
--- a/src/_updown/Makefile.am
+++ b/src/_updown/Makefile.am
@@ -5,6 +5,7 @@ EXTRA_DIST = _updown.in
_updown : _updown.in
sed \
+ -e "s:@IPSEC_SBINDIR@:$(sbindir):" \
-e "s:\@IPSEC_ROUTING_TABLE\@:$(IPSEC_ROUTING_TABLE):" \
-e "s:\@IPSEC_ROUTING_TABLE_PRIO\@:$(IPSEC_ROUTING_TABLE_PRIO):" \
$< > $@
diff --git a/src/_updown/Makefile.in b/src/_updown/Makefile.in
index 21e38da5d..52f1109e5 100644
--- a/src/_updown/Makefile.in
+++ b/src/_updown/Makefile.in
@@ -425,6 +425,7 @@ uninstall-man: uninstall-man8
_updown : _updown.in
sed \
+ -e "s:@IPSEC_SBINDIR@:$(sbindir):" \
-e "s:\@IPSEC_ROUTING_TABLE\@:$(IPSEC_ROUTING_TABLE):" \
-e "s:\@IPSEC_ROUTING_TABLE_PRIO\@:$(IPSEC_ROUTING_TABLE_PRIO):" \
$< > $@
diff --git a/src/_updown/_updown.in b/src/_updown/_updown.in
index 4002449dd..cb0404b34 100644
--- a/src/_updown/_updown.in
+++ b/src/_updown/_updown.in
@@ -16,7 +16,7 @@
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
-# RCSID $Id: _updown.in 3268 2007-10-08 19:59:18Z andreas $
+# RCSID $Id: _updown.in 3389 2007-12-12 22:12:10Z andreas $
# CAUTION: Installing a new version of strongSwan will install a new
# copy of this script, wiping out any custom changes you make. If
@@ -118,6 +118,10 @@
# restricted on the peer side.
#
+# define a minimum PATH environment in case it is not set
+PATH="/sbin:/bin:/usr/sbin:/usr/bin:@IPSEC_SBINDIR@"
+export PATH
+
# uncomment to log VPN connections
VPN_LOGGING=1
#
@@ -372,11 +376,11 @@ up-host:iptables)
# 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.
iptables -I INPUT 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
- -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
+ -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
-d $PLUTO_ME $D_MY_PORT $IPSEC_POLICY_IN -j ACCEPT
iptables -I OUTPUT 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
-s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
- -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
+ -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
#
# log IPsec host connection setup
if [ $VPN_LOGGING ]
@@ -396,11 +400,11 @@ down-host:iptables)
# 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.
iptables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
- -s $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $S_PEER_PORT \
+ -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
-d $PLUTO_ME $D_MY_PORT $IPSEC_POLICY_IN -j ACCEPT
iptables -D OUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
-s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
- -d $PLUTO_PEER_CLIENT_NET/$PLUTO_PEER_CLIENT_MASK $D_PEER_PORT -j ACCEPT
+ -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
#
# log IPsec host connection teardown
if [ $VPN_LOGGING ]
@@ -422,13 +426,11 @@ up-client:iptables)
if [ "$PLUTO_PEER_CLIENT" != "$PLUTO_MY_SOURCEIP/32" ]
then
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 \
- $IPSEC_POLICY_OUT -j ACCEPT
+ -s $PLUTO_MY_CLIENT $S_MY_PORT \
+ -d $PLUTO_PEER_CLIENT $D_PEER_PORT $IPSEC_POLICY_OUT -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 \
- $IPSEC_POLICY_IN -j ACCEPT
+ -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
+ -d $PLUTO_MY_CLIENT $D_MY_PORT $IPSEC_POLICY_IN -j ACCEPT
fi
#
# a virtual IP requires an INPUT and OUTPUT rule on the host
@@ -436,13 +438,11 @@ up-client:iptables)
if [ -n "$PLUTO_MY_SOURCEIP" -o -n "$PLUTO_HOST_ACCESS" ]
then
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_MY_CLIENT_NET/$PLUTO_MY_CLIENT_MASK $D_MY_PORT \
- $IPSEC_POLICY_IN -j ACCEPT
+ -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
+ -d $PLUTO_MY_CLIENT $D_MY_PORT $IPSEC_POLICY_IN -j ACCEPT
iptables -I OUTPUT 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 \
- $IPSEC_POLICY_OUT -j ACCEPT
+ -s $PLUTO_MY_CLIENT $S_MY_PORT \
+ -d $PLUTO_PEER_CLIENT $D_PEER_PORT $IPSEC_POLICY_OUT -j ACCEPT
fi
#
# log IPsec client connection setup
@@ -465,12 +465,12 @@ down-client:iptables)
if [ "$PLUTO_PEER_CLIENT" != "$PLUTO_MY_SOURCEIP/32" ]
then
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 \
+ -s $PLUTO_MY_CLIENT $S_MY_PORT \
+ -d $PLUTO_PEER_CLIENT $D_PEER_PORT \
$IPSEC_POLICY_OUT -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 \
+ -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
+ -d $PLUTO_MY_CLIENT $D_MY_PORT \
$IPSEC_POLICY_IN -j ACCEPT
fi
#
@@ -479,12 +479,12 @@ down-client:iptables)
if [ -n "$PLUTO_MY_SOURCEIP" -o -n "$PLUTO_HOST_ACCESS" ]
then
iptables -D INPUT -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 \
+ -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
+ -d $PLUTO_MY_CLIENT $D_MY_PORT \
$IPSEC_POLICY_IN -j ACCEPT
iptables -D OUTPUT -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 \
+ -s $PLUTO_MY_CLIENT $S_MY_PORT \
+ -d $PLUTO_PEER_CLIENT $D_PEER_PORT \
$IPSEC_POLICY_OUT -j ACCEPT
fi
#
@@ -514,11 +514,11 @@ unroute-host-v6:*|unroute-client-v6:*)
# connection to me or my client subnet being unrouted
#downroute_v6
;;
-up-host-v6:*)
+up-host-v6:)
# connection to me coming up
# If you are doing a custom version, firewall commands go here.
;;
-down-host-v6:*)
+down-host-v6:)
# connection to me going down
# If you are doing a custom version, firewall commands go here.
;;
@@ -530,6 +530,136 @@ down-client-v6:)
# connection to my client subnet going down
# If you are doing a custom version, firewall commands go here.
;;
+up-host-v6:iptables)
+ # connection to me, 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.
+ ip6tables -I INPUT 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
+ -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
+ -d $PLUTO_ME $D_MY_PORT $IPSEC_POLICY_IN -j ACCEPT
+ ip6tables -I OUTPUT 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
+ -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
+ -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
+ #
+ # log IPsec host connection setup
+ if [ $VPN_LOGGING ]
+ then
+ if [ "$PLUTO_PEER_CLIENT" == "$PLUTO_PEER/128" ]
+ then
+ logger -t $TAG -p $FAC_PRIO \
+ "+ `echo -e $PLUTO_PEER_ID` $PLUTO_PEER -- $PLUTO_ME"
+ else
+ logger -t $TAG -p $FAC_PRIO \
+ "+ `echo -e $PLUTO_PEER_ID` $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME"
+ fi
+ fi
+ ;;
+down-host-v6:iptables)
+ # connection to me, 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.
+ ip6tables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
+ -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
+ -d $PLUTO_ME $D_MY_PORT $IPSEC_POLICY_IN -j ACCEPT
+ ip6tables -D OUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
+ -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
+ -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
+ #
+ # log IPsec host connection teardown
+ if [ $VPN_LOGGING ]
+ then
+ if [ "$PLUTO_PEER_CLIENT" == "$PLUTO_PEER/128" ]
+ then
+ logger -t $TAG -p $FAC_PRIO -- \
+ "- `echo -e $PLUTO_PEER_ID` $PLUTO_PEER -- $PLUTO_ME"
+ else
+ logger -t $TAG -p $FAC_PRIO -- \
+ "- `echo -e $PLUTO_PEER_ID` $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME"
+ fi
+ fi
+ ;;
+up-client-v6:iptables)
+ # 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.
+ if [ "$PLUTO_PEER_CLIENT" != "$PLUTO_MY_SOURCEIP/128" ]
+ then
+ ip6tables -I FORWARD 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
+ -s $PLUTO_MY_CLIENT $S_MY_PORT \
+ -d $PLUTO_PEER_CLIENT $D_PEER_PORT $IPSEC_POLICY_OUT -j ACCEPT
+ ip6tables -I FORWARD 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
+ -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
+ -d $PLUTO_MY_CLIENT $D_MY_PORT $IPSEC_POLICY_IN -j ACCEPT
+ fi
+ #
+ # a virtual IP requires an INPUT and OUTPUT rule on the host
+ # or sometimes host access via the internal IP is needed
+ if [ -n "$PLUTO_MY_SOURCEIP" -o -n "$PLUTO_HOST_ACCESS" ]
+ then
+ ip6tables -I INPUT 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
+ -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
+ -d $PLUTO_MY_CLIENT $D_MY_PORT $IPSEC_POLICY_IN -j ACCEPT
+ ip6tables -I OUTPUT 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
+ -s $PLUTO_MY_CLIENT $S_MY_PORT \
+ -d $PLUTO_PEER_CLIENT $D_PEER_PORT $IPSEC_POLICY_OUT -j ACCEPT
+ fi
+ #
+ # log IPsec client connection setup
+ if [ $VPN_LOGGING ]
+ then
+ if [ "$PLUTO_PEER_CLIENT" == "$PLUTO_PEER/128" ]
+ then
+ logger -t $TAG -p $FAC_PRIO \
+ "+ `echo -e $PLUTO_PEER_ID` $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
+ else
+ logger -t $TAG -p $FAC_PRIO \
+ "+ `echo -e $PLUTO_PEER_ID` $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
+ fi
+ fi
+ ;;
+down-client-v6:iptables)
+ # 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.
+ if [ "$PLUTO_PEER_CLIENT" != "$PLUTO_MY_SOURCEIP/128" ]
+ then
+ ip6tables -D FORWARD -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
+ -s $PLUTO_MY_CLIENT $S_MY_PORT \
+ -d $PLUTO_PEER_CLIENT $D_PEER_PORT \
+ $IPSEC_POLICY_OUT -j ACCEPT
+ ip6tables -D FORWARD -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
+ -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
+ -d $PLUTO_MY_CLIENT $D_MY_PORT \
+ $IPSEC_POLICY_IN -j ACCEPT
+ fi
+ #
+ # a virtual IP requires an INPUT and OUTPUT rule on the host
+ # or sometimes host access via the internal IP is needed
+ if [ -n "$PLUTO_MY_SOURCEIP" -o -n "$PLUTO_HOST_ACCESS" ]
+ then
+ ip6tables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
+ -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
+ -d $PLUTO_MY_CLIENT $D_MY_PORT \
+ $IPSEC_POLICY_IN -j ACCEPT
+ ip6tables -D OUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
+ -s $PLUTO_MY_CLIENT $S_MY_PORT \
+ -d $PLUTO_PEER_CLIENT $D_PEER_PORT \
+ $IPSEC_POLICY_OUT -j ACCEPT
+ fi
+ #
+ # log IPsec client connection teardown
+ if [ $VPN_LOGGING ]
+ then
+ if [ "$PLUTO_PEER_CLIENT" == "$PLUTO_PEER/128" ]
+ then
+ logger -t $TAG -p $FAC_PRIO -- \
+ "- `echo -e $PLUTO_PEER_ID` $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
+ else
+ logger -t $TAG -p $FAC_PRIO -- \
+ "- `echo -e $PLUTO_PEER_ID` $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
+ fi
+ fi
+ ;;
*) echo "$0: unknown verb \`$PLUTO_VERB' or parameter \`$1'" >&2
exit 1
;;
diff --git a/src/charon/Makefile.am b/src/charon/Makefile.am
index 0d783cbbb..9111191b6 100644
--- a/src/charon/Makefile.am
+++ b/src/charon/Makefile.am
@@ -45,7 +45,7 @@ kernel/kernel_interface.c kernel/kernel_interface.h \
network/packet.c network/packet.h \
network/receiver.c network/receiver.h \
network/sender.c network/sender.h \
-network/socket.c network/socket.h \
+network/socket.h \
processing/jobs/job.h \
processing/jobs/acquire_job.c processing/jobs/acquire_job.h \
processing/jobs/callback_job.c processing/jobs/callback_job.h \
@@ -83,8 +83,16 @@ sa/tasks/ike_natd.c sa/tasks/ike_natd.h \
sa/tasks/ike_mobike.c sa/tasks/ike_mobike.h \
sa/tasks/ike_rekey.c sa/tasks/ike_rekey.h \
sa/tasks/ike_reauth.c sa/tasks/ike_reauth.h \
+sa/tasks/ike_auth_lifetime.c sa/tasks/ike_auth_lifetime.h \
sa/tasks/task.c sa/tasks/task.h
+# Use RAW socket if pluto gets built
+if USE_PLUTO
+ charon_SOURCES += network/socket-raw.c
+else
+ charon_SOURCES += network/socket.c
+endif
+
if USE_P2P
charon_SOURCES += encoding/payloads/endpoint_notify.c encoding/payloads/endpoint_notify.h \
processing/jobs/initiate_mediation_job.c processing/jobs/initiate_mediation_job.h \
@@ -104,56 +112,74 @@ if USE_LIBCURL
endif
-# build EAP plugins, EAP-Identity is always built
-#################################################
+# build EAP plugins
+###################
eap_LTLIBRARIES =
-eap_LTLIBRARIES += libeapidentity.la
-libeapidentity_la_SOURCES = sa/authenticators/eap/eap_identity.h sa/authenticators/eap/eap_identity.c
-libeapidentity_la_LDFLAGS = -module
+if USE_EAP_IDENTITY
+ eap_LTLIBRARIES += libcharon-eapidentity.la
+ libcharon_eapidentity_la_SOURCES = sa/authenticators/eap/eap_identity.h sa/authenticators/eap/eap_identity.c
+ libcharon_eapidentity_la_LDFLAGS = -module
+endif
+
+if USE_EAP_SIM
+ eap_LTLIBRARIES += libcharon-eapsim.la
+ libcharon_eapsim_la_SOURCES = sa/authenticators/eap/eap_sim.h sa/authenticators/eap/eap_sim.c
+ libcharon_eapsim_la_LDFLAGS = -module
+endif
-if BUILD_EAP_SIM
- eap_LTLIBRARIES += libeapsim.la
- libeapsim_la_SOURCES = sa/authenticators/eap/eap_sim.h sa/authenticators/eap/eap_sim.c
- libeapsim_la_LDFLAGS = -module
+if USE_EAP_MD5
+ eap_LTLIBRARIES += libcharon-eapmd5.la
+ libcharon_eapmd5_la_SOURCES = sa/authenticators/eap/eap_md5.h sa/authenticators/eap/eap_md5.c
+ libcharon_eapmd5_la_LDFLAGS = -module
endif
-# build backends, local backend is always built
-###############################################
+if USE_EAP_AKA
+ eap_LTLIBRARIES += libcharon-eapaka.la
+ libcharon_eapaka_la_SOURCES = sa/authenticators/eap/eap_aka.h sa/authenticators/eap/eap_aka.c
+ libcharon_eapaka_la_LDFLAGS = -module
+endif
+
+# build backends
+################
backend_LTLIBRARIES =
-backend_LTLIBRARIES += liblocal.la
-liblocal_la_SOURCES = config/backends/local_backend.h config/backends/local_backend.c
-liblocal_la_LDFLAGS = -module
+if USE_STROKE
+ backend_LTLIBRARIES += libcharon-local.la
+ libcharon_local_la_SOURCES = config/backends/local_backend.h config/backends/local_backend.c
+ libcharon_local_la_LDFLAGS = -module
+endif
if USE_LIBSQLITE
- backend_LTLIBRARIES += libsqlite.la
- libsqlite_la_SOURCES = config/backends/sqlite_backend.h config/backends/sqlite_backend.c
- libsqlite_la_LIBADD = -lsqlite3
- libsqlite_la_LDFLAGS = -module
+ backend_LTLIBRARIES += libcharon-sqlite.la
+ libcharon_sqlite_la_SOURCES = config/backends/sqlite_backend.h config/backends/sqlite_backend.c
+ libcharon_sqlite_la_LIBADD = -lsqlite3
+ libcharon_sqlite_la_LDFLAGS = -module
endif
-# build control interfaces, stroke interface is always built
-############################################################
+# build control interfaces
+##########################
interface_LTLIBRARIES =
-interface_LTLIBRARIES += libstroke.la
-libstroke_la_SOURCES = control/interfaces/stroke_interface.h control/interfaces/stroke_interface.c
-libstroke_la_LDFLAGS = -module
+if USE_STROKE
+ interface_LTLIBRARIES += libcharon-stroke.la
+ libcharon_stroke_la_SOURCES = control/interfaces/stroke_interface.h control/interfaces/stroke_interface.c
+ libcharon_stroke_la_LDFLAGS = -module
+endif
if USE_LIBDBUS
- interface_LTLIBRARIES += libdbus.la
- libdbus_la_SOURCES = control/interfaces/dbus_interface.h control/interfaces/dbus_interface.c
- libdbus_la_LDFLAGS = -module
- libdbus_la_LIBADD = ${dbus_LIBS}
+ interface_LTLIBRARIES += libcharon-dbus.la
+ libcharon_dbus_la_SOURCES = control/interfaces/dbus_interface.h control/interfaces/dbus_interface.c
+ libcharon_dbus_la_LDFLAGS = -module
+ libcharon_dbus_la_LIBADD = ${dbus_LIBS}
INCLUDES += ${dbus_CFLAGS}
endif
if USE_LIBXML
- interface_LTLIBRARIES += libxml.la
- libxml_la_SOURCES = control/interfaces/xml_interface.h control/interfaces/xml_interface.c
- libxml_la_LDFLAGS = -module
- libxml_la_LIBADD = ${xml_LIBS}
+ interface_LTLIBRARIES += libcharon-xml.la
+ libcharon_xml_la_SOURCES = control/interfaces/xml_interface.h control/interfaces/xml_interface.c
+ libcharon_xml_la_LDFLAGS = -module
+ libcharon_xml_la_LIBADD = ${xml_LIBS}
INCLUDES += ${xml_CFLAGS}
endif
diff --git a/src/charon/Makefile.in b/src/charon/Makefile.in
index e3b397f4e..bbae1270a 100644
--- a/src/charon/Makefile.in
+++ b/src/charon/Makefile.in
@@ -34,20 +34,29 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
ipsec_PROGRAMS = charon$(EXEEXT)
-@USE_P2P_TRUE@am__append_1 = encoding/payloads/endpoint_notify.c encoding/payloads/endpoint_notify.h \
+
+# Use RAW socket if pluto gets built
+@USE_PLUTO_TRUE@am__append_1 = network/socket-raw.c
+@USE_PLUTO_FALSE@am__append_2 = network/socket.c
+@USE_P2P_TRUE@am__append_3 = encoding/payloads/endpoint_notify.c encoding/payloads/endpoint_notify.h \
@USE_P2P_TRUE@ processing/jobs/initiate_mediation_job.c processing/jobs/initiate_mediation_job.h \
@USE_P2P_TRUE@ processing/jobs/mediation_job.c processing/jobs/mediation_job.h \
@USE_P2P_TRUE@ sa/connect_manager.c sa/connect_manager.h \
@USE_P2P_TRUE@ sa/mediation_manager.c sa/mediation_manager.h \
@USE_P2P_TRUE@ sa/tasks/ike_p2p.c sa/tasks/ike_p2p.h
-@USE_LIBCURL_TRUE@am__append_2 = -lcurl
-@BUILD_EAP_SIM_TRUE@am__append_3 = libeapsim.la
-@USE_LIBSQLITE_TRUE@am__append_4 = libsqlite.la
-@USE_LIBDBUS_TRUE@am__append_5 = libdbus.la
-@USE_LIBDBUS_TRUE@am__append_6 = ${dbus_CFLAGS}
-@USE_LIBXML_TRUE@am__append_7 = libxml.la
-@USE_LIBXML_TRUE@am__append_8 = ${xml_CFLAGS}
+@USE_LIBCURL_TRUE@am__append_4 = -lcurl
+@USE_EAP_IDENTITY_TRUE@am__append_5 = libcharon-eapidentity.la
+@USE_EAP_SIM_TRUE@am__append_6 = libcharon-eapsim.la
+@USE_EAP_MD5_TRUE@am__append_7 = libcharon-eapmd5.la
+@USE_EAP_AKA_TRUE@am__append_8 = libcharon-eapaka.la
+@USE_STROKE_TRUE@am__append_9 = libcharon-local.la
+@USE_LIBSQLITE_TRUE@am__append_10 = libcharon-sqlite.la
+@USE_STROKE_TRUE@am__append_11 = libcharon-stroke.la
+@USE_LIBDBUS_TRUE@am__append_12 = libcharon-dbus.la
+@USE_LIBDBUS_TRUE@am__append_13 = ${dbus_CFLAGS}
+@USE_LIBXML_TRUE@am__append_14 = libcharon-xml.la
+@USE_LIBXML_TRUE@am__append_15 = ${xml_CFLAGS}
subdir = src/charon
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -70,60 +79,102 @@ interfaceLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(backend_LTLIBRARIES) $(eap_LTLIBRARIES) \
$(interface_LTLIBRARIES)
am__DEPENDENCIES_1 =
-@USE_LIBDBUS_TRUE@libdbus_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
-am__libdbus_la_SOURCES_DIST = control/interfaces/dbus_interface.h \
+@USE_LIBDBUS_TRUE@libcharon_dbus_la_DEPENDENCIES = \
+@USE_LIBDBUS_TRUE@ $(am__DEPENDENCIES_1)
+am__libcharon_dbus_la_SOURCES_DIST = \
+ control/interfaces/dbus_interface.h \
control/interfaces/dbus_interface.c
-@USE_LIBDBUS_TRUE@am_libdbus_la_OBJECTS = dbus_interface.lo
-libdbus_la_OBJECTS = $(am_libdbus_la_OBJECTS)
-libdbus_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+@USE_LIBDBUS_TRUE@am_libcharon_dbus_la_OBJECTS = dbus_interface.lo
+libcharon_dbus_la_OBJECTS = $(am_libcharon_dbus_la_OBJECTS)
+libcharon_dbus_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libcharon_dbus_la_LDFLAGS) $(LDFLAGS) -o $@
+@USE_LIBDBUS_TRUE@am_libcharon_dbus_la_rpath = -rpath $(interfacedir)
+libcharon_eapaka_la_LIBADD =
+am__libcharon_eapaka_la_SOURCES_DIST = \
+ sa/authenticators/eap/eap_aka.h \
+ sa/authenticators/eap/eap_aka.c
+@USE_EAP_AKA_TRUE@am_libcharon_eapaka_la_OBJECTS = eap_aka.lo
+libcharon_eapaka_la_OBJECTS = $(am_libcharon_eapaka_la_OBJECTS)
+libcharon_eapaka_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libcharon_eapaka_la_LDFLAGS) $(LDFLAGS) -o $@
+@USE_EAP_AKA_TRUE@am_libcharon_eapaka_la_rpath = -rpath $(eapdir)
+libcharon_eapidentity_la_LIBADD =
+am__libcharon_eapidentity_la_SOURCES_DIST = \
+ sa/authenticators/eap/eap_identity.h \
+ sa/authenticators/eap/eap_identity.c
+@USE_EAP_IDENTITY_TRUE@am_libcharon_eapidentity_la_OBJECTS = \
+@USE_EAP_IDENTITY_TRUE@ eap_identity.lo
+libcharon_eapidentity_la_OBJECTS = \
+ $(am_libcharon_eapidentity_la_OBJECTS)
+libcharon_eapidentity_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libdbus_la_LDFLAGS) $(LDFLAGS) -o $@
-@USE_LIBDBUS_TRUE@am_libdbus_la_rpath = -rpath $(interfacedir)
-libeapidentity_la_LIBADD =
-am_libeapidentity_la_OBJECTS = eap_identity.lo
-libeapidentity_la_OBJECTS = $(am_libeapidentity_la_OBJECTS)
-libeapidentity_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(libcharon_eapidentity_la_LDFLAGS) $(LDFLAGS) -o $@
+@USE_EAP_IDENTITY_TRUE@am_libcharon_eapidentity_la_rpath = -rpath \
+@USE_EAP_IDENTITY_TRUE@ $(eapdir)
+libcharon_eapmd5_la_LIBADD =
+am__libcharon_eapmd5_la_SOURCES_DIST = \
+ sa/authenticators/eap/eap_md5.h \
+ sa/authenticators/eap/eap_md5.c
+@USE_EAP_MD5_TRUE@am_libcharon_eapmd5_la_OBJECTS = eap_md5.lo
+libcharon_eapmd5_la_OBJECTS = $(am_libcharon_eapmd5_la_OBJECTS)
+libcharon_eapmd5_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libeapidentity_la_LDFLAGS) $(LDFLAGS) -o $@
-libeapsim_la_LIBADD =
-am__libeapsim_la_SOURCES_DIST = sa/authenticators/eap/eap_sim.h \
+ $(libcharon_eapmd5_la_LDFLAGS) $(LDFLAGS) -o $@
+@USE_EAP_MD5_TRUE@am_libcharon_eapmd5_la_rpath = -rpath $(eapdir)
+libcharon_eapsim_la_LIBADD =
+am__libcharon_eapsim_la_SOURCES_DIST = \
+ sa/authenticators/eap/eap_sim.h \
sa/authenticators/eap/eap_sim.c
-@BUILD_EAP_SIM_TRUE@am_libeapsim_la_OBJECTS = eap_sim.lo
-libeapsim_la_OBJECTS = $(am_libeapsim_la_OBJECTS)
-libeapsim_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+@USE_EAP_SIM_TRUE@am_libcharon_eapsim_la_OBJECTS = eap_sim.lo
+libcharon_eapsim_la_OBJECTS = $(am_libcharon_eapsim_la_OBJECTS)
+libcharon_eapsim_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libeapsim_la_LDFLAGS) $(LDFLAGS) -o $@
-@BUILD_EAP_SIM_TRUE@am_libeapsim_la_rpath = -rpath $(eapdir)
-liblocal_la_LIBADD =
-am_liblocal_la_OBJECTS = local_backend.lo
-liblocal_la_OBJECTS = $(am_liblocal_la_OBJECTS)
-liblocal_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(libcharon_eapsim_la_LDFLAGS) $(LDFLAGS) -o $@
+@USE_EAP_SIM_TRUE@am_libcharon_eapsim_la_rpath = -rpath $(eapdir)
+libcharon_local_la_LIBADD =
+am__libcharon_local_la_SOURCES_DIST = config/backends/local_backend.h \
+ config/backends/local_backend.c
+@USE_STROKE_TRUE@am_libcharon_local_la_OBJECTS = local_backend.lo
+libcharon_local_la_OBJECTS = $(am_libcharon_local_la_OBJECTS)
+libcharon_local_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(liblocal_la_LDFLAGS) $(LDFLAGS) -o $@
-libsqlite_la_DEPENDENCIES =
-am__libsqlite_la_SOURCES_DIST = config/backends/sqlite_backend.h \
+ $(libcharon_local_la_LDFLAGS) $(LDFLAGS) -o $@
+@USE_STROKE_TRUE@am_libcharon_local_la_rpath = -rpath $(backenddir)
+libcharon_sqlite_la_DEPENDENCIES =
+am__libcharon_sqlite_la_SOURCES_DIST = \
+ config/backends/sqlite_backend.h \
config/backends/sqlite_backend.c
-@USE_LIBSQLITE_TRUE@am_libsqlite_la_OBJECTS = sqlite_backend.lo
-libsqlite_la_OBJECTS = $(am_libsqlite_la_OBJECTS)
-libsqlite_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+@USE_LIBSQLITE_TRUE@am_libcharon_sqlite_la_OBJECTS = \
+@USE_LIBSQLITE_TRUE@ sqlite_backend.lo
+libcharon_sqlite_la_OBJECTS = $(am_libcharon_sqlite_la_OBJECTS)
+libcharon_sqlite_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libsqlite_la_LDFLAGS) $(LDFLAGS) -o $@
-@USE_LIBSQLITE_TRUE@am_libsqlite_la_rpath = -rpath $(backenddir)
-libstroke_la_LIBADD =
-am_libstroke_la_OBJECTS = stroke_interface.lo
-libstroke_la_OBJECTS = $(am_libstroke_la_OBJECTS)
-libstroke_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(libcharon_sqlite_la_LDFLAGS) $(LDFLAGS) -o $@
+@USE_LIBSQLITE_TRUE@am_libcharon_sqlite_la_rpath = -rpath \
+@USE_LIBSQLITE_TRUE@ $(backenddir)
+libcharon_stroke_la_LIBADD =
+am__libcharon_stroke_la_SOURCES_DIST = \
+ control/interfaces/stroke_interface.h \
+ control/interfaces/stroke_interface.c
+@USE_STROKE_TRUE@am_libcharon_stroke_la_OBJECTS = stroke_interface.lo
+libcharon_stroke_la_OBJECTS = $(am_libcharon_stroke_la_OBJECTS)
+libcharon_stroke_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libstroke_la_LDFLAGS) $(LDFLAGS) -o $@
-@USE_LIBXML_TRUE@libxml_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
-am__libxml_la_SOURCES_DIST = control/interfaces/xml_interface.h \
+ $(libcharon_stroke_la_LDFLAGS) $(LDFLAGS) -o $@
+@USE_STROKE_TRUE@am_libcharon_stroke_la_rpath = -rpath $(interfacedir)
+@USE_LIBXML_TRUE@libcharon_xml_la_DEPENDENCIES = \
+@USE_LIBXML_TRUE@ $(am__DEPENDENCIES_1)
+am__libcharon_xml_la_SOURCES_DIST = \
+ control/interfaces/xml_interface.h \
control/interfaces/xml_interface.c
-@USE_LIBXML_TRUE@am_libxml_la_OBJECTS = xml_interface.lo
-libxml_la_OBJECTS = $(am_libxml_la_OBJECTS)
-libxml_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+@USE_LIBXML_TRUE@am_libcharon_xml_la_OBJECTS = xml_interface.lo
+libcharon_xml_la_OBJECTS = $(am_libcharon_xml_la_OBJECTS)
+libcharon_xml_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libxml_la_LDFLAGS) $(LDFLAGS) -o $@
-@USE_LIBXML_TRUE@am_libxml_la_rpath = -rpath $(interfacedir)
+ $(libcharon_xml_la_LDFLAGS) $(LDFLAGS) -o $@
+@USE_LIBXML_TRUE@am_libcharon_xml_la_rpath = -rpath $(interfacedir)
ipsecPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(ipsec_PROGRAMS)
am__charon_SOURCES_DIST = bus/bus.c bus/bus.h \
@@ -181,7 +232,7 @@ am__charon_SOURCES_DIST = bus/bus.c bus/bus.h \
kernel/kernel_interface.c kernel/kernel_interface.h \
network/packet.c network/packet.h network/receiver.c \
network/receiver.h network/sender.c network/sender.h \
- network/socket.c network/socket.h processing/jobs/job.h \
+ network/socket.h processing/jobs/job.h \
processing/jobs/acquire_job.c processing/jobs/acquire_job.h \
processing/jobs/callback_job.c processing/jobs/callback_job.h \
processing/jobs/delete_child_sa_job.c \
@@ -225,7 +276,9 @@ am__charon_SOURCES_DIST = bus/bus.c bus/bus.h \
sa/tasks/ike_natd.h sa/tasks/ike_mobike.c \
sa/tasks/ike_mobike.h sa/tasks/ike_rekey.c \
sa/tasks/ike_rekey.h sa/tasks/ike_reauth.c \
- sa/tasks/ike_reauth.h sa/tasks/task.c sa/tasks/task.h \
+ sa/tasks/ike_reauth.h sa/tasks/ike_auth_lifetime.c \
+ sa/tasks/ike_auth_lifetime.h sa/tasks/task.c sa/tasks/task.h \
+ network/socket-raw.c network/socket.c \
encoding/payloads/endpoint_notify.c \
encoding/payloads/endpoint_notify.h \
processing/jobs/initiate_mediation_job.c \
@@ -234,7 +287,9 @@ am__charon_SOURCES_DIST = bus/bus.c bus/bus.h \
processing/jobs/mediation_job.h sa/connect_manager.c \
sa/connect_manager.h sa/mediation_manager.c \
sa/mediation_manager.h sa/tasks/ike_p2p.c sa/tasks/ike_p2p.h
-@USE_P2P_TRUE@am__objects_1 = endpoint_notify.$(OBJEXT) \
+@USE_PLUTO_TRUE@am__objects_1 = socket-raw.$(OBJEXT)
+@USE_PLUTO_FALSE@am__objects_2 = socket.$(OBJEXT)
+@USE_P2P_TRUE@am__objects_3 = endpoint_notify.$(OBJEXT) \
@USE_P2P_TRUE@ initiate_mediation_job.$(OBJEXT) \
@USE_P2P_TRUE@ mediation_job.$(OBJEXT) \
@USE_P2P_TRUE@ connect_manager.$(OBJEXT) \
@@ -258,7 +313,7 @@ am_charon_OBJECTS = bus.$(OBJEXT) file_logger.$(OBJEXT) \
ts_payload.$(OBJEXT) unknown_payload.$(OBJEXT) \
vendor_id_payload.$(OBJEXT) kernel_interface.$(OBJEXT) \
packet.$(OBJEXT) receiver.$(OBJEXT) sender.$(OBJEXT) \
- socket.$(OBJEXT) acquire_job.$(OBJEXT) callback_job.$(OBJEXT) \
+ acquire_job.$(OBJEXT) callback_job.$(OBJEXT) \
delete_child_sa_job.$(OBJEXT) delete_ike_sa_job.$(OBJEXT) \
process_message_job.$(OBJEXT) rekey_child_sa_job.$(OBJEXT) \
rekey_ike_sa_job.$(OBJEXT) retransmit_job.$(OBJEXT) \
@@ -273,7 +328,9 @@ am_charon_OBJECTS = bus.$(OBJEXT) file_logger.$(OBJEXT) \
ike_auth.$(OBJEXT) ike_cert.$(OBJEXT) ike_config.$(OBJEXT) \
ike_delete.$(OBJEXT) ike_dpd.$(OBJEXT) ike_init.$(OBJEXT) \
ike_natd.$(OBJEXT) ike_mobike.$(OBJEXT) ike_rekey.$(OBJEXT) \
- ike_reauth.$(OBJEXT) task.$(OBJEXT) $(am__objects_1)
+ ike_reauth.$(OBJEXT) ike_auth_lifetime.$(OBJEXT) \
+ task.$(OBJEXT) $(am__objects_1) $(am__objects_2) \
+ $(am__objects_3)
charon_OBJECTS = $(am_charon_OBJECTS)
charon_DEPENDENCIES = \
$(top_builddir)/src/libstrongswan/libstrongswan.la \
@@ -290,14 +347,21 @@ CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
-SOURCES = $(libdbus_la_SOURCES) $(libeapidentity_la_SOURCES) \
- $(libeapsim_la_SOURCES) $(liblocal_la_SOURCES) \
- $(libsqlite_la_SOURCES) $(libstroke_la_SOURCES) \
- $(libxml_la_SOURCES) $(charon_SOURCES)
-DIST_SOURCES = $(am__libdbus_la_SOURCES_DIST) \
- $(libeapidentity_la_SOURCES) $(am__libeapsim_la_SOURCES_DIST) \
- $(liblocal_la_SOURCES) $(am__libsqlite_la_SOURCES_DIST) \
- $(libstroke_la_SOURCES) $(am__libxml_la_SOURCES_DIST) \
+SOURCES = $(libcharon_dbus_la_SOURCES) $(libcharon_eapaka_la_SOURCES) \
+ $(libcharon_eapidentity_la_SOURCES) \
+ $(libcharon_eapmd5_la_SOURCES) $(libcharon_eapsim_la_SOURCES) \
+ $(libcharon_local_la_SOURCES) $(libcharon_sqlite_la_SOURCES) \
+ $(libcharon_stroke_la_SOURCES) $(libcharon_xml_la_SOURCES) \
+ $(charon_SOURCES)
+DIST_SOURCES = $(am__libcharon_dbus_la_SOURCES_DIST) \
+ $(am__libcharon_eapaka_la_SOURCES_DIST) \
+ $(am__libcharon_eapidentity_la_SOURCES_DIST) \
+ $(am__libcharon_eapmd5_la_SOURCES_DIST) \
+ $(am__libcharon_eapsim_la_SOURCES_DIST) \
+ $(am__libcharon_local_la_SOURCES_DIST) \
+ $(am__libcharon_sqlite_la_SOURCES_DIST) \
+ $(am__libcharon_stroke_la_SOURCES_DIST) \
+ $(am__libcharon_xml_la_SOURCES_DIST) \
$(am__charon_SOURCES_DIST)
ETAGS = etags
CTAGS = ctags
@@ -486,7 +550,7 @@ charon_SOURCES = bus/bus.c bus/bus.h bus/listeners/file_logger.c \
kernel/kernel_interface.c kernel/kernel_interface.h \
network/packet.c network/packet.h network/receiver.c \
network/receiver.h network/sender.c network/sender.h \
- network/socket.c network/socket.h processing/jobs/job.h \
+ network/socket.h processing/jobs/job.h \
processing/jobs/acquire_job.c processing/jobs/acquire_job.h \
processing/jobs/callback_job.c processing/jobs/callback_job.h \
processing/jobs/delete_child_sa_job.c \
@@ -530,45 +594,52 @@ charon_SOURCES = bus/bus.c bus/bus.h bus/listeners/file_logger.c \
sa/tasks/ike_natd.h sa/tasks/ike_mobike.c \
sa/tasks/ike_mobike.h sa/tasks/ike_rekey.c \
sa/tasks/ike_rekey.h sa/tasks/ike_reauth.c \
- sa/tasks/ike_reauth.h sa/tasks/task.c sa/tasks/task.h \
- $(am__append_1)
+ sa/tasks/ike_reauth.h sa/tasks/ike_auth_lifetime.c \
+ sa/tasks/ike_auth_lifetime.h sa/tasks/task.c sa/tasks/task.h \
+ $(am__append_1) $(am__append_2) $(am__append_3)
INCLUDES = -I${linuxdir} -I$(top_srcdir)/src/libstrongswan \
-I$(top_srcdir)/src/charon -I$(top_srcdir)/src/stroke \
- $(am__append_6) $(am__append_8)
+ $(am__append_13) $(am__append_15)
AM_CFLAGS = -rdynamic -DIPSEC_CONFDIR=\"${confdir}\" -DIPSEC_DIR=\"${ipsecdir}\" -DIPSEC_PIDDIR=\"${piddir}\" \
-DIPSEC_EAPDIR=\"${eapdir}\" -DIPSEC_BACKENDDIR=\"${backenddir}\" -DIPSEC_INTERFACEDIR=\"${interfacedir}\"
charon_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la \
- -lgmp -lpthread -lm -ldl $(am__append_2)
-
-# build EAP plugins, EAP-Identity is always built
-#################################################
-eap_LTLIBRARIES = libeapidentity.la $(am__append_3)
-libeapidentity_la_SOURCES = sa/authenticators/eap/eap_identity.h sa/authenticators/eap/eap_identity.c
-libeapidentity_la_LDFLAGS = -module
-@BUILD_EAP_SIM_TRUE@libeapsim_la_SOURCES = sa/authenticators/eap/eap_sim.h sa/authenticators/eap/eap_sim.c
-@BUILD_EAP_SIM_TRUE@libeapsim_la_LDFLAGS = -module
-
-# build backends, local backend is always built
-###############################################
-backend_LTLIBRARIES = liblocal.la $(am__append_4)
-liblocal_la_SOURCES = config/backends/local_backend.h config/backends/local_backend.c
-liblocal_la_LDFLAGS = -module
-@USE_LIBSQLITE_TRUE@libsqlite_la_SOURCES = config/backends/sqlite_backend.h config/backends/sqlite_backend.c
-@USE_LIBSQLITE_TRUE@libsqlite_la_LIBADD = -lsqlite3
-@USE_LIBSQLITE_TRUE@libsqlite_la_LDFLAGS = -module
-
-# build control interfaces, stroke interface is always built
-############################################################
-interface_LTLIBRARIES = libstroke.la $(am__append_5) $(am__append_7)
-libstroke_la_SOURCES = control/interfaces/stroke_interface.h control/interfaces/stroke_interface.c
-libstroke_la_LDFLAGS = -module
-@USE_LIBDBUS_TRUE@libdbus_la_SOURCES = control/interfaces/dbus_interface.h control/interfaces/dbus_interface.c
-@USE_LIBDBUS_TRUE@libdbus_la_LDFLAGS = -module
-@USE_LIBDBUS_TRUE@libdbus_la_LIBADD = ${dbus_LIBS}
-@USE_LIBXML_TRUE@libxml_la_SOURCES = control/interfaces/xml_interface.h control/interfaces/xml_interface.c
-@USE_LIBXML_TRUE@libxml_la_LDFLAGS = -module
-@USE_LIBXML_TRUE@libxml_la_LIBADD = ${xml_LIBS}
+ -lgmp -lpthread -lm -ldl $(am__append_4)
+
+# build EAP plugins
+###################
+eap_LTLIBRARIES = $(am__append_5) $(am__append_6) $(am__append_7) \
+ $(am__append_8)
+@USE_EAP_IDENTITY_TRUE@libcharon_eapidentity_la_SOURCES = sa/authenticators/eap/eap_identity.h sa/authenticators/eap/eap_identity.c
+@USE_EAP_IDENTITY_TRUE@libcharon_eapidentity_la_LDFLAGS = -module
+@USE_EAP_SIM_TRUE@libcharon_eapsim_la_SOURCES = sa/authenticators/eap/eap_sim.h sa/authenticators/eap/eap_sim.c
+@USE_EAP_SIM_TRUE@libcharon_eapsim_la_LDFLAGS = -module
+@USE_EAP_MD5_TRUE@libcharon_eapmd5_la_SOURCES = sa/authenticators/eap/eap_md5.h sa/authenticators/eap/eap_md5.c
+@USE_EAP_MD5_TRUE@libcharon_eapmd5_la_LDFLAGS = -module
+@USE_EAP_AKA_TRUE@libcharon_eapaka_la_SOURCES = sa/authenticators/eap/eap_aka.h sa/authenticators/eap/eap_aka.c
+@USE_EAP_AKA_TRUE@libcharon_eapaka_la_LDFLAGS = -module
+
+# build backends
+################
+backend_LTLIBRARIES = $(am__append_9) $(am__append_10)
+@USE_STROKE_TRUE@libcharon_local_la_SOURCES = config/backends/local_backend.h config/backends/local_backend.c
+@USE_STROKE_TRUE@libcharon_local_la_LDFLAGS = -module
+@USE_LIBSQLITE_TRUE@libcharon_sqlite_la_SOURCES = config/backends/sqlite_backend.h config/backends/sqlite_backend.c
+@USE_LIBSQLITE_TRUE@libcharon_sqlite_la_LIBADD = -lsqlite3
+@USE_LIBSQLITE_TRUE@libcharon_sqlite_la_LDFLAGS = -module
+
+# build control interfaces
+##########################
+interface_LTLIBRARIES = $(am__append_11) $(am__append_12) \
+ $(am__append_14)
+@USE_STROKE_TRUE@libcharon_stroke_la_SOURCES = control/interfaces/stroke_interface.h control/interfaces/stroke_interface.c
+@USE_STROKE_TRUE@libcharon_stroke_la_LDFLAGS = -module
+@USE_LIBDBUS_TRUE@libcharon_dbus_la_SOURCES = control/interfaces/dbus_interface.h control/interfaces/dbus_interface.c
+@USE_LIBDBUS_TRUE@libcharon_dbus_la_LDFLAGS = -module
+@USE_LIBDBUS_TRUE@libcharon_dbus_la_LIBADD = ${dbus_LIBS}
+@USE_LIBXML_TRUE@libcharon_xml_la_SOURCES = control/interfaces/xml_interface.h control/interfaces/xml_interface.c
+@USE_LIBXML_TRUE@libcharon_xml_la_LDFLAGS = -module
+@USE_LIBXML_TRUE@libcharon_xml_la_LIBADD = ${xml_LIBS}
all: all-am
.SUFFIXES:
@@ -683,20 +754,24 @@ clean-interfaceLTLIBRARIES:
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
-libdbus.la: $(libdbus_la_OBJECTS) $(libdbus_la_DEPENDENCIES)
- $(libdbus_la_LINK) $(am_libdbus_la_rpath) $(libdbus_la_OBJECTS) $(libdbus_la_LIBADD) $(LIBS)
-libeapidentity.la: $(libeapidentity_la_OBJECTS) $(libeapidentity_la_DEPENDENCIES)
- $(libeapidentity_la_LINK) -rpath $(eapdir) $(libeapidentity_la_OBJECTS) $(libeapidentity_la_LIBADD) $(LIBS)
-libeapsim.la: $(libeapsim_la_OBJECTS) $(libeapsim_la_DEPENDENCIES)
- $(libeapsim_la_LINK) $(am_libeapsim_la_rpath) $(libeapsim_la_OBJECTS) $(libeapsim_la_LIBADD) $(LIBS)
-liblocal.la: $(liblocal_la_OBJECTS) $(liblocal_la_DEPENDENCIES)
- $(liblocal_la_LINK) -rpath $(backenddir) $(liblocal_la_OBJECTS) $(liblocal_la_LIBADD) $(LIBS)
-libsqlite.la: $(libsqlite_la_OBJECTS) $(libsqlite_la_DEPENDENCIES)
- $(libsqlite_la_LINK) $(am_libsqlite_la_rpath) $(libsqlite_la_OBJECTS) $(libsqlite_la_LIBADD) $(LIBS)
-libstroke.la: $(libstroke_la_OBJECTS) $(libstroke_la_DEPENDENCIES)
- $(libstroke_la_LINK) -rpath $(interfacedir) $(libstroke_la_OBJECTS) $(libstroke_la_LIBADD) $(LIBS)
-libxml.la: $(libxml_la_OBJECTS) $(libxml_la_DEPENDENCIES)
- $(libxml_la_LINK) $(am_libxml_la_rpath) $(libxml_la_OBJECTS) $(libxml_la_LIBADD) $(LIBS)
+libcharon-dbus.la: $(libcharon_dbus_la_OBJECTS) $(libcharon_dbus_la_DEPENDENCIES)
+ $(libcharon_dbus_la_LINK) $(am_libcharon_dbus_la_rpath) $(libcharon_dbus_la_OBJECTS) $(libcharon_dbus_la_LIBADD) $(LIBS)
+libcharon-eapaka.la: $(libcharon_eapaka_la_OBJECTS) $(libcharon_eapaka_la_DEPENDENCIES)
+ $(libcharon_eapaka_la_LINK) $(am_libcharon_eapaka_la_rpath) $(libcharon_eapaka_la_OBJECTS) $(libcharon_eapaka_la_LIBADD) $(LIBS)
+libcharon-eapidentity.la: $(libcharon_eapidentity_la_OBJECTS) $(libcharon_eapidentity_la_DEPENDENCIES)
+ $(libcharon_eapidentity_la_LINK) $(am_libcharon_eapidentity_la_rpath) $(libcharon_eapidentity_la_OBJECTS) $(libcharon_eapidentity_la_LIBADD) $(LIBS)
+libcharon-eapmd5.la: $(libcharon_eapmd5_la_OBJECTS) $(libcharon_eapmd5_la_DEPENDENCIES)
+ $(libcharon_eapmd5_la_LINK) $(am_libcharon_eapmd5_la_rpath) $(libcharon_eapmd5_la_OBJECTS) $(libcharon_eapmd5_la_LIBADD) $(LIBS)
+libcharon-eapsim.la: $(libcharon_eapsim_la_OBJECTS) $(libcharon_eapsim_la_DEPENDENCIES)
+ $(libcharon_eapsim_la_LINK) $(am_libcharon_eapsim_la_rpath) $(libcharon_eapsim_la_OBJECTS) $(libcharon_eapsim_la_LIBADD) $(LIBS)
+libcharon-local.la: $(libcharon_local_la_OBJECTS) $(libcharon_local_la_DEPENDENCIES)
+ $(libcharon_local_la_LINK) $(am_libcharon_local_la_rpath) $(libcharon_local_la_OBJECTS) $(libcharon_local_la_LIBADD) $(LIBS)
+libcharon-sqlite.la: $(libcharon_sqlite_la_OBJECTS) $(libcharon_sqlite_la_DEPENDENCIES)
+ $(libcharon_sqlite_la_LINK) $(am_libcharon_sqlite_la_rpath) $(libcharon_sqlite_la_OBJECTS) $(libcharon_sqlite_la_LIBADD) $(LIBS)
+libcharon-stroke.la: $(libcharon_stroke_la_OBJECTS) $(libcharon_stroke_la_DEPENDENCIES)
+ $(libcharon_stroke_la_LINK) $(am_libcharon_stroke_la_rpath) $(libcharon_stroke_la_OBJECTS) $(libcharon_stroke_la_LIBADD) $(LIBS)
+libcharon-xml.la: $(libcharon_xml_la_OBJECTS) $(libcharon_xml_la_DEPENDENCIES)
+ $(libcharon_xml_la_LINK) $(am_libcharon_xml_la_rpath) $(libcharon_xml_la_OBJECTS) $(libcharon_xml_la_LIBADD) $(LIBS)
install-ipsecPROGRAMS: $(ipsec_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(ipsecdir)" || $(MKDIR_P) "$(DESTDIR)$(ipsecdir)"
@@ -756,8 +831,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/delete_child_sa_job.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/delete_ike_sa_job.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/delete_payload.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_aka.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_authenticator.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_identity.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_md5.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_method.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_payload.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_sim.Plo@am__quote@
@@ -768,6 +845,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generator.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id_payload.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_auth.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_auth_lifetime.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_cert.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_cfg.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ike_config.Po@am__quote@
@@ -814,6 +892,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/send_dpd_job.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/send_keepalive_job.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sender.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket-raw.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/socket.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sqlite_backend.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stroke_interface.Plo@am__quote@
@@ -857,6 +936,13 @@ dbus_interface.lo: control/interfaces/dbus_interface.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dbus_interface.lo `test -f 'control/interfaces/dbus_interface.c' || echo '$(srcdir)/'`control/interfaces/dbus_interface.c
+eap_aka.lo: sa/authenticators/eap/eap_aka.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eap_aka.lo -MD -MP -MF $(DEPDIR)/eap_aka.Tpo -c -o eap_aka.lo `test -f 'sa/authenticators/eap/eap_aka.c' || echo '$(srcdir)/'`sa/authenticators/eap/eap_aka.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/eap_aka.Tpo $(DEPDIR)/eap_aka.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/authenticators/eap/eap_aka.c' object='eap_aka.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eap_aka.lo `test -f 'sa/authenticators/eap/eap_aka.c' || echo '$(srcdir)/'`sa/authenticators/eap/eap_aka.c
+
eap_identity.lo: sa/authenticators/eap/eap_identity.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eap_identity.lo -MD -MP -MF $(DEPDIR)/eap_identity.Tpo -c -o eap_identity.lo `test -f 'sa/authenticators/eap/eap_identity.c' || echo '$(srcdir)/'`sa/authenticators/eap/eap_identity.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/eap_identity.Tpo $(DEPDIR)/eap_identity.Plo
@@ -864,6 +950,13 @@ eap_identity.lo: sa/authenticators/eap/eap_identity.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eap_identity.lo `test -f 'sa/authenticators/eap/eap_identity.c' || echo '$(srcdir)/'`sa/authenticators/eap/eap_identity.c
+eap_md5.lo: sa/authenticators/eap/eap_md5.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eap_md5.lo -MD -MP -MF $(DEPDIR)/eap_md5.Tpo -c -o eap_md5.lo `test -f 'sa/authenticators/eap/eap_md5.c' || echo '$(srcdir)/'`sa/authenticators/eap/eap_md5.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/eap_md5.Tpo $(DEPDIR)/eap_md5.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/authenticators/eap/eap_md5.c' object='eap_md5.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o eap_md5.lo `test -f 'sa/authenticators/eap/eap_md5.c' || echo '$(srcdir)/'`sa/authenticators/eap/eap_md5.c
+
eap_sim.lo: sa/authenticators/eap/eap_sim.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT eap_sim.lo -MD -MP -MF $(DEPDIR)/eap_sim.Tpo -c -o eap_sim.lo `test -f 'sa/authenticators/eap/eap_sim.c' || echo '$(srcdir)/'`sa/authenticators/eap/eap_sim.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/eap_sim.Tpo $(DEPDIR)/eap_sim.Plo
@@ -1473,20 +1566,6 @@ sender.obj: network/sender.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sender.obj `if test -f 'network/sender.c'; then $(CYGPATH_W) 'network/sender.c'; else $(CYGPATH_W) '$(srcdir)/network/sender.c'; fi`
-socket.o: network/socket.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT socket.o -MD -MP -MF $(DEPDIR)/socket.Tpo -c -o socket.o `test -f 'network/socket.c' || echo '$(srcdir)/'`network/socket.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/socket.Tpo $(DEPDIR)/socket.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='network/socket.c' object='socket.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o socket.o `test -f 'network/socket.c' || echo '$(srcdir)/'`network/socket.c
-
-socket.obj: network/socket.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT socket.obj -MD -MP -MF $(DEPDIR)/socket.Tpo -c -o socket.obj `if test -f 'network/socket.c'; then $(CYGPATH_W) 'network/socket.c'; else $(CYGPATH_W) '$(srcdir)/network/socket.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/socket.Tpo $(DEPDIR)/socket.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='network/socket.c' object='socket.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o socket.obj `if test -f 'network/socket.c'; then $(CYGPATH_W) 'network/socket.c'; else $(CYGPATH_W) '$(srcdir)/network/socket.c'; fi`
-
acquire_job.o: processing/jobs/acquire_job.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT acquire_job.o -MD -MP -MF $(DEPDIR)/acquire_job.Tpo -c -o acquire_job.o `test -f 'processing/jobs/acquire_job.c' || echo '$(srcdir)/'`processing/jobs/acquire_job.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/acquire_job.Tpo $(DEPDIR)/acquire_job.Po
@@ -1991,6 +2070,20 @@ ike_reauth.obj: sa/tasks/ike_reauth.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_reauth.obj `if test -f 'sa/tasks/ike_reauth.c'; then $(CYGPATH_W) 'sa/tasks/ike_reauth.c'; else $(CYGPATH_W) '$(srcdir)/sa/tasks/ike_reauth.c'; fi`
+ike_auth_lifetime.o: sa/tasks/ike_auth_lifetime.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_auth_lifetime.o -MD -MP -MF $(DEPDIR)/ike_auth_lifetime.Tpo -c -o ike_auth_lifetime.o `test -f 'sa/tasks/ike_auth_lifetime.c' || echo '$(srcdir)/'`sa/tasks/ike_auth_lifetime.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_auth_lifetime.Tpo $(DEPDIR)/ike_auth_lifetime.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/tasks/ike_auth_lifetime.c' object='ike_auth_lifetime.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_auth_lifetime.o `test -f 'sa/tasks/ike_auth_lifetime.c' || echo '$(srcdir)/'`sa/tasks/ike_auth_lifetime.c
+
+ike_auth_lifetime.obj: sa/tasks/ike_auth_lifetime.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ike_auth_lifetime.obj -MD -MP -MF $(DEPDIR)/ike_auth_lifetime.Tpo -c -o ike_auth_lifetime.obj `if test -f 'sa/tasks/ike_auth_lifetime.c'; then $(CYGPATH_W) 'sa/tasks/ike_auth_lifetime.c'; else $(CYGPATH_W) '$(srcdir)/sa/tasks/ike_auth_lifetime.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ike_auth_lifetime.Tpo $(DEPDIR)/ike_auth_lifetime.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sa/tasks/ike_auth_lifetime.c' object='ike_auth_lifetime.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ike_auth_lifetime.obj `if test -f 'sa/tasks/ike_auth_lifetime.c'; then $(CYGPATH_W) 'sa/tasks/ike_auth_lifetime.c'; else $(CYGPATH_W) '$(srcdir)/sa/tasks/ike_auth_lifetime.c'; fi`
+
task.o: sa/tasks/task.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT task.o -MD -MP -MF $(DEPDIR)/task.Tpo -c -o task.o `test -f 'sa/tasks/task.c' || echo '$(srcdir)/'`sa/tasks/task.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/task.Tpo $(DEPDIR)/task.Po
@@ -2005,6 +2098,34 @@ task.obj: sa/tasks/task.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o task.obj `if test -f 'sa/tasks/task.c'; then $(CYGPATH_W) 'sa/tasks/task.c'; else $(CYGPATH_W) '$(srcdir)/sa/tasks/task.c'; fi`
+socket-raw.o: network/socket-raw.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT socket-raw.o -MD -MP -MF $(DEPDIR)/socket-raw.Tpo -c -o socket-raw.o `test -f 'network/socket-raw.c' || echo '$(srcdir)/'`network/socket-raw.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/socket-raw.Tpo $(DEPDIR)/socket-raw.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='network/socket-raw.c' object='socket-raw.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o socket-raw.o `test -f 'network/socket-raw.c' || echo '$(srcdir)/'`network/socket-raw.c
+
+socket-raw.obj: network/socket-raw.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT socket-raw.obj -MD -MP -MF $(DEPDIR)/socket-raw.Tpo -c -o socket-raw.obj `if test -f 'network/socket-raw.c'; then $(CYGPATH_W) 'network/socket-raw.c'; else $(CYGPATH_W) '$(srcdir)/network/socket-raw.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/socket-raw.Tpo $(DEPDIR)/socket-raw.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='network/socket-raw.c' object='socket-raw.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o socket-raw.obj `if test -f 'network/socket-raw.c'; then $(CYGPATH_W) 'network/socket-raw.c'; else $(CYGPATH_W) '$(srcdir)/network/socket-raw.c'; fi`
+
+socket.o: network/socket.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT socket.o -MD -MP -MF $(DEPDIR)/socket.Tpo -c -o socket.o `test -f 'network/socket.c' || echo '$(srcdir)/'`network/socket.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/socket.Tpo $(DEPDIR)/socket.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='network/socket.c' object='socket.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o socket.o `test -f 'network/socket.c' || echo '$(srcdir)/'`network/socket.c
+
+socket.obj: network/socket.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT socket.obj -MD -MP -MF $(DEPDIR)/socket.Tpo -c -o socket.obj `if test -f 'network/socket.c'; then $(CYGPATH_W) 'network/socket.c'; else $(CYGPATH_W) '$(srcdir)/network/socket.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/socket.Tpo $(DEPDIR)/socket.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='network/socket.c' object='socket.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o socket.obj `if test -f 'network/socket.c'; then $(CYGPATH_W) 'network/socket.c'; else $(CYGPATH_W) '$(srcdir)/network/socket.c'; fi`
+
endpoint_notify.o: encoding/payloads/endpoint_notify.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT endpoint_notify.o -MD -MP -MF $(DEPDIR)/endpoint_notify.Tpo -c -o endpoint_notify.o `test -f 'encoding/payloads/endpoint_notify.c' || echo '$(srcdir)/'`encoding/payloads/endpoint_notify.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/endpoint_notify.Tpo $(DEPDIR)/endpoint_notify.Po
diff --git a/src/charon/bus/bus.c b/src/charon/bus/bus.c
index 5fda36925..e53ac43ce 100644
--- a/src/charon/bus/bus.c
+++ b/src/charon/bus/bus.c
@@ -24,6 +24,8 @@
#include <pthread.h>
+#include <daemon.h>
+
ENUM(signal_names, SIG_ANY, SIG_MAX,
/** should not get printed */
"SIG_ANY",
@@ -53,104 +55,74 @@ ENUM(signal_names, SIG_ANY, SIG_MAX,
"SIG_MAX",
);
-typedef struct active_listener_t active_listener_t;
+typedef struct private_bus_t private_bus_t;
/**
- * information for a active listener
+ * Private data of a bus_t object.
*/
-struct active_listener_t {
-
- /**
- * associated thread
- */
- pthread_t id;
-
- /**
- * condvar to wait for a signal
- */
- pthread_cond_t cond;
-
- /**
- * state of the thread
- */
- enum {
- /** not registered, do not wait for thread */
- UNREGISTERED,
- /** registered, if a signal occurs, wait until it is LISTENING */
- REGISTERED,
- /** listening, deliver signal */
- LISTENING,
- } state;
-
- /**
- * currently processed signals type
- */
- signal_t signal;
-
+struct private_bus_t {
/**
- * verbosity level of the signal
+ * Public part of a bus_t object.
*/
- level_t level;
+ bus_t public;
/**
- * current processed signals thread number
+ * List of registered listeners as entry_t's
*/
- int thread;
+ linked_list_t *listeners;
/**
- * currently processed signals ike_sa
+ * mutex to synchronize active listeners
*/
- ike_sa_t *ike_sa;
+ pthread_mutex_t mutex;
/**
- * currently processed signals format string
+ * Thread local storage for a unique, simple thread ID
*/
- char *format;
+ pthread_key_t thread_id;
/**
- * currently processed signals format varargs
+ * Thread local storage the threads IKE_SA
*/
- va_list args;
-
+ pthread_key_t thread_sa;
};
-typedef struct private_bus_t private_bus_t;
+typedef struct entry_t entry_t;
/**
- * Private data of a bus_t object.
+ * a listener entry, either active or passive
*/
-struct private_bus_t {
- /**
- * Public part of a bus_t object.
- */
- bus_t public;
-
- /**
- * List of registered listeners implementing the bus_t interface
- */
- linked_list_t *listeners;
-
+struct entry_t {
+
/**
- * List of active listeners with listener_state TRUE
+ * registered listener interface
*/
- linked_list_t *active_listeners;
+ bus_listener_t *listener;
/**
- * mutex to synchronize active listeners
+ * is this a active listen() call with a blocking thread
*/
- pthread_mutex_t mutex;
+ bool blocker;
/**
- * Thread local storage for a unique, simple thread ID
+ * condvar where active listeners wait
*/
- pthread_key_t thread_id;
+ pthread_cond_t cond;
+};
+
+/**
+ * create a listener entry
+ */
+static entry_t *entry_create(bus_listener_t *listener, bool blocker)
+{
+ entry_t *this = malloc_thing(entry_t);
- /**
- * Thread local storage the threads IKE_SA
- */
- pthread_key_t thread_sa;
+ this->listener = listener;
+ this->blocker = blocker;
+ pthread_cond_init(&this->cond, NULL);
-};
+ return this;
+}
/**
* Get a unique thread number for a calling thread. Since
@@ -160,7 +132,7 @@ struct private_bus_t {
static int get_thread_number(private_bus_t *this)
{
static long current_num = 0;
- static long stored_num;
+ long stored_num;
stored_num = (long)pthread_getspecific(this->thread_id);
if (stored_num == 0)
@@ -180,7 +152,7 @@ static int get_thread_number(private_bus_t *this)
static void add_listener(private_bus_t *this, bus_listener_t *listener)
{
pthread_mutex_lock(&this->mutex);
- this->listeners->insert_last(this->listeners, listener);
+ this->listeners->insert_last(this->listeners, entry_create(listener, FALSE));
pthread_mutex_unlock(&this->mutex);
}
@@ -190,15 +162,16 @@ static void add_listener(private_bus_t *this, bus_listener_t *listener)
static void remove_listener(private_bus_t *this, bus_listener_t *listener)
{
iterator_t *iterator;
- bus_listener_t *current;
+ entry_t *entry;
pthread_mutex_lock(&this->mutex);
iterator = this->listeners->create_iterator(this->listeners, TRUE);
- while (iterator->iterate(iterator, (void**)&current))
+ while (iterator->iterate(iterator, (void**)&entry))
{
- if (current == listener)
+ if (entry->listener == listener)
{
iterator->remove(iterator);
+ free(entry);
break;
}
}
@@ -206,109 +179,67 @@ static void remove_listener(private_bus_t *this, bus_listener_t *listener)
pthread_mutex_unlock(&this->mutex);
}
+typedef struct cleanup_data_t cleanup_data_t;
+
+/**
+ * data to remove a listener using pthread_cleanup handler
+ */
+struct cleanup_data_t {
+ /** bus instance */
+ private_bus_t *this;
+ /** listener entry */
+ entry_t *entry;
+};
+
/**
- * Get the listener object for the calling thread
+ * pthread_cleanup handler to remove a listener
*/
-static active_listener_t *get_active_listener(private_bus_t *this)
+static void listener_cleanup(cleanup_data_t *data)
{
- active_listener_t *current, *found = NULL;
iterator_t *iterator;
-
- /* if the thread was here once before, we have a active_listener record */
- iterator = this->active_listeners->create_iterator(this->active_listeners, TRUE);
- while (iterator->iterate(iterator, (void**)&current))
+ entry_t *entry;
+
+ iterator = data->this->listeners->create_iterator(data->this->listeners, TRUE);
+ while (iterator->iterate(iterator, (void**)&entry))
{
- if (current->id == pthread_self())
+ if (entry == data->entry)
{
- found = current;
+ iterator->remove(iterator);
+ free(entry);
break;
}
}
iterator->destroy(iterator);
-
- if (found == NULL)
- {
- /* create a new object for a never-seen thread */
- found = malloc_thing(active_listener_t);
- found->id = pthread_self();
- pthread_cond_init(&found->cond, NULL);
- this->active_listeners->insert_last(this->active_listeners, found);
- }
-
- return found;
-}
-
-/**
- * disable a listener to cleanly clean up
- */
-static void unregister(active_listener_t *listener)
-{
- listener->state = UNREGISTERED;
- pthread_cond_broadcast(&listener->cond);
}
/**
* Implementation of bus_t.listen.
*/
-static signal_t listen_(private_bus_t *this, level_t *level, int *thread,
- ike_sa_t **ike_sa, char** format, va_list* args)
+static void listen_(private_bus_t *this, bus_listener_t *listener, job_t *job)
{
- active_listener_t *listener;
- int oldstate;
-
- pthread_mutex_lock(&this->mutex);
- listener = get_active_listener(this);
- /* go "listening", say hello to a thread which have a signal for us */
- listener->state = LISTENING;
- pthread_cond_broadcast(&listener->cond);
- /* wait until it has us delivered a signal, and go back to "registered".
- * we allow cancellation here, but must cleanly disable the listener. */
- pthread_cleanup_push((void*)pthread_mutex_unlock, &this->mutex);
- pthread_cleanup_push((void*)unregister, listener);
- pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
- pthread_cond_wait(&listener->cond, &this->mutex);
- pthread_setcancelstate(oldstate, NULL);
- pthread_cleanup_pop(0);
- pthread_cleanup_pop(0);
-
- pthread_mutex_unlock(&this->mutex);
-
- /* return signal values */
- *level = listener->level;
- *thread = listener->thread;
- *ike_sa = listener->ike_sa;
- *format = listener->format;
- va_copy(*args, listener->args);
- va_end(listener->args);
+ int old;
+ cleanup_data_t data;
- return listener->signal;
-}
+ data.this = this;
+ data.entry = entry_create(listener, TRUE);
-/**
- * Implementation of bus_t.set_listen_state.
- */
-static void set_listen_state(private_bus_t *this, bool active)
-{
- active_listener_t *listener;
-
pthread_mutex_lock(&this->mutex);
-
- listener = get_active_listener(this);
- if (active)
- {
- listener->state = REGISTERED;
- }
- else
+ this->listeners->insert_last(this->listeners, data.entry);
+ charon->processor->queue_job(charon->processor, job);
+ pthread_cleanup_push((void*)pthread_mutex_unlock, &this->mutex);
+ pthread_cleanup_push((void*)listener_cleanup, &data);
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old);
+ while (data.entry->blocker)
{
- listener->state = UNREGISTERED;
- /* say hello to signal emitter; we are finished processing the signal */
- pthread_cond_broadcast(&listener->cond);
+ pthread_cond_wait(&data.entry->cond, &this->mutex);
}
-
- pthread_mutex_unlock(&this->mutex);
+ pthread_setcancelstate(old, NULL);
+ pthread_cleanup_pop(FALSE);
+ /* unlock mutex */
+ pthread_cleanup_pop(TRUE);
+ free(data.entry);
}
-
/**
* Implementation of bus_t.set_sa.
*/
@@ -324,72 +255,37 @@ static void vsignal(private_bus_t *this, signal_t signal, level_t level,
char* format, va_list args)
{
iterator_t *iterator;
- bus_listener_t *listener;
- active_listener_t *active_listener;
+ entry_t *entry;
ike_sa_t *ike_sa;
long thread;
+ pthread_mutex_lock(&this->mutex);
ike_sa = pthread_getspecific(this->thread_sa);
thread = get_thread_number(this);
- pthread_mutex_lock(&this->mutex);
-
- /* do the job for all passive bus_listeners */
iterator = this->listeners->create_iterator(this->listeners, TRUE);
- while (iterator->iterate(iterator, (void**)&listener))
+ while (iterator->iterate(iterator, (void**)&entry))
{
va_list args_copy;
va_copy(args_copy, args);
- if (!listener->signal(listener, signal, level, thread,
- ike_sa, format, args_copy))
+ if (!entry->listener->signal(entry->listener, signal, level, thread,
+ ike_sa, format, args_copy))
{
- /* unregister listener if requested */
iterator->remove(iterator);
+ if (entry->blocker)
+ {
+ entry->blocker = FALSE;
+ pthread_cond_signal(&entry->cond);
+ }
+ else
+ {
+ free(entry);
+ }
}
va_end(args_copy);
}
iterator->destroy(iterator);
- /* wake up all active listeners */
- iterator = this->active_listeners->create_iterator(this->active_listeners, TRUE);
- while (iterator->iterate(iterator, (void**)&active_listener))
- {
- /* wait until all threads are registered. But if the thread raising
- * the signal is the same as the one that listens, we skip it.
- * Otherwise we would deadlock. */
- while (active_listener->id != pthread_self() &&
- active_listener->state == REGISTERED)
- {
- pthread_cond_wait(&active_listener->cond, &this->mutex);
- }
- /* if thread is listening now, give it the signal to process */
- if (active_listener->state == LISTENING)
- {
- active_listener->level = level;
- active_listener->thread = thread;
- active_listener->ike_sa = ike_sa;
- active_listener->signal = signal;
- active_listener->format = format;
- va_copy(active_listener->args, args);
- active_listener->state = REGISTERED;
- pthread_cond_broadcast(&active_listener->cond);
- }
- }
-
- /* we must wait now until all are not in state REGISTERED,
- * as they may still use our arguments */
- iterator->reset(iterator);
- while (iterator->iterate(iterator, (void**)&active_listener))
- {
- /* do not wait for ourself, it won't happen (see above) */
- while (active_listener->id != pthread_self() &&
- active_listener->state == REGISTERED)
- {
- pthread_cond_wait(&active_listener->cond, &this->mutex);
- }
- }
- iterator->destroy(iterator);
-
pthread_mutex_unlock(&this->mutex);
}
@@ -411,8 +307,7 @@ static void signal_(private_bus_t *this, signal_t signal, level_t level,
*/
static void destroy(private_bus_t *this)
{
- this->active_listeners->destroy_function(this->active_listeners, free);
- this->listeners->destroy(this->listeners);
+ this->listeners->destroy_function(this->listeners, free);
free(this);
}
@@ -425,18 +320,17 @@ bus_t *bus_create()
this->public.add_listener = (void(*)(bus_t*,bus_listener_t*))add_listener;
this->public.remove_listener = (void(*)(bus_t*,bus_listener_t*))remove_listener;
- this->public.listen = (signal_t(*)(bus_t*,level_t*,int*,ike_sa_t**,char**,va_list*))listen_;
- this->public.set_listen_state = (void(*)(bus_t*,bool))set_listen_state;
+ this->public.listen = (void(*)(bus_t*, bus_listener_t *listener, job_t *job))listen_;
this->public.set_sa = (void(*)(bus_t*,ike_sa_t*))set_sa;
this->public.signal = (void(*)(bus_t*,signal_t,level_t,char*,...))signal_;
this->public.vsignal = (void(*)(bus_t*,signal_t,level_t,char*,va_list))vsignal;
this->public.destroy = (void(*)(bus_t*)) destroy;
this->listeners = linked_list_create();
- this->active_listeners = linked_list_create();
pthread_mutex_init(&this->mutex, NULL);
pthread_key_create(&this->thread_id, NULL);
pthread_key_create(&this->thread_sa, NULL);
- return &(this->public);
+ return &this->public;
}
+
diff --git a/src/charon/bus/bus.h b/src/charon/bus/bus.h
index 00f1ab7ac..f71018444 100644
--- a/src/charon/bus/bus.h
+++ b/src/charon/bus/bus.h
@@ -32,6 +32,7 @@ typedef struct bus_t bus_t;
#include <sa/ike_sa.h>
#include <sa/child_sa.h>
+#include <processing/jobs/job.h>
/**
@@ -251,9 +252,7 @@ struct bus_listener_t {
* in receiving event signals registers at the bus. Any signals sent to
* are delivered to all registered listeners.
* To deliver signals to threads, the blocking listen() call may be used
- * to wait for a signal. However, passive listeners should be preferred,
- * as listening actively requires some synchronization overhead as data
- * must be passed from the raising thread to the listening thread.
+ * to wait for a signal.
*
* @ingroup bus
*/
@@ -280,44 +279,19 @@ struct bus_t {
void (*remove_listener) (bus_t *this, bus_listener_t *listener);
/**
- * @brief Listen actively on the bus.
+ * @brief Register a listener and block the calling thread.
*
- * As we are fully multithreaded, we must provide a mechanism
- * for active threads to listen to the bus. With the listen() method,
- * a thread waits until a signal occurs, and then processes it.
- * To prevent the listen() calling thread to miss signals emitted while
- * it processes a signal, registration is required. This is done through
- * the set_listen_state() method, see below.
- *
- * The listen() function is (has) a thread cancellation point, so you might
- * want to register cleanup handlers.
+ * This call registers a listener and blocks the calling thread until
+ * its listeners function returns FALSE. This allows to wait for certain
+ * events. The associated job is executed after the listener has been
+ * registered, this allows to listen on events we initiate with the job
+ * without missing any signals.
*
* @param this bus
- * @param level verbosity level of the signal
- * @param thread receives thread number emitted the signal
- * @param ike_sa receives the IKE_SA involved in the signal, or NULL
- * @param format receives the format string supplied with the signal
- * @param va_list receives the variable argument list for format
- * @return the emitted signal type
+ * @param listener listener to register
+ * @param job job to execute asynchronously when registered, or NULL
*/
- signal_t (*listen) (bus_t *this, level_t* level, int *thread,
- ike_sa_t **ike_sa, char** format, va_list* args);
-
- /**
- * @brief Set the listening state of the calling thread.
- *
- * To prevent message loss for active listeners using listen(), threads
- * must register themself to the bus before starting to listen(). When
- * a signal occurs, the emitter waits until all threads with listen_state
- * TRUE are waiting in the listen() method to process the signal.
- * It is important that a thread with listen_state TRUE calls listen()
- * periodically, or sets it's listening state to FALSE; otherwise
- * all signal emitting threads get blocked on the bus.
- *
- * @param this bus
- * @param active TRUE to set to listening
- */
- void (*set_listen_state) (bus_t *this, bool active);
+ void (*listen)(bus_t *this, bus_listener_t *listener, job_t *job);
/**
* @brief Set the IKE_SA the calling thread is using.
@@ -355,6 +329,10 @@ struct bus_t {
*
* Same as bus_t.signal(), but uses va_list argument list.
*
+ * @todo Improve performace of vsignal implementation. This method is
+ * called extensively and therefore shouldn't allocate heap memory or
+ * do other expensive tasks!
+ *
* @param this bus
* @param singal kind of the signal (up, down, rekeyed, ...)
* @param level verbosity level of the signal
diff --git a/src/charon/config/backends/sqlite_backend.c b/src/charon/config/backends/sqlite_backend.c
index 33093a735..e1c96c870 100644
--- a/src/charon/config/backends/sqlite_backend.c
+++ b/src/charon/config/backends/sqlite_backend.c
@@ -186,15 +186,15 @@ static peer_cfg_t *process_peer_cfg_row(private_sqlite_backend_t *this,
2, ike_cfg, local_id, remote_id, NULL, NULL, linked_list_create(),
sqlite3_column_int(stmt, 4), /* cert_policy */
sqlite3_column_int(stmt, 5), /* auth_method */
- sqlite3_column_int(stmt, 6), /* eap_type */
+ sqlite3_column_int(stmt, 6), 0 /* eap_type, vendor */
sqlite3_column_int(stmt, 7), /* keyingtries */
- sqlite3_column_int(stmt, 8), /* lifetime */
- sqlite3_column_int(stmt, 9), /* rekeytime */
- sqlite3_column_int(stmt, 10), /* jitter */
- sqlite3_column_int(stmt, 13), /* reauth */
+ sqlite3_column_int(stmt, 8), /* rekey_time */
+ sqlite3_column_int(stmt, 9), /* reauth_time */
+ sqlite3_column_int(stmt, 10), /* jitter_time */
+ sqlite3_column_int(stmt, 11), /* over_time */
sqlite3_column_int(stmt, 14), /* mobike */
- sqlite3_column_int(stmt, 11), /* dpd_delay */
- sqlite3_column_int(stmt, 12), /* dpd_action */
+ sqlite3_column_int(stmt, 12), /* dpd_delay */
+ sqlite3_column_int(stmt, 13), /* dpd_action */
local_vip, remote_vip, FALSE, NULL, NULL);
add_children(this, peer_cfg, sqlite3_column_int(stmt, 0));
return peer_cfg;
@@ -225,8 +225,9 @@ static peer_cfg_t *get_peer_cfg(private_sqlite_backend_t *this,
if (sqlite3_prepare_v2(this->db,
"SELECT peer_configs.oid, name, local_id, remote_id, cert_policy, "
- "auth_method, eap_type, keyingtries, lifetime, rekeytime, jitter, "
- "dpd_delay, dpd_action, reauth, mobike, local_vip, remote_vip, "
+ "auth_method, eap_type, keyingtries, "
+ "rekey_time, reauth_time, jitter_time, over_time, "
+ "dpd_delay, dpd_action, mobike, local_vip, remote_vip, "
"local, remote, certreq "
"FROM peer_configs, ike_configs "
"ON peer_configs.ike_cfg = ike_configs.oid "
diff --git a/src/charon/config/credentials/local_credential_store.c b/src/charon/config/credentials/local_credential_store.c
index b71e9e9e2..b838f032d 100644
--- a/src/charon/config/credentials/local_credential_store.c
+++ b/src/charon/config/credentials/local_credential_store.c
@@ -18,6 +18,8 @@
* 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.
+ *
+ * RCSID $Id: local_credential_store.c 3346 2007-11-16 20:23:29Z andreas $
*/
#include <sys/stat.h>
@@ -1394,7 +1396,7 @@ static void load_secrets(private_local_credential_store_t *this, bool reload)
{
continue;
}
- if (!extract_token(&ids, ':', &line))
+ if (!extract_last_token(&ids, ':', &line))
{
DBG1(DBG_CFG, "line %d: missing ':' separator", line_nr);
goto error;
diff --git a/src/charon/config/peer_cfg.c b/src/charon/config/peer_cfg.c
index d61ed9512..0b5d391c4 100644
--- a/src/charon/config/peer_cfg.c
+++ b/src/charon/config/peer_cfg.c
@@ -127,14 +127,14 @@ struct private_peer_cfg_t {
eap_type_t eap_type;
/**
- * number of tries after giving up if peer does not respond
+ * EAP vendor ID if vendor specific type is used
*/
- u_int32_t keyingtries;
+ u_int32_t eap_vendor;
/**
- * user reauthentication instead of rekeying
+ * number of tries after giving up if peer does not respond
*/
- bool use_reauth;
+ u_int32_t keyingtries;
/**
* enable support for MOBIKE
@@ -142,20 +142,24 @@ struct private_peer_cfg_t {
bool use_mobike;
/**
- * Time before an SA gets invalid
+ * Time before starting rekeying
+ */
+ u_int32_t rekey_time;
+
+ /**
+ * Time before starting reauthentication
*/
- u_int32_t lifetime;
+ u_int32_t reauth_time;
/**
- * Time before an SA gets rekeyed
+ * Time, which specifies the range of a random value substracted from above.
*/
- u_int32_t rekeytime;
+ u_int32_t jitter_time;
/**
- * Time, which specifies the range of a random value
- * substracted from lifetime.
+ * Delay before deleting a rekeying/reauthenticating SA
*/
- u_int32_t jitter;
+ u_int32_t over_time;
/**
* What to do with an SA when other peer seams to be dead?
@@ -339,8 +343,9 @@ static auth_method_t get_auth_method(private_peer_cfg_t *this)
/**
* Implementation of connection_t.get_eap_type.
*/
-static eap_type_t get_eap_type(private_peer_cfg_t *this)
+static eap_type_t get_eap_type(private_peer_cfg_t *this, u_int32_t *vendor)
{
+ *vendor = this->eap_vendor;
return this->eap_type;
}
@@ -353,29 +358,45 @@ static u_int32_t get_keyingtries(private_peer_cfg_t *this)
}
/**
- * Implementation of peer_cfg_t.get_soft_lifetime
+ * Implementation of peer_cfg_t.get_rekey_time.
*/
-static u_int32_t get_lifetime(private_peer_cfg_t *this, bool rekey)
+static u_int32_t get_rekey_time(private_peer_cfg_t *this)
{
- if (rekey)
+ if (this->rekey_time == 0)
{
- if (this->jitter == 0)
- {
- return this->rekeytime;
- }
- return this->rekeytime - (random() % this->jitter);
+ return 0;
+ }
+ if (this->jitter_time == 0)
+ {
+ return this->rekey_time;
}
- return this->lifetime;
+ return this->rekey_time - (random() % this->jitter_time);
}
-
+
+/**
+ * Implementation of peer_cfg_t.get_reauth_time.
+ */
+static u_int32_t get_reauth_time(private_peer_cfg_t *this)
+{
+ if (this->reauth_time == 0)
+ {
+ return 0;
+ }
+ if (this->jitter_time == 0)
+ {
+ return this->reauth_time;
+ }
+ return this->reauth_time - (random() % this->jitter_time);
+}
+
/**
- * Implementation of peer_cfg_t.use_reauth.
+ * Implementation of peer_cfg_t.get_over_time.
*/
-static bool use_reauth(private_peer_cfg_t *this)
+static u_int32_t get_over_time(private_peer_cfg_t *this)
{
- return this->use_reauth;
+ return this->over_time;
}
-
+
/**
* Implementation of peer_cfg_t.use_mobike.
*/
@@ -503,9 +524,10 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
identification_t *my_ca, identification_t *other_ca,
linked_list_t *groups, cert_policy_t cert_policy,
auth_method_t auth_method, eap_type_t eap_type,
- u_int32_t keyingtries, u_int32_t lifetime,
- u_int32_t rekeytime, u_int32_t jitter,
- bool reauth, bool mobike,
+ u_int32_t eap_vendor,
+ u_int32_t keyingtries, u_int32_t rekey_time,
+ u_int32_t reauth_time, u_int32_t jitter_time,
+ u_int32_t over_time, bool mobike,
u_int32_t dpd_delay, dpd_action_t dpd_action,
host_t *my_virtual_ip, host_t *other_virtual_ip,
bool p2p_mediation, peer_cfg_t *p2p_mediated_by,
@@ -527,10 +549,11 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
this->public.get_groups = (linked_list_t* (*)(peer_cfg_t *))get_groups;
this->public.get_cert_policy = (cert_policy_t (*) (peer_cfg_t *))get_cert_policy;
this->public.get_auth_method = (auth_method_t (*) (peer_cfg_t *))get_auth_method;
- this->public.get_eap_type = (eap_type_t (*) (peer_cfg_t *))get_eap_type;
+ this->public.get_eap_type = (eap_type_t (*) (peer_cfg_t *,u_int32_t*))get_eap_type;
this->public.get_keyingtries = (u_int32_t (*) (peer_cfg_t *))get_keyingtries;
- this->public.get_lifetime = (u_int32_t (*) (peer_cfg_t *, bool rekey))get_lifetime;
- this->public.use_reauth = (bool (*) (peer_cfg_t *))use_reauth;
+ this->public.get_rekey_time = (u_int32_t(*)(peer_cfg_t*))get_rekey_time;
+ this->public.get_reauth_time = (u_int32_t(*)(peer_cfg_t*))get_reauth_time;
+ this->public.get_over_time = (u_int32_t(*)(peer_cfg_t*))get_over_time;
this->public.use_mobike = (bool (*) (peer_cfg_t *))use_mobike;
this->public.get_dpd_delay = (u_int32_t (*) (peer_cfg_t *))get_dpd_delay;
this->public.get_dpd_action = (dpd_action_t (*) (peer_cfg_t *))get_dpd_action;
@@ -558,11 +581,20 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
this->cert_policy = cert_policy;
this->auth_method = auth_method;
this->eap_type = eap_type;
+ this->eap_vendor = eap_vendor;
this->keyingtries = keyingtries;
- this->lifetime = lifetime;
- this->rekeytime = rekeytime;
- this->jitter = jitter;
- this->use_reauth = reauth;
+ this->rekey_time = rekey_time;
+ this->reauth_time = reauth_time;
+ if (rekey_time && jitter_time > rekey_time)
+ {
+ jitter_time = rekey_time;
+ }
+ if (reauth_time && jitter_time > reauth_time)
+ {
+ jitter_time = reauth_time;
+ }
+ this->jitter_time = jitter_time;
+ this->over_time = over_time;
this->use_mobike = mobike;
this->dpd_delay = dpd_delay;
this->dpd_action = dpd_action;
diff --git a/src/charon/config/peer_cfg.h b/src/charon/config/peer_cfg.h
index 3d238e6aa..7f1dbcab6 100644
--- a/src/charon/config/peer_cfg.h
+++ b/src/charon/config/peer_cfg.h
@@ -229,11 +229,16 @@ struct peer_cfg_t {
/**
* @brief Get the EAP type to use for peer authentication.
+ *
+ * If vendor specific types are used, a vendor ID != 0 is returned to
+ * to vendor argument. Then the returned type is specific for that
+ * vendor ID.
*
* @param this calling object
+ * @param vendor receives vendor specifier, 0 for predefined EAP types
* @return authentication method
*/
- eap_type_t (*get_eap_type) (peer_cfg_t *this);
+ eap_type_t (*get_eap_type) (peer_cfg_t *this, u_int32_t *vendor);
/**
* @brief Get the max number of retries after timeout.
@@ -244,27 +249,28 @@ struct peer_cfg_t {
u_int32_t (*get_keyingtries) (peer_cfg_t *this);
/**
- * @brief Get the lifetime of a IKE_SA.
+ * @brief Get a time to start rekeying (is randomized with jitter).
*
- * If "rekey" is set to TRUE, a lifetime is returned before the first
- * rekeying should be started. If it is FALSE, the actual lifetime is
- * returned when the IKE_SA must be deleted.
- * The rekey time automatically contains a jitter to avoid simlutaneous
- * rekeying.
- *
- * @param this child_config
- * @param rekey TRUE to get rekey time
- * @return lifetime in seconds
+ * @param this calling object
+ * @return time in s when to start rekeying, 0 disables rekeying
*/
- u_int32_t (*get_lifetime) (peer_cfg_t *this, bool rekey);
+ u_int32_t (*get_rekey_time)(peer_cfg_t *this);
/**
- * @brief Should a full reauthentication be done instead of rekeying?
- *
+ * @brief Get a time to start reauthentication (is randomized with jitter).
+ *
* @param this calling object
- * @return TRUE to use full reauthentication
+ * @return time in s when to start reauthentication, 0 disables it
+ */
+ u_int32_t (*get_reauth_time)(peer_cfg_t *this);
+
+ /**
+ * @brief Get the timeout of a rekeying/reauthenticating SA.
+ *
+ * @param thsi calling object
+ * @return timeout in s
*/
- bool (*use_reauth) (peer_cfg_t *this);
+ u_int32_t (*get_over_time)(peer_cfg_t *this);
/**
* @brief Use MOBIKE (RFC4555) if peer supports it?
@@ -392,10 +398,12 @@ struct peer_cfg_t {
* @param cert_policy should we send a certificate payload?
* @param auth_method auth method to use to authenticate us
* @param eap_type EAP type to use for peer authentication
+ * @param eap_vendor EAP vendor identifier, if vendor specific type is used
* @param keyingtries how many keying tries should be done before giving up
- * @param lifetime lifetime before deleting an SA
- * @param rekeytime lifetime before rekeying an SA
- * @param jitter range of random to substract from rekeytime
+ * @param rekey_time timeout before starting rekeying
+ * @param reauth_time timeout before starting reauthentication
+ * @param jitter_time timerange to randomly substract from rekey/reauth time
+ * @param over_time maximum overtime before closing a rekeying/reauth SA
* @param reauth sould be done reauthentication instead of rekeying?
* @param mobike use MOBIKE (RFC4555) if peer supports it
* @param dpd_delay after how many seconds of inactivity to check DPD
@@ -414,9 +422,10 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ikev_version, ike_cfg_t *ike_cfg,
identification_t *my_ca, identification_t *other_ca,
linked_list_t *groups, cert_policy_t cert_policy,
auth_method_t auth_method, eap_type_t eap_type,
- u_int32_t keyingtries, u_int32_t lifetime,
- u_int32_t rekeytime, u_int32_t jitter,
- bool reauth, bool mobike,
+ u_int32_t eap_vendor,
+ u_int32_t keyingtries, u_int32_t rekey_time,
+ u_int32_t reauth_time, u_int32_t jitter_time,
+ u_int32_t over_time, bool mobike,
u_int32_t dpd_delay, dpd_action_t dpd_action,
host_t *my_virtual_ip, host_t *other_virtual_ip,
bool p2p_mediation, peer_cfg_t *p2p_mediated_by,
diff --git a/src/charon/control/interface_manager.c b/src/charon/control/interface_manager.c
index c71036567..c14903c7d 100644
--- a/src/charon/control/interface_manager.c
+++ b/src/charon/control/interface_manager.c
@@ -56,18 +56,24 @@ struct private_interface_manager_t {
linked_list_t *handles;
};
+
/**
* helper struct to map bus listener callbacks to interface callbacks
*/
struct interface_bus_listener_t {
/**
- * bus listener callback function (called)
+ * public bus listener interface
*/
- bus_listener_t listener;
+ bus_listener_t public;
+
+ /**
+ * status of the operation, return to method callers
+ */
+ status_t status;
/**
- * IKE_SA to use for message filtering
+ * IKE SA to filter log output
*/
ike_sa_t *ike_sa;
@@ -82,12 +88,48 @@ struct interface_bus_listener_t {
void *param;
/**
- * caller has cancelled its listening subscription
+ * child configuration, used for initiate
+ */
+ child_cfg_t *child_cfg;
+
+ /**
+ * peer configuration, used for initiate
+ */
+ peer_cfg_t *peer_cfg;
+
+ /**
+ * unique ID, used for various methods
+ */
+ u_int32_t id;
+};
+
+
+typedef struct interface_job_t interface_job_t;
+
+/**
+ * job for asynchronous listen operations
+ */
+struct interface_job_t {
+ /**
+ * job interface
+ */
+ job_t public;
+
+ /**
+ * associated listener
*/
- bool cancelled;
+ interface_bus_listener_t listener;
};
/**
+ * Implements the famous nop operation
+ */
+static void nop(job_t *job)
+{
+ /* NOP */
+}
+
+/**
* Implementation of interface_manager_t.create_ike_sa_iterator.
*/
static iterator_t* create_ike_sa_iterator(interface_manager_t *this)
@@ -106,17 +148,16 @@ static bool initiate_listener(interface_bus_listener_t *this, signal_t signal,
{
if (!this->callback(this->param, signal, level, ike_sa, format, args))
{
- this->cancelled = TRUE;
return FALSE;
}
switch (signal)
{
+ case CHILD_UP_SUCCESS:
+ this->status = SUCCESS;
+ return FALSE;
case IKE_UP_FAILED:
case CHILD_UP_FAILED:
- case CHILD_UP_SUCCESS:
- {
return FALSE;
- }
default:
break;
}
@@ -125,112 +166,82 @@ static bool initiate_listener(interface_bus_listener_t *this, signal_t signal,
}
/**
- * listener function for terminate_ike
+ * execute function for initiate
*/
-static bool terminate_ike_listener(interface_bus_listener_t *this, signal_t signal,
- level_t level, int thread, ike_sa_t *ike_sa,
- char* format, va_list args)
+static status_t initiate_execute(interface_job_t *job)
{
- if (this->ike_sa == ike_sa)
+ ike_sa_t *ike_sa;
+ ike_cfg_t *ike_cfg;
+ interface_bus_listener_t *listener = &job->listener;
+ peer_cfg_t *peer_cfg = listener->peer_cfg;
+
+ ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
+ ike_sa = charon->ike_sa_manager->checkout_by_peer(charon->ike_sa_manager,
+ ike_cfg->get_my_host(ike_cfg), ike_cfg->get_other_host(ike_cfg),
+ peer_cfg->get_my_id(peer_cfg), peer_cfg->get_other_id(peer_cfg));
+ listener->ike_sa = ike_sa;
+
+ if (ike_sa->get_peer_cfg(ike_sa) == NULL)
{
- if (!this->callback(this->param, signal, level, ike_sa, format, args))
- {
- this->cancelled = TRUE;
- return FALSE;
- }
- switch (signal)
- {
- case IKE_DOWN_FAILED:
- case IKE_DOWN_SUCCESS:
- {
- return FALSE;
- }
- default:
- break;
- }
+ ike_sa->set_peer_cfg(ike_sa, peer_cfg);
}
- return TRUE;
-}
-
-/**
- * listener function for terminate_child
- */
-static bool terminate_child_listener(interface_bus_listener_t *this, signal_t signal,
- level_t level, int thread, ike_sa_t *ike_sa,
- char* format, va_list args)
-{
- if (this->ike_sa == ike_sa)
+ peer_cfg->destroy(peer_cfg);
+
+ if (ike_sa->initiate(ike_sa, listener->child_cfg) != SUCCESS)
{
- if (!this->callback(this->param, signal, level, ike_sa, format, args))
- {
- this->cancelled = TRUE;
- return FALSE;
- }
- switch (signal)
- {
- case IKE_DOWN_FAILED:
- case IKE_DOWN_SUCCESS:
- case CHILD_DOWN_FAILED:
- case CHILD_DOWN_SUCCESS:
- {
- return FALSE;
- }
- default:
- break;
- }
+ return charon->ike_sa_manager->checkin_and_destroy(
+ charon->ike_sa_manager, ike_sa);
}
- return TRUE;
+ return charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
}
/**
- * listener function for route
+ * Implementation of interface_manager_t.initiate.
*/
-static bool route_listener(interface_bus_listener_t *this, signal_t signal,
- level_t level, int thread, ike_sa_t *ike_sa,
- char* format, va_list args)
+static status_t initiate(private_interface_manager_t *this,
+ peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
+ interface_manager_cb_t callback, void *param)
{
- if (this->ike_sa == ike_sa)
+ interface_job_t job;
+
+ job.listener.public.signal = (void*)initiate_listener;
+ job.listener.ike_sa = NULL;
+ job.listener.callback = callback;
+ job.listener.param = param;
+ job.listener.status = FAILED;
+ job.listener.child_cfg = child_cfg;
+ job.listener.peer_cfg = peer_cfg;
+ job.public.execute = (void*)initiate_execute;
+ job.public.destroy = nop;
+
+ if (callback == NULL)
{
- if (!this->callback(this->param, signal, level, ike_sa, format, args))
- {
- this->cancelled = TRUE;
- return FALSE;
- }
- switch (signal)
- {
- case CHILD_ROUTE_SUCCESS:
- case CHILD_ROUTE_FAILED:
- {
- return FALSE;
- }
- default:
- break;
- }
+ return initiate_execute(&job);
}
- return TRUE;
+ charon->bus->listen(charon->bus, (bus_listener_t*)&job.listener, (job_t*)&job);
+ return job.listener.status;
}
/**
- * listener function for unroute
+ * listener function for terminate_ike
*/
-static bool unroute_listener(interface_bus_listener_t *this, signal_t signal,
- level_t level, int thread, ike_sa_t *ike_sa,
- char* format, va_list args)
+static bool terminate_ike_listener(interface_bus_listener_t *this, signal_t signal,
+ level_t level, int thread, ike_sa_t *ike_sa,
+ char* format, va_list args)
{
if (this->ike_sa == ike_sa)
{
if (!this->callback(this->param, signal, level, ike_sa, format, args))
{
- this->cancelled = TRUE;
return FALSE;
}
switch (signal)
{
- case CHILD_UNROUTE_SUCCESS:
- case CHILD_UNROUTE_FAILED:
- {
+ case IKE_DOWN_SUCCESS:
+ this->status = SUCCESS;
+ return FALSE;
+ case IKE_DOWN_FAILED:
return FALSE;
- }
default:
break;
}
@@ -239,102 +250,29 @@ static bool unroute_listener(interface_bus_listener_t *this, signal_t signal,
}
/**
- * remove a previously registered listener from the bus
+ * execute function for terminate_ike
*/
-static void remove_listener(interface_bus_listener_t *listener)
-{
- charon->bus->remove_listener(charon->bus, &listener->listener);
-}
-
-/**
- * Implementation of interface_manager_t.initiate.
- */
-static status_t initiate(private_interface_manager_t *this,
- peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
- interface_manager_cb_t callback, void *param)
+static status_t terminate_ike_execute(interface_job_t *job)
{
ike_sa_t *ike_sa;
- ike_cfg_t *ike_cfg;
- status_t retval = FAILED;
- interface_bus_listener_t listener;
+ interface_bus_listener_t *listener = &job->listener;
- ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
- ike_sa = charon->ike_sa_manager->checkout_by_peer(charon->ike_sa_manager,
- ike_cfg->get_my_host(ike_cfg), ike_cfg->get_other_host(ike_cfg),
- peer_cfg->get_my_id(peer_cfg), peer_cfg->get_other_id(peer_cfg));
-
- if (ike_sa->get_peer_cfg(ike_sa) == NULL)
- {
- ike_sa->set_peer_cfg(ike_sa, peer_cfg);
- }
- peer_cfg->destroy(peer_cfg);
-
- listener.listener.signal = (void*)initiate_listener;
- listener.callback = callback;
- listener.ike_sa = ike_sa;
- listener.param = param;
- listener.cancelled = FALSE;
-
- /* we listen passively to catch the signals we are raising in
- * ike_sa->delete(). */
- if (callback)
- {
- charon->bus->add_listener(charon->bus, &listener.listener);
- }
- charon->bus->set_listen_state(charon->bus, TRUE);
- if (ike_sa->initiate(ike_sa, child_cfg) != SUCCESS)
- {
- charon->bus->set_listen_state(charon->bus, FALSE);
- charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
- return FAILED;
- }
- charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
-
- if (callback == NULL)
+ ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
+ listener->id, FALSE);
+ if (ike_sa == NULL)
{
- /* don't wait for a result if no callback is specified */
- charon->bus->set_listen_state(charon->bus, FALSE);
- return NEED_MORE;
- }
+ SIG(IKE_DOWN_FAILED, "unable to terminate, IKE_SA with "
+ "ID %d not found", listener->id);
+ return NOT_FOUND;
+ }
+ listener->ike_sa = ike_sa;
- /* wait until we get a result */
- while (TRUE)
+ if (ike_sa->delete(ike_sa) == DESTROY_ME)
{
- level_t level;
- signal_t signal;
- int thread;
- ike_sa_t *current;
- char* format;
- va_list args;
-
- /* stop listening if the passive listener returned FALSE */
- if (listener.cancelled)
- {
- retval = NEED_MORE;
- break;
- }
- pthread_cleanup_push((void*)remove_listener, &listener);
- signal = charon->bus->listen(charon->bus, &level, &thread,
- &current, &format, &args);
- pthread_cleanup_pop(0);
- /* ike_sa is a valid pointer until we get one of the signals */
- if (ike_sa == current)
- {
- switch (signal)
- {
- case CHILD_UP_SUCCESS:
- retval = SUCCESS;
- case CHILD_UP_FAILED:
- case IKE_UP_FAILED:
- break;
- default:
- continue;
- }
- break;
- }
+ return charon->ike_sa_manager->checkin_and_destroy(
+ charon->ike_sa_manager, ike_sa);
}
- charon->bus->set_listen_state(charon->bus, FALSE);
- return retval;
+ return charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
}
/**
@@ -343,107 +281,78 @@ static status_t initiate(private_interface_manager_t *this,
static status_t terminate_ike(interface_manager_t *this, u_int32_t unique_id,
interface_manager_cb_t callback, void *param)
{
- ike_sa_t *ike_sa;
- status_t status = FAILED;;
- interface_bus_listener_t listener;
+ interface_job_t job;
- ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
- unique_id, FALSE);
- if (ike_sa == NULL)
- {
- return NOT_FOUND;
- }
-
- /* we listen passively to catch the signals we are raising in
- * ike_sa->delete(). */
- listener.listener.signal = (void*)terminate_ike_listener;
- listener.callback = callback;
- listener.ike_sa = ike_sa;
- listener.param = param;
- listener.cancelled = FALSE;
- if (callback)
- {
- charon->bus->add_listener(charon->bus, &listener.listener);
- }
- charon->bus->set_listen_state(charon->bus, TRUE);
- status = ike_sa->delete(ike_sa);
- if (status == DESTROY_ME)
+ job.listener.public.signal = (void*)terminate_ike_listener;
+ job.listener.ike_sa = NULL;
+ job.listener.callback = callback;
+ job.listener.param = param;
+ job.listener.status = FAILED;
+ job.listener.id = unique_id;
+ job.public.execute = (void*)terminate_ike_execute;
+ job.public.destroy = nop;
+
+ if (callback == NULL)
{
- charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
+ return terminate_ike_execute(&job);
}
- else
+ charon->bus->listen(charon->bus, (bus_listener_t*)&job.listener, (job_t*)&job);
+ return job.listener.status;
+}
+/**
+ * listener function for terminate_child
+ */
+static bool terminate_child_listener(interface_bus_listener_t *this, signal_t signal,
+ level_t level, int thread, ike_sa_t *ike_sa,
+ char* format, va_list args)
+{
+ if (this->ike_sa == ike_sa)
{
- charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
-
- /* wait until IKE_SA is cleanly deleted using a delete message */
- while (TRUE)
+ if (!this->callback(this->param, signal, level, ike_sa, format, args))
{
- level_t level;
- signal_t signal;
- int thread;
- ike_sa_t *current;
- char* format;
- va_list args;
-
- /* stop listening if the passive listener returned FALSE */
- if (listener.cancelled)
- {
- status = NEED_MORE;
- break;
- }
- pthread_cleanup_push((void*)remove_listener, &listener);
- signal = charon->bus->listen(charon->bus, &level, &thread,
- &current, &format, &args);
- pthread_cleanup_pop(0);
-
- /* even if we checked in the IKE_SA, the pointer is valid until
- * we get an IKE_DOWN_... */
- if (ike_sa == current)
- {
- switch (signal)
- {
- case IKE_DOWN_FAILED:
- case IKE_DOWN_SUCCESS:
- {
- status = SUCCESS;
- break;
- }
- default:
- continue;
- }
+ return FALSE;
+ }
+ switch (signal)
+ {
+ case CHILD_DOWN_SUCCESS:
+ case IKE_DOWN_SUCCESS:
+ this->status = SUCCESS;
+ return FALSE;
+ case IKE_DOWN_FAILED:
+ case CHILD_DOWN_FAILED:
+ return FALSE;
+ default:
break;
- }
}
}
- charon->bus->set_listen_state(charon->bus, FALSE);
-
- return status;
+ return TRUE;
}
/**
- * Implementation of interface_manager_t.terminate_child.
+ * execute function for terminate_child
*/
-static status_t terminate_child(interface_manager_t *this, u_int32_t reqid,
- interface_manager_cb_t callback, void *param)
+static status_t terminate_child_execute(interface_job_t *job)
{
ike_sa_t *ike_sa;
child_sa_t *child_sa;
iterator_t *iterator;
- status_t status = FAILED;
- interface_bus_listener_t listener;
+ interface_bus_listener_t *listener = &job->listener;
ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
- reqid, TRUE);
+ listener->id, TRUE);
if (ike_sa == NULL)
{
+ SIG(CHILD_DOWN_FAILED, "unable to terminate, CHILD_SA with "
+ "ID %d not found", listener->id);
return NOT_FOUND;
}
+ listener->ike_sa = ike_sa;
iterator = ike_sa->create_child_sa_iterator(ike_sa);
while (iterator->iterate(iterator, (void**)&child_sa))
{
if (child_sa->get_state(child_sa) != CHILD_ROUTED &&
- child_sa->get_reqid(child_sa) == reqid)
+ child_sa->get_reqid(child_sa) == listener->id)
{
break;
}
@@ -453,160 +362,203 @@ static status_t terminate_child(interface_manager_t *this, u_int32_t reqid,
if (child_sa == NULL)
{
+ SIG(CHILD_DOWN_FAILED, "unable to terminate, established CHILD_SA with "
+ "ID %d not found", listener->id);
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
return NOT_FOUND;
}
- listener.listener.signal = (void*)terminate_child_listener;
- listener.callback = callback;
- listener.ike_sa = ike_sa;
- listener.param = param;
- listener.cancelled = FALSE;
-
- /* we listen passively to catch the signals we are raising */
- if (callback)
+ if (ike_sa->delete_child_sa(ike_sa, child_sa->get_protocol(child_sa),
+ child_sa->get_spi(child_sa, TRUE)) == DESTROY_ME)
{
- charon->bus->add_listener(charon->bus, &listener.listener);
+ return charon->ike_sa_manager->checkin_and_destroy(
+ charon->ike_sa_manager, ike_sa);
}
- charon->bus->set_listen_state(charon->bus, TRUE);
- status = ike_sa->delete_child_sa(ike_sa, child_sa->get_protocol(child_sa),
- child_sa->get_spi(child_sa, TRUE));
- if (status == DESTROY_ME)
+ return charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+}
+
+/**
+ * Implementation of interface_manager_t.terminate_child.
+ */
+static status_t terminate_child(interface_manager_t *this, u_int32_t reqid,
+ interface_manager_cb_t callback, void *param)
+{
+ interface_job_t job;
+
+ job.listener.public.signal = (void*)terminate_child_listener;
+ job.listener.ike_sa = NULL;
+ job.listener.callback = callback;
+ job.listener.param = param;
+ job.listener.status = FAILED;
+ job.listener.id = reqid;
+ job.public.execute = (void*)terminate_child_execute;
+ job.public.destroy = nop;
+
+ if (callback == NULL)
{
- charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
+ return terminate_child_execute(&job);
}
- else
+ charon->bus->listen(charon->bus, (bus_listener_t*)&job.listener, (job_t*)&job);
+ return job.listener.status;
+}
+
+/**
+ * listener function for route
+ */
+static bool route_listener(interface_bus_listener_t *this, signal_t signal,
+ level_t level, int thread, ike_sa_t *ike_sa,
+ char* format, va_list args)
+{
+ if (this->ike_sa == ike_sa)
{
- charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
-
- /* wait until CHILD_SA is cleanly deleted using a delete message */
- while (TRUE)
+ if (!this->callback(this->param, signal, level, ike_sa, format, args))
{
- level_t level;
- signal_t signal;
- int thread;
- ike_sa_t *current;
- char* format;
- va_list args;
-
- /* stop listening if the passive listener returned FALSE */
- if (listener.cancelled)
- {
- status = NEED_MORE;
- break;
- }
- pthread_cleanup_push((void*)remove_listener, &listener);
- signal = charon->bus->listen(charon->bus, &level, &thread,
- &current, &format, &args);
- pthread_cleanup_pop(0);
- /* even if we checked in the IKE_SA, the pointer is valid until
- * we get an IKE_DOWN_... */
- if (ike_sa == current)
- {
- switch (signal)
- {
- case IKE_DOWN_FAILED:
- case IKE_DOWN_SUCCESS:
- case CHILD_DOWN_FAILED:
- case CHILD_DOWN_SUCCESS:
- {
- status = SUCCESS;
- break;
- }
- default:
- continue;
- }
+ return FALSE;
+ }
+ switch (signal)
+ {
+ case CHILD_ROUTE_SUCCESS:
+ this->status = SUCCESS;
+ return FALSE;
+ case CHILD_ROUTE_FAILED:
+ return FALSE;
+ default:
break;
- }
}
}
- charon->bus->set_listen_state(charon->bus, FALSE);
-
- return status;
+ return TRUE;
}
/**
- * Implementation of interface_manager_t.route.
+ * execute function for route
*/
-static status_t route(interface_manager_t *this,
- peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
- interface_manager_cb_t callback, void *param)
+static status_t route_execute(interface_job_t *job)
{
ike_sa_t *ike_sa;
ike_cfg_t *ike_cfg;
- status_t status = SUCCESS;
+ interface_bus_listener_t *listener = &job->listener;
+ peer_cfg_t *peer_cfg = listener->peer_cfg;
ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
ike_sa = charon->ike_sa_manager->checkout_by_peer(charon->ike_sa_manager,
ike_cfg->get_my_host(ike_cfg), ike_cfg->get_other_host(ike_cfg),
peer_cfg->get_my_id(peer_cfg), peer_cfg->get_other_id(peer_cfg));
+ listener->ike_sa = ike_sa;
if (ike_sa->get_peer_cfg(ike_sa) == NULL)
{
ike_sa->set_peer_cfg(ike_sa, peer_cfg);
}
-
- /* we listen passively only, as routing is done by one thread only */
- if (callback)
+ if (ike_sa->route(ike_sa, listener->child_cfg) == DESTROY_ME)
{
- interface_bus_listener_t listener;
-
- listener.listener.signal = (void*)route_listener;
- listener.callback = callback;
- listener.ike_sa = ike_sa;
- listener.param = param;
- listener.cancelled = FALSE;
- charon->bus->add_listener(charon->bus, &listener.listener);
+ return charon->ike_sa_manager->checkin_and_destroy(
+ charon->ike_sa_manager, ike_sa);
}
+ return charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+}
+
+/**
+ * Implementation of interface_manager_t.route.
+ */
+static status_t route(interface_manager_t *this,
+ peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
+ interface_manager_cb_t callback, void *param)
+{
+ interface_job_t job;
- if (ike_sa->route(ike_sa, child_cfg) != SUCCESS)
+ job.listener.public.signal = (void*)route_listener;
+ job.listener.ike_sa = NULL;
+ job.listener.callback = callback;
+ job.listener.param = param;
+ job.listener.status = FAILED;
+ job.listener.peer_cfg = peer_cfg;
+ job.listener.child_cfg = child_cfg;
+ job.public.execute = (void*)route_execute;
+ job.public.destroy = nop;
+
+ if (callback == NULL)
{
- status = FAILED;
+ return route_execute(&job);
}
- charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
- return status;
+ charon->bus->listen(charon->bus, (bus_listener_t*)&job.listener, (job_t*)&job);
+ return job.listener.status;
}
/**
- * Implementation of interface_manager_t.unroute.
+ * listener function for unroute
*/
-static status_t unroute(interface_manager_t *this, u_int32_t reqid,
- interface_manager_cb_t callback, void *param)
+static bool unroute_listener(interface_bus_listener_t *this, signal_t signal,
+ level_t level, int thread, ike_sa_t *ike_sa,
+ char* format, va_list args)
+{
+ if (this->ike_sa == ike_sa)
+ {
+ if (!this->callback(this->param, signal, level, ike_sa, format, args))
+ {
+ return FALSE;
+ }
+ switch (signal)
+ {
+ case CHILD_UNROUTE_SUCCESS:
+ this->status = SUCCESS;
+ return FALSE;
+ case CHILD_UNROUTE_FAILED:
+ return FALSE;
+ default:
+ break;
+ }
+ }
+ return TRUE;
+}
+/**
+ * execute function for unroute
+ */
+static status_t unroute_execute(interface_job_t *job)
{
ike_sa_t *ike_sa;
- status_t status;
+ interface_bus_listener_t *listener = &job->listener;
ike_sa = charon->ike_sa_manager->checkout_by_id(charon->ike_sa_manager,
- reqid, TRUE);
+ listener->id, TRUE);
if (ike_sa == NULL)
{
+ SIG(CHILD_DOWN_FAILED, "unable to unroute, CHILD_SA with "
+ "ID %d not found", listener->id);
return NOT_FOUND;
}
-
- /* we listen passively only, as routing is done by one thread only */
- if (callback)
+ listener->ike_sa = ike_sa;
+ if (ike_sa->unroute(ike_sa, listener->id) == DESTROY_ME)
{
- interface_bus_listener_t listener;
-
- listener.listener.signal = (void*)unroute_listener;
- listener.callback = callback;
- listener.ike_sa = ike_sa;
- listener.param = param;
- listener.cancelled = FALSE;
- charon->bus->add_listener(charon->bus, &listener.listener);
+ return charon->ike_sa_manager->checkin_and_destroy(
+ charon->ike_sa_manager, ike_sa);
}
- status = ike_sa->unroute(ike_sa, reqid);
- if (status == DESTROY_ME)
- {
- charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
- status = SUCCESS;
- }
- else
+ return charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+}
+
+/**
+ * Implementation of interface_manager_t.unroute.
+ */
+static status_t unroute(interface_manager_t *this, u_int32_t reqid,
+ interface_manager_cb_t callback, void *param)
+{
+ interface_job_t job;
+
+ job.listener.public.signal = (void*)unroute_listener;
+ job.listener.ike_sa = NULL;
+ job.listener.callback = callback;
+ job.listener.param = param;
+ job.listener.status = FAILED;
+ job.listener.id = reqid;
+ job.public.execute = (void*)unroute_execute;
+ job.public.destroy = nop;
+
+ if (callback == NULL)
{
- charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+ return unroute_execute(&job);
}
- return status;
+ charon->bus->listen(charon->bus, (bus_listener_t*)&job.listener, (job_t*)&job);
+ return job.listener.status;
}
/**
diff --git a/src/charon/control/interfaces/stroke_interface.c b/src/charon/control/interfaces/stroke_interface.c
index 66ed423ae..b51d53ebd 100755
--- a/src/charon/control/interfaces/stroke_interface.c
+++ b/src/charon/control/interfaces/stroke_interface.c
@@ -239,13 +239,13 @@ static void stroke_add_conn(stroke_msg_t *msg, FILE *out)
bool other_ca_same =FALSE;
host_t *my_host, *other_host, *my_subnet, *other_subnet;
host_t *my_vip = NULL, *other_vip = NULL;
- linked_list_t *my_groups = linked_list_create();
linked_list_t *other_groups = linked_list_create();
proposal_t *proposal;
traffic_selector_t *my_ts, *other_ts;
char *interface;
bool use_existing = FALSE;
iterator_t *iterator;
+ u_int32_t vendor;
pop_string(msg, &msg->add_conn.name);
DBG1(DBG_CFG, "received stroke: add connection '%s'", msg->add_conn.name);
@@ -262,7 +262,7 @@ static void stroke_add_conn(stroke_msg_t *msg, FILE *out)
DBG2(DBG_CFG, " p2p_mediated_by=%s", msg->add_conn.p2p.mediated_by);
DBG2(DBG_CFG, " p2p_peerid=%s", msg->add_conn.p2p.peerid);
- my_host = msg->add_conn.me.address?
+ my_host = msg->add_conn.me.address ?
host_create_from_string(msg->add_conn.me.address, IKE_PORT) : NULL;
if (my_host == NULL)
{
@@ -365,11 +365,11 @@ static void stroke_add_conn(stroke_msg_t *msg, FILE *out)
}
}
else
-#endif /* P2P */
{
- // no peer ID supplied, assume right ID
+ /* no peer ID supplied, assume right ID */
peer_id = other_id->clone(other_id);
}
+#endif /* P2P */
my_subnet = host_create_from_string(msg->add_conn.me.subnet ?
msg->add_conn.me.subnet : msg->add_conn.me.address, IKE_PORT);
@@ -544,7 +544,8 @@ static void stroke_add_conn(stroke_msg_t *msg, FILE *out)
&& ietfAttr_list_equals(other_groups, peer_cfg->get_groups(peer_cfg))
&& peer_cfg->get_ike_version(peer_cfg) == (msg->add_conn.ikev2 ? 2 : 1)
&& peer_cfg->get_auth_method(peer_cfg) == msg->add_conn.auth_method
- && peer_cfg->get_eap_type(peer_cfg) == msg->add_conn.eap_type)
+ && peer_cfg->get_eap_type(peer_cfg, &vendor) == msg->add_conn.eap_type
+ && vendor == msg->add_conn.eap_vendor)
{
DBG1(DBG_CFG, "reusing existing configuration '%s'",
peer_cfg->get_name(peer_cfg));
@@ -564,9 +565,8 @@ static void stroke_add_conn(stroke_msg_t *msg, FILE *out)
other_host->destroy(other_host);
other_id->destroy(other_id);
other_ca->destroy(other_ca);
- peer_id->destroy(peer_id);
+ DESTROY_IF(peer_id);
DESTROY_IF(mediated_by_cfg);
- ietfAttr_list_destroy(my_groups);
ietfAttr_list_destroy(other_groups);
}
else
@@ -613,15 +613,25 @@ static void stroke_add_conn(stroke_msg_t *msg, FILE *out)
ike_cfg->add_proposal(ike_cfg, proposal);
}
+ u_int32_t rekey = 0, reauth = 0, over, jitter;
+
+ jitter = msg->add_conn.rekey.margin * msg->add_conn.rekey.fuzz / 100;
+ over = msg->add_conn.rekey.margin;
+ if (msg->add_conn.rekey.reauth)
+ {
+ reauth = msg->add_conn.rekey.ike_lifetime - over;
+ }
+ else
+ {
+ rekey = msg->add_conn.rekey.ike_lifetime - over;
+ }
peer_cfg = peer_cfg_create(msg->add_conn.name, msg->add_conn.ikev2 ? 2 : 1,
ike_cfg, my_id, other_id, my_ca, other_ca, other_groups,
- msg->add_conn.me.sendcert,
- msg->add_conn.auth_method, msg->add_conn.eap_type,
- msg->add_conn.rekey.tries, msg->add_conn.rekey.ike_lifetime,
- msg->add_conn.rekey.ike_lifetime - msg->add_conn.rekey.margin,
- msg->add_conn.rekey.margin * msg->add_conn.rekey.fuzz / 100,
- msg->add_conn.rekey.reauth, msg->add_conn.mobike,
+ msg->add_conn.me.sendcert, msg->add_conn.auth_method,
+ msg->add_conn.eap_type, msg->add_conn.eap_vendor,
+ msg->add_conn.rekey.tries, rekey, reauth, jitter, over,
+ msg->add_conn.mobike,
msg->add_conn.dpd.delay, msg->add_conn.dpd.action, my_vip, other_vip,
msg->add_conn.p2p.mediation, mediated_by_cfg, peer_id);
}
@@ -1104,9 +1114,8 @@ static void stroke_del_ca(stroke_msg_t *msg, FILE *out)
*/
static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
{
- peer_cfg_t *cfg = ike_sa->get_peer_cfg(ike_sa);
ike_sa_id_t *id = ike_sa->get_id(ike_sa);
- u_int32_t next, now = time(NULL);
+ u_int32_t rekey, reauth;
fprintf(out, "%12s[%d]: %N, %H[%D]...%H[%D]\n",
ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa),
@@ -1116,21 +1125,26 @@ static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
if (all)
{
- fprintf(out, "%12s[%d]: IKE SPIs: %.16llx_i%s %.16llx_r%s, ",
+ fprintf(out, "%12s[%d]: IKE SPIs: %.16llx_i%s %.16llx_r%s",
ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa),
id->get_initiator_spi(id), id->is_initiator(id) ? "*" : "",
id->get_responder_spi(id), id->is_initiator(id) ? "" : "*");
- ike_sa->get_stats(ike_sa, &next);
- if (next)
+ rekey = ike_sa->get_statistic(ike_sa, STAT_REKEY_TIME);
+ reauth = ike_sa->get_statistic(ike_sa, STAT_REAUTH_TIME);
+ if (rekey)
{
- fprintf(out, "%s in %V\n", cfg->use_reauth(cfg) ?
- "reauthentication" : "rekeying", &now, &next);
+ fprintf(out, ", rekeying in %V", &rekey);
}
- else
+ if (reauth)
{
- fprintf(out, "rekeying disabled\n");
+ fprintf(out, ", reauthentication in %V", &reauth);
}
+ if (!rekey && !reauth)
+ {
+ fprintf(out, ", rekeying disabled");
+ }
+ fprintf(out, "\n");
}
}
@@ -1188,7 +1202,7 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
if (rekey)
{
- fprintf(out, "in %V", &now, &rekey);
+ fprintf(out, "in %#V", &now, &rekey);
}
else
{
@@ -1692,7 +1706,6 @@ static job_requeue_t stroke_process(int *fdp)
return JOB_REQUEUE_NONE;
}
-
/**
* Implementation of private_stroke_interface_t.stroke_receive.
*/
diff --git a/src/charon/control/interfaces/xml_interface.c b/src/charon/control/interfaces/xml_interface.c
index 02da1064d..aa2a554a0 100644
--- a/src/charon/control/interfaces/xml_interface.c
+++ b/src/charon/control/interfaces/xml_interface.c
@@ -91,6 +91,9 @@ static void write_id(xmlTextWriterPtr writer, char *element, identification_t *i
char *type = "";
while (TRUE)
{
+ case ID_ANY:
+ type = "any";
+ break;
case ID_IPV4_ADDR:
type = "ipv4";
break;
@@ -114,9 +117,6 @@ static void write_id(xmlTextWriterPtr writer, char *element, identification_t *i
xmlTextWriterWriteFormatString(writer, "%D", id);
break;
}
- case ID_ANY:
- xmlTextWriterWriteAttribute(writer, "type", "any");
- break;
default:
/* TODO: base64 keyid */
xmlTextWriterWriteAttribute(writer, "type", "keyid");
@@ -146,17 +146,15 @@ static void write_address(xmlTextWriterPtr writer, char *element, host_t *host)
}
/**
- * write a childEnd
+ * write networks element
*/
-static void write_childend(xmlTextWriterPtr writer, child_sa_t *child, bool local)
+static void write_networks(xmlTextWriterPtr writer, char *element,
+ linked_list_t *list)
{
iterator_t *iterator;
- linked_list_t *list;
traffic_selector_t *ts;
- xmlTextWriterWriteFormatElement(writer, "spi", "%lx",
- htonl(child->get_spi(child, local)));
- xmlTextWriterStartElement(writer, "networks");
- list = child->get_traffic_selectors(child, local);
+
+ xmlTextWriterStartElement(writer, element);
iterator = list->create_iterator(list, TRUE);
while (iterator->iterate(iterator, (void**)&ts))
{
@@ -171,6 +169,19 @@ static void write_childend(xmlTextWriterPtr writer, child_sa_t *child, bool loca
}
/**
+ * write a childEnd
+ */
+static void write_childend(xmlTextWriterPtr writer, child_sa_t *child, bool local)
+{
+ linked_list_t *list;
+
+ xmlTextWriterWriteFormatElement(writer, "spi", "%lx",
+ htonl(child->get_spi(child, local)));
+ list = child->get_traffic_selectors(child, local);
+ write_networks(writer, "networks", list);
+}
+
+/**
* write a child_sa_t
*/
static void write_child(xmlTextWriterPtr writer, child_sa_t *child)
@@ -284,6 +295,201 @@ static void request_query_ikesa(xmlTextReaderPtr reader, xmlTextWriterPtr writer
}
/**
+ * process a configlist query request message
+ */
+static void request_query_config(xmlTextReaderPtr reader, xmlTextWriterPtr writer)
+{
+ iterator_t *iterator;
+ peer_cfg_t *peer_cfg;
+
+ /* <configlist> */
+ xmlTextWriterStartElement(writer, "configlist");
+
+ iterator = charon->backends->create_iterator(charon->backends);
+ while (iterator->iterate(iterator, (void**)&peer_cfg))
+ {
+ iterator_t *children;
+ child_cfg_t *child_cfg;
+ ike_cfg_t *ike_cfg;
+ linked_list_t *list;
+
+ if (peer_cfg->get_ike_version(peer_cfg) != 2)
+ { /* only IKEv2 connections yet */
+ continue;
+ }
+
+ /* <peerconfig> */
+ xmlTextWriterStartElement(writer, "peerconfig");
+ xmlTextWriterWriteElement(writer, "name", peer_cfg->get_name(peer_cfg));
+ write_id(writer, "local", peer_cfg->get_my_id(peer_cfg));
+ write_id(writer, "remote", peer_cfg->get_other_id(peer_cfg));
+
+ /* <ikeconfig> */
+ ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
+ xmlTextWriterStartElement(writer, "ikeconfig");
+ write_address(writer, "local", ike_cfg->get_my_host(ike_cfg));
+ write_address(writer, "remote", ike_cfg->get_other_host(ike_cfg));
+ xmlTextWriterEndElement(writer);
+ /* </ikeconfig> */
+
+ /* <childconfiglist> */
+ xmlTextWriterStartElement(writer, "childconfiglist");
+ children = peer_cfg->create_child_cfg_iterator(peer_cfg);
+ while (children->iterate(children, (void**)&child_cfg))
+ {
+ /* <childconfig> */
+ xmlTextWriterStartElement(writer, "childconfig");
+ xmlTextWriterWriteElement(writer, "name",
+ child_cfg->get_name(child_cfg));
+ list = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, NULL);
+ write_networks(writer, "local", list);
+ list->destroy_offset(list, offsetof(traffic_selector_t, destroy));
+ list = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, NULL);
+ write_networks(writer, "remote", list);
+ list->destroy_offset(list, offsetof(traffic_selector_t, destroy));
+ xmlTextWriterEndElement(writer);
+ /* </childconfig> */
+ }
+ children->destroy(children);
+ /* </childconfiglist> */
+ xmlTextWriterEndElement(writer);
+ /* </peerconfig> */
+ xmlTextWriterEndElement(writer);
+ }
+ iterator->destroy(iterator);
+ /* </configlist> */
+ xmlTextWriterEndElement(writer);
+}
+
+/**
+ * callback which logs to a XML writer
+ */
+static bool xml_callback(xmlTextWriterPtr writer, signal_t signal, level_t level,
+ ike_sa_t* ike_sa, char* format, va_list args)
+{
+ if (level <= 1)
+ {
+ /* <item> */
+ xmlTextWriterStartElement(writer, "item");
+ xmlTextWriterWriteFormatAttribute(writer, "level", "%d", level);
+ xmlTextWriterWriteFormatAttribute(writer, "source", "%N", signal_names, signal);
+ xmlTextWriterWriteFormatAttribute(writer, "thread", "%u", pthread_self());
+ xmlTextWriterWriteVFormatString(writer, format, args);
+ xmlTextWriterEndElement(writer);
+ /* </item> */
+ }
+ return TRUE;
+}
+
+/**
+ * process a *terminate control request message
+ */
+static void request_control_terminate(xmlTextReaderPtr reader,
+ xmlTextWriterPtr writer, bool ike)
+{
+ if (xmlTextReaderRead(reader) &&
+ xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT)
+ {
+ const char *str;
+ u_int32_t id;
+ status_t status;
+
+ str = xmlTextReaderConstValue(reader);
+ if (str == NULL || !(id = atoi(str)))
+ {
+ DBG1(DBG_CFG, "error parsing XML id string");
+ return;
+ }
+ DBG1(DBG_CFG, "terminating %s_SA %d", ike ? "IKE" : "CHILD", id);
+
+ /* <log> */
+ xmlTextWriterStartElement(writer, "log");
+ if (ike)
+ {
+ status = charon->interfaces->terminate_ike(
+ charon->interfaces, id,
+ (interface_manager_cb_t)xml_callback, writer);
+ }
+ else
+ {
+ status = charon->interfaces->terminate_child(
+ charon->interfaces, id,
+ (interface_manager_cb_t)xml_callback, writer);
+ }
+ /* </log> */
+ xmlTextWriterEndElement(writer);
+ xmlTextWriterWriteFormatElement(writer, "status", "%d", status);
+ }
+}
+
+/**
+ * process a *initiate control request message
+ */
+static void request_control_initiate(xmlTextReaderPtr reader,
+ xmlTextWriterPtr writer, bool ike)
+{
+ if (xmlTextReaderRead(reader) &&
+ xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT)
+ {
+ const char *str;
+ status_t status = FAILED;
+ peer_cfg_t *peer;
+ child_cfg_t *child = NULL;
+ iterator_t *iterator;
+
+ str = xmlTextReaderConstValue(reader);
+ if (str == NULL)
+ {
+ DBG1(DBG_CFG, "error parsing XML config name string");
+ return;
+ }
+ DBG1(DBG_CFG, "initiating %s_SA %s", ike ? "IKE" : "CHILD", str);
+
+ /* <log> */
+ xmlTextWriterStartElement(writer, "log");
+ peer = charon->backends->get_peer_cfg_by_name(charon->backends, (char*)str);
+ if (peer)
+ {
+ iterator = peer->create_child_cfg_iterator(peer);
+ if (ike)
+ {
+ if (!iterator->iterate(iterator, (void**)&child))
+ {
+ child = NULL;
+ }
+ child->get_ref(child);
+ }
+ else
+ {
+ while (iterator->iterate(iterator, (void**)&child))
+ {
+ if (streq(child->get_name(child), str))
+ {
+ child->get_ref(child);
+ break;
+ }
+ child = NULL;
+ }
+ }
+ iterator->destroy(iterator);
+ if (child)
+ {
+ status = charon->interfaces->initiate(charon->interfaces,
+ peer, child, (interface_manager_cb_t)xml_callback,
+ writer);
+ }
+ else
+ {
+ peer->destroy(peer);
+ }
+ }
+ /* </log> */
+ xmlTextWriterEndElement(writer);
+ xmlTextWriterWriteFormatElement(writer, "status", "%d", status);
+ }
+}
+
+/**
* process a query request
*/
static void request_query(xmlTextReaderPtr reader, xmlTextWriterPtr writer)
@@ -299,6 +505,11 @@ static void request_query(xmlTextReaderPtr reader, xmlTextWriterPtr writer)
request_query_ikesa(reader, writer);
break;
}
+ if (streq(xmlTextReaderConstName(reader), "configlist"))
+ {
+ request_query_config(reader, writer);
+ break;
+ }
}
}
/* </query> */
@@ -306,6 +517,43 @@ static void request_query(xmlTextReaderPtr reader, xmlTextWriterPtr writer)
}
/**
+ * process a control request
+ */
+static void request_control(xmlTextReaderPtr reader, xmlTextWriterPtr writer)
+{
+ /* <control> */
+ xmlTextWriterStartElement(writer, "control");
+ while (xmlTextReaderRead(reader))
+ {
+ if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT)
+ {
+ if (streq(xmlTextReaderConstName(reader), "ikesaterminate"))
+ {
+ request_control_terminate(reader, writer, TRUE);
+ break;
+ }
+ if (streq(xmlTextReaderConstName(reader), "childsaterminate"))
+ {
+ request_control_terminate(reader, writer, FALSE);
+ break;
+ }
+ if (streq(xmlTextReaderConstName(reader), "ikesainitiate"))
+ {
+ request_control_initiate(reader, writer, TRUE);
+ break;
+ }
+ if (streq(xmlTextReaderConstName(reader), "childsainitiate"))
+ {
+ request_control_initiate(reader, writer, FALSE);
+ break;
+ }
+ }
+ }
+ /* </control> */
+ xmlTextWriterEndElement(writer);
+}
+
+/**
* process a request message
*/
static void request(xmlTextReaderPtr reader, char *id, int fd)
@@ -337,6 +585,11 @@ static void request(xmlTextReaderPtr reader, char *id, int fd)
request_query(reader, writer);
break;
}
+ if (streq(xmlTextReaderConstName(reader), "control"))
+ {
+ request_control(reader, writer);
+ break;
+ }
}
}
/* </message> and close document */
diff --git a/src/charon/daemon.c b/src/charon/daemon.c
index 9e151c305..ee9710424 100644
--- a/src/charon/daemon.c
+++ b/src/charon/daemon.c
@@ -338,7 +338,7 @@ static bool initialize(private_daemon_t *this, bool syslog, level_t levels[])
this->public.interfaces = interface_manager_create();
this->public.backends = backend_manager_create();
this->public.kernel_interface = kernel_interface_create();
- this->public.socket = socket_create(IKEV2_UDP_PORT, IKEV2_NATT_PORT);
+ this->public.socket = socket_create();
this->public.sender = sender_create();
this->public.receiver = receiver_create();
diff --git a/src/charon/encoding/payloads/configuration_attribute.c b/src/charon/encoding/payloads/configuration_attribute.c
index 0aa82169f..afd08c6be 100644
--- a/src/charon/encoding/payloads/configuration_attribute.c
+++ b/src/charon/encoding/payloads/configuration_attribute.c
@@ -165,7 +165,7 @@ static status_t verify(private_configuration_attribute_t *this)
default:
DBG1(DBG_ENC, "unknown attribute type %N",
configuration_attribute_type_names, this->attribute_type);
- return FAILED;
+ break;
}
if (failed)
diff --git a/src/charon/encoding/payloads/eap_payload.c b/src/charon/encoding/payloads/eap_payload.c
index 79ab32fe5..345114af0 100644
--- a/src/charon/encoding/payloads/eap_payload.c
+++ b/src/charon/encoding/payloads/eap_payload.c
@@ -235,11 +235,23 @@ static u_int8_t get_identifier(private_eap_payload_t *this)
/**
* Implementation of eap_payload_t.get_type.
*/
-static eap_type_t get_type(private_eap_payload_t *this)
+static eap_type_t get_type(private_eap_payload_t *this, u_int32_t *vendor)
{
+ eap_type_t type;
+
+ *vendor = 0;
if (this->data.len > 4)
{
- return *(this->data.ptr + 4);
+ type = *(this->data.ptr + 4);
+ if (type != EAP_EXPANDED)
+ {
+ return type;
+ }
+ if (this->data.len >= 12)
+ {
+ *vendor = ntohl(*(u_int32_t*)(this->data.ptr + 4)) & 0x00FFFFFF;
+ return ntohl(*(u_int32_t*)(this->data.ptr + 8));
+ }
}
return 0;
}
@@ -275,7 +287,7 @@ eap_payload_t *eap_payload_create()
this->public.set_data = (void (*) (eap_payload_t *,chunk_t))set_data;
this->public.get_code = (eap_code_t (*) (eap_payload_t*))get_code;
this->public.get_identifier = (u_int8_t (*) (eap_payload_t*))get_identifier;
- this->public.get_type = (eap_type_t (*) (eap_payload_t*))get_type;
+ this->public.get_type = (eap_type_t (*) (eap_payload_t*,u_int32_t*))get_type;
/* private variables */
this->critical = FALSE;
@@ -329,3 +341,4 @@ eap_payload_t *eap_payload_create_nak()
this->set_data(this, data);
return this;
}
+
diff --git a/src/charon/encoding/payloads/eap_payload.h b/src/charon/encoding/payloads/eap_payload.h
index 13c0ade80..3addbb838 100644
--- a/src/charon/encoding/payloads/eap_payload.h
+++ b/src/charon/encoding/payloads/eap_payload.h
@@ -95,9 +95,10 @@ struct eap_payload_t {
* @brief Get the EAP method type.
*
* @param this calling eap_payload_t object
- * @return EAP method type
+ * @param vendor pointer receiving vendor identifier
+ * @return EAP method type, vendor specific if vendor != 0
*/
- eap_type_t (*get_type) (eap_payload_t *this);
+ eap_type_t (*get_type) (eap_payload_t *this, u_int32_t *vendor);
/**
* @brief Destroys an eap_payload_t object.
diff --git a/src/charon/encoding/payloads/endpoint_notify.c b/src/charon/encoding/payloads/endpoint_notify.c
index 30f3ecd5f..98bfb2ea0 100644
--- a/src/charon/encoding/payloads/endpoint_notify.c
+++ b/src/charon/encoding/payloads/endpoint_notify.c
@@ -76,6 +76,13 @@ struct private_endpoint_notify_t {
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
+ENUM(p2p_endpoint_type_names, HOST, RELAYED,
+ "HOST",
+ "SERVER_REFLEXIVE",
+ "PEER_REFLEXIVE",
+ "RELAYED"
+);
+
/**
* Helper functions to parse integer values
*/
@@ -152,14 +159,10 @@ static status_t parse_notification_data(private_endpoint_notify_t *this, chunk_t
switch(this->family)
{
- case NO_FAMILY:
- this->endpoint = NULL;
- break;
-
case IPv6:
addr_family = AF_INET6;
addr.len = 16;
- // fall-through
+ /* fall-through */
case IPv4:
if (parse_uint16(&cur, top, &port) != SUCCESS)
{
@@ -177,8 +180,11 @@ static status_t parse_notification_data(private_endpoint_notify_t *this, chunk_t
this->endpoint = host_create_from_chunk(addr_family, addr, port);
break;
+ case NO_FAMILY:
+ default:
+ this->endpoint = NULL;
+ break;
}
-
return SUCCESS;
}
@@ -213,7 +219,7 @@ static chunk_t build_notification_data(private_endpoint_notify_t *this)
}
port_chunk = chunk_from_thing(port);
- // data = prio | family | type | port | addr
+ /* data = prio | family | type | port | addr */
data = chunk_cat("ccccc", prio_chunk, family_chunk, type_chunk,
port_chunk, addr_chunk);
DBG3(DBG_IKE, "p2p_endpoint_data %B", &data);
@@ -251,7 +257,7 @@ static u_int32_t get_priority(private_endpoint_notify_t *this)
*/
static void set_priority(private_endpoint_notify_t *this, u_int32_t priority)
{
- return this->priority = priority;
+ this->priority = priority;
}
/**
@@ -368,13 +374,15 @@ endpoint_notify_t *endpoint_notify_create_from_host(p2p_endpoint_type_t type, ho
this->priority = pow(2, 16) * P2P_PRIO_PEER;
break;
case RELAYED:
+ default:
this->priority = pow(2, 16) * P2P_PRIO_RELAY;
break;
}
this->priority += 65535;
- if (!host) {
+ if (!host)
+ {
return &this->public;
}
@@ -387,7 +395,8 @@ endpoint_notify_t *endpoint_notify_create_from_host(p2p_endpoint_type_t type, ho
this->family = IPv6;
break;
default:
- // unsupported family type, we do not set the hsot (family is set to NO_FAMILY)
+ /* unsupported family type, we do not set the hsot
+ * (family is set to NO_FAMILY) */
return &this->public;
}
diff --git a/src/charon/encoding/payloads/endpoint_notify.h b/src/charon/encoding/payloads/endpoint_notify.h
index 272301d5b..4a3a68f95 100644
--- a/src/charon/encoding/payloads/endpoint_notify.h
+++ b/src/charon/encoding/payloads/endpoint_notify.h
@@ -35,6 +35,11 @@ typedef struct endpoint_notify_t endpoint_notify_t;
#include <encoding/payloads/notify_payload.h>
+/**
+ * @brief P2P endpoint families.
+ *
+ * @ingroup payloads
+ */
enum p2p_endpoint_family_t {
NO_FAMILY = 0,
@@ -47,6 +52,11 @@ enum p2p_endpoint_family_t {
};
+/**
+ * @brief P2P endpoint types.
+ *
+ * @ingroup payloads
+ */
enum p2p_endpoint_type_t {
NO_TYPE = 0,
@@ -64,6 +74,13 @@ enum p2p_endpoint_type_t {
};
/**
+ * enum name for p2p_endpoint_type_t.
+ *
+ * @ingroup payloads
+ */
+extern enum_name_t *p2p_endpoint_type_names;
+
+/**
* @brief Class representing a P2P_ENDPOINT notify. In fact it's not
* the notify per se, but the notification data of that notify that is
* handled with this class.
diff --git a/src/charon/encoding/payloads/ike_header.c b/src/charon/encoding/payloads/ike_header.c
index 7253e4f51..3a171b095 100644
--- a/src/charon/encoding/payloads/ike_header.c
+++ b/src/charon/encoding/payloads/ike_header.c
@@ -192,7 +192,8 @@ static status_t verify(private_ike_header_t *this)
if (this->initiator_spi == 0
#ifdef P2P
- // we allow zero spi for INFORMATIONAL exchanges, to allow P2P connectivity checks
+ /* we allow zero spi for INFORMATIONAL exchanges,
+ * to allow P2P connectivity checks */
&& this->exchange_type != INFORMATIONAL
#endif /* P2P */
)
diff --git a/src/charon/encoding/payloads/notify_payload.c b/src/charon/encoding/payloads/notify_payload.c
index 74a6c3197..d32257af6 100644
--- a/src/charon/encoding/payloads/notify_payload.c
+++ b/src/charon/encoding/payloads/notify_payload.c
@@ -57,13 +57,9 @@ ENUM_NEXT(notify_type_names, SINGLE_PAIR_REQUIRED, UNEXPECTED_NAT_DETECTED, AUTH
"INVALID_SELECTORS",
"UNACCEPTABLE_ADDRESSES",
"UNEXPECTED_NAT_DETECTED");
-#ifdef P2P
ENUM_NEXT(notify_type_names, P2P_CONNECT_FAILED, P2P_CONNECT_FAILED, UNEXPECTED_NAT_DETECTED,
"P2P_CONNECT_FAILED");
ENUM_NEXT(notify_type_names, INITIAL_CONTACT, AUTH_LIFETIME, P2P_CONNECT_FAILED,
-#else
-ENUM_NEXT(notify_type_names, INITIAL_CONTACT, AUTH_LIFETIME, UNEXPECTED_NAT_DETECTED,
-#endif /* P2P */
"INITIAL_CONTACT",
"SET_WINDOW_SIZE",
"ADDITIONAL_TS_POSSIBLE",
@@ -86,7 +82,6 @@ ENUM_NEXT(notify_type_names, INITIAL_CONTACT, AUTH_LIFETIME, UNEXPECTED_NAT_DETE
"AUTH_LIFETIME");
ENUM_NEXT(notify_type_names, EAP_ONLY_AUTHENTICATION, EAP_ONLY_AUTHENTICATION, AUTH_LIFETIME,
"EAP_ONLY_AUTHENTICATION");
-#ifdef P2P
ENUM_NEXT(notify_type_names, USE_BEET_MODE, USE_BEET_MODE, EAP_ONLY_AUTHENTICATION,
"USE_BEET_MODE");
ENUM_NEXT(notify_type_names, P2P_MEDIATION, P2P_RESPONSE, USE_BEET_MODE,
@@ -97,9 +92,6 @@ ENUM_NEXT(notify_type_names, P2P_MEDIATION, P2P_RESPONSE, USE_BEET_MODE,
"P2P_SESSIONKEY",
"P2P_RESPONSE");
ENUM_END(notify_type_names, P2P_RESPONSE);
-#else
-ENUM_END(notify_type_names, EAP_ONLY_AUTHENTICATION);
-#endif /* P2P */
ENUM_BEGIN(notify_type_short_names, UNSUPPORTED_CRITICAL_PAYLOAD, UNSUPPORTED_CRITICAL_PAYLOAD,
@@ -128,13 +120,9 @@ ENUM_NEXT(notify_type_short_names, SINGLE_PAIR_REQUIRED, UNEXPECTED_NAT_DETECTED
"INVAL_SEL",
"UNACCEPT_ADDR",
"UNEXPECT_NAT");
-#ifdef P2P
ENUM_NEXT(notify_type_short_names, P2P_CONNECT_FAILED, P2P_CONNECT_FAILED, UNEXPECTED_NAT_DETECTED,
"P2P_CONN_FAIL");
ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, AUTH_LIFETIME, P2P_CONNECT_FAILED,
-#else
-ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, AUTH_LIFETIME, UNEXPECTED_NAT_DETECTED,
-#endif /* P2P */
"INIT_CONTACT",
"SET_WINSIZE",
"ADD_TS_POSS",
@@ -157,7 +145,6 @@ ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, AUTH_LIFETIME, UNEXPECTED_NA
"AUTH_LFT");
ENUM_NEXT(notify_type_short_names, EAP_ONLY_AUTHENTICATION, EAP_ONLY_AUTHENTICATION, AUTH_LIFETIME,
"EAP_ONLY");
-#ifdef P2P
ENUM_NEXT(notify_type_short_names, USE_BEET_MODE, USE_BEET_MODE, EAP_ONLY_AUTHENTICATION,
"BEET_MODE");
ENUM_NEXT(notify_type_short_names, P2P_MEDIATION, P2P_RESPONSE, USE_BEET_MODE,
@@ -168,9 +155,6 @@ ENUM_NEXT(notify_type_short_names, P2P_MEDIATION, P2P_RESPONSE, USE_BEET_MODE,
"P2P_SKEY",
"P2P_R");
ENUM_END(notify_type_short_names, P2P_RESPONSE);
-#else
-ENUM_END(notify_type_short_names, EAP_ONLY_AUTHENTICATION);
-#endif /* P2P */
typedef struct private_notify_payload_t private_notify_payload_t;
@@ -342,7 +326,15 @@ static status_t verify(private_notify_payload_t *this)
}
break;
}
- // FIXME: check size of P2P-NAT-T payloads
+ case AUTH_LIFETIME:
+ {
+ if (this->notification_data.len != 4)
+ {
+ bad_length = TRUE;
+ }
+ break;
+ }
+ /* FIXME: check size of P2P-NAT-T payloads */
default:
/* TODO: verify */
break;
diff --git a/src/charon/encoding/payloads/notify_payload.h b/src/charon/encoding/payloads/notify_payload.h
index 4a9ad992b..03f61d473 100644
--- a/src/charon/encoding/payloads/notify_payload.h
+++ b/src/charon/encoding/payloads/notify_payload.h
@@ -68,10 +68,9 @@ enum notify_type_t {
INVALID_SELECTORS = 39,
UNACCEPTABLE_ADDRESSES = 40,
UNEXPECTED_NAT_DETECTED = 41,
-#ifdef P2P
/* P2P-NAT-T, private use */
P2P_CONNECT_FAILED = 8192,
-#endif /* P2P */
+
/* notify status messages */
INITIAL_CONTACT = 16384,
SET_WINDOW_SIZE = 16385,
@@ -99,7 +98,6 @@ enum notify_type_t {
EAP_ONLY_AUTHENTICATION = 40960,
/* BEET mode, not even a draft yet. private use */
USE_BEET_MODE = 40961,
-#ifdef P2P
/* P2P-NAT-T, private use */
P2P_MEDIATION = 40962,
P2P_ENDPOINT = 40963,
@@ -107,7 +105,6 @@ enum notify_type_t {
P2P_SESSIONID = 40965,
P2P_SESSIONKEY = 40966,
P2P_RESPONSE = 40967
-#endif /* P2P */
};
/**
diff --git a/src/charon/network/socket-raw.c b/src/charon/network/socket-raw.c
new file mode 100644
index 000000000..3b76ae570
--- /dev/null
+++ b/src/charon/network/socket-raw.c
@@ -0,0 +1,771 @@
+/**
+ * @file socket.c
+ *
+ * @brief Implementation of socket_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
+ * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005 Jan Hutter
+ * 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 <pthread.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip6.h>
+#include <netinet/udp.h>
+#include <linux/ipsec.h>
+#include <linux/filter.h>
+#include <net/if.h>
+
+#include "socket.h"
+
+#include <daemon.h>
+
+/* constants for packet handling */
+#define IP_LEN sizeof(struct iphdr)
+#define IP6_LEN sizeof(struct ip6_hdr)
+#define UDP_LEN sizeof(struct udphdr)
+#define MARKER_LEN sizeof(u_int32_t)
+
+/* offsets for packet handling */
+#define IP_PROTO_OFFSET 9
+#define IP6_PROTO_OFFSET 6
+#define IKE_VERSION_OFFSET 17
+#define IKE_LENGTH_OFFSET 24
+
+/* from linux/in.h */
+#ifndef IP_IPSEC_POLICY
+#define IP_IPSEC_POLICY 16
+#endif /*IP_IPSEC_POLICY*/
+
+/* from linux/udp.h */
+#ifndef UDP_ENCAP
+#define UDP_ENCAP 100
+#endif /*UDP_ENCAP*/
+
+#ifndef UDP_ENCAP_ESPINUDP
+#define UDP_ENCAP_ESPINUDP 2
+#endif /*UDP_ENCAP_ESPINUDP*/
+
+/* needed for older kernel headers */
+#ifndef IPV6_2292PKTINFO
+#define IPV6_2292PKTINFO 2
+#endif /*IPV6_2292PKTINFO*/
+
+/* missing on uclibc */
+#ifndef IPV6_IPSEC_POLICY
+#define IPV6_IPSEC_POLICY 34
+#endif /*IPV6_IPSEC_POLICY*/
+
+typedef struct private_socket_t private_socket_t;
+
+/**
+ * Private data of an socket_t object
+ */
+struct private_socket_t{
+ /**
+ * public functions
+ */
+ socket_t public;
+
+ /**
+ * regular port
+ */
+ int port;
+
+ /**
+ * port used for nat-t
+ */
+ int natt_port;
+
+ /**
+ * raw receiver socket for IPv4
+ */
+ int recv4;
+
+ /**
+ * raw receiver socket for IPv6
+ */
+ int recv6;
+
+ /**
+ * send socket on regular port for IPv4
+ */
+ int send4;
+
+ /**
+ * send socket on regular port for IPv6
+ */
+ int send6;
+
+ /**
+ * send socket on nat-t port for IPv4
+ */
+ int send4_natt;
+
+ /**
+ * send socket on nat-t port for IPv6
+ */
+ int send6_natt;
+};
+
+/**
+ * implementation of socket_t.receive
+ */
+static status_t receiver(private_socket_t *this, packet_t **packet)
+{
+ char buffer[MAX_PACKET];
+ chunk_t data;
+ packet_t *pkt;
+ struct udphdr *udp;
+ host_t *source = NULL, *dest = NULL;
+ int bytes_read = 0;
+ int data_offset, oldstate;
+ fd_set rfds;
+
+ FD_ZERO(&rfds);
+
+ if (this->recv4)
+ {
+ FD_SET(this->recv4, &rfds);
+ }
+ if (this->recv6)
+ {
+ FD_SET(this->recv6, &rfds);
+ }
+
+ DBG2(DBG_NET, "waiting for data on raw sockets");
+
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
+ if (select(max(this->recv4, this->recv6) + 1, &rfds, NULL, NULL, NULL) <= 0)
+ {
+ pthread_setcancelstate(oldstate, NULL);
+ return FAILED;
+ }
+ pthread_setcancelstate(oldstate, NULL);
+
+ if (this->recv4 && FD_ISSET(this->recv4, &rfds))
+ {
+ /* IPv4 raw sockets return the IP header. We read src/dest
+ * information directly from the raw header */
+ struct iphdr *ip;
+ struct sockaddr_in src, dst;
+
+ bytes_read = recv(this->recv4, buffer, MAX_PACKET, 0);
+ if (bytes_read < 0)
+ {
+ DBG1(DBG_NET, "error reading from IPv4 socket: %s", strerror(errno));
+ return FAILED;
+ }
+ DBG3(DBG_NET, "received IPv4 packet %b", buffer, bytes_read);
+
+ /* read source/dest from raw IP/UDP header */
+ if (bytes_read < IP_LEN + UDP_LEN + MARKER_LEN)
+ {
+ DBG1(DBG_NET, "received IPv4 packet too short (%d bytes)",
+ bytes_read);
+ return FAILED;
+ }
+ ip = (struct iphdr*) buffer;
+ udp = (struct udphdr*) (buffer + IP_LEN);
+ src.sin_family = AF_INET;
+ src.sin_addr.s_addr = ip->saddr;
+ src.sin_port = udp->source;
+ dst.sin_family = AF_INET;
+ dst.sin_addr.s_addr = ip->daddr;
+ dst.sin_port = udp->dest;
+ source = host_create_from_sockaddr((sockaddr_t*)&src);
+ dest = host_create_from_sockaddr((sockaddr_t*)&dst);
+
+ pkt = packet_create();
+ pkt->set_source(pkt, source);
+ pkt->set_destination(pkt, dest);
+ DBG2(DBG_NET, "received packet: from %#H to %#H", source, dest);
+ data_offset = IP_LEN + UDP_LEN;
+ /* remove non esp marker */
+ if (dest->get_port(dest) == IKEV2_NATT_PORT)
+ {
+ data_offset += MARKER_LEN;
+ }
+ /* fill in packet */
+ data.len = bytes_read - data_offset;
+ data.ptr = malloc(data.len);
+ memcpy(data.ptr, buffer + data_offset, data.len);
+ pkt->set_data(pkt, data);
+ }
+ else if (this->recv6 && FD_ISSET(this->recv6, &rfds))
+ {
+ /* IPv6 raw sockets return no IP header. We must query
+ * src/dest via socket options/ancillary data */
+ struct msghdr msg;
+ struct cmsghdr *cmsgptr;
+ struct sockaddr_in6 src, dst;
+ struct iovec iov;
+ char ancillary[64];
+
+ msg.msg_name = &src;
+ msg.msg_namelen = sizeof(src);
+ iov.iov_base = buffer;
+ iov.iov_len = sizeof(buffer);
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = ancillary;
+ msg.msg_controllen = sizeof(ancillary);
+ msg.msg_flags = 0;
+
+ bytes_read = recvmsg(this->recv6, &msg, 0);
+ if (bytes_read < 0)
+ {
+ DBG1(DBG_NET, "error reading from IPv6 socket: %s", strerror(errno));
+ return FAILED;
+ }
+ DBG3(DBG_NET, "received IPv6 packet %b", buffer, bytes_read);
+
+ if (bytes_read < IP_LEN + UDP_LEN + MARKER_LEN)
+ {
+ DBG3(DBG_NET, "received IPv6 packet too short (%d bytes)",
+ bytes_read);
+ return FAILED;
+ }
+
+ /* read ancillary data to get destination address */
+ for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
+ cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
+ {
+ if (cmsgptr->cmsg_len == 0)
+ {
+ DBG1(DBG_NET, "error reading IPv6 ancillary data");
+ return FAILED;
+ }
+ if (cmsgptr->cmsg_level == SOL_IPV6 &&
+ cmsgptr->cmsg_type == IPV6_2292PKTINFO)
+ {
+ struct in6_pktinfo *pktinfo;
+ pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsgptr);
+
+ memset(&dst, 0, sizeof(dst));
+ memcpy(&dst.sin6_addr, &pktinfo->ipi6_addr, sizeof(dst.sin6_addr));
+ dst.sin6_family = AF_INET6;
+ udp = (struct udphdr*) (buffer);
+ dst.sin6_port = udp->dest;
+ src.sin6_port = udp->source;
+ dest = host_create_from_sockaddr((sockaddr_t*)&dst);
+ }
+ }
+ /* ancillary data missing? */
+ if (dest == NULL)
+ {
+ DBG1(DBG_NET, "error reading IPv6 packet header");
+ return FAILED;
+ }
+
+ source = host_create_from_sockaddr((sockaddr_t*)&src);
+
+ pkt = packet_create();
+ pkt->set_source(pkt, source);
+ pkt->set_destination(pkt, dest);
+ DBG2(DBG_NET, "received packet: from %#H to %#H", source, dest);
+ data_offset = UDP_LEN;
+ /* remove non esp marker */
+ if (dest->get_port(dest) == IKEV2_NATT_PORT)
+ {
+ data_offset += MARKER_LEN;
+ }
+ /* fill in packet */
+ data.len = bytes_read - data_offset;
+ data.ptr = malloc(data.len);
+ memcpy(data.ptr, buffer + data_offset, data.len);
+ pkt->set_data(pkt, data);
+ }
+ else
+ {
+ /* oops, shouldn't happen */
+ return FAILED;
+ }
+
+ /* return packet */
+ *packet = pkt;
+ return SUCCESS;
+}
+
+/**
+ * implementation of socket_t.send
+ */
+status_t sender(private_socket_t *this, packet_t *packet)
+{
+ int sport, skt, family;
+ ssize_t bytes_sent;
+ chunk_t data, marked;
+ host_t *src, *dst;
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+ struct iovec iov;
+
+ src = packet->get_source(packet);
+ dst = packet->get_destination(packet);
+ data = packet->get_data(packet);
+
+ DBG2(DBG_NET, "sending packet: from %#H to %#H", src, dst);
+
+ /* send data */
+ sport = src->get_port(src);
+ family = dst->get_family(dst);
+ if (sport == IKEV2_UDP_PORT)
+ {
+ if (family == AF_INET)
+ {
+ skt = this->send4;
+ }
+ else
+ {
+ skt = this->send6;
+ }
+ }
+ else if (sport == IKEV2_NATT_PORT)
+ {
+ if (family == AF_INET)
+ {
+ skt = this->send4_natt;
+ }
+ else
+ {
+ skt = this->send6_natt;
+ }
+ /* NAT keepalives without marker */
+ if (data.len != 1 || data.ptr[0] != 0xFF)
+ {
+ /* add non esp marker to packet */
+ if (data.len > MAX_PACKET - MARKER_LEN)
+ {
+ DBG1(DBG_NET, "unable to send packet: it's too big (%d bytes)",
+ data.len);
+ return FAILED;
+ }
+ marked = chunk_alloc(data.len + MARKER_LEN);
+ memset(marked.ptr, 0, MARKER_LEN);
+ memcpy(marked.ptr + MARKER_LEN, data.ptr, data.len);
+ /* let the packet do the clean up for us */
+ packet->set_data(packet, marked);
+ data = marked;
+ }
+ }
+ else
+ {
+ DBG1(DBG_NET, "unable to locate a send socket for port %d", sport);
+ return FAILED;
+ }
+
+ memset(&msg, 0, sizeof(struct msghdr));
+ msg.msg_name = dst->get_sockaddr(dst);;
+ msg.msg_namelen = *dst->get_sockaddr_len(dst);
+ iov.iov_base = data.ptr;
+ iov.iov_len = data.len;
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_flags = 0;
+
+ if (!dst->is_anyaddr(dst))
+ {
+ if (family == AF_INET)
+ {
+ char buf[CMSG_SPACE(sizeof(struct in_pktinfo))];
+ struct in_pktinfo *pktinfo;
+ struct sockaddr_in *sin;
+
+ msg.msg_control = buf;
+ msg.msg_controllen = sizeof(buf);
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_level = SOL_IP;
+ cmsg->cmsg_type = IP_PKTINFO;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
+ pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg);
+ memset(pktinfo, 0, sizeof(struct in_pktinfo));
+ sin = (struct sockaddr_in*)src->get_sockaddr(src);
+ memcpy(&pktinfo->ipi_spec_dst, &sin->sin_addr, sizeof(struct in_addr));
+ }
+ else
+ {
+ char buf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
+ struct in6_pktinfo *pktinfo;
+ struct sockaddr_in6 *sin;
+
+ msg.msg_control = buf;
+ msg.msg_controllen = sizeof(buf);
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_level = SOL_IPV6;
+ cmsg->cmsg_type = IPV6_2292PKTINFO;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
+ pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsg);
+ memset(pktinfo, 0, sizeof(struct in6_pktinfo));
+ sin = (struct sockaddr_in6*)src->get_sockaddr(src);
+ memcpy(&pktinfo->ipi6_addr, &sin->sin6_addr, sizeof(struct in6_addr));
+ }
+ }
+
+ bytes_sent = sendmsg(skt, &msg, 0);
+
+ if (bytes_sent != data.len)
+ {
+ DBG1(DBG_NET, "error writing to socket: %s", strerror(errno));
+ return FAILED;
+ }
+ return SUCCESS;
+}
+
+/**
+ * open a socket to send packets
+ */
+static int open_send_socket(private_socket_t *this, int family, u_int16_t port)
+{
+ int on = TRUE;
+ int type = UDP_ENCAP_ESPINUDP;
+ struct sockaddr_storage addr;
+ u_int sol, ipsec_policy;
+ struct sadb_x_policy policy;
+ int skt;
+
+ memset(&addr, 0, sizeof(addr));
+ /* precalculate constants depending on address family */
+ switch (family)
+ {
+ case AF_INET:
+ {
+ struct sockaddr_in *sin = (struct sockaddr_in *)&addr;
+ sin->sin_family = AF_INET;
+ sin->sin_addr.s_addr = INADDR_ANY;
+ sin->sin_port = htons(port);
+ sol = SOL_IP;
+ ipsec_policy = IP_IPSEC_POLICY;
+ break;
+ }
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr;
+ sin6->sin6_family = AF_INET6;
+ memcpy(&sin6->sin6_addr, &in6addr_any, sizeof(in6addr_any));
+ sin6->sin6_port = htons(port);
+ sol = SOL_IPV6;
+ ipsec_policy = IPV6_IPSEC_POLICY;
+ break;
+ }
+ default:
+ return 0;
+ }
+
+ skt = socket(family, SOCK_DGRAM, IPPROTO_UDP);
+ if (skt < 0)
+ {
+ DBG1(DBG_NET, "could not open send socket: %s", strerror(errno));
+ return 0;
+ }
+
+ if (setsockopt(skt, SOL_SOCKET, SO_REUSEADDR, (void*)&on, sizeof(on)) < 0)
+ {
+ DBG1(DBG_NET, "unable to set SO_REUSEADDR on send socket: %s",
+ strerror(errno));
+ close(skt);
+ return 0;
+ }
+
+ /* bypass outgoung IKE traffic on send socket */
+ memset(&policy, 0, sizeof(policy));
+ policy.sadb_x_policy_len = sizeof(policy) / sizeof(u_int64_t);
+ policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
+ policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS;
+ policy.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
+
+ if (setsockopt(skt, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
+ {
+ DBG1(DBG_NET, "unable to set IPSEC_POLICY on send socket: %s",
+ strerror(errno));
+ close(skt);
+ return 0;
+ }
+
+ /* We don't receive packets on the send socket, but we need a INBOUND policy.
+ * Otherwise, UDP decapsulation does not work!!! */
+ policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
+ if (setsockopt(skt, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
+ {
+ DBG1(DBG_NET, "unable to set IPSEC_POLICY on send socket: %s",
+ strerror(errno));
+ close(skt);
+ return 0;
+ }
+
+ /* bind the send socket */
+ if (bind(skt, (struct sockaddr *)&addr, sizeof(addr)) < 0)
+ {
+ DBG1(DBG_NET, "unable to bind send socket: %s",
+ strerror(errno));
+ close(skt);
+ return 0;
+ }
+
+ if (family == AF_INET)
+ {
+ /* enable UDP decapsulation globally, only for one socket needed */
+ if (setsockopt(skt, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0)
+ {
+ DBG1(DBG_NET, "unable to set UDP_ENCAP: %s; NAT-T may fail",
+ strerror(errno));
+ }
+ }
+
+ return skt;
+}
+
+/**
+ * open a socket to receive packets
+ */
+static int open_recv_socket(private_socket_t *this, int family)
+{
+ int skt;
+ int on = TRUE;
+ u_int proto_offset, ip_len, sol, ipsec_policy, udp_header, ike_header;
+ struct sadb_x_policy policy;
+
+ /* precalculate constants depending on address family */
+ switch (family)
+ {
+ case AF_INET:
+ proto_offset = IP_PROTO_OFFSET;
+ ip_len = IP_LEN;
+ sol = SOL_IP;
+ ipsec_policy = IP_IPSEC_POLICY;
+ break;
+ case AF_INET6:
+ proto_offset = IP6_PROTO_OFFSET;
+ ip_len = 0; /* IPv6 raw sockets contain no IP header */
+ sol = SOL_IPV6;
+ ipsec_policy = IPV6_IPSEC_POLICY;
+ break;
+ default:
+ return 0;
+ }
+ udp_header = ip_len;
+ ike_header = ip_len + UDP_LEN;
+
+ /* This filter code filters out all non-IKEv2 traffic on
+ * a SOCK_RAW IP_PROTP_UDP socket. Handling of other
+ * IKE versions is done in pluto.
+ */
+ struct sock_filter ikev2_filter_code[] =
+ {
+ /* Destination Port must be either port or natt_port */
+ BPF_STMT(BPF_LD+BPF_H+BPF_ABS, udp_header + 2),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IKEV2_UDP_PORT, 1, 0),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IKEV2_NATT_PORT, 5, 12),
+ /* port */
+ /* IKE version must be 2.0 */
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, ike_header + IKE_VERSION_OFFSET),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x20, 0, 10),
+ /* packet length is length in IKEv2 header + ip header + udp header */
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, ike_header + IKE_LENGTH_OFFSET),
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, ip_len + UDP_LEN),
+ BPF_STMT(BPF_RET+BPF_A, 0),
+ /* natt_port */
+ /* nat-t: check for marker */
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, ike_header),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 5),
+ /* nat-t: IKE version must be 2.0 */
+ BPF_STMT(BPF_LD+BPF_B+BPF_ABS, ike_header + MARKER_LEN + IKE_VERSION_OFFSET),
+ BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x20, 0, 3),
+ /* nat-t: packet length is length in IKEv2 header + ip header + udp header + non esp marker */
+ BPF_STMT(BPF_LD+BPF_W+BPF_ABS, ike_header + MARKER_LEN + IKE_LENGTH_OFFSET),
+ BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, ip_len + UDP_LEN + MARKER_LEN),
+ BPF_STMT(BPF_RET+BPF_A, 0),
+ /* packet doesn't match, ignore */
+ BPF_STMT(BPF_RET+BPF_K, 0),
+ };
+
+ /* Filter struct to use with setsockopt */
+ struct sock_fprog ikev2_filter = {
+ sizeof(ikev2_filter_code) / sizeof(struct sock_filter),
+ ikev2_filter_code
+ };
+
+ /* set up a raw socket */
+ skt = socket(family, SOCK_RAW, IPPROTO_UDP);
+ if (skt < 0)
+ {
+ DBG1(DBG_NET, "unable to create raw socket: %s", strerror(errno));
+ return 0;
+ }
+
+ if (setsockopt(skt, SOL_SOCKET, SO_ATTACH_FILTER,
+ &ikev2_filter, sizeof(ikev2_filter)) < 0)
+ {
+ DBG1(DBG_NET, "unable to attach IKEv2 filter to raw socket: %s",
+ strerror(errno));
+ close(skt);
+ return 0;
+ }
+
+ if (family == AF_INET6 &&
+ /* we use IPV6_2292PKTINFO, as IPV6_PKTINFO is defined as
+ * 2 or 50 depending on kernel header version */
+ setsockopt(skt, sol, IPV6_2292PKTINFO, &on, sizeof(on)) < 0)
+ {
+ DBG1(DBG_NET, "unable to set IPV6_PKTINFO on raw socket: %s",
+ strerror(errno));
+ close(skt);
+ return 0;
+ }
+
+ /* bypass incomining IKE traffic on this socket */
+ memset(&policy, 0, sizeof(policy));
+ policy.sadb_x_policy_len = sizeof(policy) / sizeof(u_int64_t);
+ policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
+ policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS;
+ policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
+
+ if (setsockopt(skt, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
+ {
+ DBG1(DBG_NET, "unable to set IPSEC_POLICY on raw socket: %s",
+ strerror(errno));
+ close(skt);
+ return 0;
+ }
+
+ return skt;
+}
+
+/**
+ * implementation of socket_t.destroy
+ */
+static void destroy(private_socket_t *this)
+{
+ if (this->recv4)
+ {
+ close(this->recv4);
+ }
+ if (this->recv6)
+ {
+ close(this->recv6);
+ }
+ if (this->send4)
+ {
+ close(this->send4);
+ }
+ if (this->send6)
+ {
+ close(this->send6);
+ }
+ if (this->send4_natt)
+ {
+ close(this->send4_natt);
+ }
+ if (this->send6_natt)
+ {
+ close(this->send6_natt);
+ }
+ free(this);
+}
+
+/*
+ * See header for description
+ */
+socket_t *socket_create()
+{
+ int key;
+ private_socket_t *this = malloc_thing(private_socket_t);
+
+ /* public functions */
+ this->public.send = (status_t(*)(socket_t*, packet_t*))sender;
+ this->public.receive = (status_t(*)(socket_t*, packet_t**))receiver;
+ this->public.destroy = (void(*)(socket_t*)) destroy;
+
+ this->recv4 = 0;
+ this->recv6 = 0;
+ this->send4 = 0;
+ this->send6 = 0;
+ this->send4_natt = 0;
+ this->send6_natt = 0;
+
+ /* we open a AF_KEY socket to autoload the af_key module. Otherwise
+ * setsockopt(IPSEC_POLICY) won't work. */
+ key = socket(AF_KEY, SOCK_RAW, PF_KEY_V2);
+ if (key == 0)
+ {
+ charon->kill(charon, "could not open AF_KEY socket");
+ }
+ close(key);
+
+ this->recv4 = open_recv_socket(this, AF_INET);
+ if (this->recv4 == 0)
+ {
+ DBG1(DBG_NET, "could not open IPv4 receive socket, IPv4 disabled");
+ }
+ else
+ {
+ this->send4 = open_send_socket(this, AF_INET, IKEV2_UDP_PORT);
+ if (this->send4 == 0)
+ {
+ DBG1(DBG_NET, "could not open IPv4 send socket, IPv4 disabled");
+ close(this->recv4);
+ }
+ else
+ {
+ this->send4_natt = open_send_socket(this, AF_INET, IKEV2_NATT_PORT);
+ if (this->send4_natt == 0)
+ {
+ DBG1(DBG_NET, "could not open IPv4 NAT-T send socket");
+ }
+ }
+ }
+
+ this->recv6 = open_recv_socket(this, AF_INET6);
+ if (this->recv6 == 0)
+ {
+ DBG1(DBG_NET, "could not open IPv6 receive socket, IPv6 disabled");
+ }
+ else
+ {
+ this->send6 = open_send_socket(this, AF_INET6, IKEV2_UDP_PORT);
+ if (this->send6 == 0)
+ {
+ DBG1(DBG_NET, "could not open IPv6 send socket, IPv6 disabled");
+ close(this->recv6);
+ }
+ else
+ {
+ this->send6_natt = open_send_socket(this, AF_INET6, IKEV2_NATT_PORT);
+ if (this->send6_natt == 0)
+ {
+ DBG1(DBG_NET, "could not open IPv6 NAT-T send socket");
+ }
+ }
+ }
+
+ if (!(this->send4 || this->send6) || !(this->recv4 || this->recv6))
+ {
+ DBG1(DBG_NET, "could not create any sockets");
+ destroy(this);
+ charon->kill(charon, "socket initialization failed");
+ }
+
+ return (socket_t*)this;
+}
diff --git a/src/charon/network/socket.c b/src/charon/network/socket.c
index dd231ebed..a4c407579 100644
--- a/src/charon/network/socket.c
+++ b/src/charon/network/socket.c
@@ -7,7 +7,7 @@
/*
* Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
- * Copyright (C) 2005-2006 Martin Willi
+ * Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -43,18 +43,9 @@
#include <daemon.h>
-/* constants for packet handling */
-#define IP_LEN sizeof(struct iphdr)
-#define IP6_LEN sizeof(struct ip6_hdr)
-#define UDP_LEN sizeof(struct udphdr)
+/* length of non-esp marker */
#define MARKER_LEN sizeof(u_int32_t)
-/* offsets for packet handling */
-#define IP_PROTO_OFFSET 9
-#define IP6_PROTO_OFFSET 6
-#define IKE_VERSION_OFFSET 17
-#define IKE_LENGTH_OFFSET 24
-
/* from linux/in.h */
#ifndef IP_IPSEC_POLICY
#define IP_IPSEC_POLICY 16
@@ -84,51 +75,31 @@ typedef struct private_socket_t private_socket_t;
/**
* Private data of an socket_t object
*/
-struct private_socket_t{
+struct private_socket_t {
/**
* public functions
*/
socket_t public;
-
- /**
- * regular port
- */
- int port;
-
- /**
- * port used for nat-t
- */
- int natt_port;
/**
- * raw receiver socket for IPv4
+ * IPv4 socket (500)
*/
- int recv4;
+ int ipv4;
/**
- * raw receiver socket for IPv6
- */
- int recv6;
-
- /**
- * send socket on regular port for IPv4
+ * IPv4 socket for NATT (4500)
*/
- int send4;
-
- /**
- * send socket on regular port for IPv6
- */
- int send6;
-
+ int ipv4_natt;
+
/**
- * send socket on nat-t port for IPv4
+ * IPv6 socket (500)
*/
- int send4_natt;
-
+ int ipv6;
+
/**
- * send socket on nat-t port for IPv6
+ * IPv6 socket for NATT (4500)
*/
- int send6_natt;
+ int ipv6_natt;
};
/**
@@ -139,91 +110,72 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
char buffer[MAX_PACKET];
chunk_t data;
packet_t *pkt;
- struct udphdr *udp;
host_t *source = NULL, *dest = NULL;
int bytes_read = 0;
int data_offset, oldstate;
fd_set rfds;
+ int max_fd = 0, selected = 0;
+ u_int16_t port;
FD_ZERO(&rfds);
- if (this->recv4)
+ if (this->ipv4)
{
- FD_SET(this->recv4, &rfds);
+ FD_SET(this->ipv4, &rfds);
}
- if (this->recv6)
+ if (this->ipv4_natt)
{
- FD_SET(this->recv6, &rfds);
+ FD_SET(this->ipv4_natt, &rfds);
}
+ if (this->ipv6)
+ {
+ FD_SET(this->ipv6, &rfds);
+ }
+ if (this->ipv6_natt)
+ {
+ FD_SET(this->ipv6_natt, &rfds);
+ }
+ max_fd = max(max(this->ipv4, this->ipv4_natt), max(this->ipv6, this->ipv6_natt));
- DBG2(DBG_NET, "waiting for data on raw sockets");
-
+ DBG2(DBG_NET, "waiting for data on sockets");
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
- if (select(max(this->recv4, this->recv6) + 1, &rfds, NULL, NULL, NULL) <= 0)
+ if (select(max_fd + 1, &rfds, NULL, NULL, NULL) <= 0)
{
pthread_setcancelstate(oldstate, NULL);
return FAILED;
}
pthread_setcancelstate(oldstate, NULL);
- if (this->recv4 && FD_ISSET(this->recv4, &rfds))
+ if (FD_ISSET(this->ipv4, &rfds))
{
- /* IPv4 raw sockets return the IP header. We read src/dest
- * information directly from the raw header */
- struct iphdr *ip;
- struct sockaddr_in src, dst;
-
- bytes_read = recv(this->recv4, buffer, MAX_PACKET, 0);
- if (bytes_read < 0)
- {
- DBG1(DBG_NET, "error reading from IPv4 socket: %s", strerror(errno));
- return FAILED;
- }
- DBG3(DBG_NET, "received IPv4 packet %b", buffer, bytes_read);
-
- /* read source/dest from raw IP/UDP header */
- if (bytes_read < IP_LEN + UDP_LEN + MARKER_LEN)
- {
- DBG1(DBG_NET, "received IPv4 packet too short (%d bytes)",
- bytes_read);
- return FAILED;
- }
- ip = (struct iphdr*) buffer;
- udp = (struct udphdr*) (buffer + IP_LEN);
- src.sin_family = AF_INET;
- src.sin_addr.s_addr = ip->saddr;
- src.sin_port = udp->source;
- dst.sin_family = AF_INET;
- dst.sin_addr.s_addr = ip->daddr;
- dst.sin_port = udp->dest;
- source = host_create_from_sockaddr((sockaddr_t*)&src);
- dest = host_create_from_sockaddr((sockaddr_t*)&dst);
-
- pkt = packet_create();
- pkt->set_source(pkt, source);
- pkt->set_destination(pkt, dest);
- DBG2(DBG_NET, "received packet: from %#H to %#H", source, dest);
- data_offset = IP_LEN + UDP_LEN;
- /* remove non esp marker */
- if (dest->get_port(dest) == this->natt_port)
- {
- data_offset += MARKER_LEN;
- }
- /* fill in packet */
- data.len = bytes_read - data_offset;
- data.ptr = malloc(data.len);
- memcpy(data.ptr, buffer + data_offset, data.len);
- pkt->set_data(pkt, data);
+ port = IKEV2_UDP_PORT;
+ selected = this->ipv4;
}
- else if (this->recv6 && FD_ISSET(this->recv6, &rfds))
+ if (FD_ISSET(this->ipv4_natt, &rfds))
+ {
+ port = IKEV2_NATT_PORT;
+ selected = this->ipv4_natt;
+ }
+ if (FD_ISSET(this->ipv6, &rfds))
+ {
+ port = IKEV2_UDP_PORT;
+ selected = this->ipv6;
+ }
+ if (FD_ISSET(this->ipv6_natt, &rfds))
+ {
+ port = IKEV2_NATT_PORT;
+ selected = this->ipv6_natt;
+ }
+ if (selected)
{
- /* IPv6 raw sockets return no IP header. We must query
- * src/dest via socket options/ancillary data */
struct msghdr msg;
struct cmsghdr *cmsgptr;
- struct sockaddr_in6 src, dst;
struct iovec iov;
char ancillary[64];
+ union {
+ struct sockaddr_in in4;
+ struct sockaddr_in6 in6;
+ } src;
msg.msg_name = &src;
msg.msg_namelen = sizeof(src);
@@ -234,18 +186,17 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
msg.msg_control = ancillary;
msg.msg_controllen = sizeof(ancillary);
msg.msg_flags = 0;
-
- bytes_read = recvmsg(this->recv6, &msg, 0);
+ bytes_read = recvmsg(selected, &msg, 0);
if (bytes_read < 0)
{
- DBG1(DBG_NET, "error reading from IPv6 socket: %s", strerror(errno));
+ DBG1(DBG_NET, "error reading socket: %s", strerror(errno));
return FAILED;
}
- DBG3(DBG_NET, "received IPv6 packet %b", buffer, bytes_read);
+ DBG3(DBG_NET, "received packet %b", buffer, bytes_read);
- if (bytes_read < IP_LEN + UDP_LEN + MARKER_LEN)
+ if (bytes_read < MARKER_LEN)
{
- DBG3(DBG_NET, "received IPv6 packet too short (%d bytes)",
+ DBG3(DBG_NET, "received packet too short (%d bytes)",
bytes_read);
return FAILED;
}
@@ -256,40 +207,55 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
{
if (cmsgptr->cmsg_len == 0)
{
- DBG1(DBG_NET, "error reading IPv6 ancillary data");
+ DBG1(DBG_NET, "error reading ancillary data");
return FAILED;
- }
+ }
+
if (cmsgptr->cmsg_level == SOL_IPV6 &&
cmsgptr->cmsg_type == IPV6_2292PKTINFO)
{
struct in6_pktinfo *pktinfo;
pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsgptr);
+ struct sockaddr_in6 dst;
memset(&dst, 0, sizeof(dst));
memcpy(&dst.sin6_addr, &pktinfo->ipi6_addr, sizeof(dst.sin6_addr));
dst.sin6_family = AF_INET6;
- udp = (struct udphdr*) (buffer);
- dst.sin6_port = udp->dest;
- src.sin6_port = udp->source;
+ dst.sin6_port = htons(port);
dest = host_create_from_sockaddr((sockaddr_t*)&dst);
}
+ if (cmsgptr->cmsg_level == SOL_IP &&
+ cmsgptr->cmsg_type == IP_PKTINFO)
+ {
+ struct in_pktinfo *pktinfo;
+ pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsgptr);
+ struct sockaddr_in dst;
+
+ memset(&dst, 0, sizeof(dst));
+ memcpy(&dst.sin_addr, &pktinfo->ipi_addr, sizeof(dst.sin_addr));
+ dst.sin_family = AF_INET;
+ dst.sin_port = htons(port);
+ dest = host_create_from_sockaddr((sockaddr_t*)&dst);
+ }
+ if (dest)
+ {
+ break;
+ }
}
- /* ancillary data missing? */
if (dest == NULL)
{
- DBG1(DBG_NET, "error reading IPv6 packet header");
+ DBG1(DBG_NET, "error reading IP header");
return FAILED;
}
-
source = host_create_from_sockaddr((sockaddr_t*)&src);
pkt = packet_create();
pkt->set_source(pkt, source);
pkt->set_destination(pkt, dest);
DBG2(DBG_NET, "received packet: from %#H to %#H", source, dest);
- data_offset = UDP_LEN;
+ data_offset = 0;
/* remove non esp marker */
- if (dest->get_port(dest) == this->natt_port)
+ if (dest->get_port(dest) == IKEV2_NATT_PORT)
{
data_offset += MARKER_LEN;
}
@@ -304,7 +270,6 @@ static status_t receiver(private_socket_t *this, packet_t **packet)
/* oops, shouldn't happen */
return FAILED;
}
-
/* return packet */
*packet = pkt;
return SUCCESS;
@@ -332,26 +297,26 @@ status_t sender(private_socket_t *this, packet_t *packet)
/* send data */
sport = src->get_port(src);
family = dst->get_family(dst);
- if (sport == this->port)
+ if (sport == IKEV2_UDP_PORT)
{
if (family == AF_INET)
{
- skt = this->send4;
+ skt = this->ipv4;
}
else
{
- skt = this->send6;
+ skt = this->ipv6;
}
}
- else if (sport == this->natt_port)
+ else if (sport == IKEV2_NATT_PORT)
{
if (family == AF_INET)
{
- skt = this->send4_natt;
+ skt = this->ipv4_natt;
}
else
{
- skt = this->send6_natt;
+ skt = this->ipv6_natt;
}
/* NAT keepalives without marker */
if (data.len != 1 || data.ptr[0] != 0xFF)
@@ -437,12 +402,12 @@ status_t sender(private_socket_t *this, packet_t *packet)
/**
* open a socket to send packets
*/
-static int open_send_socket(private_socket_t *this, int family, u_int16_t port)
+static int open_socket(private_socket_t *this, int family, u_int16_t port)
{
int on = TRUE;
int type = UDP_ENCAP_ESPINUDP;
struct sockaddr_storage addr;
- u_int sol, ipsec_policy;
+ u_int sol, ipsec_policy, pktinfo;
struct sadb_x_policy policy;
int skt;
@@ -458,6 +423,7 @@ static int open_send_socket(private_socket_t *this, int family, u_int16_t port)
sin->sin_port = htons(port);
sol = SOL_IP;
ipsec_policy = IP_IPSEC_POLICY;
+ pktinfo = IP_PKTINFO;
break;
}
case AF_INET6:
@@ -468,6 +434,7 @@ static int open_send_socket(private_socket_t *this, int family, u_int16_t port)
sin6->sin6_port = htons(port);
sol = SOL_IPV6;
ipsec_policy = IPV6_IPSEC_POLICY;
+ pktinfo = IPV6_2292PKTINFO;
break;
}
default:
@@ -477,39 +444,34 @@ static int open_send_socket(private_socket_t *this, int family, u_int16_t port)
skt = socket(family, SOCK_DGRAM, IPPROTO_UDP);
if (skt < 0)
{
- DBG1(DBG_NET, "could not open send socket: %s", strerror(errno));
+ DBG1(DBG_NET, "could not open socket: %s", strerror(errno));
return 0;
}
-
if (setsockopt(skt, SOL_SOCKET, SO_REUSEADDR, (void*)&on, sizeof(on)) < 0)
{
- DBG1(DBG_NET, "unable to set SO_REUSEADDR on send socket: %s",
- strerror(errno));
+ DBG1(DBG_NET, "unable to set SO_REUSEADDR on socket: %s", strerror(errno));
close(skt);
return 0;
}
- /* bypass outgoung IKE traffic on send socket */
+ /* bypass IKE traffic on socket */
memset(&policy, 0, sizeof(policy));
policy.sadb_x_policy_len = sizeof(policy) / sizeof(u_int64_t);
policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS;
- policy.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
+ policy.sadb_x_policy_dir = IPSEC_DIR_OUTBOUND;
if (setsockopt(skt, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
{
- DBG1(DBG_NET, "unable to set IPSEC_POLICY on send socket: %s",
+ DBG1(DBG_NET, "unable to set IPSEC_POLICY on socket: %s",
strerror(errno));
close(skt);
return 0;
}
-
- /* We don't receive packets on the send socket, but we need a INBOUND policy.
- * Otherwise, UDP decapsulation does not work!!! */
policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
if (setsockopt(skt, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
{
- DBG1(DBG_NET, "unable to set IPSEC_POLICY on send socket: %s",
+ DBG1(DBG_NET, "unable to set IPSEC_POLICY on socket: %s",
strerror(errno));
close(skt);
return 0;
@@ -518,138 +480,25 @@ static int open_send_socket(private_socket_t *this, int family, u_int16_t port)
/* bind the send socket */
if (bind(skt, (struct sockaddr *)&addr, sizeof(addr)) < 0)
{
- DBG1(DBG_NET, "unable to bind send socket: %s",
- strerror(errno));
+ DBG1(DBG_NET, "unable to bind socket: %s", strerror(errno));
close(skt);
return 0;
}
- if (family == AF_INET)
+ /* get additional packet info on receive */
+ if (setsockopt(skt, sol, pktinfo, &on, sizeof(on)) < 0)
{
- /* enable UDP decapsulation globally, only for one socket needed */
- if (setsockopt(skt, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0)
- {
- DBG1(DBG_NET, "unable to set UDP_ENCAP: %s; NAT-T may fail",
- strerror(errno));
- }
- }
-
- return skt;
-}
-
-/**
- * open a socket to receive packets
- */
-static int open_recv_socket(private_socket_t *this, int family)
-{
- int skt;
- int on = TRUE;
- u_int proto_offset, ip_len, sol, ipsec_policy, udp_header, ike_header;
- struct sadb_x_policy policy;
-
- /* precalculate constants depending on address family */
- switch (family)
- {
- case AF_INET:
- proto_offset = IP_PROTO_OFFSET;
- ip_len = IP_LEN;
- sol = SOL_IP;
- ipsec_policy = IP_IPSEC_POLICY;
- break;
- case AF_INET6:
- proto_offset = IP6_PROTO_OFFSET;
- ip_len = 0; /* IPv6 raw sockets contain no IP header */
- sol = SOL_IPV6;
- ipsec_policy = IPV6_IPSEC_POLICY;
- break;
- default:
- return 0;
- }
- udp_header = ip_len;
- ike_header = ip_len + UDP_LEN;
-
- /* This filter code filters out all non-IKEv2 traffic on
- * a SOCK_RAW IP_PROTP_UDP socket. Handling of other
- * IKE versions is done in pluto.
- */
- struct sock_filter ikev2_filter_code[] =
- {
- /* Destination Port must be either port or natt_port */
- BPF_STMT(BPF_LD+BPF_H+BPF_ABS, udp_header + 2),
- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, this->port, 1, 0),
- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, this->natt_port, 5, 12),
- /* port */
- /* IKE version must be 2.0 */
- BPF_STMT(BPF_LD+BPF_B+BPF_ABS, ike_header + IKE_VERSION_OFFSET),
- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x20, 0, 10),
- /* packet length is length in IKEv2 header + ip header + udp header */
- BPF_STMT(BPF_LD+BPF_W+BPF_ABS, ike_header + IKE_LENGTH_OFFSET),
- BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, ip_len + UDP_LEN),
- BPF_STMT(BPF_RET+BPF_A, 0),
- /* natt_port */
- /* nat-t: check for marker */
- BPF_STMT(BPF_LD+BPF_W+BPF_ABS, ike_header),
- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0, 0, 5),
- /* nat-t: IKE version must be 2.0 */
- BPF_STMT(BPF_LD+BPF_B+BPF_ABS, ike_header + MARKER_LEN + IKE_VERSION_OFFSET),
- BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x20, 0, 3),
- /* nat-t: packet length is length in IKEv2 header + ip header + udp header + non esp marker */
- BPF_STMT(BPF_LD+BPF_W+BPF_ABS, ike_header + MARKER_LEN + IKE_LENGTH_OFFSET),
- BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, ip_len + UDP_LEN + MARKER_LEN),
- BPF_STMT(BPF_RET+BPF_A, 0),
- /* packet doesn't match, ignore */
- BPF_STMT(BPF_RET+BPF_K, 0),
- };
-
- /* Filter struct to use with setsockopt */
- struct sock_fprog ikev2_filter = {
- sizeof(ikev2_filter_code) / sizeof(struct sock_filter),
- ikev2_filter_code
- };
-
- /* set up a raw socket */
- skt = socket(family, SOCK_RAW, IPPROTO_UDP);
- if (skt < 0)
- {
- DBG1(DBG_NET, "unable to create raw socket: %s", strerror(errno));
- return 0;
- }
-
- if (setsockopt(skt, SOL_SOCKET, SO_ATTACH_FILTER,
- &ikev2_filter, sizeof(ikev2_filter)) < 0)
- {
- DBG1(DBG_NET, "unable to attach IKEv2 filter to raw socket: %s",
- strerror(errno));
+ DBG1(DBG_NET, "unable to set IP_PKTINFO on socket: %s", strerror(errno));
close(skt);
return 0;
}
- if (family == AF_INET6 &&
- /* we use IPV6_2292PKTINFO, as IPV6_PKTINFO is defined as
- * 2 or 50 depending on kernel header version */
- setsockopt(skt, sol, IPV6_2292PKTINFO, &on, sizeof(on)) < 0)
+ /* enable UDP decapsulation globally, only for one socket needed */
+ if (family == AF_INET && port == IKEV2_NATT_PORT &&
+ setsockopt(skt, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0)
{
- DBG1(DBG_NET, "unable to set IPV6_PKTINFO on raw socket: %s",
- strerror(errno));
- close(skt);
- return 0;
- }
-
- /* bypass incomining IKE traffic on this socket */
- memset(&policy, 0, sizeof(policy));
- policy.sadb_x_policy_len = sizeof(policy) / sizeof(u_int64_t);
- policy.sadb_x_policy_exttype = SADB_X_EXT_POLICY;
- policy.sadb_x_policy_type = IPSEC_POLICY_BYPASS;
- policy.sadb_x_policy_dir = IPSEC_DIR_INBOUND;
-
- if (setsockopt(skt, sol, ipsec_policy, &policy, sizeof(policy)) < 0)
- {
- DBG1(DBG_NET, "unable to set IPSEC_POLICY on raw socket: %s",
- strerror(errno));
- close(skt);
- return 0;
+ DBG1(DBG_NET, "unable to set UDP_ENCAP: %s", strerror(errno));
}
-
return skt;
}
@@ -658,29 +507,21 @@ static int open_recv_socket(private_socket_t *this, int family)
*/
static void destroy(private_socket_t *this)
{
- if (this->recv4)
- {
- close(this->recv4);
- }
- if (this->recv6)
- {
- close(this->recv6);
- }
- if (this->send4)
+ if (this->ipv4)
{
- close(this->send4);
+ close(this->ipv4);
}
- if (this->send6)
+ if (this->ipv4_natt)
{
- close(this->send6);
+ close(this->ipv4_natt);
}
- if (this->send4_natt)
+ if (this->ipv6)
{
- close(this->send4_natt);
+ close(this->ipv6);
}
- if (this->send6_natt)
+ if (this->ipv6_natt)
{
- close(this->send6_natt);
+ close(this->ipv6_natt);
}
free(this);
}
@@ -688,7 +529,7 @@ static void destroy(private_socket_t *this)
/*
* See header for description
*/
-socket_t *socket_create(u_int16_t port, u_int16_t natt_port)
+socket_t *socket_create()
{
int key;
private_socket_t *this = malloc_thing(private_socket_t);
@@ -698,14 +539,10 @@ socket_t *socket_create(u_int16_t port, u_int16_t natt_port)
this->public.receive = (status_t(*)(socket_t*, packet_t**))receiver;
this->public.destroy = (void(*)(socket_t*)) destroy;
- this->port = port;
- this->natt_port = natt_port;
- this->recv4 = 0;
- this->recv6 = 0;
- this->send4 = 0;
- this->send6 = 0;
- this->send4_natt = 0;
- this->send6_natt = 0;
+ this->ipv4 = 0;
+ this->ipv6 = 0;
+ this->ipv4_natt = 0;
+ this->ipv6_natt = 0;
/* we open a AF_KEY socket to autoload the af_key module. Otherwise
* setsockopt(IPSEC_POLICY) won't work. */
@@ -715,59 +552,41 @@ socket_t *socket_create(u_int16_t port, u_int16_t natt_port)
charon->kill(charon, "could not open AF_KEY socket");
}
close(key);
-
- this->recv4 = open_recv_socket(this, AF_INET);
- if (this->recv4 == 0)
+
+ this->ipv4 = open_socket(this, AF_INET, IKEV2_UDP_PORT);
+ if (this->ipv4 == 0)
{
- DBG1(DBG_NET, "could not open IPv4 receive socket, IPv4 disabled");
+ DBG1(DBG_NET, "could not open IPv4 socket, IPv4 disabled");
}
else
{
- this->send4 = open_send_socket(this, AF_INET, this->port);
- if (this->send4 == 0)
+ this->ipv4_natt = open_socket(this, AF_INET, IKEV2_NATT_PORT);
+ if (this->ipv4_natt == 0)
{
- DBG1(DBG_NET, "could not open IPv4 send socket, IPv4 disabled");
- close(this->recv4);
- }
- else
- {
- this->send4_natt = open_send_socket(this, AF_INET, this->natt_port);
- if (this->send4_natt == 0)
- {
- DBG1(DBG_NET, "could not open IPv4 NAT-T send socket");
- }
+ DBG1(DBG_NET, "could not open IPv4 NAT-T socket");
}
}
-
- this->recv6 = open_recv_socket(this, AF_INET6);
- if (this->recv6 == 0)
+
+ this->ipv6 = open_socket(this, AF_INET6, IKEV2_UDP_PORT);
+ if (this->ipv6 == 0)
{
- DBG1(DBG_NET, "could not open IPv6 receive socket, IPv6 disabled");
+ DBG1(DBG_NET, "could not open IPv6 socket, IPv6 disabled");
}
else
{
- this->send6 = open_send_socket(this, AF_INET6, this->port);
- if (this->send6 == 0)
+ this->ipv6_natt = open_socket(this, AF_INET6, IKEV2_NATT_PORT);
+ if (this->ipv6_natt == 0)
{
- DBG1(DBG_NET, "could not open IPv6 send socket, IPv6 disabled");
- close(this->recv6);
- }
- else
- {
- this->send6_natt = open_send_socket(this, AF_INET6, this->natt_port);
- if (this->send6_natt == 0)
- {
- DBG1(DBG_NET, "could not open IPv6 NAT-T send socket");
- }
+ DBG1(DBG_NET, "could not open IPv6 NAT-T socket");
}
}
- if (!(this->send4 || this->send6) || !(this->recv4 || this->recv6))
+ if (!this->ipv4 && !this->ipv6)
{
DBG1(DBG_NET, "could not create any sockets");
destroy(this);
charon->kill(charon, "socket initialization failed");
- }
-
+ }
return (socket_t*)this;
}
+
diff --git a/src/charon/network/socket.h b/src/charon/network/socket.h
index ef60fa7b6..4d8251325 100644
--- a/src/charon/network/socket.h
+++ b/src/charon/network/socket.h
@@ -100,13 +100,11 @@ struct socket_t {
/**
* @brief Create a socket_t, wich binds multiple sockets.
*
- * @param port port to bind socket to
- * @param natt_port port to float to in NAT-T
* @return socket_t object
*
* @ingroup network
*/
-socket_t *socket_create(u_int16_t port, u_int16_t natt_port);
+socket_t *socket_create();
#endif /*SOCKET_H_*/
diff --git a/src/charon/processing/jobs/callback_job.c b/src/charon/processing/jobs/callback_job.c
index 6f534e0f7..53297916e 100644
--- a/src/charon/processing/jobs/callback_job.c
+++ b/src/charon/processing/jobs/callback_job.c
@@ -121,12 +121,7 @@ static void cancel(private_callback_job_t *this)
{
pthread_t thread;
- /* wait until thread has started */
pthread_mutex_lock(&this->mutex);
- while (this->thread == 0)
- {
- pthread_cond_wait(&this->condvar, &this->mutex);
- }
thread = this->thread;
/* terminate its children */
@@ -134,8 +129,11 @@ static void cancel(private_callback_job_t *this)
pthread_mutex_unlock(&this->mutex);
/* terminate thread */
- pthread_cancel(thread);
- pthread_join(thread, NULL);
+ if (thread)
+ {
+ pthread_cancel(thread);
+ pthread_join(thread, NULL);
+ }
}
/**
@@ -159,6 +157,7 @@ static void execute(private_callback_job_t *this)
continue;
case JOB_REQUEUE_FAIR:
{
+ this->thread = 0;
charon->processor->queue_job(charon->processor,
&this->public.job_interface);
break;
@@ -166,6 +165,7 @@ static void execute(private_callback_job_t *this)
case JOB_REQUEUE_NONE:
default:
{
+ this->thread = 0;
cleanup = TRUE;
break;
}
diff --git a/src/charon/processing/jobs/initiate_mediation_job.c b/src/charon/processing/jobs/initiate_mediation_job.c
index d78f8a202..b8d516e22 100644
--- a/src/charon/processing/jobs/initiate_mediation_job.c
+++ b/src/charon/processing/jobs/initiate_mediation_job.c
@@ -73,7 +73,7 @@ static bool initiate_callback(private_initiate_mediation_job_t *this, signal_t s
{
if (signal == CHILD_UP_SUCCESS)
{
- // mediation connection is up
+ /* mediation connection is up */
this->mediation_sa_id = ike_sa->get_id(ike_sa);
this->mediation_sa_id = this->mediation_sa_id->clone(this->mediation_sa_id);
return FALSE;
@@ -85,7 +85,7 @@ static bool initiate_callback(private_initiate_mediation_job_t *this, signal_t s
* Implementation of job_t.execute.
*/
static void initiate(private_initiate_mediation_job_t *this)
-{//FIXME: check the logging
+{ /* FIXME: check the logging */
ike_sa_t *mediated_sa, *mediation_sa;
peer_cfg_t *mediated_cfg, *mediation_cfg;
@@ -94,7 +94,8 @@ static void initiate(private_initiate_mediation_job_t *this)
if (mediated_sa)
{
mediated_cfg = mediated_sa->get_peer_cfg(mediated_sa);
- mediated_cfg->get_ref(mediated_cfg); // get_peer_cfg returns an internal object
+ /* get_peer_cfg returns an internal object */
+ mediated_cfg->get_ref(mediated_cfg);
charon->ike_sa_manager->checkin(charon->ike_sa_manager, mediated_sa);
@@ -107,18 +108,19 @@ static void initiate(private_initiate_mediation_job_t *this)
{
mediated_cfg->destroy(mediated_cfg);
mediation_cfg->destroy(mediation_cfg);
- charon->bus->set_sa(charon->bus, mediated_sa); // this pointer should still be valid
+ /* this pointer should still be valid */
+ charon->bus->set_sa(charon->bus, mediated_sa);
DBG1(DBG_IKE, "mediation with the same peer is already in progress, queued");
destroy(this);
return;
}
-
- mediation_cfg->get_ref(mediation_cfg); // we need an additional reference because initiate consumes one
+ /* we need an additional reference because initiate consumes one */
+ mediation_cfg->get_ref(mediation_cfg);
- // this function call blocks until the connection is up or failed
- // we do not check the status, but NEED_MORE would be returned on success
- // because the registered callback returns FALSE then
- // this->mediation_sa_id is set in the callback
+ /* this function call blocks until the connection is up or failed
+ * we do not check the status, but NEED_MORE would be returned on success
+ * because the registered callback returns FALSE then
+ * this->mediation_sa_id is set in the callback */
charon->interfaces->initiate(charon->interfaces,
mediation_cfg, NULL, (interface_manager_cb_t)initiate_callback, this);
if (!this->mediation_sa_id)
@@ -127,7 +129,7 @@ static void initiate(private_initiate_mediation_job_t *this)
mediation_cfg->get_name(mediation_cfg));
mediation_cfg->destroy(mediation_cfg);
mediated_cfg->destroy(mediated_cfg);
- charon->bus->set_sa(charon->bus, mediated_sa); // this pointer should still be valid
+ charon->bus->set_sa(charon->bus, mediated_sa);
SIG(IKE_UP_FAILED, "mediation failed");
destroy(this);
return;
@@ -146,7 +148,7 @@ static void initiate(private_initiate_mediation_job_t *this)
mediated_cfg->destroy(mediated_cfg);
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, mediation_sa);
- charon->bus->set_sa(charon->bus, mediated_sa); // this pointer should still be valid
+ charon->bus->set_sa(charon->bus, mediated_sa);
SIG(IKE_UP_FAILED, "mediation failed");
destroy(this);
return;
@@ -164,7 +166,7 @@ static void initiate(private_initiate_mediation_job_t *this)
* Implementation of job_t.execute.
*/
static void reinitiate(private_initiate_mediation_job_t *this)
-{//FIXME: check the logging
+{ /* FIXME: check the logging */
ike_sa_t *mediated_sa, *mediation_sa;
peer_cfg_t *mediated_cfg;
@@ -173,7 +175,7 @@ static void reinitiate(private_initiate_mediation_job_t *this)
if (mediated_sa)
{
mediated_cfg = mediated_sa->get_peer_cfg(mediated_sa);
- mediated_cfg->get_ref(mediated_cfg); // get_peer_cfg returns an internal object
+ mediated_cfg->get_ref(mediated_cfg);
charon->ike_sa_manager->checkin(charon->ike_sa_manager, mediated_sa);
mediation_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
@@ -187,7 +189,7 @@ static void reinitiate(private_initiate_mediation_job_t *this)
mediated_cfg->destroy(mediated_cfg);
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, mediation_sa);
- charon->bus->set_sa(charon->bus, mediated_sa); // this pointer should still be valid
+ charon->bus->set_sa(charon->bus, mediated_sa);
SIG(IKE_UP_FAILED, "mediation failed");
destroy(this);
return;
diff --git a/src/charon/processing/jobs/mediation_job.c b/src/charon/processing/jobs/mediation_job.c
index 6f5f74372..3b9d363d7 100644
--- a/src/charon/processing/jobs/mediation_job.c
+++ b/src/charon/processing/jobs/mediation_job.c
@@ -104,7 +104,7 @@ static void execute(private_mediation_job_t *this)
{
if (this->callback)
{
- // send callback to a peer
+ /* send callback to a peer */
if (target_sa->callback(target_sa, this->source) != SUCCESS)
{
DBG1(DBG_JOB, "callback for '%D' to '%D' failed",
@@ -116,14 +116,14 @@ static void execute(private_mediation_job_t *this)
}
else
{
- // normal mediation between two peers
+ /* normal mediation between two peers */
if (target_sa->relay(target_sa, this->source, this->session_id,
this->session_key, this->endpoints, this->response) != SUCCESS)
{
DBG1(DBG_JOB, "mediation between '%D' and '%D' failed",
this->source, this->target);
charon->ike_sa_manager->checkin(charon->ike_sa_manager, target_sa);
- // FIXME: notify the initiator
+ /* FIXME: notify the initiator */
destroy(this);
return;
}
diff --git a/src/charon/processing/jobs/process_message_job.c b/src/charon/processing/jobs/process_message_job.c
index ec2e7735d..91e7a80bf 100644
--- a/src/charon/processing/jobs/process_message_job.c
+++ b/src/charon/processing/jobs/process_message_job.c
@@ -60,12 +60,13 @@ static void execute(private_process_message_job_t *this)
ike_sa_t *ike_sa;
#ifdef P2P
- // if this is an unencrypted INFORMATIONAL exchange it is likely a
- // connectivity check
+ /* if this is an unencrypted INFORMATIONAL exchange it is likely a
+ * connectivity check. */
if (this->message->get_exchange_type(this->message) == INFORMATIONAL &&
this->message->get_first_payload_type(this->message) != ENCRYPTED)
{
- // theoretically this could also be an error message see RFC 4306, section 1.5.
+ /* theoretically this could also be an error message
+ * see RFC 4306, section 1.5. */
DBG1(DBG_NET, "received unencrypted informational: from %#H to %#H",
this->message->get_source(this->message),
this->message->get_destination(this->message));
diff --git a/src/charon/processing/scheduler.c b/src/charon/processing/scheduler.c
index 2706585b0..ededb479a 100644
--- a/src/charon/processing/scheduler.c
+++ b/src/charon/processing/scheduler.c
@@ -87,6 +87,8 @@ struct private_scheduler_t {
* Condvar to wait for next job.
*/
pthread_cond_t condvar;
+
+ bool cancelled;
};
/**
@@ -148,9 +150,7 @@ static job_requeue_t schedule(private_scheduler_t * this)
pthread_cond_wait(&this->condvar, &this->mutex);
}
pthread_setcancelstate(oldstate, NULL);
- pthread_cleanup_pop(0);
-
- pthread_mutex_unlock(&this->mutex);
+ pthread_cleanup_pop(TRUE);
return JOB_REQUEUE_DIRECT;
}
@@ -234,6 +234,7 @@ static void schedule_job(private_scheduler_t *this, job_t *job, u_int32_t time)
*/
static void destroy(private_scheduler_t *this)
{
+ this->cancelled = TRUE;
this->job->cancel(this->job);
this->list->destroy_function(this->list, (void*)event_destroy);
free(this);
@@ -251,6 +252,7 @@ scheduler_t * scheduler_create()
this->public.destroy = (void(*)(scheduler_t*)) destroy;
this->list = linked_list_create();
+ this->cancelled = FALSE;
pthread_mutex_init(&this->mutex, NULL);
pthread_cond_init(&this->condvar, NULL);
diff --git a/src/charon/sa/authenticators/eap/eap_aka.c b/src/charon/sa/authenticators/eap/eap_aka.c
new file mode 100644
index 000000000..8fb1f85cd
--- /dev/null
+++ b/src/charon/sa/authenticators/eap/eap_aka.c
@@ -0,0 +1,1440 @@
+/**
+ * @file eap_aka.c
+ *
+ * @brief Implementation of eap_aka_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2006 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.
+ */
+
+
+/* The EAP-AKA method uses it's own simple parser for processing EAP-AKA
+ * payloads, as the IKEv2 parser is not suitable for that job. There are
+ * two simple methods for parsing payloads, read_header() and read_attribute().
+ * Every EAP-AKA payload consists of a header and a list of attributes. Those
+ * functions mentioned read the data and return the type of the found
+ * attribute/EAP-AKA-type. For generating a EAP-AKA message, we have a
+ * build_aka_payload(), which builds the whole message from a variable
+ * argument list containing its attributes.
+ * The processing of messages is split up in various functions:
+ * - peer_process() - General processing multiplexer for the peer
+ * - peer_process_challenge() - Specific AKA-Challenge processor
+ * - peer_process_notification() - Processing of AKA-Notification
+ * - server_process() - General processing multiplexer for the server
+ * - peer_process_challenge() - Processing of a received Challenge response
+ * - peer_process_synchronize() - Process a sequence number synchronization
+ * - server_initiate() - Initiation method for the server, calls
+ * - server_initiate_challenge() - Initiation of AKA-Challenge
+ */
+
+#include <string.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include "eap_aka.h"
+
+#include <daemon.h>
+#include <library.h>
+#include <utils/randomizer.h>
+#include <crypto/hashers/hasher.h>
+#include <crypto/prfs/fips_prf.h>
+
+/* Use test vectors specified in S.S0055
+#define TEST_VECTORS */
+
+#define RAND_LENGTH 16
+#define RES_LENGTH 16
+#define SQN_LENGTH 6
+#define K_LENGTH 16
+#define MAC_LENGTH 8
+#define CK_LENGTH 16
+#define IK_LENGTH 16
+#define AK_LENGTH 6
+#define AMF_LENGTH 2
+#define FMK_LENGTH 4
+#define AUTN_LENGTH (SQN_LENGTH + AMF_LENGTH + MAC_LENGTH)
+#define AUTS_LENGTH (SQN_LENGTH + MAC_LENGTH)
+#define PAYLOAD_LENGTH 64
+#define MK_LENGTH 20
+#define MSK_LENGTH 64
+#define EMSK_LENGTH 64
+#define KAUTH_LENGTH 16
+#define KENCR_LENGTH 16
+#define AT_MAC_LENGTH 16
+
+#define F1 0x42
+#define F1STAR 0x43
+#define F2 0x44
+#define F3 0x45
+#define F4 0x46
+#define F5 0x47
+#define F5STAR 0x48
+
+ENUM_BEGIN(aka_subtype_names, AKA_CHALLENGE, AKA_IDENTITY,
+ "AKA_CHALLENGE",
+ "AKA_AUTHENTICATION_REJECT",
+ "AKA_3",
+ "AKA_SYNCHRONIZATION_FAILURE",
+ "AKA_IDENTITY");
+ENUM_NEXT(aka_subtype_names, AKA_NOTIFICATION, AKA_CLIENT_ERROR, AKA_IDENTITY,
+ "AKA_NOTIFICATION",
+ "AKA_REAUTHENTICATION",
+ "AKA_CLIENT_ERROR");
+ENUM_END(aka_subtype_names, AKA_CLIENT_ERROR);
+
+
+ENUM_BEGIN(aka_attribute_names, AT_END, AT_CLIENT_ERROR_CODE,
+ "AT_END",
+ "AT_0",
+ "AT_RAND",
+ "AT_AUTN",
+ "AT_RES",
+ "AT_AUTS",
+ "AT_5",
+ "AT_PADDING",
+ "AT_NONCE_MT",
+ "AT_8",
+ "AT_9",
+ "AT_PERMANENT_ID_REQ",
+ "AT_MAC",
+ "AT_NOTIFICATION",
+ "AT_ANY_ID_REQ",
+ "AT_IDENTITY",
+ "AT_VERSION_LIST",
+ "AT_SELECTED_VERSION",
+ "AT_FULLAUTH_ID_REQ",
+ "AT_18",
+ "AT_COUNTER",
+ "AT_COUNTER_TOO_SMALL",
+ "AT_NONCE_S",
+ "AT_CLIENT_ERROR_CODE");
+ENUM_NEXT(aka_attribute_names, AT_IV, AT_RESULT_IND, AT_CLIENT_ERROR_CODE,
+ "AT_IV",
+ "AT_ENCR_DATA",
+ "AT_131",
+ "AT_NEXT_PSEUDONYM",
+ "AT_NEXT_REAUTH_ID",
+ "AT_CHECKCODE",
+ "AT_RESULT_IND");
+ENUM_END(aka_attribute_names, AT_RESULT_IND);
+
+
+typedef struct private_eap_aka_t private_eap_aka_t;
+
+/**
+ * Private data of an eap_aka_t object.
+ */
+struct private_eap_aka_t {
+
+ /**
+ * Public authenticator_t interface.
+ */
+ eap_aka_t public;
+
+ /**
+ * ID of the server
+ */
+ identification_t *server;
+
+ /**
+ * ID of the peer
+ */
+ identification_t *peer;
+
+ /**
+ * Key for EAP MAC
+ */
+ chunk_t k_auth;
+
+ /**
+ * Key for EAP encryption
+ */
+ chunk_t k_encr;
+
+ /**
+ * MSK
+ */
+ chunk_t msk;
+
+ /**
+ * Extendend MSK
+ */
+ chunk_t emsk;
+
+ /**
+ * Expected result from client XRES
+ */
+ chunk_t xres;
+
+ /**
+ * Shared secret K from ipsec.conf (padded)
+ */
+ chunk_t k;
+
+ /**
+ * random value RAND generated by server
+ */
+ chunk_t rand;
+};
+
+/** Family key, as proposed in S.S0055 */
+static u_int8_t fmk_buf[] = {0x41, 0x48, 0x41, 0x47};
+static chunk_t fmk = chunk_from_buf(fmk_buf);
+
+/** Authentication management field */
+static u_int8_t amf_buf[] = {0x00, 0x01};
+static chunk_t amf = chunk_from_buf(amf_buf);
+
+/** AT_CLIENT_ERROR_CODE AKA attribute */
+static u_int8_t client_error_code_buf[] = {0, 0};
+static chunk_t client_error_code = chunk_from_buf(client_error_code_buf);
+
+/** previously used sqn by peer, next one must be greater */
+static u_int8_t peer_sqn_buf[6];
+static chunk_t peer_sqn = chunk_from_buf(peer_sqn_buf);
+
+/** set SQN to the current time */
+static void update_sqn(u_int8_t *sqn, time_t offset)
+{
+ timeval_t time;
+ gettimeofday(&time, NULL);
+ /* set sqb_sqn to an integer containing seconds followed by most
+ * significant useconds */
+ time.tv_sec = htonl(time.tv_sec + offset);
+ /* usec's are never larger than 0x000f423f, so we shift the 12 first bits */
+ time.tv_usec <<= 12;
+ time.tv_usec = htonl(time.tv_usec);
+ memcpy(sqn, &time.tv_sec, 4);
+ memcpy(sqn + 4, &time.tv_usec, 2);
+}
+
+/** initialize peers SQN to the current system time at startup */
+static void __attribute__ ((constructor))init_sqn(void)
+{
+ update_sqn(peer_sqn_buf, 0);
+}
+
+/**
+ * Binary represnation of the polynom T^160 + T^5 + T^3 + T^2 + 1
+ */
+static u_int8_t g[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x2d
+};
+
+/**
+ * Predefined random bits from the RAND Corporation book
+ */
+static u_int8_t a[] = {
+ 0x9d, 0xe9, 0xc9, 0xc8, 0xef, 0xd5, 0x78, 0x11,
+ 0x48, 0x23, 0x14, 0x01, 0x90, 0x1f, 0x2d, 0x49,
+ 0x3f, 0x4c, 0x63, 0x65
+};
+
+/**
+ * Predefined random bits from the RAND Corporation book
+ */
+static u_int8_t b[] = {
+ 0x75, 0xef, 0xd1, 0x5c, 0x4b, 0x8f, 0x8f, 0x51,
+ 0x4e, 0xf3, 0xbc, 0xc3, 0x79, 0x4a, 0x76, 0x5e,
+ 0x7e, 0xec, 0x45, 0xe0
+};
+
+/**
+ * Multiplicate two mpz_t with bits interpreted as polynoms.
+ */
+static void mpz_mul_poly(mpz_t r, mpz_t a, mpz_t b)
+{
+ mpz_t bm, rm;
+ int current = 0, shifted = 0, shift;
+
+ mpz_init_set(bm, b);
+ mpz_init_set_ui(rm, 0);
+ /* scan through a, for each found bit: */
+ while ((current = mpz_scan1(a, current)) != ULONG_MAX)
+ {
+ /* XOR shifted b into r */
+ shift = current - shifted;
+ mpz_mul_2exp(bm, bm, shift);
+ shifted += shift;
+ mpz_xor(rm, rm, bm);
+ current++;
+ }
+
+ mpz_swap(r, rm);
+ mpz_clear(rm);
+ mpz_clear(bm);
+}
+
+/**
+ * Calculate the sum of a + b interpreted as polynoms.
+ */
+static void mpz_add_poly(mpz_t res, mpz_t a, mpz_t b)
+{
+ /* addition of polynominals is just the XOR */
+ mpz_xor(res, a, b);
+}
+
+/**
+ * Calculate the remainder of a/b interpreted as polynoms.
+ */
+static void mpz_mod_poly(mpz_t r, mpz_t a, mpz_t b)
+{
+ /* Example:
+ * a = 10001010
+ * b = 00000101
+ */
+ int a_bit, b_bit, diff;
+ mpz_t bm, am;
+
+ mpz_init_set(am, a);
+ mpz_init(bm);
+
+ a_bit = mpz_sizeinbase(a, 2);
+ b_bit = mpz_sizeinbase(b, 2);
+
+ /* don't do anything if b > a */
+ if (a_bit >= b_bit)
+ {
+ /* shift b left to align up most signaficant "1" to a:
+ * a = 10001010
+ * b = 10100000
+ */
+ mpz_mul_2exp(bm, b, a_bit - b_bit);
+ do
+ {
+ /* XOR b into a, this kills the most significant "1":
+ * a = 00101010
+ */
+ mpz_xor(am, am, bm);
+ /* find the next most significant "1" in a, and align up b:
+ * a = 00101010
+ * b = 00101000
+ */
+ diff = a_bit - mpz_sizeinbase(am, 2);
+ mpz_div_2exp(bm, bm, diff);
+ a_bit -= diff;
+ }
+ while (b_bit <= mpz_sizeinbase(bm, 2));
+ /* While b is not shifted to its original value */
+ }
+ /* after another iteration:
+ * a = 00000010
+ * which is the polynomial modulo
+ */
+
+ mpz_swap(r, am);
+ mpz_clear(am);
+ mpz_clear(bm);
+}
+
+/**
+ * Step 4 of the various fx() functions:
+ * Polynomial whiten calculations
+ */
+static void step4(u_int8_t x[])
+{
+ mpz_t xm, am, bm, gm;
+
+ mpz_init(xm);
+ mpz_init(am);
+ mpz_init(bm);
+ mpz_init(gm);
+
+ mpz_import(xm, HASH_SIZE_SHA1, 1, 1, 1, 0, x);
+ mpz_import(am, sizeof(a), 1, 1, 1, 0, a);
+ mpz_import(bm, sizeof(b), 1, 1, 1, 0, b);
+ mpz_import(gm, sizeof(g), 1, 1, 1, 0, g);
+
+ mpz_mul_poly(xm, am, xm);
+ mpz_add_poly(xm, bm, xm);
+ mpz_mod_poly(xm, xm, gm);
+
+ mpz_export(x, NULL, 1, HASH_SIZE_SHA1, 1, 0, xm);
+
+ mpz_clear(xm);
+ mpz_clear(am);
+ mpz_clear(bm);
+ mpz_clear(gm);
+}
+
+/**
+ * Step 3 of the various fx() functions:
+ * XOR the key into the SHA1 IV
+ */
+static void step3(chunk_t k, chunk_t payload, u_int8_t h[])
+{
+ u_int8_t iv[] = {
+ 0x67,0x45,0x23,0x01,0xEF,0xCD,0xAB,0x89,0x98,0xBA,
+ 0xDC,0xFE,0x10,0x32,0x54,0x76,0xC3,0xD2,0xE1,0xF0,
+ };
+
+ /* XOR key into IV */
+ memxor(iv, k.ptr, k.len);
+
+ /* hash it with the G() function defined in FIPS 186-2 from fips_prf.h */
+ g_sha1(iv, payload, h);
+}
+
+/**
+ * Calculation function for f2(), f3(), f4()
+ */
+static void fx(u_int8_t f, chunk_t k, chunk_t rand, u_int8_t out[])
+{
+ chunk_t payload = chunk_alloca(PAYLOAD_LENGTH);
+ u_int8_t h[HASH_SIZE_SHA1];
+ u_int8_t i;
+
+ for (i = 0; i < 2; i++)
+ {
+ memset(payload.ptr, 0x5c, payload.len);
+ payload.ptr[11] ^= f;
+ memxor(payload.ptr + 12, fmk.ptr, fmk.len);
+ memxor(payload.ptr + 24, rand.ptr, rand.len);
+
+ payload.ptr[3] ^= i;
+ payload.ptr[19] ^= i;
+ payload.ptr[35] ^= i;
+ payload.ptr[51] ^= i;
+
+ step3(k, payload, h);
+ step4(h);
+ memcpy(out + i * 8, h, 8);
+ }
+}
+
+/**
+ * Calculation function of f1() and f1star()
+ */
+static void f1x(u_int8_t f, chunk_t k, chunk_t rand, chunk_t sqn,
+ chunk_t amf, u_int8_t mac[])
+{
+ /* generate MAC = f1(FMK, SQN, RAND, AMF)
+ * K is loaded into hashers IV; FMK, RAND, SQN, AMF are XORed in a 512-bit
+ * payload which gets hashed
+ */
+ chunk_t payload = chunk_alloca(PAYLOAD_LENGTH);
+ u_int8_t h[HASH_SIZE_SHA1];
+
+ memset(payload.ptr, 0x5c, PAYLOAD_LENGTH);
+ payload.ptr[11] ^= f;
+ memxor(payload.ptr + 12, fmk.ptr, fmk.len);
+ memxor(payload.ptr + 16, rand.ptr, rand.len);
+ memxor(payload.ptr + 34, sqn.ptr, sqn.len);
+ memxor(payload.ptr + 42, amf.ptr, amf.len);
+
+ step3(k, payload, h);
+ step4(h);
+ memcpy(mac, h, MAC_LENGTH);
+}
+
+/**
+ * Calculation function of f5() and f5star()
+ */
+static void f5x(u_int8_t f, chunk_t k, chunk_t rand, u_int8_t ak[])
+{
+ chunk_t payload = chunk_alloca(PAYLOAD_LENGTH);
+ u_int8_t h[HASH_SIZE_SHA1];
+
+ memset(payload.ptr, 0x5c, payload.len);
+ payload.ptr[11] ^= f;
+ memxor(payload.ptr + 12, fmk.ptr, fmk.len);
+ memxor(payload.ptr + 16, rand.ptr, rand.len);
+
+ step3(k, payload, h);
+ step4(h);
+ memcpy(ak, h, AK_LENGTH);
+}
+
+/**
+ * Calculate the MAC from a RAND, SQN, AMF value using K
+ */
+static void f1(chunk_t k, chunk_t rand, chunk_t sqn, chunk_t amf, u_int8_t mac[])
+{
+ f1x(F1, k, rand, sqn, amf, mac);
+ DBG3(DBG_IKE, "MAC %b", mac, MAC_LENGTH);
+}
+
+/**
+ * Calculate the MACS from a RAND, SQN, AMF value using K
+ */
+static void f1star(chunk_t k, chunk_t rand, chunk_t sqn, chunk_t amf, u_int8_t macs[])
+{
+ f1x(F1STAR, k, rand, sqn, amf, macs);
+ DBG3(DBG_IKE, "MACS %b", macs, MAC_LENGTH);
+}
+
+/**
+ * Calculate RES from RAND using K
+ */
+static void f2(chunk_t k, chunk_t rand, u_int8_t res[])
+{
+ fx(F2, k, rand, res);
+ DBG3(DBG_IKE, "RES %b", res, RES_LENGTH);
+}
+
+/**
+ * Calculate CK from RAND using K
+ */
+static void f3(chunk_t k, chunk_t rand, u_int8_t ck[])
+{
+ fx(F3, k, rand, ck);
+ DBG3(DBG_IKE, "CK %b", ck, CK_LENGTH);
+}
+
+/**
+ * Calculate IK from RAND using K
+ */
+static void f4(chunk_t k, chunk_t rand, u_int8_t ik[])
+{
+ fx(F4, k, rand, ik);
+ DBG3(DBG_IKE, "IK %b", ik, IK_LENGTH);
+}
+
+/**
+ * Calculate AK from a RAND using K
+ */
+static void f5(chunk_t k, chunk_t rand, u_int8_t ak[])
+{
+ f5x(F5, k, rand, ak);
+ DBG3(DBG_IKE, "AK %b", ak, AK_LENGTH);
+}
+
+/**
+ * Calculate AKS from a RAND using K
+ */
+static void f5star(chunk_t k, chunk_t rand, u_int8_t aks[])
+{
+ f5x(F5STAR, k, rand, aks);
+ DBG3(DBG_IKE, "AKS %b", aks, AK_LENGTH);
+}
+
+/**
+ * derive the keys needed for EAP_AKA
+ */
+static void derive_keys(private_eap_aka_t *this, identification_t *id)
+{
+ hasher_t *hasher;
+ prf_t *prf;
+ chunk_t ck, ik, mk, identity, tmp;
+
+ ck = chunk_alloca(CK_LENGTH);
+ ik = chunk_alloca(IK_LENGTH);
+ mk = chunk_alloca(MK_LENGTH);
+ identity = id->get_encoding(id);
+
+ /* MK = SHA1( Identity | IK | CK ) */
+ f3(this->k, this->rand, ck.ptr);
+ f4(this->k, this->rand, ik.ptr);
+ DBG3(DBG_IKE, "Identity %B", &identity);
+ tmp = chunk_cata("ccc", identity, ik, ck);
+ DBG3(DBG_IKE, "Identity|IK|CK %B", &tmp);
+ hasher = hasher_create(HASH_SHA1);
+ hasher->get_hash(hasher, tmp, mk.ptr);
+ hasher->destroy(hasher);
+
+ /* K_encr | K_auth | MSK | EMSK = prf(0) | prf(0)
+ * FIPS PRF has 320 bit block size, we need 160 byte for keys
+ * => run prf four times */
+ prf = prf_create(PRF_FIPS_SHA1_160);
+ prf->set_key(prf, mk);
+ tmp = chunk_alloca(prf->get_block_size(prf) * 4);
+ prf->get_bytes(prf, chunk_empty, tmp.ptr);
+ prf->get_bytes(prf, chunk_empty, tmp.ptr + tmp.len / 4 * 1);
+ prf->get_bytes(prf, chunk_empty, tmp.ptr + tmp.len / 4 * 2);
+ prf->get_bytes(prf, chunk_empty, tmp.ptr + tmp.len / 4 * 3);
+ prf->destroy(prf);
+ chunk_free(&this->k_encr);
+ chunk_free(&this->k_auth);
+ chunk_free(&this->msk);
+ chunk_free(&this->emsk);
+ chunk_split(tmp, "aaaa", 16, &this->k_encr, 16, &this->k_auth,
+ 64, &this->msk, 64, &this->emsk);
+ DBG3(DBG_IKE, "MK %B", &mk);
+ DBG3(DBG_IKE, "PRF res %B", &tmp);
+ DBG3(DBG_IKE, "K_encr %B", &this->k_encr);
+ DBG3(DBG_IKE, "K_auth %B", &this->k_auth);
+ DBG3(DBG_IKE, "MSK %B", &this->msk);
+ DBG3(DBG_IKE, "EMSK %B", &this->emsk);
+}
+
+/*
+ * Get a shared key from ipsec.secrets.
+ * We use the standard keys as used in preshared key authentication. As
+ * these keys have an undefined length, we:
+ * - strip them if they are longer
+ * - fill them up with '\0' if they are shorter
+ */
+static status_t load_key(identification_t *me, identification_t *other, chunk_t *k)
+{
+ chunk_t shared_key;
+
+ if (charon->credentials->get_eap_key(charon->credentials, me,
+ other, &shared_key) != SUCCESS)
+ {
+ return NOT_FOUND;
+ }
+ chunk_free(k);
+ *k = chunk_alloc(K_LENGTH);
+ memset(k->ptr, '\0', k->len);
+ memcpy(k->ptr, shared_key.ptr, min(shared_key.len, k->len));
+ chunk_free(&shared_key);
+ return SUCCESS;
+}
+
+/**
+ * skip EAP_AKA header in message and returns its AKA subtype
+ */
+static aka_subtype_t read_header(chunk_t *message)
+{
+ aka_subtype_t type;
+
+ if (message->len < 8)
+ {
+ *message = chunk_empty;
+ return 0;
+ }
+ type = *(message->ptr + 5);
+ *message = chunk_skip(*message, 8);
+ return type;
+}
+
+/**
+ * read the next attribute from the chunk data
+ */
+static aka_attribute_t read_attribute(chunk_t *data, chunk_t *attr_data)
+{
+ aka_attribute_t attribute;
+ size_t length;
+
+ DBG3(DBG_IKE, "reading attribute from %B", data);
+
+ if (data->len < 2)
+ {
+ return AT_END;
+ }
+ /* read attribute and length */
+ attribute = *data->ptr++;
+ length = *data->ptr++ * 4 - 2;
+ data->len -= 2;
+ DBG3(DBG_IKE, "found attribute %N with length %d",
+ aka_attribute_names, attribute, length);
+ if (length > data->len)
+ {
+ return AT_END;
+ }
+ /* apply attribute value to attr_data */
+ attr_data->len = length;
+ attr_data->ptr = data->ptr;
+ /* update data to point to next attribute */
+ *data = chunk_skip(*data, length);
+ return attribute;
+}
+
+/**
+ * Build an AKA payload from different attributes.
+ * The variable argument takes an aka_attribute_t
+ * followed by its data in a chunk.
+ */
+static eap_payload_t *build_aka_payload(private_eap_aka_t *this, eap_code_t code,
+ u_int8_t identifier, aka_subtype_t type, ...)
+{
+ chunk_t message = chunk_alloca(512); /* is enought for all current messages */
+ chunk_t pos = message;
+ eap_payload_t *payload;
+ va_list args;
+ aka_attribute_t attr;
+ u_int8_t *mac_pos = NULL;
+
+ /* write EAP header, skip length bytes */
+ *pos.ptr++ = code;
+ *pos.ptr++ = identifier;
+ pos.ptr += 2;
+ pos.len -= 4;
+ /* write AKA header with type and subtype, null reserved bytes */
+ *pos.ptr++ = EAP_AKA;
+ *pos.ptr++ = type;
+ *pos.ptr++ = 0;
+ *pos.ptr++ = 0;
+ pos.len -= 4;
+
+ va_start(args, type);
+ while ((attr = va_arg(args, aka_attribute_t)) != AT_END)
+ {
+ chunk_t data = va_arg(args, chunk_t);
+
+ DBG3(DBG_IKE, "building %N %B", aka_attribute_names, attr, &data);
+
+ /* write attribute header */
+ *pos.ptr++ = attr;
+ pos.len--;
+
+ switch (attr)
+ {
+ case AT_RES:
+ {
+ /* attribute length in 4byte words */
+ *pos.ptr = data.len/4 + 1;
+ pos = chunk_skip(pos, 1);
+ /* RES length in bits */
+ *(u_int16_t*)pos.ptr = htons(data.len * 8);
+ pos = chunk_skip(pos, sizeof(u_int16_t));
+ memcpy(pos.ptr, data.ptr, data.len);
+ pos = chunk_skip(pos, data.len);
+ break;
+ }
+ case AT_AUTN:
+ case AT_RAND:
+ {
+ *pos.ptr++ = data.len/4 + 1; pos.len--;
+ *pos.ptr++ = 0; pos.len--;
+ *pos.ptr++ = 0; pos.len--;
+ memcpy(pos.ptr, data.ptr, data.len);
+ pos = chunk_skip(pos, data.len);
+ break;
+ }
+ case AT_MAC:
+ {
+ *pos.ptr++ = 5; pos.len--;
+ *pos.ptr++ = 0; pos.len--;
+ *pos.ptr++ = 0; pos.len--;
+ mac_pos = pos.ptr;
+ /* MAC is calculated over message including zeroed AT_MAC attribute */
+ memset(mac_pos, 0, AT_MAC_LENGTH);
+ pos.ptr += AT_MAC_LENGTH;
+ pos.len -= AT_MAC_LENGTH;
+ break;
+ }
+ default:
+ {
+ /* length is data length in 4-bytes + 1 for header */
+ *pos.ptr = data.len/4 + 1;
+ pos = chunk_skip(pos, 1);
+ memcpy(pos.ptr, data.ptr, data.len);
+ pos = chunk_skip(pos, data.len);
+ }
+ }
+ }
+ va_end(args);
+
+ /* calculate message length, write into header */
+ message.len = pos.ptr - message.ptr;
+ *(u_int16_t*)(message.ptr + 2) = htons(message.len);
+
+ /* create MAC if AT_MAC attribte was included */
+ if (mac_pos)
+ {
+ signer_t *signer = signer_create(AUTH_HMAC_SHA1_128);
+ signer->set_key(signer, this->k_auth);
+ DBG3(DBG_IKE, "AT_MAC signature of %B", &message);
+ DBG3(DBG_IKE, "using key %B", &this->k_auth);
+ signer->get_signature(signer, message, mac_pos);
+ DBG3(DBG_IKE, "is %b", mac_pos, AT_MAC_LENGTH);
+ signer->destroy(signer);
+ }
+
+ /* payload constructor takes data with some bytes skipped */
+ payload = eap_payload_create_data(message);
+
+ DBG3(DBG_IKE, "created EAP message %B", &message);
+ return payload;
+}
+
+/**
+ * Initiate a AKA-Challenge using SQN
+ */
+static status_t server_initiate_challenge(private_eap_aka_t *this, chunk_t sqn, eap_payload_t **out)
+{
+ randomizer_t *randomizer;
+ status_t status;
+ chunk_t mac, ak, autn;
+
+ mac = chunk_alloca(MAC_LENGTH);
+ ak = chunk_alloca(AK_LENGTH);
+ chunk_free(&this->rand);
+ chunk_free(&this->xres);
+
+ /* generate RAND:
+ * we use our standard randomizer, not f0() proposed in S.S0055
+ */
+ randomizer = randomizer_create();
+ status = randomizer->allocate_pseudo_random_bytes(randomizer, RAND_LENGTH, &this->rand);
+ randomizer->destroy(randomizer);
+ if (status != SUCCESS)
+ {
+ DBG1(DBG_IKE, "generating RAND for EAP-AKA authentication failed");
+ return FAILED;
+ }
+
+# ifdef TEST_VECTORS
+ /* Test vector for RAND */
+ u_int8_t test_rand[] = {
+ 0x4b,0x05,0x2b,0x20,0xe2,0xa0,0x6c,0x8f,
+ 0xf7,0x00,0xda,0x51,0x2b,0x4e,0x11,0x1e,
+ };
+ memcpy(this->rand.ptr, test_rand, this->rand.len);
+# endif /* TEST_VECTORS */
+
+ /* Get the shared key K: */
+ if (load_key(this->server, this->peer, &this->k) != SUCCESS)
+ {
+ DBG1(DBG_IKE, "no shared key found for IDs '%D' - '%D' to authenticate "
+ "with EAP-AKA", this->server, this->peer);
+ return FAILED;
+ }
+
+# ifdef TEST_VECTORS
+ /* Test vector for K */
+ u_int8_t test_k[] = {
+ 0xad,0x1b,0x5a,0x15,0x9b,0xe8,0x6b,0x2c,
+ 0xa6,0x6c,0x7a,0xe4,0x0b,0xba,0x9b,0x9d,
+ };
+ memcpy(this->k.ptr, test_k, this->k.len);
+# endif /* TEST_VECTORS */
+
+ /* generate MAC */
+ f1(this->k, this->rand, sqn, amf, mac.ptr);
+
+ /* generate AK */
+ f5(this->k, this->rand, ak.ptr);
+
+ /* precalculate XRES as expected from client */
+ this->xres = chunk_alloc(RES_LENGTH);
+ f2(this->k, this->rand, this->xres.ptr);
+
+ /* calculate AUTN = (SQN xor AK) || AMF || MAC */
+ autn = chunk_cata("ccc", sqn, amf, mac);
+ memxor(autn.ptr, ak.ptr, ak.len);
+ DBG3(DBG_IKE, "AUTN %B", &autn);
+
+
+ /* derive K_encr, K_auth, MSK, EMSK */
+ derive_keys(this, this->peer);
+
+ /* build payload */
+ *out = build_aka_payload(this, EAP_REQUEST, 0, AKA_CHALLENGE,
+ AT_RAND, this->rand, AT_AUTN, autn, AT_MAC,
+ chunk_empty, AT_END);
+ return NEED_MORE;
+}
+
+/**
+ * Implementation of eap_method_t.initiate for an EAP_AKA server
+ */
+static status_t server_initiate(private_eap_aka_t *this, eap_payload_t **out)
+{
+ chunk_t sqn = chunk_alloca(SQN_LENGTH);
+
+ /* we use an offset of 3 minutes to tolerate clock inaccuracy
+ * without the need to synchronize sequence numbers */
+ update_sqn(sqn.ptr, 180);
+
+# ifdef TEST_VECTORS
+ /* Test vector for SQN */
+ u_int8_t test_sqn[] = {0x00,0x00,0x00,0x00,0x00,0x01};
+ memcpy(sqn.ptr, test_sqn, sqn.len);
+# endif /* TEST_VECTORS */
+
+ return server_initiate_challenge(this, sqn, out);
+}
+
+static status_t server_process_synchronize(private_eap_aka_t *this,
+ eap_payload_t *in, eap_payload_t **out)
+{
+ chunk_t attr, auts = chunk_empty, pos, message, macs, xmacs, sqn, aks, amf;
+ u_int i;
+
+ message = in->get_data(in);
+ pos = message;
+ read_header(&pos);
+
+ /* iterate over attributes */
+ while (TRUE)
+ {
+ aka_attribute_t attribute = read_attribute(&pos, &attr);
+ switch (attribute)
+ {
+ case AT_END:
+ break;
+ case AT_AUTS:
+ auts = attr;
+ continue;
+ default:
+ if (attribute >= 0 && attribute <= 127)
+ {
+ DBG1(DBG_IKE, "found non skippable attribute %N",
+ aka_attribute_names, attribute);
+ return FAILED;
+ }
+ DBG1(DBG_IKE, "ignoring skippable attribute %N",
+ aka_attribute_names, attribute);
+ continue;
+ }
+ break;
+ }
+
+ if (auts.len != AUTS_LENGTH)
+ {
+ DBG1(DBG_IKE, "synchronization request didn't contain useable AUTS");
+ return FAILED;
+ }
+
+ chunk_split(auts, "mm", SQN_LENGTH, &sqn, MAC_LENGTH, &macs);
+ aks = chunk_alloca(AK_LENGTH);
+ f5star(this->k, this->rand, aks.ptr);
+ /* decrypt serial number by XORing AKS */
+ memxor(sqn.ptr, aks.ptr, aks.len);
+
+ /* verify MACS */
+ xmacs = chunk_alloca(MAC_LENGTH);
+ amf = chunk_alloca(AMF_LENGTH);
+ /* an AMF of zero is used for MACS calculation */
+ memset(amf.ptr, 0, amf.len);
+ f1star(this->k, this->rand, sqn, amf, xmacs.ptr);
+ if (!chunk_equals(macs, xmacs))
+ {
+ DBG1(DBG_IKE, "received MACS does not match XMACS");
+ DBG3(DBG_IKE, "MACS %B XMACS %B", &macs, &xmacs);
+ return FAILED;
+ }
+
+ /* retry the challenge with the received SQN + 1*/
+ for (i = SQN_LENGTH - 1; i >= 0; i--)
+ {
+ if (++sqn.ptr[i] != 0)
+ {
+ break;
+ }
+ }
+ return server_initiate_challenge(this, sqn, out);
+}
+
+/**
+ * process an AKA_Challenge response
+ */
+static status_t server_process_challenge(private_eap_aka_t *this, eap_payload_t *in)
+{
+ chunk_t attr, res = chunk_empty, at_mac = chunk_empty, pos, message;
+
+ message = in->get_data(in);
+ pos = message;
+ read_header(&pos);
+
+ /* iterate over attributes */
+ while (TRUE)
+ {
+ aka_attribute_t attribute = read_attribute(&pos, &attr);
+ switch (attribute)
+ {
+ case AT_END:
+ break;
+ case AT_RES:
+ res = attr;
+ if (attr.len == 2 + RES_LENGTH &&
+ *(u_int16_t*)attr.ptr == htons(RES_LENGTH * 8))
+ {
+ res = chunk_skip(attr, 2);
+ }
+ continue;
+
+ case AT_MAC:
+ attr = chunk_skip(attr, 2);
+ at_mac = chunk_clonea(attr);
+ /* zero MAC in message for MAC verification */
+ memset(attr.ptr, 0, attr.len);
+ continue;
+ default:
+ if (attribute >= 0 && attribute <= 127)
+ {
+ DBG1(DBG_IKE, "found non skippable attribute %N",
+ aka_attribute_names, attribute);
+ return FAILED;
+ }
+ DBG1(DBG_IKE, "ignoring skippable attribute %N",
+ aka_attribute_names, attribute);
+ continue;
+ }
+ break;
+ }
+
+ /* verify EAP message MAC AT_MAC */
+ {
+ bool valid;
+ signer_t *signer = signer_create(AUTH_HMAC_SHA1_128);
+ signer->set_key(signer, this->k_auth);
+ DBG3(DBG_IKE, "verifying AT_MAC signature of %B", &message);
+ DBG3(DBG_IKE, "using key %B", &this->k_auth);
+ valid = signer->verify_signature(signer, message, at_mac);
+ signer->destroy(signer);
+ if (!valid)
+ {
+ DBG1(DBG_IKE, "MAC in AT_MAC attribute verification failed");
+ return FAILED;
+ }
+ }
+
+ /* compare received RES against stored precalculated XRES */
+ if (!chunk_equals(res, this->xres))
+ {
+ DBG1(DBG_IKE, "received RES does not match XRES");
+ DBG3(DBG_IKE, "RES %Bb XRES %B", &res, &this->xres);
+ return FAILED;
+ }
+ return SUCCESS;
+}
+
+/**
+ * Implementation of eap_method_t.process for EAP_AKA servers
+ */
+static status_t server_process(private_eap_aka_t *this,
+ eap_payload_t *in, eap_payload_t **out)
+{
+ chunk_t message;
+ aka_subtype_t type;
+
+ message = in->get_data(in);
+ type = read_header(&message);
+
+ DBG3(DBG_IKE, "received EAP message %B", &message);
+
+ switch (type)
+ {
+ case AKA_CHALLENGE:
+ {
+ return server_process_challenge(this, in);
+ }
+ case AKA_AUTHENTICATION_REJECT:
+ case AKA_CLIENT_ERROR:
+ {
+ DBG1(DBG_IKE, "received %N, authentication failed",
+ aka_subtype_names, type);
+ return FAILED;
+ }
+ case AKA_SYNCHRONIZATION_FAILURE:
+ {
+ DBG1(DBG_IKE, "received %N, retrying with received SQN",
+ aka_subtype_names, type);
+ return server_process_synchronize(this, in, out);
+ }
+ default:
+ DBG1(DBG_IKE, "received unknown AKA subtype %N, authentication failed",
+ aka_subtype_names, type);
+ return FAILED;
+ }
+}
+
+/**
+ * Process an incoming AKA-Challenge client side
+ */
+static status_t peer_process_challenge(private_eap_aka_t *this,
+ eap_payload_t *in, eap_payload_t **out)
+{
+ chunk_t attr = chunk_empty;
+ chunk_t autn = chunk_empty, at_mac = chunk_empty;
+ chunk_t ak, sqn, sqn_ak, mac, xmac, res, amf, message, pos;
+ u_int8_t identifier;
+
+ ak = chunk_alloca(AK_LENGTH);
+ xmac = chunk_alloca(MAC_LENGTH);
+ res = chunk_alloca(RES_LENGTH);
+ chunk_free(&this->rand);
+
+ message = in->get_data(in);
+ pos = message;
+ read_header(&pos);
+ identifier = in->get_identifier(in);
+
+ DBG3(DBG_IKE, "reading attributes from %B", &pos);
+
+ /* iterate over attributes */
+ while (TRUE)
+ {
+ aka_attribute_t attribute = read_attribute(&pos, &attr);
+ switch (attribute)
+ {
+ case AT_END:
+ break;
+ case AT_RAND:
+ this->rand = chunk_clone(chunk_skip(attr, 2));
+ continue;
+ case AT_AUTN:
+ autn = chunk_skip(attr, 2);
+ continue;
+ case AT_MAC:
+ attr = chunk_skip(attr, 2);
+ at_mac = chunk_clonea(attr);
+ /* set MAC in message to zero for own MAC verification */
+ memset(attr.ptr, 0, attr.len);
+ continue;
+ default:
+ if (attribute >= 0 && attribute <= 127)
+ {
+ /* non skippable attribute, abort */
+ *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CLIENT_ERROR,
+ AT_CLIENT_ERROR_CODE, client_error_code, AT_END);
+ DBG1(DBG_IKE, "found non skippable attribute %N, sending %N %d",
+ aka_attribute_names, attribute,
+ aka_attribute_names, AT_CLIENT_ERROR_CODE, 0);
+ return NEED_MORE;
+ }
+ DBG1(DBG_IKE, "ignoring skippable attribute %N",
+ aka_attribute_names, attribute);
+ continue;
+ }
+ break;
+ }
+
+ if (this->rand.len != RAND_LENGTH || autn.len != AUTN_LENGTH)
+ {
+ /* required attributes wrong/not found, abort */
+ *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CLIENT_ERROR,
+ AT_CLIENT_ERROR_CODE, client_error_code, AT_END);
+ DBG1(DBG_IKE, "could not find valid RAND/AUTN attribute, sending %N %d",
+ aka_attribute_names, AT_CLIENT_ERROR_CODE, 0);
+ return NEED_MORE;
+ }
+
+ DBG3(DBG_IKE, "using autn %B", &autn);
+ /* split up AUTN = SQN xor AK | AMF | MAC */
+ chunk_split(autn, "mmm", SQN_LENGTH, &sqn_ak, AMF_LENGTH, &amf, MAC_LENGTH, &mac);
+
+ /* Get the shared key K: */
+ chunk_free(&this->k);
+ if (load_key(this->peer, this->server, &this->k) != SUCCESS)
+ {
+ *out = build_aka_payload(this, EAP_RESPONSE, identifier,
+ AKA_AUTHENTICATION_REJECT, AT_END);
+ DBG3(DBG_IKE, "no shared key found for IDs '%D' - '%D' to authenticate "
+ "with EAP-AKA, sending %N", this->peer, this->server,
+ aka_subtype_names, AKA_AUTHENTICATION_REJECT);
+ return NEED_MORE;
+ }
+ DBG3(DBG_IKE, "using K %B", &this->k);
+# ifdef TEST_VECTORS
+ /* Test vector for K */
+ u_int8_t test_k[] = {
+ 0xad,0x1b,0x5a,0x15,0x9b,0xe8,0x6b,0x2c,
+ 0xa6,0x6c,0x7a,0xe4,0x0b,0xba,0x9b,0x9d,
+ };
+ memcpy(this->k.ptr, test_k, this->k.len);
+# endif /* TEST_VECTORS */
+
+ /* calculate anonymity key AK */
+ f5(this->k, this->rand, ak.ptr);
+ DBG3(DBG_IKE, "using rand %B", &this->rand);
+ DBG3(DBG_IKE, "using ak %B", &ak);
+ /* XOR AK into SQN to decrypt it */
+
+ sqn = chunk_clonea(sqn_ak);
+
+ DBG3(DBG_IKE, "using ak xor sqn %B", &sqn_ak);
+ memxor(sqn.ptr, ak.ptr, sqn.len);
+ DBG3(DBG_IKE, "using sqn %B", &sqn);
+
+ /* calculate expected MAC and compare against received one */
+ f1(this->k, this->rand, sqn, amf, xmac.ptr);
+ if (!chunk_equals(mac, xmac))
+ {
+ *out = build_aka_payload(this, EAP_RESPONSE, identifier,
+ AKA_AUTHENTICATION_REJECT, AT_END);
+ DBG1(DBG_IKE, "received MAC does not match XMAC, sending %N",
+ aka_subtype_names, AKA_AUTHENTICATION_REJECT);
+ DBG3(DBG_IKE, "MAC %B\nXMAC %B", &mac, &xmac);
+ return NEED_MORE;
+ }
+
+#if SEQ_CHECK
+ if (memcmp(peer_sqn.ptr, sqn.ptr, sqn.len) >= 0)
+ {
+ /* sequence number invalid. send AUTS */
+ chunk_t auts, macs, aks, amf;
+
+ macs = chunk_alloca(MAC_LENGTH);
+ aks = chunk_alloca(AK_LENGTH);
+ amf = chunk_alloca(AMF_LENGTH);
+
+ /* AMF is set to zero in AKA_SYNCHRONIZATION_FAILURE */
+ memset(amf.ptr, 0, amf.len);
+ /* AKS = f5*(RAND) */
+ f5star(this->k, this->rand, aks.ptr);
+ /* MACS = f1*(RAND) */
+ f1star(this->k, this->rand, peer_sqn, amf, macs.ptr);
+ /* AUTS = SQN xor AKS | MACS */
+ memxor(aks.ptr, peer_sqn.ptr, aks.len);
+ auts = chunk_cata("cc", aks, macs);
+
+ *out = build_aka_payload(this, EAP_RESPONSE, identifier,
+ AKA_SYNCHRONIZATION_FAILURE,
+ AT_AUTS, auts, AT_END);
+ DBG1(DBG_IKE, "received SQN invalid, sending %N",
+ aka_subtype_names, AKA_SYNCHRONIZATION_FAILURE);
+ DBG3(DBG_IKE, "received SQN %B\ncurrent SQN %B", &sqn, &peer_sqn);
+ return NEED_MORE;
+ }
+#endif /* SEQ_CHECK */
+
+ /* derive K_encr, K_auth, MSK, EMSK */
+ derive_keys(this, this->peer);
+
+ /* verify EAP message MAC AT_MAC */
+ {
+ bool valid;
+ signer_t *signer = signer_create(AUTH_HMAC_SHA1_128);
+ signer->set_key(signer, this->k_auth);
+
+ DBG3(DBG_IKE, "verifying AT_MAC signature of %B", &message);
+ DBG3(DBG_IKE, "using key %B", &this->k_auth);
+ valid = signer->verify_signature(signer, message, at_mac);
+ signer->destroy(signer);
+ if (!valid)
+ {
+ *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CLIENT_ERROR,
+ AT_CLIENT_ERROR_CODE, client_error_code, AT_END);
+ DBG1(DBG_IKE, "MAC in AT_MAC attribute verification "
+ "failed, sending %N %d", aka_attribute_names,
+ AT_CLIENT_ERROR_CODE, 0);
+ return NEED_MORE;
+ }
+ }
+
+ /* update stored SQN to the received one */
+ memcpy(peer_sqn.ptr, sqn.ptr, sqn.len);
+
+ /* calculate RES */
+ f2(this->k, this->rand, res.ptr);
+
+ /* build response */
+ *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CHALLENGE,
+ AT_RES, res, AT_MAC, chunk_empty, AT_END);
+ return NEED_MORE;
+}
+
+/**
+ * Process an incoming AKA-Notification as client
+ */
+static status_t peer_process_notification(private_eap_aka_t *this,
+ eap_payload_t *in, eap_payload_t **out)
+{
+ chunk_t message, pos, attr;
+ u_int8_t identifier;
+
+ message = in->get_data(in);
+ pos = message;
+ read_header(&pos);
+ identifier = in->get_identifier(in);
+
+ DBG3(DBG_IKE, "reading attributes from %B", &pos);
+
+ /* iterate over attributes */
+ while (TRUE)
+ {
+ aka_attribute_t attribute = read_attribute(&pos, &attr);
+ switch (attribute)
+ {
+ case AT_END:
+ break;
+ case AT_NOTIFICATION:
+ {
+ u_int16_t code;
+
+ if (attr.len != 2)
+ {
+ DBG1(DBG_IKE, "received invalid AKA notification, ignored");
+ continue;
+ }
+ code = ntohs(*(u_int16_t*)attr.ptr);
+ switch (code)
+ {
+ case 0:
+ DBG1(DBG_IKE, "received AKA notification 'general "
+ "failure after authentication' (%d)", code);
+ return FAILED;
+ case 16384:
+ DBG1(DBG_IKE, "received AKA notification 'general "
+ "failure' (%d)", code);
+ return FAILED;
+ case 32768:
+ DBG1(DBG_IKE, "received AKA notification 'successfully "
+ "authenticated' (%d)", code);
+ continue;
+ case 1026:
+ DBG1(DBG_IKE, "received AKA notification 'access "
+ "temporarily denied' (%d)", code);
+ return FAILED;
+ case 1031:
+ DBG1(DBG_IKE, "received AKA notification 'not "
+ "subscribed to service' (%d)", code);
+ return FAILED;
+ default:
+ DBG1(DBG_IKE, "received AKA notification code %d, "
+ "ignored", code);
+ continue;
+ }
+ }
+ default:
+ if (attribute >= 0 && attribute <= 127)
+ {
+ DBG1(DBG_IKE, "ignoring non-skippable attribute %N in %N",
+ aka_attribute_names, attribute, aka_subtype_names,
+ AKA_NOTIFICATION);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "ignoring skippable attribute %N",
+ aka_attribute_names, attribute);
+ }
+ continue;
+ }
+ break;
+ }
+ return NEED_MORE;
+}
+
+/**
+ * Implementation of eap_method_t.process for an EAP_AKA peer
+ */
+static status_t peer_process(private_eap_aka_t *this,
+ eap_payload_t *in, eap_payload_t **out)
+{
+ aka_subtype_t type;
+ chunk_t message;
+ u_int8_t identifier;
+
+ message = in->get_data(in);
+ type = read_header(&message);
+ identifier = in->get_identifier(in);
+
+ DBG3(DBG_IKE, "received EAP message %B", &message);
+
+ switch (type)
+ {
+ case AKA_CHALLENGE:
+ {
+ return peer_process_challenge(this, in, out);
+ }
+ case AKA_NOTIFICATION:
+ {
+ return peer_process_notification(this, in, out);
+ }
+ default:
+ {
+ *out = build_aka_payload(this, EAP_RESPONSE, identifier, AKA_CLIENT_ERROR,
+ AT_CLIENT_ERROR_CODE, client_error_code, AT_END);
+ DBG1(DBG_IKE, "received unsupported %N request, sending %N %d",
+ aka_subtype_names, type,
+ aka_attribute_names, AT_CLIENT_ERROR_CODE, 0);
+ return NEED_MORE;
+ }
+ }
+}
+
+/**
+ * Implementation of eap_method_t.initiate for an EAP AKA peer
+ */
+static status_t peer_initiate(private_eap_aka_t *this, eap_payload_t **out)
+{
+ /* peer never initiates */
+ return FAILED;
+}
+
+/**
+ * Implementation of eap_method_t.get_type.
+ */
+static eap_type_t get_type(private_eap_aka_t *this, u_int32_t *vendor)
+{
+ *vendor = 0;
+ return EAP_AKA;
+}
+
+/**
+ * Implementation of eap_method_t.get_msk.
+ */
+static status_t get_msk(private_eap_aka_t *this, chunk_t *msk)
+{
+ if (this->msk.ptr)
+ {
+ *msk = this->msk;
+ return SUCCESS;
+ }
+ return FAILED;
+}
+
+/**
+ * Implementation of eap_method_t.is_mutual.
+ */
+static bool is_mutual(private_eap_aka_t *this)
+{
+ return TRUE;
+}
+
+/**
+ * Implementation of eap_method_t.destroy.
+ */
+static void destroy(private_eap_aka_t *this)
+{
+ chunk_free(&this->k_encr);
+ chunk_free(&this->k_auth);
+ chunk_free(&this->msk);
+ chunk_free(&this->emsk);
+ chunk_free(&this->xres);
+ chunk_free(&this->k);
+ chunk_free(&this->rand);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+eap_aka_t *eap_create(eap_role_t role,
+ identification_t *server, identification_t *peer)
+{
+ private_eap_aka_t *this = malloc_thing(private_eap_aka_t);
+
+ /* public functions */
+ switch (role)
+ {
+ case EAP_SERVER:
+ this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))server_initiate;
+ this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))server_process;
+ break;
+ case EAP_PEER:
+ this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))peer_initiate;
+ this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))peer_process;
+ break;
+ default:
+ free(this);
+ return NULL;
+ }
+ this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type;
+ this->public.eap_method_interface.is_mutual = (bool(*)(eap_method_t*))is_mutual;
+ this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
+ this->public.eap_method_interface.destroy = (void(*)(eap_method_t*))destroy;
+
+ /* private data */
+ this->server = server;
+ this->peer = peer;
+ this->k_encr = chunk_empty;
+ this->k_auth = chunk_empty;
+ this->msk = chunk_empty;
+ this->emsk = chunk_empty;
+ this->xres = chunk_empty;
+ this->k = chunk_empty;
+ this->rand = chunk_empty;
+
+ return &this->public;
+}
diff --git a/src/charon/sa/authenticators/eap/eap_aka.h b/src/charon/sa/authenticators/eap/eap_aka.h
new file mode 100644
index 000000000..a886863be
--- /dev/null
+++ b/src/charon/sa/authenticators/eap/eap_aka.h
@@ -0,0 +1,141 @@
+/**
+ * @file eap_aka.h
+ *
+ * @brief Interface of eap_aka_t.
+ *
+ */
+
+/*
+ * Copyright (C) 2006 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.
+ */
+
+#ifndef EAP_AKA_H_
+#define EAP_AKA_H_
+
+typedef struct eap_aka_t eap_aka_t;
+typedef enum aka_subtype_t aka_subtype_t;
+typedef enum aka_attribute_t aka_attribute_t;
+
+#include <sa/authenticators/eap/eap_method.h>
+
+
+/**
+ * Subtypes of AKA messages
+ */
+enum aka_subtype_t {
+ AKA_CHALLENGE = 1,
+ AKA_AUTHENTICATION_REJECT = 2,
+ AKA_SYNCHRONIZATION_FAILURE = 4,
+ AKA_IDENTITY = 5,
+ AKA_NOTIFICATION = 12,
+ AKA_REAUTHENTICATION = 13,
+ AKA_CLIENT_ERROR = 14,
+};
+
+/**
+ * enum names for aka_subtype_t
+ */
+extern enum_name_t *aka_subtype_names;
+
+/**
+ * Attribute types in AKA messages
+ */
+enum aka_attribute_t {
+ /** defines the end of attribute list */
+ AT_END = -1,
+ AT_RAND = 1,
+ AT_AUTN = 2,
+ AT_RES = 3,
+ AT_AUTS = 4,
+ AT_PADDING = 6,
+ AT_NONCE_MT = 7,
+ AT_PERMANENT_ID_REQ = 10,
+ AT_MAC = 11,
+ AT_NOTIFICATION = 12,
+ AT_ANY_ID_REQ = 13,
+ AT_IDENTITY = 14,
+ AT_VERSION_LIST = 15,
+ AT_SELECTED_VERSION = 16,
+ AT_FULLAUTH_ID_REQ = 17,
+ AT_COUNTER = 19,
+ AT_COUNTER_TOO_SMALL = 20,
+ AT_NONCE_S = 21,
+ AT_CLIENT_ERROR_CODE = 22,
+ AT_IV = 129,
+ AT_ENCR_DATA = 130,
+ AT_NEXT_PSEUDONYM = 132,
+ AT_NEXT_REAUTH_ID = 133,
+ AT_CHECKCODE = 134,
+ AT_RESULT_IND = 135,
+};
+
+/**
+ * enum names for aka_attribute_t
+ */
+extern enum_name_t *aka_attribute_names;
+
+/** check SEQ values as client for validity, disabled by default */
+#ifndef SEQ_CHECK
+# define SEQ_CHECK 0
+#endif
+
+/**
+ * @brief Implementation of the eap_method_t interface using EAP-AKA.
+ *
+ * EAP-AKA uses 3rd generation mobile phone standard authentication
+ * mechanism for authentication. It is a mutual authentication
+ * mechanism which establishs a shared key and therefore supports EAP_ONLY
+ * authentication. This implementation follows the standard of the
+ * 3GPP2 (S.S0055) and not the one of 3GGP.
+ * The shared key used for authentication is from ipsec.secrets. The
+ * peers ID is used to query it.
+ * The AKA mechanism uses sequence numbers to detect replay attacks. The
+ * peer stores the sequence number normally in a USIM and accepts
+ * incremental sequence numbers (incremental for lifetime of the USIM). To
+ * prevent a complex sequence number management, this implementation uses
+ * a sequence number derived from time. It is initialized to the startup
+ * time of the daemon. As long as the (UTC) time of the system is not
+ * turned back while the daemon is not running, this method is secure.
+ * To enable time based SEQs, #define SEQ_CHECK as 1. Default is to accept
+ * any SEQ numbers. This allows an attacker to do replay attacks. But since
+ * the server has proven his identity via IKE, such an attack is only
+ * possible between server and AAA (if any).
+ *
+ * @b Constructors:
+ * - eap_aka_create()
+ * - eap_client_create() using eap_method EAP_AKA
+ *
+ * @ingroup eap
+ */
+struct eap_aka_t {
+
+ /**
+ * Implemented eap_method_t interface.
+ */
+ eap_method_t eap_method_interface;
+};
+
+/**
+ * @brief Creates the EAP method EAP-AKA.
+ *
+ * @param server ID of the EAP server
+ * @param peer ID of the EAP client
+ * @return eap_aka_t object
+ *
+ * @ingroup eap
+ */
+eap_aka_t *eap_create(eap_role_t role,
+ identification_t *server, identification_t *peer);
+
+#endif /* EAP_AKA_H_ */
diff --git a/src/charon/sa/authenticators/eap/eap_md5.c b/src/charon/sa/authenticators/eap/eap_md5.c
new file mode 100644
index 000000000..0ca9fc566
--- /dev/null
+++ b/src/charon/sa/authenticators/eap/eap_md5.c
@@ -0,0 +1,282 @@
+/**
+ * @file eap_md5.c
+ *
+ * @brief Implementation of eap_md5_t.
+ *
+ */
+
+/*
+ * 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 "eap_md5.h"
+
+#include <daemon.h>
+#include <library.h>
+
+typedef struct private_eap_md5_t private_eap_md5_t;
+
+/**
+ * Private data of an eap_md5_t object.
+ */
+struct private_eap_md5_t {
+
+ /**
+ * Public authenticator_t interface.
+ */
+ eap_md5_t public;
+
+ /**
+ * ID of the server
+ */
+ identification_t *server;
+
+ /**
+ * ID of the peer
+ */
+ identification_t *peer;
+
+ /**
+ * challenge sent by the server
+ */
+ chunk_t challenge;
+
+ /**
+ * EAP message identififier
+ */
+ u_int8_t identifier;
+};
+
+typedef struct eap_md5_header_t eap_md5_header_t;
+
+/**
+ * packed eap MD5 header struct
+ */
+struct eap_md5_header_t {
+ /** EAP code (REQUEST/RESPONSE) */
+ u_int8_t code;
+ /** unique message identifier */
+ u_int8_t identifier;
+ /** length of whole message */
+ u_int16_t length;
+ /** EAP type */
+ u_int8_t type;
+ /** length of value (challenge) */
+ u_int8_t value_size;
+ /** actual value */
+ u_int8_t value[];
+} __attribute__((__packed__));
+
+#define CHALLENGE_LEN 16
+#define PAYLOAD_LEN (CHALLENGE_LEN + sizeof(eap_md5_header_t))
+
+/**
+ * Hash the challenge string, create response
+ */
+static status_t hash_challenge(private_eap_md5_t *this, chunk_t *response)
+{
+ chunk_t concat, secret;
+ hasher_t *hasher;
+
+ if (charon->credentials->get_eap_key(charon->credentials, this->server,
+ this->peer, &secret) != SUCCESS)
+ {
+ DBG1(DBG_IKE, "no EAP key found for hosts '%D' - '%D'",
+ this->server, this->peer);
+ return NOT_FOUND;
+ }
+ concat = chunk_cata("cmc", chunk_from_thing(this->identifier),
+ secret, this->challenge);
+ hasher = hasher_create(HASH_MD5);
+ hasher->allocate_hash(hasher, concat, response);
+ hasher->destroy(hasher);
+ return SUCCESS;
+}
+
+/**
+ * Implementation of eap_method_t.initiate for the peer
+ */
+static status_t initiate_peer(private_eap_md5_t *this, eap_payload_t **out)
+{
+ /* peer never initiates */
+ return FAILED;
+}
+
+/**
+ * Implementation of eap_method_t.initiate for the server
+ */
+static status_t initiate_server(private_eap_md5_t *this, eap_payload_t **out)
+{
+ randomizer_t *randomizer;
+ status_t status;
+ eap_md5_header_t *req;
+
+ randomizer = randomizer_create();
+ status = randomizer->allocate_pseudo_random_bytes(randomizer, CHALLENGE_LEN,
+ &this->challenge);
+ randomizer->destroy(randomizer);
+ if (status != SUCCESS)
+ {
+ return FAILED;
+ }
+
+ req = alloca(PAYLOAD_LEN);
+ req->length = htons(PAYLOAD_LEN);
+ req->code = EAP_REQUEST;
+ req->identifier = this->identifier;
+ req->type = EAP_MD5;
+ req->value_size = this->challenge.len;
+ memcpy(req->value, this->challenge.ptr, this->challenge.len);
+
+ *out = eap_payload_create_data(chunk_create((void*)req, PAYLOAD_LEN));
+ return NEED_MORE;
+}
+
+/**
+ * Implementation of eap_method_t.process for the peer
+ */
+static status_t process_peer(private_eap_md5_t *this,
+ eap_payload_t *in, eap_payload_t **out)
+{
+ chunk_t response;
+ chunk_t data;
+ eap_md5_header_t *req;
+
+ this->identifier = in->get_identifier(in);
+ data = in->get_data(in);
+ this->challenge = chunk_clone(chunk_skip(data, 6));
+ if (data.len < 6 || this->challenge.len < *(data.ptr + 5))
+ {
+ DBG1(DBG_IKE, "received invalid EAP-MD5 message");
+ return FAILED;
+ }
+ if (hash_challenge(this, &response) != SUCCESS)
+ {
+ return FAILED;
+ }
+ req = alloca(PAYLOAD_LEN);
+ req->length = htons(PAYLOAD_LEN);
+ req->code = EAP_RESPONSE;
+ req->identifier = this->identifier;
+ req->type = EAP_MD5;
+ req->value_size = response.len;
+ memcpy(req->value, response.ptr, response.len);
+ chunk_free(&response);
+
+ *out = eap_payload_create_data(chunk_create((void*)req, PAYLOAD_LEN));
+ return NEED_MORE;
+}
+
+/**
+ * Implementation of eap_method_t.process for the server
+ */
+static status_t process_server(private_eap_md5_t *this,
+ eap_payload_t *in, eap_payload_t **out)
+{
+ chunk_t response, expected;
+ chunk_t data;
+
+ if (this->identifier != in->get_identifier(in))
+ {
+ DBG1(DBG_IKE, "received invalid EAP-MD5 message");
+ return FAILED;
+ }
+ if (hash_challenge(this, &expected) != SUCCESS)
+ {
+ return FAILED;
+ }
+ data = in->get_data(in);
+ response = chunk_skip(data, 6);
+
+ if (response.len < expected.len ||
+ !memeq(response.ptr, expected.ptr, expected.len))
+ {
+ chunk_free(&expected);
+ DBG1(DBG_IKE, "EAP-MD5 verification failed");
+ return FAILED;
+ }
+ chunk_free(&expected);
+ return SUCCESS;
+}
+
+/**
+ * Implementation of eap_method_t.get_type.
+ */
+static eap_type_t get_type(private_eap_md5_t *this, u_int32_t *vendor)
+{
+ *vendor = 0;
+ return EAP_MD5;
+}
+
+/**
+ * Implementation of eap_method_t.get_msk.
+ */
+static status_t get_msk(private_eap_md5_t *this, chunk_t *msk)
+{
+ return FAILED;
+}
+
+/**
+ * Implementation of eap_method_t.is_mutual.
+ */
+static bool is_mutual(private_eap_md5_t *this)
+{
+ return FALSE;
+}
+
+/**
+ * Implementation of eap_method_t.destroy.
+ */
+static void destroy(private_eap_md5_t *this)
+{
+ chunk_free(&this->challenge);
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+eap_md5_t *eap_create(eap_role_t role,
+ identification_t *server, identification_t *peer)
+{
+ private_eap_md5_t *this = malloc_thing(private_eap_md5_t);
+
+ /* public functions */
+ switch (role)
+ {
+ case EAP_SERVER:
+ this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_server;
+ this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process_server;
+ break;
+ case EAP_PEER:
+ this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_peer;
+ this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process_peer;
+ break;
+ default:
+ free(this);
+ return NULL;
+ }
+ this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type;
+ this->public.eap_method_interface.is_mutual = (bool(*)(eap_method_t*))is_mutual;
+ this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
+ this->public.eap_method_interface.destroy = (void(*)(eap_method_t*))destroy;
+
+ /* private data */
+ this->peer = peer;
+ this->server = server;
+ this->challenge = chunk_empty;
+ this->identifier = random();
+
+ return &this->public;
+}
diff --git a/src/charon/sa/authenticators/eap/eap_md5.h b/src/charon/sa/authenticators/eap/eap_md5.h
new file mode 100644
index 000000000..260210b59
--- /dev/null
+++ b/src/charon/sa/authenticators/eap/eap_md5.h
@@ -0,0 +1,59 @@
+/**
+ * @file eap_md5.h
+ *
+ * @brief Interface of eap_md5_t.
+ *
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef EAP_MD5_H_
+#define EAP_MD5_H_
+
+typedef struct eap_md5_t eap_md5_t;
+
+#include <sa/authenticators/eap/eap_method.h>
+
+/**
+ * @brief Implementation of the eap_method_t interface using EAP-MD5 (CHAP).
+ *
+ * @b Constructors:
+ * - eap_md5_create()
+ * - eap_client_create() using eap_method EAP_MD5
+ *
+ * @ingroup eap
+ */
+struct eap_md5_t {
+
+ /**
+ * Implemented eap_method_t interface.
+ */
+ eap_method_t eap_method_interface;
+};
+
+/**
+ * @brief Creates the EAP method EAP-MD5.
+ *
+ * @param server ID of the EAP server
+ * @param peer ID of the EAP client
+ * @return eap_md5_t object
+ *
+ * @ingroup eap
+ */
+eap_md5_t *eap_create(eap_role_t role,
+ identification_t *server, identification_t *peer);
+
+#endif /* EAP_MD5_H_ */
diff --git a/src/charon/sa/authenticators/eap/eap_method.c b/src/charon/sa/authenticators/eap/eap_method.c
index e4a58f0a3..7434ca2a1 100644
--- a/src/charon/sa/authenticators/eap/eap_method.c
+++ b/src/charon/sa/authenticators/eap/eap_method.c
@@ -45,7 +45,10 @@ ENUM_NEXT(eap_type_names, EAP_SIM, EAP_SIM, EAP_TOKEN_CARD,
"EAP_SIM");
ENUM_NEXT(eap_type_names, EAP_AKA, EAP_AKA, EAP_SIM,
"EAP_AKA");
-ENUM_END(eap_type_names, EAP_AKA);
+ENUM_NEXT(eap_type_names, EAP_EXPANDED, EAP_EXPERIMENTAL, EAP_AKA,
+ "EAP_EXPANDED",
+ "EAP_EXPERIMENTAL");
+ENUM_END(eap_type_names, EAP_EXPERIMENTAL);
ENUM(eap_code_names, EAP_REQUEST, EAP_FAILURE,
"EAP_REQUEST",
@@ -67,6 +70,7 @@ typedef struct module_entry_t module_entry_t;
*/
struct module_entry_t {
eap_type_t type;
+ u_int32_t vendor;
void *handle;
eap_constructor_t constructor;
};
@@ -85,7 +89,8 @@ void eap_method_unload()
while (modules->remove_last(modules, (void**)&entry) == SUCCESS)
{
- DBG2(DBG_CFG, "unloaded module for %N", eap_type_names, entry->type);
+ DBG2(DBG_CFG, "unloaded module EAP module %d-%d",
+ entry->type, entry->vendor);
dlclose(entry->handle);
free(entry);
}
@@ -165,11 +170,19 @@ void eap_method_load(char *directory)
dlclose(module.handle);
continue;
}
- module.type = method->get_type(method);
+ module.type = method->get_type(method, &module.vendor);
method->destroy(method);
- DBG1(DBG_CFG, " loaded EAP method %N successfully from %s",
- eap_type_names, module.type, entry->d_name);
+ if (module.vendor)
+ {
+ DBG1(DBG_CFG, " loaded EAP method %d, vendor %d successfully from %s",
+ module.type, module.vendor, entry->d_name);
+ }
+ else
+ {
+ DBG1(DBG_CFG, " loaded EAP method %N successfully from %s",
+ eap_type_names, module.type, entry->d_name);
+ }
loaded_module = malloc_thing(module_entry_t);
memcpy(loaded_module, &module, sizeof(module));
@@ -181,9 +194,8 @@ void eap_method_load(char *directory)
/*
* Described in header.
*/
-eap_method_t *eap_method_create(eap_type_t type, eap_role_t role,
- identification_t *server,
- identification_t *peer)
+eap_method_t *eap_method_create(eap_type_t type, u_int32_t vendor, eap_role_t role,
+ identification_t *server, identification_t *peer)
{
eap_method_t *method = NULL;
iterator_t *iterator;
@@ -192,7 +204,7 @@ eap_method_t *eap_method_create(eap_type_t type, eap_role_t role,
iterator = modules->create_iterator(modules, TRUE);
while (iterator->iterate(iterator, (void**)&entry))
{
- if (entry->type == type)
+ if (entry->type == type && entry->vendor == vendor)
{
method = entry->constructor(role, server, peer);
if (method)
@@ -205,8 +217,16 @@ eap_method_t *eap_method_create(eap_type_t type, eap_role_t role,
if (method == NULL)
{
- DBG1(DBG_CFG, "no EAP module found for %N %N",
- eap_type_names, type, eap_role_names, role);
+ if (vendor)
+ {
+ DBG1(DBG_CFG, "no vendor %d specific EAP module found for method "
+ "%d %N", vendor, type, eap_role_names, role);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "no EAP module found for %N %N",
+ eap_type_names, type, eap_role_names, role);
+ }
}
return method;
}
diff --git a/src/charon/sa/authenticators/eap/eap_method.h b/src/charon/sa/authenticators/eap/eap_method.h
index d43dc001f..8675fd8ec 100644
--- a/src/charon/sa/authenticators/eap/eap_method.h
+++ b/src/charon/sa/authenticators/eap/eap_method.h
@@ -62,6 +62,8 @@ enum eap_type_t {
EAP_TOKEN_CARD = 6,
EAP_SIM = 18,
EAP_AKA = 23,
+ EAP_EXPANDED = 254,
+ EAP_EXPERIMENTAL = 255,
};
/**
@@ -148,9 +150,10 @@ struct eap_method_t {
* @brief Get the EAP type implemented in this method.
*
* @param this calling object
+ * @param vendor pointer receiving vendor identifier for type, 0 for none
* @return type of the EAP method
*/
- eap_type_t (*get_type) (eap_method_t *this);
+ eap_type_t (*get_type) (eap_method_t *this, u_int32_t *vendor);
/**
* @brief Check if this EAP method authenticates the server.
@@ -188,6 +191,7 @@ struct eap_method_t {
* @brief Creates an EAP method for a specific type and role.
*
* @param eap_type EAP type to use
+ * @param eap_vendor vendor identifier if a vendor specifc EAP type is used
* @param role role of the eap_method, server or peer
* @param server ID of acting server
* @param peer ID of involved peer (client)
@@ -195,8 +199,9 @@ struct eap_method_t {
*
* @ingroup eap
*/
-eap_method_t *eap_method_create(eap_type_t eap_type, eap_role_t role,
- identification_t *server, identification_t *peer);
+eap_method_t *eap_method_create(eap_type_t eap_type, u_int32_t eap_vendor,
+ eap_role_t role, identification_t *server,
+ identification_t *peer);
/**
* @brief (Re-)Load all EAP modules in the EAP modules directory.
diff --git a/src/charon/sa/authenticators/eap/eap_sim.c b/src/charon/sa/authenticators/eap/eap_sim.c
index 38d7f2534..c9eb5ce8f 100644
--- a/src/charon/sa/authenticators/eap/eap_sim.c
+++ b/src/charon/sa/authenticators/eap/eap_sim.c
@@ -264,6 +264,7 @@ static eap_payload_t *build_payload(private_eap_sim_t *this, u_int8_t identifier
}
case AT_IDENTITY:
{
+ u_int16_t act_len = data.len;
/* align up to four byte */
if (data.len % 4)
{
@@ -275,7 +276,7 @@ static eap_payload_t *build_payload(private_eap_sim_t *this, u_int8_t identifier
*pos.ptr = data.len/4 + 1;
pos = chunk_skip(pos, 1);
/* actual length in bytes */
- *(u_int16_t*)pos.ptr = htons(data.len);
+ *(u_int16_t*)pos.ptr = htons(act_len);
pos = chunk_skip(pos, sizeof(u_int16_t));
memcpy(pos.ptr, data.ptr, data.len);
pos = chunk_skip(pos, data.len);
@@ -697,8 +698,9 @@ static status_t initiate(private_eap_sim_t *this, eap_payload_t **out)
/**
* Implementation of eap_method_t.get_type.
*/
-static eap_type_t get_type(private_eap_sim_t *this)
+static eap_type_t get_type(private_eap_sim_t *this, u_int32_t *vendor)
{
+ *vendor = 0;
return EAP_SIM;
}
@@ -785,7 +787,7 @@ eap_sim_t *eap_create(eap_role_t role,
/* public functions */
this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate;
this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process;
- this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*))get_type;
+ this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type;
this->public.eap_method_interface.is_mutual = (bool(*)(eap_method_t*))is_mutual;
this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
this->public.eap_method_interface.destroy = (void(*)(eap_method_t*))destroy;
diff --git a/src/charon/sa/authenticators/eap_authenticator.c b/src/charon/sa/authenticators/eap_authenticator.c
index 6e2f73a43..6250604a6 100644
--- a/src/charon/sa/authenticators/eap_authenticator.c
+++ b/src/charon/sa/authenticators/eap_authenticator.c
@@ -138,7 +138,7 @@ static status_t build(private_eap_authenticator_t *this, chunk_t ike_sa_init,
* Implementation of eap_authenticator_t.initiate
*/
static status_t initiate(private_eap_authenticator_t *this, eap_type_t type,
- eap_payload_t **out)
+ u_int32_t vendor, eap_payload_t **out)
{
/* if initiate() is called, role is always server */
this->role = EAP_SERVER;
@@ -151,21 +151,30 @@ static status_t initiate(private_eap_authenticator_t *this, eap_type_t type,
return FAILED;
}
- DBG1(DBG_IKE, "requesting %N authentication", eap_type_names, type);
- this->method = eap_method_create(type, this->role,
+ if (vendor)
+ {
+ DBG1(DBG_IKE, "requesting vendor specific EAP authentication %d-%d",
+ type, vendor);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "requesting %N authentication", eap_type_names, type);
+ }
+ this->method = eap_method_create(type, vendor, this->role,
this->ike_sa->get_my_id(this->ike_sa),
this->ike_sa->get_other_id(this->ike_sa));
if (this->method == NULL)
{
- DBG1(DBG_IKE, "configured EAP server method %N not supported, sending %N",
- eap_type_names, type, eap_code_names, EAP_FAILURE);
+
+ DBG1(DBG_IKE, "configured EAP server method not supported, sending %N",
+ eap_code_names, EAP_FAILURE);
*out = eap_payload_create_code(EAP_FAILURE);
return FAILED;
}
if (this->method->initiate(this->method, out) != NEED_MORE)
{
- DBG1(DBG_IKE, "failed to initiate %N, sending %N",
+ DBG1(DBG_IKE, "failed to initiate EAP exchange, sending %N",
eap_type_names, type, eap_code_names, EAP_FAILURE);
*out = eap_payload_create_code(EAP_FAILURE);
return FAILED;
@@ -179,11 +188,14 @@ static status_t initiate(private_eap_authenticator_t *this, eap_type_t type,
static status_t process_peer(private_eap_authenticator_t *this,
eap_payload_t *in, eap_payload_t **out)
{
- eap_type_t type = in->get_type(in);
+ eap_type_t type;
+ u_int32_t vendor;
- if (type == EAP_IDENTITY)
+ type = in->get_type(in, &vendor);
+
+ if (!vendor && type == EAP_IDENTITY)
{
- eap_method_t *method = eap_method_create(type, EAP_PEER,
+ eap_method_t *method = eap_method_create(type, 0, EAP_PEER,
this->ike_sa->get_other_id(this->ike_sa),
this->ike_sa->get_my_id(this->ike_sa));
@@ -205,32 +217,57 @@ static status_t process_peer(private_eap_authenticator_t *this,
/* create an eap_method for the first call */
if (this->method == NULL)
{
- DBG1(DBG_IKE, "EAP server requested %N authentication",
- eap_type_names, type);
- this->method = eap_method_create(type, EAP_PEER,
+ if (vendor)
+ {
+ DBG1(DBG_IKE, "EAP server requested vendor specific EAP method %d-%d",
+ type, vendor);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "EAP server requested %N authentication",
+ eap_type_names, type);
+ }
+ this->method = eap_method_create(type, vendor, EAP_PEER,
this->ike_sa->get_other_id(this->ike_sa),
this->ike_sa->get_my_id(this->ike_sa));
if (this->method == NULL)
{
DBG1(DBG_IKE, "EAP server requested unsupported "
- "EAP method %N, sending EAP_NAK", eap_type_names, type);
+ "EAP method, sending EAP_NAK");
*out = eap_payload_create_nak();
return NEED_MORE;
}
}
+ type = this->method->get_type(this->method, &vendor);
+
switch (this->method->process(this->method, in, out))
{
case NEED_MORE:
return NEED_MORE;
case SUCCESS:
- DBG1(DBG_IKE, "EAP method %N succeded",
- eap_type_names, this->method->get_type(this->method));
+ if (vendor)
+ {
+ DBG1(DBG_IKE, "EAP vendor specific method %d-%d succeded",
+ type, vendor);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "EAP method %N succeded", eap_type_names, type);
+ }
return SUCCESS;
case FAILED:
default:
- DBG1(DBG_IKE, "EAP method %N failed",
- eap_type_names, this->method->get_type(this->method));
+ if (vendor)
+ {
+ DBG1(DBG_IKE, "EAP vendor specific method %d-%d failed",
+ type, vendor);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "EAP method %N failed",
+ eap_type_names, type);
+ }
return FAILED;
}
}
@@ -241,6 +278,11 @@ static status_t process_peer(private_eap_authenticator_t *this,
static status_t process_server(private_eap_authenticator_t *this,
eap_payload_t *in, eap_payload_t **out)
{
+ eap_type_t type;
+ u_int32_t vendor;
+
+ type = this->method->get_type(this->method, &vendor);
+
switch (this->method->process(this->method, in, out))
{
case NEED_MORE:
@@ -248,22 +290,35 @@ static status_t process_server(private_eap_authenticator_t *this,
case SUCCESS:
if (this->method->get_msk(this->method, &this->msk) == SUCCESS)
{
- DBG1(DBG_IKE, "EAP method %N succeded, MSK established",
- eap_type_names, this->method->get_type(this->method));
this->msk = chunk_clone(this->msk);
}
+ if (vendor)
+ {
+ DBG1(DBG_IKE, "EAP vendor specific method %d-%d succeded, "
+ "%sMSK established", type, vendor,
+ this->msk.ptr ? "" : "no ");
+ }
else
{
- DBG1(DBG_IKE, "EAP method %N succeded, no MSK established",
- eap_type_names, this->method->get_type(this->method));
+ DBG1(DBG_IKE, "EAP method %N succeded, %sMSK established",
+ eap_type_names, type, this->msk.ptr ? "" : "no ");
}
*out = eap_payload_create_code(EAP_SUCCESS);
return SUCCESS;
case FAILED:
default:
- DBG1(DBG_IKE, "EAP method %N failed for peer %D",
- eap_type_names, this->method->get_type(this->method),
- this->ike_sa->get_other_id(this->ike_sa));
+ if (vendor)
+ {
+ DBG1(DBG_IKE, "EAP vendor specific method %d-%d failed for "
+ "peer %D", type, vendor,
+ this->ike_sa->get_other_id(this->ike_sa));
+ }
+ else
+ {
+ DBG1(DBG_IKE, "EAP method %N failed for peer %D",
+ eap_type_names, type,
+ this->ike_sa->get_other_id(this->ike_sa));
+ }
*out = eap_payload_create_code(EAP_FAILURE);
return FAILED;
}
@@ -363,7 +418,7 @@ eap_authenticator_t *eap_authenticator_create(ike_sa_t *ike_sa)
this->public.authenticator_interface.destroy = (void(*)(authenticator_t*))destroy;
this->public.is_mutual = (bool(*)(eap_authenticator_t*))is_mutual;
- this->public.initiate = (status_t(*)(eap_authenticator_t*,eap_type_t,eap_payload_t**))initiate;
+ this->public.initiate = (status_t(*)(eap_authenticator_t*,eap_type_t,u_int32_t,eap_payload_t**))initiate;
this->public.process = (status_t(*)(eap_authenticator_t*,eap_payload_t*,eap_payload_t**))process;
/* private data */
diff --git a/src/charon/sa/authenticators/eap_authenticator.h b/src/charon/sa/authenticators/eap_authenticator.h
index 64a3267d7..cf2180ee3 100644
--- a/src/charon/sa/authenticators/eap_authenticator.h
+++ b/src/charon/sa/authenticators/eap_authenticator.h
@@ -105,15 +105,16 @@ struct eap_authenticator_t {
* this method. If initiate() returns NEED_MORE, the EAP authentication
* process started. In any case, a payload is created in "out".
*
- * @param this calling object
- * @param type EAP method to use to authenticate client
- * @param out created initiaal EAP message to send
+ * @param this calling object
+ * @param type EAP method to use to authenticate client
+ * @param vendor EAP vendor identifier, if type is vendor specific, or 0
+ * @param out created initiaal EAP message to send
* @return
* - FAILED, if initiation failed
* - NEED_MORE, if more EAP exchanges reqired
*/
status_t (*initiate) (eap_authenticator_t* this, eap_type_t type,
- eap_payload_t **out);
+ u_int32_t vendor, eap_payload_t **out);
/**
* @brief Process an EAP message.
diff --git a/src/charon/sa/child_sa.c b/src/charon/sa/child_sa.c
index 44f0298d5..b6c71a8b5 100644
--- a/src/charon/sa/child_sa.c
+++ b/src/charon/sa/child_sa.c
@@ -354,7 +354,7 @@ static void updown(private_child_sa_t *this, bool up)
up ? "up" : "down",
policy->my_ts->is_host(policy->my_ts,
this->me.addr) ? "-host" : "-client",
- this->me.addr->get_family(this->me.addr) == AF_INET ? "" : "-ipv6",
+ this->me.addr->get_family(this->me.addr) == AF_INET ? "" : "-v6",
this->config->get_name(this->config),
this->iface ? this->iface : "unknown",
this->reqid,
diff --git a/src/charon/sa/connect_manager.c b/src/charon/sa/connect_manager.c
index d583e01bb..d0f3cde8d 100644
--- a/src/charon/sa/connect_manager.c
+++ b/src/charon/sa/connect_manager.c
@@ -32,13 +32,13 @@
#include <processing/jobs/initiate_mediation_job.h>
#include <encoding/payloads/endpoint_notify.h>
-// base timeout
-// the sending interval is P2P_INTERVAL * active checklists (N)
-// retransmission timeout is P2P_INTERVAL * N * checks in waiting state (NW)
-#define P2P_INTERVAL 20 // 20 ms
-// min retransmission timeout (RTO is P2P_INTERVAL * N * checks in waiting state)
-#define P2P_RTO_MIN 100 // 100 ms
-// max number of retransmissions (+ the initial check)
+/* base timeout
+ * the sending interval is P2P_INTERVAL * active checklists (N)
+ * retransmission timeout is P2P_INTERVAL * N * checks in waiting state (NW) */
+#define P2P_INTERVAL 20 /* ms */
+/* min retransmission timeout (RTO is P2P_INTERVAL * N * checks in waiting state) */
+#define P2P_RTO_MIN 100 /* ms */
+/* max number of retransmissions (+ the initial check) */
#define P2P_MAX_RETRANS 2
@@ -212,7 +212,8 @@ static void check_list_destroy(check_list_t *this)
DESTROY_OFFSET_IF(this->responder.endpoints, offsetof(endpoint_notify_t, destroy));
DESTROY_FUNCTION_IF(this->pairs, (void*)endpoint_pair_destroy);
- DESTROY_IF(this->triggered); // this list contains some of the same elements as contained in this->pairs
+ /* this list contains some of the same elements as contained in this->pairs */
+ DESTROY_IF(this->triggered);
free(this);
}
@@ -489,8 +490,6 @@ static initiate_data_t *initiate_data_create(check_list_t *checklist, initiated_
return this;
}
-// -----------------------------------------------------------------------------
-
/**
* Find an initiated connection by the peers' ids
*/
@@ -641,9 +640,6 @@ static status_t endpoints_contain(linked_list_t *endpoints, host_t *host, endpoi
return status;
}
-// -----------------------------------------------------------------------------
-
-
/**
* Updates the state of the whole checklist
*/
@@ -659,7 +655,8 @@ static void update_checklist_state(check_list_t *checklist)
switch(current->state)
{
case CHECK_WAITING:
- // at least one is still waiting -> checklist remains in waiting state
+ /* at least one is still waiting -> checklist remains
+ * in waiting state */
iterator->destroy(iterator);
return;
case CHECK_IN_PROGRESS:
@@ -668,6 +665,8 @@ static void update_checklist_state(check_list_t *checklist)
case CHECK_SUCCEEDED:
succeeded = TRUE;
break;
+ default:
+ break;
}
}
iterator->destroy(iterator);
@@ -832,7 +831,6 @@ static void prune_pairs(linked_list_t *pairs)
{
iterator_t *iterator, *search;
endpoint_pair_t *current, *other;
- bool inserted = FALSE;
u_int32_t id = 0;
iterator = pairs->create_iterator(pairs, TRUE);
@@ -851,10 +849,10 @@ static void prune_pairs(linked_list_t *pairs)
if (current->local->equals(current->local, other->local) &&
current->remote->equals(current->remote, other->remote))
{
- // since the list of pairs is sorted by priority in descending
- // order, and we iterate the list from the beginning, we are
- // sure that the priority of 'other' is lower than that of
- // 'current', remove it
+ /* since the list of pairs is sorted by priority in descending
+ * order, and we iterate the list from the beginning, we are
+ * sure that the priority of 'other' is lower than that of
+ * 'current', remove it */
DBG1(DBG_IKE, "pruning endpoint pair %H - %H with priority %d",
other->local, other->remote, other->priority);
search->remove(search);
@@ -896,8 +894,6 @@ static void build_pairs(check_list_t *checklist)
prune_pairs(checklist->pairs);
}
-// -----------------------------------------------------------------------------
-
/**
* Processes the payloads of a connectivity check and returns the extracted data
*/
@@ -936,7 +932,7 @@ static status_t process_payloads(message_t *message, check_t *check)
}
check->endpoint = endpoint;
check->endpoint_raw = chunk_clone(notify->get_notification_data(notify));
- DBG3(DBG_IKE, "received P2P_ENDPOINT notify");
+ DBG2(DBG_IKE, "received P2P_ENDPOINT notify");
break;
}
case P2P_SESSIONID:
@@ -1000,9 +996,6 @@ static chunk_t build_signature(private_connect_manager_t *this,
return sig_hash;
}
-// -----------------------------------------------------------------------------
-
-// forward declarations
static void queue_retransmission(private_connect_manager_t *this, chunk_t session_id, u_int32_t mid);
static void schedule_checks(private_connect_manager_t *this, check_list_t *checklist, u_int32_t time);
static void finish_checks(private_connect_manager_t *this, check_list_t *checklist);
@@ -1061,11 +1054,13 @@ retransmit_end:
case CHECK_FAILED:
finish_checks(this, checklist);
break;
+ default:
+ break;
}
pthread_mutex_unlock(&(this->mutex));
- // we reschedule it manually
+ /* we reschedule it manually */
return JOB_REQUEUE_NONE;
}
@@ -1192,13 +1187,13 @@ static job_requeue_t sender(sender_data_t *data)
check_destroy(check);
- // schedule this job again
+ /* schedule this job again */
u_int32_t N = this->checklists->get_count(this->checklists);
schedule_checks(this, checklist, P2P_INTERVAL * N);
pthread_mutex_unlock(&(this->mutex));
- // we reschedule it manually
+ /* we reschedule it manually */
return JOB_REQUEUE_NONE;
}
@@ -1240,8 +1235,10 @@ static job_requeue_t initiate_mediated(initiate_data_t *data)
}
else
{
- // this should (can?) not happen
+ /* this should (can?) not happen */
}
+
+ return JOB_REQUEUE_NONE;
}
/**
@@ -1270,9 +1267,10 @@ static void finish_checks(private_connect_manager_t *this, check_list_t *checkli
}
}
- //remove_checklist(this, checklist);
- //check_list_destroy(checklist);
- // FIXME: we should do this ^^^ after a specific timeout on the responder side
+ /* remove_checklist(this, checklist);
+ * check_list_destroy(checklist);
+ * FIXME: we should do this ^^^ after a specific timeout on the
+ * responder side */
}
/**
@@ -1313,6 +1311,8 @@ static void process_response(private_connect_manager_t *this, check_t *check,
case CHECK_FAILED:
finish_checks(this, checklist);
break;
+ default:
+ break;
}
}
else
@@ -1343,16 +1343,16 @@ static void process_request(private_connect_manager_t *this, check_t *check,
switch(pair->state)
{
case CHECK_IN_PROGRESS:
- pair->retransmitted = P2P_MAX_RETRANS; // prevent retransmissions
- // FIXME: we should wait to the next rto to send the triggered check
- // fall-through
+ /* prevent retransmissions */
+ pair->retransmitted = P2P_MAX_RETRANS;
+ /* FIXME: we should wait to the next rto to send the triggered check
+ * fall-through */
case CHECK_WAITING:
case CHECK_FAILED:
queue_triggered_check(checklist, pair);
break;
case CHECK_SUCCEEDED:
default:
- // do nothing
break;
}
}
@@ -1451,8 +1451,6 @@ static void process_check(private_connect_manager_t *this, message_t *message)
check_destroy(check);
}
-// -----------------------------------------------------------------------------
-
/**
* Implementation of connect_manager_t.check_and_register.
*/
@@ -1568,7 +1566,8 @@ static status_t set_responder_data(private_connect_manager_t *this,
build_pairs(checklist);
- schedule_checks(this, checklist, 0); // send the first check immediately
+ /* send the first check immediately */
+ schedule_checks(this, checklist, 0);
pthread_mutex_unlock(&(this->mutex));
diff --git a/src/charon/sa/ike_sa.c b/src/charon/sa/ike_sa.c
index 9d7a17e89..9cada2cb5 100644
--- a/src/charon/sa/ike_sa.c
+++ b/src/charon/sa/ike_sa.c
@@ -51,6 +51,7 @@
#include <sa/tasks/ike_natd.h>
#include <sa/tasks/ike_mobike.h>
#include <sa/tasks/ike_auth.h>
+#include <sa/tasks/ike_auth_lifetime.h>
#include <sa/tasks/ike_config.h>
#include <sa/tasks/ike_cert.h>
#include <sa/tasks/ike_rekey.h>
@@ -68,6 +69,7 @@
#ifdef P2P
#include <sa/tasks/ike_p2p.h>
+#include <processing/jobs/initiate_mediation_job.h>
#endif
#ifndef RESOLV_CONF
@@ -248,6 +250,8 @@ struct private_ike_sa_t {
u_int32_t established;
/** when IKE_SA gets rekeyed */
u_int32_t rekey;
+ /** when IKE_SA gets reauthenticated */
+ u_int32_t reauth;
/** when IKE_SA gets deleted */
u_int32_t delete;
} time;
@@ -256,6 +260,11 @@ struct private_ike_sa_t {
* how many times we have retried so far (keyingtries)
*/
u_int32_t keyingtry;
+
+ /**
+ * are we the initiator of this IKE_SA (rekeying does not affect this flag)
+ */
+ bool ike_initiator;
};
/**
@@ -307,16 +316,31 @@ static char *get_name(private_ike_sa_t *this)
return "(unnamed)";
}
-
/**
- * Implementation of ike_sa_t.get_stats.
+ * Implementation of ike_sa_t.get_statistic.
*/
-static void get_stats(private_ike_sa_t *this, u_int32_t *next_rekeying)
+static u_int32_t get_statistic(private_ike_sa_t *this, statistic_t kind)
{
- if (next_rekeying)
+ time_t now = time(NULL);
+
+ switch (kind)
{
- *next_rekeying = this->time.rekey;
+ case STAT_REKEY_TIME:
+ if (this->time.rekey > now)
+ {
+ return this->time.rekey - now;
+ }
+ break;
+ case STAT_REAUTH_TIME:
+ if (this->time.reauth > now)
+ {
+ return this->time.reauth - now;
+ }
+ break;
+ default:
+ break;
}
+ return 0;
}
/**
@@ -493,10 +517,6 @@ static void set_condition(private_ike_sa_t *this, ike_condition_t condition,
this->conditions |= condition;
switch (condition)
{
- case COND_STALE:
- DBG1(DBG_IKE, "no route to %H, setting IKE_SA to stale",
- this->other_host);
- break;
case COND_NAT_HERE:
DBG1(DBG_IKE, "local host is behind NAT, sending keep alives");
this->conditions |= COND_NAT_ANY;
@@ -519,9 +539,6 @@ static void set_condition(private_ike_sa_t *this, ike_condition_t condition,
this->conditions &= ~condition;
switch (condition)
{
- case COND_STALE:
- DBG1(DBG_IKE, "new route to %H found", this->other_host);
- break;
case COND_NAT_HERE:
case COND_NAT_FAKE:
case COND_NAT_THERE:
@@ -610,36 +627,58 @@ static void set_state(private_ike_sa_t *this, ike_sa_state_t state)
if (this->state == IKE_CONNECTING)
{
job_t *job;
- u_int32_t now = time(NULL);
- u_int32_t soft, hard;
- bool reauth;
+ u_int32_t t;
- this->time.established = now;
- /* start DPD checks */
- send_dpd(this);
+ /* calculate rekey, reauth and lifetime */
+ this->time.established = time(NULL);
- /* schedule rekeying/reauthentication */
- soft = this->peer_cfg->get_lifetime(this->peer_cfg, TRUE);
- hard = this->peer_cfg->get_lifetime(this->peer_cfg, FALSE);
- reauth = this->peer_cfg->use_reauth(this->peer_cfg);
- DBG1(DBG_IKE, "scheduling %s in %ds, maximum lifetime %ds",
- reauth ? "reauthentication": "rekeying", soft, hard);
-
- if (soft)
+ /* schedule rekeying if we have a time which is smaller than
+ * an already scheduled rekeying */
+ t = this->peer_cfg->get_rekey_time(this->peer_cfg);
+ if (t && (this->time.rekey == 0 ||
+ (this->time.rekey > t + this->time.established)))
{
- this->time.rekey = now + soft;
- job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, reauth);
- charon->scheduler->schedule_job(charon->scheduler, job,
- soft * 1000);
+ this->time.rekey = t + this->time.established;
+ job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, FALSE);
+ charon->scheduler->schedule_job(charon->scheduler,
+ job, t * 1000);
+ DBG1(DBG_IKE, "scheduling rekeying in %ds", t);
}
-
- if (hard)
+ t = this->peer_cfg->get_reauth_time(this->peer_cfg);
+ if (t && (this->time.reauth == 0 ||
+ (this->time.reauth > t + this->time.established)))
{
- this->time.delete = now + hard;
+ this->time.reauth = t + this->time.established;
+ job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE);
+ charon->scheduler->schedule_job(charon->scheduler,
+ job, t * 1000);
+ DBG1(DBG_IKE, "scheduling reauthentication in %ds", t);
+ }
+ t = this->peer_cfg->get_over_time(this->peer_cfg);
+ if (this->time.rekey || this->time.reauth)
+ {
+ if (this->time.reauth == 0)
+ {
+ this->time.delete = this->time.rekey;
+ }
+ else if (this->time.rekey == 0)
+ {
+ this->time.delete = this->time.reauth;
+ }
+ else
+ {
+ this->time.delete = min(this->time.rekey, this->time.reauth);
+ }
+ this->time.delete += t;
+ t = this->time.delete - this->time.established;
job = (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE);
charon->scheduler->schedule_job(charon->scheduler, job,
- hard * 1000);
+ t * 1000);
+ DBG1(DBG_IKE, "maximum IKE_SA lifetime %ds", t);
}
+
+ /* start DPD checks */
+ send_dpd(this);
}
break;
}
@@ -681,17 +720,17 @@ static void set_virtual_ip(private_ike_sa_t *this, bool local, host_t *ip)
{
if (local)
{
- if (this->my_virtual_ip)
- {
- DBG1(DBG_IKE, "removing old virtual IP %H", this->my_virtual_ip);
- charon->kernel_interface->del_ip(charon->kernel_interface,
- this->my_virtual_ip);
- this->my_virtual_ip->destroy(this->my_virtual_ip);
- }
DBG1(DBG_IKE, "installing new virtual IP %H", ip);
if (charon->kernel_interface->add_ip(charon->kernel_interface, ip,
this->my_host) == SUCCESS)
{
+ if (this->my_virtual_ip)
+ {
+ DBG1(DBG_IKE, "removing old virtual IP %H", this->my_virtual_ip);
+ charon->kernel_interface->del_ip(charon->kernel_interface,
+ this->my_virtual_ip);
+ }
+ DESTROY_IF(this->my_virtual_ip);
this->my_virtual_ip = ip->clone(ip);
}
else
@@ -859,6 +898,8 @@ static void send_notify_response(private_ike_sa_t *this, message_t *request,
this->other_host = request->get_source(request);
this->other_host = this->other_host->clone(this->other_host);
}
+ response->set_source(response, this->my_host->clone(this->my_host));
+ response->set_destination(response, this->other_host->clone(this->other_host));
if (generate_message(this, response, &packet) == SUCCESS)
{
charon->sender->send(charon->sender, packet);
@@ -973,6 +1014,8 @@ static status_t initiate(private_ike_sa_t *this, child_cfg_t *child_cfg)
return DESTROY_ME;
}
+ this->ike_initiator = TRUE;
+
task = (task_t*)ike_init_create(&this->public, TRUE, NULL);
this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_natd_create(&this->public, TRUE);
@@ -983,6 +1026,8 @@ static status_t initiate(private_ike_sa_t *this, child_cfg_t *child_cfg)
this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_config_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
+ task = (task_t*)ike_auth_lifetime_create(&this->public, TRUE);
+ this->task_manager->queue_task(this->task_manager, task);
if (this->peer_cfg->use_mobike(this->peer_cfg))
{
task = (task_t*)ike_mobike_create(&this->public, TRUE);
@@ -997,7 +1042,7 @@ static status_t initiate(private_ike_sa_t *this, child_cfg_t *child_cfg)
#ifdef P2P
if (this->peer_cfg->get_mediated_by(this->peer_cfg))
{
- // mediated connection, initiate mediation process
+ /* mediated connection, initiate mediation process */
job_t *job = (job_t*)initiate_mediation_job_create(this->ike_sa_id, child_cfg);
child_cfg->destroy(child_cfg);
charon->processor->queue_job(charon->processor, job);
@@ -1006,14 +1051,14 @@ static status_t initiate(private_ike_sa_t *this, child_cfg_t *child_cfg)
else if (this->peer_cfg->is_mediation(this->peer_cfg))
{
if (this->state == IKE_ESTABLISHED)
- {// FIXME: we should try to find a better solution to this
+ { /* FIXME: we should try to find a better solution to this */
SIG(CHILD_UP_SUCCESS, "mediation connection is already up and running");
}
}
else
#endif /* P2P */
{
- // normal IKE_SA with CHILD_SA
+ /* normal IKE_SA with CHILD_SA */
task = (task_t*)child_create_create(&this->public, child_cfg);
child_cfg->destroy(child_cfg);
this->task_manager->queue_task(this->task_manager, task);
@@ -1026,7 +1071,7 @@ static status_t initiate(private_ike_sa_t *this, child_cfg_t *child_cfg)
* Implementation of ike_sa_t.acquire.
*/
static status_t acquire(private_ike_sa_t *this, u_int32_t reqid)
-{// FIXME: P2P-NAT-T
+{ /* FIXME: P2P-NAT-T */
child_cfg_t *child_cfg;
iterator_t *iterator;
child_sa_t *current, *child_sa = NULL;
@@ -1073,6 +1118,8 @@ static status_t acquire(private_ike_sa_t *this, u_int32_t reqid)
this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_config_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
+ task = (task_t*)ike_auth_lifetime_create(&this->public, TRUE);
+ this->task_manager->queue_task(this->task_manager, task);
if (this->peer_cfg->use_mobike(this->peer_cfg))
{
task = (task_t*)ike_mobike_create(&this->public, TRUE);
@@ -1350,7 +1397,7 @@ static status_t process_message(private_ike_sa_t *this, message_t *message)
* Implementation of ike_sa_t.retransmit.
*/
static status_t retransmit(private_ike_sa_t *this, u_int32_t message_id)
-{// FIXME: P2P-NAT-T
+{ /* FIXME: P2P-NAT-T */
this->time.outbound = time(NULL);
if (this->task_manager->retransmit(this->task_manager, message_id) != SUCCESS)
{
@@ -1467,6 +1514,8 @@ static status_t retransmit(private_ike_sa_t *this, u_int32_t message_id)
task = (task_t*)child_create_create(&new->public, child_cfg);
new->task_manager->queue_task(new->task_manager, task);
}
+ task = (task_t*)ike_auth_lifetime_create(&new->public, TRUE);
+ new->task_manager->queue_task(new->task_manager, task);
if (this->peer_cfg->use_mobike(this->peer_cfg))
{
task = (task_t*)ike_mobike_create(&new->public, TRUE);
@@ -1900,14 +1949,59 @@ static status_t rekey(private_ike_sa_t *this)
static status_t reestablish(private_ike_sa_t *this)
{
task_t *task;
-
+
+ /* we can't reauthenticate as responder when we use EAP or virtual IPs.
+ * If the peer does not support RFC4478, there is no way to keep the
+ * IKE_SA up. */
+ if (!this->ike_initiator)
+ {
+ DBG1(DBG_IKE, "initiator did not reauthenticate as requested");
+ if (this->other_virtual_ip != NULL ||
+ has_condition(this, COND_EAP_AUTHENTICATED))
+ {
+ time_t now = time(NULL);
+
+ DBG1(DBG_IKE, "IKE_SA will timeout in %#V", &now, &this->time.delete);
+ return FAILED;
+ }
+ else
+ {
+ DBG1(DBG_IKE, "reauthenticating actively");
+ }
+ }
task = (task_t*)ike_reauth_create(&this->public);
this->task_manager->queue_task(this->task_manager, task);
-
+
return this->task_manager->initiate(this->task_manager);
}
/**
+ * Implementation of ike_sa_t.set_auth_lifetime.
+ */
+static void set_auth_lifetime(private_ike_sa_t *this, u_int32_t lifetime)
+{
+ job_t *job;
+ u_int32_t reduction = this->peer_cfg->get_over_time(this->peer_cfg);
+
+ this->time.reauth = time(NULL) + lifetime - reduction;
+ job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE);
+
+ if (lifetime < reduction)
+ {
+ DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, starting reauthentication",
+ lifetime);
+ charon->processor->queue_job(charon->processor, job);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, scheduling reauthentication"
+ " in %ds", lifetime, lifetime - reduction);
+ charon->scheduler->schedule_job(charon->scheduler, job,
+ (lifetime - reduction) * 1000);
+ }
+}
+
+/**
* Implementation of ike_sa_t.roam.
*/
static status_t roam(private_ike_sa_t *this, bool address)
@@ -1933,7 +2027,6 @@ static status_t roam(private_ike_sa_t *this, bool address)
me = charon->kernel_interface->get_source_addr(charon->kernel_interface,
other);
- set_condition(this, COND_STALE, FALSE);
if (me)
{
if (me->ip_equals(me, this->my_host) &&
@@ -1977,6 +2070,7 @@ static status_t inherit(private_ike_sa_t *this, private_ike_sa_t *other)
this->other_host = other->other_host->clone(other->other_host);
this->my_id = other->my_id->clone(other->my_id);
this->other_id = other->other_id->clone(other->other_id);
+ this->ike_initiator = other->ike_initiator;
/* apply virtual assigned IPs... */
if (other->my_virtual_ip)
@@ -2007,6 +2101,24 @@ static status_t inherit(private_ike_sa_t *this, private_ike_sa_t *other)
/* move pending tasks to the new IKE_SA */
this->task_manager->adopt_tasks(this->task_manager, other->task_manager);
+ /* reauthentication timeout survives a rekeying */
+ if (other->time.reauth)
+ {
+ time_t reauth, delete, now = time(NULL);
+
+ this->time.reauth = other->time.reauth;
+ reauth = this->time.reauth - now;
+ delete = reauth + this->peer_cfg->get_over_time(this->peer_cfg);
+ this->time.delete = this->time.reauth + delete;
+ DBG1(DBG_IKE, "rescheduling reauthentication in %ds after rekeying, "
+ "lifetime reduced to %ds", reauth, delete);
+ charon->scheduler->schedule_job(charon->scheduler,
+ (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE),
+ reauth * 1000);
+ charon->scheduler->schedule_job(charon->scheduler,
+ (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE),
+ delete * 1000);
+ }
/* we have to initate here, there may be new tasks to handle */
return this->task_manager->initiate(this->task_manager);
}
@@ -2177,7 +2289,7 @@ static void destroy(private_ike_sa_t *this)
if (this->peer_cfg && this->peer_cfg->is_mediation(this->peer_cfg) &&
!this->ike_sa_id->is_initiator(this->ike_sa_id))
{
- // mediation server
+ /* mediation server */
charon->mediation_manager->remove(charon->mediation_manager, this->ike_sa_id);
}
DESTROY_IF(this->server_reflexive_host);
@@ -2207,8 +2319,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
/* Public functions */
this->public.get_state = (ike_sa_state_t (*)(ike_sa_t*)) get_state;
this->public.set_state = (void (*)(ike_sa_t*,ike_sa_state_t)) set_state;
- this->public.get_stats = (void (*)(ike_sa_t*,u_int32_t*))get_stats;
this->public.get_name = (char* (*)(ike_sa_t*))get_name;
+ this->public.get_statistic = (u_int32_t(*)(ike_sa_t*, statistic_t kind))get_statistic;
this->public.process_message = (status_t (*)(ike_sa_t*, message_t*)) process_message;
this->public.initiate = (status_t (*)(ike_sa_t*,child_cfg_t*)) initiate;
this->public.route = (status_t (*)(ike_sa_t*,child_cfg_t*)) route;
@@ -2256,6 +2368,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->public.destroy_child_sa = (status_t (*)(ike_sa_t*,protocol_id_t,u_int32_t))destroy_child_sa;
this->public.rekey = (status_t (*)(ike_sa_t*))rekey;
this->public.reestablish = (status_t (*)(ike_sa_t*))reestablish;
+ this->public.set_auth_lifetime = (void(*)(ike_sa_t*, u_int32_t lifetime))set_auth_lifetime;
this->public.roam = (status_t(*)(ike_sa_t*,bool))roam;
this->public.inherit = (status_t (*)(ike_sa_t*,ike_sa_t*))inherit;
this->public.generate_message = (status_t (*)(ike_sa_t*,message_t*,packet_t**))generate_message;
@@ -2296,6 +2409,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->time.inbound = this->time.outbound = time(NULL);
this->time.established = 0;
this->time.rekey = 0;
+ this->time.reauth = 0;
this->time.delete = 0;
this->ike_cfg = NULL;
this->peer_cfg = NULL;
@@ -2307,6 +2421,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->additional_addresses = linked_list_create();
this->pending_updates = 0;
this->keyingtry = 0;
+ this->ike_initiator = FALSE;
#ifdef P2P
this->server_reflexive_host = NULL;
#endif /* P2P */
diff --git a/src/charon/sa/ike_sa.h b/src/charon/sa/ike_sa.h
index 99f09e98a..975447d9c 100644
--- a/src/charon/sa/ike_sa.h
+++ b/src/charon/sa/ike_sa.h
@@ -29,6 +29,7 @@
typedef enum ike_extension_t ike_extension_t;
typedef enum ike_condition_t ike_condition_t;
typedef enum ike_sa_state_t ike_sa_state_t;
+typedef enum statistic_t statistic_t;
typedef struct ike_sa_t ike_sa_t;
#include <library.h>
@@ -115,9 +116,25 @@ enum ike_condition_t {
COND_NAT_FAKE = (1<<3),
/**
- * peer is currently not reachable (due missing route, ...)
+ * peer has ben authenticated using EAP
*/
- COND_STALE = (1<<4),
+ COND_EAP_AUTHENTICATED = (1<<4),
+};
+
+/**
+ * Information and statistics to query from an SA
+ */
+enum statistic_t {
+
+ /**
+ * Relative time for scheduled rekeying
+ */
+ STAT_REKEY_TIME,
+
+ /**
+ * Relative time for scheduled reauthentication
+ */
+ STAT_REAUTH_TIME,
};
/**
@@ -234,13 +251,6 @@ struct ike_sa_t {
ike_sa_state_t (*get_state) (ike_sa_t *this);
/**
- * @brief Get some statistics about this IKE_SA.
- *
- * @param next_rekeying when the next rekeying is scheduled
- */
- void (*get_stats)(ike_sa_t *this, u_int32_t *next_rekeying);
-
- /**
* @brief Set the state of the IKE_SA.
*
* @param this calling object
@@ -257,6 +267,15 @@ struct ike_sa_t {
char* (*get_name) (ike_sa_t *this);
/**
+ * @brief Get statistic values from the IKE_SA.
+ *
+ * @param this calling object
+ * @param kind kind of requested value
+ * @return value as integer
+ */
+ u_int32_t (*get_statistic)(ike_sa_t *this, statistic_t kind);
+
+ /**
* @brief Get the own host address.
*
* @param this calling object
@@ -846,6 +865,14 @@ struct ike_sa_t {
status_t (*reestablish) (ike_sa_t *this);
/**
+ * @brief Set the lifetime limit received from a AUTH_LIFETIME notify.
+ *
+ * @param this calling object
+ * @param lifetime lifetime in seconds
+ */
+ void (*set_auth_lifetime)(ike_sa_t *this, u_int32_t lifetime);
+
+ /**
* @brief Set the virtual IP to use for this IKE_SA and its children.
*
* The virtual IP is assigned per IKE_SA, not per CHILD_SA. It has the same
diff --git a/src/charon/sa/mediation_manager.c b/src/charon/sa/mediation_manager.c
index fca53a940..f6137304d 100644
--- a/src/charon/sa/mediation_manager.c
+++ b/src/charon/sa/mediation_manager.c
@@ -240,7 +240,7 @@ static void update_sa_id(private_mediation_manager_t *this, identification_t *pe
DBG2(DBG_IKE, "changing registered IKE_SA ID of peer '%D'", peer_id);
peer->ike_sa_id = ike_sa_id ? ike_sa_id->clone(ike_sa_id) : NULL;
- // send callbacks to registered peers
+ /* send callbacks to registered peers */
identification_t *requester;
while(peer->requested_by->remove_last(peer->requested_by, (void**)&requester) == SUCCESS)
{
@@ -295,7 +295,7 @@ static ike_sa_id_t *check_and_register(private_mediation_manager_t *this,
if (!peer->ike_sa_id)
{
- // the peer is not online
+ /* the peer is not online */
DBG2(DBG_IKE, "requested peer '%D' is offline, registering peer '%D'", peer_id, requester);
register_peer(peer, requester);
pthread_mutex_unlock(&(this->mutex));
diff --git a/src/charon/sa/task_manager.c b/src/charon/sa/task_manager.c
index f4484774e..89f527aba 100644
--- a/src/charon/sa/task_manager.c
+++ b/src/charon/sa/task_manager.c
@@ -30,6 +30,7 @@
#include <sa/tasks/ike_natd.h>
#include <sa/tasks/ike_mobike.h>
#include <sa/tasks/ike_auth.h>
+#include <sa/tasks/ike_auth_lifetime.h>
#include <sa/tasks/ike_cert.h>
#include <sa/tasks/ike_rekey.h>
#include <sa/tasks/ike_delete.h>
@@ -338,6 +339,7 @@ static status_t build_request(private_task_manager_t *this)
activate_task(this, IKE_AUTHENTICATE);
activate_task(this, IKE_CONFIG);
activate_task(this, CHILD_CREATE);
+ activate_task(this, IKE_AUTH_LIFETIME);
activate_task(this, IKE_MOBIKE);
}
break;
@@ -690,19 +692,21 @@ static status_t process_request(private_task_manager_t *this,
#ifdef P2P
task = (task_t*)ike_p2p_create(this->ike_sa, FALSE);
this->passive_tasks->insert_last(this->passive_tasks, task);
-#endif /* P2P */
+#endif /* P2P */
task = (task_t*)ike_auth_create(this->ike_sa, FALSE);
this->passive_tasks->insert_last(this->passive_tasks, task);
task = (task_t*)ike_config_create(this->ike_sa, FALSE);
this->passive_tasks->insert_last(this->passive_tasks, task);
task = (task_t*)child_create_create(this->ike_sa, NULL);
this->passive_tasks->insert_last(this->passive_tasks, task);
+ task = (task_t*)ike_auth_lifetime_create(this->ike_sa, FALSE);
+ this->passive_tasks->insert_last(this->passive_tasks, task);
task = (task_t*)ike_mobike_create(this->ike_sa, FALSE);
this->passive_tasks->insert_last(this->passive_tasks, task);
break;
}
case CREATE_CHILD_SA:
- {//FIXME: we should prevent this on mediation connections
+ { /* FIXME: we should prevent this on mediation connections */
bool notify_found = FALSE, ts_found = FALSE;
iterator = message->get_payload_iterator(message);
while (iterator->iterate(iterator, (void**)&payload))
@@ -772,8 +776,12 @@ static status_t process_request(private_task_manager_t *this,
case UNACCEPTABLE_ADDRESSES:
case UNEXPECTED_NAT_DETECTED:
case COOKIE2:
- task = (task_t*)ike_mobike_create(this->ike_sa,
- FALSE);
+ task = (task_t*)ike_mobike_create(
+ this->ike_sa, FALSE);
+ break;
+ case AUTH_LIFETIME:
+ task = (task_t*)ike_auth_lifetime_create(
+ this->ike_sa, FALSE);
break;
default:
break;
diff --git a/src/charon/sa/tasks/ike_auth.c b/src/charon/sa/tasks/ike_auth.c
index a3cd6a2bc..de88a0abe 100644
--- a/src/charon/sa/tasks/ike_auth.c
+++ b/src/charon/sa/tasks/ike_auth.c
@@ -297,6 +297,7 @@ static status_t collect_other_init_data(private_ike_auth_t *this, message_t *mes
return NEED_MORE;
}
+
/**
* Implementation of task_t.build to create AUTH payload from EAP data
*/
@@ -520,6 +521,7 @@ static status_t process_r(private_ike_auth_t *this, message_t *message)
break;
case NOT_FOUND:
/* use EAP if no AUTH payload found */
+ this->ike_sa->set_condition(this->ike_sa, COND_EAP_AUTHENTICATED, TRUE);
this->eap_auth = eap_authenticator_create(this->ike_sa);
break;
default:
@@ -546,6 +548,7 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
{
peer_cfg_t *config;
eap_type_t eap_type;
+ u_int32_t eap_vendor;
eap_payload_t *eap_payload;
status_t status;
@@ -590,10 +593,11 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
return FAILED;
}
-
+
/* initiate EAP authenitcation */
- eap_type = config->get_eap_type(config);
- status = this->eap_auth->initiate(this->eap_auth, eap_type, &eap_payload);
+ eap_type = config->get_eap_type(config, &eap_vendor);
+ status = this->eap_auth->initiate(this->eap_auth, eap_type,
+ eap_vendor, &eap_payload);
message->add_payload(message, (payload_t*)eap_payload);
if (status != NEED_MORE)
{
@@ -645,6 +649,12 @@ static status_t process_i(private_ike_auth_t *this, message_t *message)
case ADDITIONAL_IP6_ADDRESS:
/* handled in ike_mobike task */
break;
+ case AUTH_LIFETIME:
+ /* handled in ike_auth_lifetime task */
+ break;
+ case P2P_ENDPOINT:
+ /* handled in ike_p2p task */
+ break;
default:
{
if (type < 16383)
diff --git a/src/charon/sa/tasks/ike_auth_lifetime.c b/src/charon/sa/tasks/ike_auth_lifetime.c
new file mode 100644
index 000000000..9d37ec608
--- /dev/null
+++ b/src/charon/sa/tasks/ike_auth_lifetime.c
@@ -0,0 +1,200 @@
+/**
+ * @file ike_auth_lifetime.c
+ *
+ * @brief Implementation of the ike_auth_lifetime task.
+ *
+ */
+
+/*
+ * 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 "ike_auth_lifetime.h"
+
+#include <daemon.h>
+#include <encoding/payloads/notify_payload.h>
+
+
+typedef struct private_ike_auth_lifetime_t private_ike_auth_lifetime_t;
+
+/**
+ * Private members of a ike_auth_lifetime_t task.
+ */
+struct private_ike_auth_lifetime_t {
+
+ /**
+ * Public methods and task_t interface.
+ */
+ ike_auth_lifetime_t public;
+
+ /**
+ * Assigned IKE_SA.
+ */
+ ike_sa_t *ike_sa;
+};
+
+/**
+ * add the AUTH_LIFETIME notify to the message
+ */
+static void add_auth_lifetime(private_ike_auth_lifetime_t *this, message_t *message)
+{
+ chunk_t chunk;
+ u_int32_t lifetime;
+
+ lifetime = this->ike_sa->get_statistic(this->ike_sa, STAT_REAUTH_TIME);
+ if (lifetime)
+ {
+ chunk = chunk_from_thing(lifetime);
+ *(u_int32_t*)chunk.ptr = htonl(lifetime);
+ message->add_notify(message, FALSE, AUTH_LIFETIME, chunk);
+ }
+}
+
+/**
+ * read notifys from message and evaluate them
+ */
+static void process_payloads(private_ike_auth_lifetime_t *this, message_t *message)
+{
+ iterator_t *iterator;
+ payload_t *payload;
+ notify_payload_t *notify;
+
+ iterator = message->get_payload_iterator(message);
+ while (iterator->iterate(iterator, (void**)&payload))
+ {
+ if (payload->get_type(payload) == NOTIFY)
+ {
+ notify = (notify_payload_t*)payload;
+ switch (notify->get_notify_type(notify))
+ {
+ case AUTH_LIFETIME:
+ {
+ chunk_t data = notify->get_notification_data(notify);
+ u_int32_t lifetime = ntohl(*(u_int32_t*)data.ptr);
+ this->ike_sa->set_auth_lifetime(this->ike_sa, lifetime);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+ iterator->destroy(iterator);
+}
+
+/**
+ * Implementation of task_t.process for initiator
+ */
+static status_t build_i(private_ike_auth_lifetime_t *this, message_t *message)
+{
+ if (message->get_exchange_type(message) == INFORMATIONAL)
+ {
+ add_auth_lifetime(this, message);
+ return SUCCESS;
+ }
+ return NEED_MORE;
+}
+
+/**
+ * Implementation of task_t.process for responder
+ */
+static status_t process_r(private_ike_auth_lifetime_t *this, message_t *message)
+{
+ if (message->get_exchange_type(message) == INFORMATIONAL)
+ {
+ process_payloads(this, message);
+ return SUCCESS;
+ }
+ return NEED_MORE;
+}
+
+/**
+ * Implementation of task_t.build for responder
+ */
+static status_t build_r(private_ike_auth_lifetime_t *this, message_t *message)
+{
+ if (message->get_exchange_type(message) == IKE_AUTH &&
+ this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
+ {
+ add_auth_lifetime(this, message);
+ return SUCCESS;
+ }
+ return NEED_MORE;
+}
+
+/**
+ * Implementation of task_t.process for initiator
+ */
+static status_t process_i(private_ike_auth_lifetime_t *this, message_t *message)
+{
+ if (message->get_exchange_type(message) == IKE_AUTH &&
+ this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
+ {
+ process_payloads(this, message);
+ return SUCCESS;
+ }
+ return NEED_MORE;
+}
+
+/**
+ * Implementation of task_t.get_type
+ */
+static task_type_t get_type(private_ike_auth_lifetime_t *this)
+{
+ return IKE_AUTH_LIFETIME;
+}
+
+/**
+ * Implementation of task_t.migrate
+ */
+static void migrate(private_ike_auth_lifetime_t *this, ike_sa_t *ike_sa)
+{
+ this->ike_sa = ike_sa;
+}
+
+/**
+ * Implementation of task_t.destroy
+ */
+static void destroy(private_ike_auth_lifetime_t *this)
+{
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+ike_auth_lifetime_t *ike_auth_lifetime_create(ike_sa_t *ike_sa, bool initiator)
+{
+ private_ike_auth_lifetime_t *this = malloc_thing(private_ike_auth_lifetime_t);
+
+ this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
+ this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
+ this->public.task.destroy = (void(*)(task_t*))destroy;
+
+ if (initiator)
+ {
+ this->public.task.build = (status_t(*)(task_t*,message_t*))build_i;
+ this->public.task.process = (status_t(*)(task_t*,message_t*))process_i;
+ }
+ else
+ {
+ this->public.task.build = (status_t(*)(task_t*,message_t*))build_r;
+ this->public.task.process = (status_t(*)(task_t*,message_t*))process_r;
+ }
+
+ this->ike_sa = ike_sa;
+
+ return &this->public;
+}
+
diff --git a/src/charon/sa/tasks/ike_auth_lifetime.h b/src/charon/sa/tasks/ike_auth_lifetime.h
new file mode 100644
index 000000000..500b89d39
--- /dev/null
+++ b/src/charon/sa/tasks/ike_auth_lifetime.h
@@ -0,0 +1,61 @@
+/**
+ * @file ike_auth_lifetime.h
+ *
+ * @brief Interface ike_auth_lifetime_t.
+ *
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef IKE_AUTH_LIFETIME_H_
+#define IKE_AUTH_LIFETIME_H_
+
+typedef struct ike_auth_lifetime_t ike_auth_lifetime_t;
+
+#include <library.h>
+#include <sa/ike_sa.h>
+#include <sa/tasks/task.h>
+
+/**
+ * @brief Task of type IKE_AUTH_LIFETIME, implements RFC4478.
+ *
+ * This task exchanges lifetimes for IKE_AUTH to force a client to
+ * reauthenticate before the responders lifetime reaches the limit.
+ *
+ * @b Constructors:
+ * - ike_auth_lifetime_create()
+ *
+ * @ingroup tasks
+ */
+struct ike_auth_lifetime_t {
+
+ /**
+ * Implements the task_t interface
+ */
+ task_t task;
+};
+
+/**
+ * @brief Create a new IKE_AUTH_LIFETIME task.
+ *
+ * @param ike_sa IKE_SA this task works for
+ * @param initiator TRUE if taks is initiated by us
+ * @return ike_auth_lifetime task to handle by the task_manager
+ */
+ike_auth_lifetime_t *ike_auth_lifetime_create(ike_sa_t *ike_sa, bool initiator);
+
+#endif /* IKE_MOBIKE_H_ */
+
diff --git a/src/charon/sa/tasks/ike_mobike.c b/src/charon/sa/tasks/ike_mobike.c
index d1fc8c695..a53c243f0 100644
--- a/src/charon/sa/tasks/ike_mobike.c
+++ b/src/charon/sa/tasks/ike_mobike.c
@@ -287,7 +287,7 @@ static void transmit(private_ike_mobike_t *this, packet_t *packet)
static status_t build_i(private_ike_mobike_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_AUTH &&
- message->get_payload(message, SECURITY_ASSOCIATION))
+ message->get_payload(message, ID_INITIATOR))
{
message->add_notify(message, FALSE, MOBIKE_SUPPORTED, chunk_empty);
build_address_list(this, message);
@@ -317,7 +317,7 @@ static status_t build_i(private_ike_mobike_t *this, message_t *message)
static status_t process_r(private_ike_mobike_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_AUTH &&
- message->get_payload(message, SECURITY_ASSOCIATION))
+ message->get_payload(message, ID_INITIATOR))
{
process_payloads(this, message);
}
@@ -348,7 +348,7 @@ static status_t process_r(private_ike_mobike_t *this, message_t *message)
static status_t build_r(private_ike_mobike_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_AUTH &&
- message->get_payload(message, SECURITY_ASSOCIATION))
+ this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
{
if (this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
{
@@ -378,7 +378,7 @@ static status_t build_r(private_ike_mobike_t *this, message_t *message)
static status_t process_i(private_ike_mobike_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_AUTH &&
- message->get_payload(message, SECURITY_ASSOCIATION))
+ this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
{
process_payloads(this, message);
return SUCCESS;
diff --git a/src/charon/sa/tasks/ike_p2p.c b/src/charon/sa/tasks/ike_p2p.c
index de5a2e30e..84b88e16b 100644
--- a/src/charon/sa/tasks/ike_p2p.c
+++ b/src/charon/sa/tasks/ike_p2p.c
@@ -34,7 +34,7 @@
#define P2P_SESSIONID_LEN 8
#define P2P_SESSIONKEY_LEN 16
-// FIXME: proposed values
+/* FIXME: proposed values */
#define P2P_SESSIONID_MIN_LEN 4
#define P2P_SESSIONID_MAX_LEN 16
#define P2P_SESSIONKEY_MIN_LEN 8
@@ -119,8 +119,6 @@ struct private_ike_p2p_t {
};
-// -----------------------------------------------------------------------------
-
/**
* Adds a list of endpoints as notifies to a given message
*/
@@ -146,7 +144,7 @@ static void gather_and_add_endpoints(private_ike_p2p_t *this, message_t *message
host_t *addr, *host;
u_int16_t port;
- // get the port that is used to communicate with the ms
+ /* get the port that is used to communicate with the ms */
host = this->ike_sa->get_my_host(this->ike_sa);
port = host->get_port(host);
@@ -215,7 +213,8 @@ static void process_payloads(private_ike_p2p_t *this, message_t *message)
DBG1(DBG_IKE, "received invalid P2P_ENDPOINT notify");
break;
}
- DBG2(DBG_IKE, "received P2P_ENDPOINT notify");
+ DBG1(DBG_IKE, "received %N P2P_ENDPOINT %#H", p2p_endpoint_type_names,
+ endpoint->get_type(endpoint), endpoint->get_host(endpoint));
this->remote_endpoints->insert_last(this->remote_endpoints, endpoint);
break;
@@ -253,8 +252,6 @@ static void process_payloads(private_ike_p2p_t *this, message_t *message)
iterator->destroy(iterator);
}
-// -----------------------------------------------------------------------------
-
/**
* Implementation of task_t.process for initiator
*/
@@ -296,8 +293,8 @@ static status_t build_i(private_ike_p2p_t *this, message_t *message)
if (!this->response)
{
- // only the initiator creates a session ID. the responder returns
- // the session ID that it received from the initiator
+ /* only the initiator creates a session ID. the responder returns
+ * the session ID that it received from the initiator */
if (rand->allocate_pseudo_random_bytes(rand,
P2P_SESSIONID_LEN, &this->session_id) != SUCCESS)
{
@@ -326,7 +323,7 @@ static status_t build_i(private_ike_p2p_t *this, message_t *message)
}
else
{
- // FIXME: should we make that configurable
+ /* FIXME: should we make that configurable */
message->add_notify(message, FALSE, P2P_CALLBACK, chunk_empty);
}
@@ -334,8 +331,9 @@ static status_t build_i(private_ike_p2p_t *this, message_t *message)
break;
}
+ default:
+ break;
}
-
return NEED_MORE;
}
@@ -387,11 +385,11 @@ static status_t process_r(private_ike_p2p_t *this, message_t *message)
}
DBG1(DBG_IKE, "received P2P_CONNECT");
-
break;
}
+ default:
+ break;
}
-
return NEED_MORE;
}
@@ -420,16 +418,16 @@ static status_t build_r(private_ike_p2p_t *this, message_t *message)
if (this->response)
{
- // FIXME: handle result of set_responder_data
- // as initiator, upon receiving a response from another peer,
- // update the checklist and start sending checks
+ /* FIXME: handle result of set_responder_data
+ * as initiator, upon receiving a response from another peer,
+ * update the checklist and start sending checks */
charon->connect_manager->set_responder_data(charon->connect_manager,
this->session_id, this->session_key, this->remote_endpoints);
}
else
{
- // FIXME: handle result of set_initiator_data
- // as responder, create a checklist with the initiator's data
+ /* FIXME: handle result of set_initiator_data
+ * as responder, create a checklist with the initiator's data */
charon->connect_manager->set_initiator_data(charon->connect_manager,
this->peer_id, this->ike_sa->get_my_id(this->ike_sa),
this->session_id, this->session_key, this->remote_endpoints,
@@ -440,9 +438,10 @@ static status_t build_r(private_ike_p2p_t *this, message_t *message)
return FAILED;
}
}
-
break;
}
+ default:
+ break;
}
return SUCCESS;
}
@@ -469,20 +468,19 @@ static status_t process_i(private_ike_p2p_t *this, message_t *message)
case IKE_AUTH:
{
process_payloads(this, message);
-
- //FIXME: we should update the server reflexive endpoint somehow, if mobike notices a change
-
+ /* FIXME: we should update the server reflexive endpoint somehow,
+ * if mobike notices a change */
endpoint_notify_t *reflexive;
- if (this->remote_endpoints->get_first(this->remote_endpoints, (void**)&reflexive) == SUCCESS &&
- reflexive->get_type(reflexive) == SERVER_REFLEXIVE)
- {//FIXME: should we accept this endpoint even if we did not send a request?
+ if (this->remote_endpoints->get_first(this->remote_endpoints,
+ (void**)&reflexive) == SUCCESS &&
+ reflexive->get_type(reflexive) == SERVER_REFLEXIVE)
+ { /* FIXME: should we accept this endpoint even if we did not send
+ * a request? */
host_t *endpoint = reflexive->get_host(reflexive);
- DBG2(DBG_IKE, "received server reflexive endpoint %#H", endpoint);
this->ike_sa->set_server_reflexive_host(this->ike_sa, endpoint->clone(endpoint));
}
-
- // FIXME: what if it failed? e.g. AUTH failure
+ /* FIXME: what if it failed? e.g. AUTH failure */
SIG(CHILD_UP_SUCCESS, "established mediation connection without CHILD_SA successfully");
break;
@@ -494,22 +492,23 @@ static status_t process_i(private_ike_p2p_t *this, message_t *message)
if (this->failed)
{
DBG1(DBG_IKE, "peer '%D' is not online", this->peer_id);
- // FIXME: notify the mediated connection (job?)
- // FIXME: probably delete the created checklist, at least as responder
+ /* FIXME: notify the mediated connection (job?)
+ * FIXME: probably delete the created checklist, at least as
+ * responder */
}
else
{
if (this->response)
{
- // FIXME: handle result of set_responder_data
- // as responder, we update the checklist and start sending checks
+ /* FIXME: handle result of set_responder_data.
+ * as responder, we update the checklist and start sending checks */
charon->connect_manager->set_responder_data(charon->connect_manager,
this->session_id, this->session_key, this->local_endpoints);
}
else
{
- // FIXME: handle result of set_initiator_data
- // as initiator, we create a checklist and set the initiator's data
+ /* FIXME: handle result of set_initiator_data
+ * as initiator, we create a checklist and set the initiator's data */
charon->connect_manager->set_initiator_data(charon->connect_manager,
this->ike_sa->get_my_id(this->ike_sa), this->peer_id,
this->session_id, this->session_key, this->local_endpoints,
@@ -518,12 +517,12 @@ static status_t process_i(private_ike_p2p_t *this, message_t *message)
}
break;
}
+ default:
+ break;
}
return SUCCESS;
}
-// -----------------------------------------------------------------------------
-
/**
* Implementation of task_t.process for initiator (mediation server)
*/
@@ -542,21 +541,19 @@ static status_t build_i_ms(private_ike_p2p_t *this, message_t *message)
}
else
{
- notify_payload_t *notify;
-
if (this->response)
{
message->add_notify(message, FALSE, P2P_RESPONSE, chunk_empty);
- }
-
+ }
message->add_notify(message, FALSE, P2P_SESSIONID, this->session_id);
message->add_notify(message, FALSE, P2P_SESSIONKEY, this->session_key);
add_endpoints_to_message(message, this->remote_endpoints);
}
-
break;
}
+ default:
+ break;
}
return NEED_MORE;
@@ -614,9 +611,10 @@ static status_t process_r_ms(private_ike_p2p_t *this, message_t *message)
this->invalid_syntax = TRUE;
break;
}
-
break;
}
+ default:
+ break;
}
return NEED_MORE;
@@ -679,7 +677,7 @@ static status_t build_r_ms(private_ike_p2p_t *this, message_t *message)
if (!peer_sa)
{
- // the peer is not online
+ /* the peer is not online */
message->add_notify(message, TRUE, P2P_CONNECT_FAILED, chunk_empty);
break;
}
@@ -691,6 +689,8 @@ static status_t build_r_ms(private_ike_p2p_t *this, message_t *message)
break;
}
+ default:
+ break;
}
return SUCCESS;
}
@@ -700,18 +700,9 @@ static status_t build_r_ms(private_ike_p2p_t *this, message_t *message)
*/
static status_t process_i_ms(private_ike_p2p_t *this, message_t *message)
{
- switch(message->get_exchange_type(message))
- {
- case P2P_CONNECT:
- {
- break;
- }
- }
return SUCCESS;
}
-// -----------------------------------------------------------------------------
-
/**
* Implementation of ike_p2p.connect
*/
@@ -813,7 +804,7 @@ ike_p2p_t *ike_p2p_create(ike_sa_t *ike_sa, bool initiator)
}
else
{
- // mediation server
+ /* mediation server */
if (initiator)
{
this->public.task.build = (status_t(*)(task_t*,message_t*))build_i_ms;
diff --git a/src/charon/sa/tasks/task.c b/src/charon/sa/tasks/task.c
index e9d0c4da1..cc20a8861 100644
--- a/src/charon/sa/tasks/task.c
+++ b/src/charon/sa/tasks/task.c
@@ -28,6 +28,7 @@ ENUM(task_type_names, IKE_INIT, CHILD_REKEY,
"IKE_NATD",
"IKE_MOBIKE",
"IKE_AUTHENTICATE",
+ "IKE_AUTH_LIFETIME",
"IKE_CERT",
"IKE_CONFIG",
"IKE_REKEY",
diff --git a/src/charon/sa/tasks/task.h b/src/charon/sa/tasks/task.h
index dd2bb8a83..a59207711 100644
--- a/src/charon/sa/tasks/task.h
+++ b/src/charon/sa/tasks/task.h
@@ -45,6 +45,8 @@ enum task_type_t {
IKE_MOBIKE,
/** authenticate the initiated IKE_SA */
IKE_AUTHENTICATE,
+ /** AUTH_LIFETIME negotiation, RFC4478 */
+ IKE_AUTH_LIFETIME,
/** exchange certificates and requests */
IKE_CERT,
/** Configuration payloads, virtual IP and such */
diff --git a/src/ipsec/ipsec.in b/src/ipsec/ipsec.in
index 5b35c87a5..707612e92 100755
--- a/src/ipsec/ipsec.in
+++ b/src/ipsec/ipsec.in
@@ -14,7 +14,11 @@
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
-# RCSID $Id: ipsec.in 3268 2007-10-08 19:59:18Z andreas $
+# RCSID $Id: ipsec.in 3390 2007-12-12 22:27:40Z andreas $
+
+# define a minimum PATH environment in case it is not set
+PATH="/sbin:/bin:/usr/sbin:/usr/bin:@IPSEC_SBINDIR@"
+export PATH
# name and version of the ipsec implementation
IPSEC_NAME="@IPSEC_NAME@"
@@ -97,26 +101,36 @@ down)
if [ "$#" -ne 1 ]
then
echo "Usage: ipsec down <connection name>"
- exit 1
+ exit 2
fi
- if test -e $IPSEC_PLUTO_PID
+ rc=7
+ if [ -e $IPSEC_PLUTO_PID ]
then
$IPSEC_WHACK --name "$1" --terminate
+ rc="$?"
fi
- if test -e $IPSEC_CHARON_PID
+ if [ -e $IPSEC_CHARON_PID ]
then
$IPSEC_STROKE down "$1"
+ rc="$?"
fi
- exit 0
+ exit "$rc"
;;
listalgs|listpubkeys|\listcards|\rereadgroups)
op="$1"
shift
- if test -e $IPSEC_PLUTO_PID
+ if [ -e $IPSEC_PLUTO_PID ]
then
$IPSEC_WHACK "$@" "--$op"
+ exit "$?"
+ else
+ if [ -e $IPSEC_CHARON_PID ]
+ then
+ exit 3
+ else
+ exit 7
+ fi
fi
- exit 0
;;
listcerts|listcacerts|listaacerts|\
listacerts|listgroups|listocspcerts|\
@@ -125,75 +139,92 @@ rereadsecrets|rereadcacerts|rereadaacerts|\
rereadacerts|rereadocspcerts|rereadcrls|\
rereadall|purgeocsp)
op="$1"
+ rc=7
shift
- if test -e $IPSEC_PLUTO_PID
+ if [ -e $IPSEC_PLUTO_PID ]
then
$IPSEC_WHACK "$@" "--$op"
+ rc="$?"
fi
- if test -e $IPSEC_CHARON_PID
+ if [ -e $IPSEC_CHARON_PID ]
then
$IPSEC_STROKE "$op" "$@"
+ rc="$?"
fi
- exit 0
+ exit "$rc"
;;
ready)
shift
- if test -e $IPSEC_PLUTO_PID
+ if [ -e $IPSEC_PLUTO_PID ]
then
$IPSEC_WHACK --listen
+ exit 0
+ else
+ exit 7
fi
- exit 0
;;
reload)
- if test -e $IPSEC_STARTER_PID
+ rc=7
+ if [ -e $IPSEC_STARTER_PID ]
then
- echo "Reloading strongSwan IPsec configuration..." >&2
- kill -s USR1 `cat $IPSEC_STARTER_PID`
+ echo "Reloading strongSwan IPsec configuration..." >&2
+ kill -s USR1 `cat $IPSEC_STARTER_PID` 2>/dev/null && rc=0
else
- echo "ipsec starter is not running" >&2
+ echo "Reloading strongSwan IPsec failed: starter is not running" >&2
fi
- exit 0
+ exit "$rc"
;;
restart)
$IPSEC_SBINDIR/ipsec stop
sleep 2
shift
- $IPSEC_SBINDIR/ipsec start "$@"
- exit 0
+ exec $IPSEC_SBINDIR/ipsec start "$@"
;;
route|unroute)
op="$1"
+ rc=7
shift
if [ "$#" -ne 1 ]
then
- echo "Usage: ipsec $op <connection name>"
- exit 1
+ echo "Usage: ipsec $op <connection name>"
+ exit 2
fi
- if test -e $IPSEC_PLUTO_PID
+ if [ -e $IPSEC_PLUTO_PID ]
then
$IPSEC_WHACK --name "$1" "--$op"
+ rc="$?"
fi
- if test -e $IPSEC_CHARON_PID
+ if [ -e $IPSEC_CHARON_PID ]
then
$IPSEC_STROKE "$op" "$1"
+ rc="$?"
fi
- exit 0
+ exit "$rc"
;;
scencrypt|scdecrypt)
op="$1"
shift
- if test -e $IPSEC_PLUTO_PID
+ if [ -e $IPSEC_PLUTO_PID ]
then
$IPSEC_WHACK "--$op" "$@"
+ exit "$?"
+ else
+ exit 7
fi
- exit 0
;;
secrets)
- if test -e $IPSEC_PLUTO_PID
+ rc=7
+ if [ -e $IPSEC_PLUTO_PID ]
then
$IPSEC_WHACK --rereadsecrets
+ rc="$?"
fi
- exit 0
+ if [ -e $IPSEC_CHARON_PID ]
+ then
+ $IPSEC_STROKE rereadsecrets
+ rc="$?"
+ fi
+ exit "$rc"
;;
start)
shift
@@ -201,36 +232,64 @@ start)
;;
status|statusall)
op="$1"
+ # Return value is slightly different for the status command:
+ # 0 - service up and running
+ # 1 - service dead, but /var/run/ pid file exists
+ # 2 - service dead, but /var/lock/ lock file exists
+ # 3 - service not running (unused)
+ # 4 - service status unknown :-(
+ # 5--199 reserved (5--99 LSB, 100--149 distro, 150--199 appl.)
shift
- if test $# -eq 0
+ if [ $# -eq 0 ]
then
- if test -e $IPSEC_PLUTO_PID
+ if [ -e $IPSEC_PLUTO_PID ]
then
$IPSEC_WHACK "--$op"
fi
- if test -e $IPSEC_CHARON_PID
+ if [ -e $IPSEC_CHARON_PID ]
then
$IPSEC_STROKE "$op"
fi
else
- if test -e $IPSEC_PLUTO_PID
+ if [ -e $IPSEC_PLUTO_PID ]
then
$IPSEC_WHACK --name "$1" "--$op"
fi
- if test -e $IPSEC_CHARON_PID
+ if [ -e $IPSEC_CHARON_PID ]
then
$IPSEC_STROKE "$op" "$1"
fi
fi
- exit 0
+ if [ -e $IPSEC_STARTER_PID ]
+ then
+ kill -0 `cat $IPSEC_STARTER_PID` 2>/dev/null
+ exit $?
+ fi
+ exit 3
;;
stop)
- if test -e $IPSEC_STARTER_PID
+ # stopping a not-running service is considered as success
+ if [ -e $IPSEC_STARTER_PID ]
then
- echo "Stopping strongSwan IPsec..." >&2
- kill `cat $IPSEC_STARTER_PID`
+ echo "Stopping strongSwan IPsec..." >&2
+ spid=`cat $IPSEC_STARTER_PID`
+ if [ -n "$spid" ]
+ then
+ kill $spid 2>/dev/null
+ loop=5
+ while [ $loop -gt 0 ] ; do
+ kill -s 0 $spid 2>/dev/null || break
+ sleep 1
+ loop=$(($loop - 1))
+ done
+ if [ $loop -eq 0 ]
+ then
+ kill -s KILL $spid 2>/dev/null
+ rm -f $IPSEC_STARTER_PID
+ fi
+ fi
else
- echo "ipsec starter is not running" >&2
+ echo "Stopping strongSwan IPsec failed: starter is not running" >&2
fi
exit 0
;;
@@ -239,27 +298,31 @@ up)
if [ "$#" -ne 1 ]
then
echo "Usage: ipsec up <connection name>"
- exit 1
+ exit 2
fi
- if test -e $IPSEC_PLUTO_PID
+ rc=7
+ if [ -e $IPSEC_PLUTO_PID ]
then
$IPSEC_WHACK --name "$1" --initiate
+ rc="$?"
fi
- if test -e $IPSEC_CHARON_PID
+ if [ -e $IPSEC_CHARON_PID ]
then
- $IPSEC_STROKE up "$1"
+ $IPSEC_STROKE up "$1"
+ rc="$?"
fi
- exit 0
+ exit "$rc"
;;
update)
- if test -e $IPSEC_STARTER_PID
+ if [ -e $IPSEC_STARTER_PID ]
then
echo "Updating strongSwan IPsec configuration..." >&2
kill -s HUP `cat $IPSEC_STARTER_PID`
+ exit 0
else
- echo "ipsec starter is not running" >&2
+ echo "Updating strongSwan IPsec failed: starter is not running" >&2
+ exit 7
fi
- exit 0
;;
version|--version)
echo "Linux $IPSEC_NAME $IPSEC_VERSION"
@@ -269,7 +332,7 @@ version|--version)
;;
--*)
echo "$0: unknown option \`$1' (perhaps command name was omitted?)" >&2
- exit 1
+ exit 2
;;
esac
@@ -278,13 +341,13 @@ shift
path="$IPSEC_DIR/$cmd"
-if test ! -x "$path"
+if [ ! -x "$path" ]
then
path="$IPSEC_DIR/$cmd"
- if test ! -x "$path"
+ if [ ! -x "$path" ]
then
echo "$0: unknown IPsec command \`$cmd' (\`ipsec --help' for list)" >&2
- exit 1
+ exit 2
fi
fi
diff --git a/src/libstrongswan/crypto/ac.c b/src/libstrongswan/crypto/ac.c
index 1367494f8..641ce5d64 100644
--- a/src/libstrongswan/crypto/ac.c
+++ b/src/libstrongswan/crypto/ac.c
@@ -20,7 +20,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: ac.c 3300 2007-10-12 21:53:18Z andreas $
+ * RCSID $Id: ac.c 3355 2007-11-20 12:06:40Z martin $
*/
#include <string.h>
@@ -544,7 +544,7 @@ static void list(const private_x509ac_t *this, FILE *out, bool utc)
fprintf(out, " validity: not before %#T, ", &this->notBefore, utc);
if (now < this->notBefore)
{
- fprintf(out, "not valid yet (valid in %V)\n", &now, &this->notBefore);
+ fprintf(out, "not valid yet (valid in %#V)\n", &now, &this->notBefore);
}
else
{
@@ -554,14 +554,14 @@ static void list(const private_x509ac_t *this, FILE *out, bool utc)
fprintf(out, " not after %#T, ", &this->notAfter, utc);
if (now > this->notAfter)
{
- fprintf(out, "expired (%V ago)\n", &now, &this->notAfter);
+ fprintf(out, "expired (%#V ago)\n", &now, &this->notAfter);
}
else
{
fprintf(out, "ok");
if (now > this->notAfter - ACERT_WARNING_INTERVAL * 60 * 60 * 24)
{
- fprintf(out, " (expires in %V)", &now, &this->notAfter);
+ fprintf(out, " (expires in %#V)", &now, &this->notAfter);
}
fprintf(out, " \n");
}
diff --git a/src/libstrongswan/crypto/ca.c b/src/libstrongswan/crypto/ca.c
index a78590954..510e3528e 100644
--- a/src/libstrongswan/crypto/ca.c
+++ b/src/libstrongswan/crypto/ca.c
@@ -279,11 +279,11 @@ static void list_certinfos(private_ca_info_t *this, FILE *out, bool utc)
fprintf(out, "%#T, until %#T, ", &thisUpdate, utc, &nextUpdate, utc);
if (now > nextUpdate)
{
- fprintf(out, "expired (%V ago)\n", &now, &nextUpdate);
+ fprintf(out, "expired (%#V ago)\n", &now, &nextUpdate);
}
else
{
- fprintf(out, "ok (expires in %V)\n", &now, &nextUpdate);
+ fprintf(out, "ok (expires in %#V)\n", &now, &nextUpdate);
}
fprintf(out, " serial: %#B, %N\n", &serial,
cert_status_names, certinfo->get_status(certinfo));
@@ -654,7 +654,7 @@ static cert_status_t verify_by_ocsp(private_ca_info_t* this,
if (comparison > 0)
{
- iterator->insert_after(iterator, (void *)cached_certinfo);
+ this->certinfos->insert_last(this->certinfos, (void *)cached_certinfo);
}
else
{
diff --git a/src/libstrongswan/crypto/crl.c b/src/libstrongswan/crypto/crl.c
index d52078ea9..ab23bb9ec 100755
--- a/src/libstrongswan/crypto/crl.c
+++ b/src/libstrongswan/crypto/crl.c
@@ -19,7 +19,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: crl.c 3300 2007-10-12 21:53:18Z andreas $
+ * RCSID $Id: crl.c 3355 2007-11-20 12:06:40Z martin $
*/
#include <sys/stat.h>
@@ -463,11 +463,11 @@ static void list(private_crl_t *this, FILE* out, bool utc)
}
else if (now > this->nextUpdate)
{
- fprintf(out, "expired (%V ago)\n", &now, &this->nextUpdate);
+ fprintf(out, "expired (%#V ago)\n", &now, &this->nextUpdate);
}
else if (now > this->nextUpdate - CRL_WARNING_INTERVAL * 60 * 60 * 24)
{
- fprintf(out, "ok (expires in %V)\n", &now, &this->nextUpdate);
+ fprintf(out, "ok (expires in %#V)\n", &now, &this->nextUpdate);
}
else
{
diff --git a/src/libstrongswan/crypto/x509.c b/src/libstrongswan/crypto/x509.c
index d9093fc62..6f154b36f 100755
--- a/src/libstrongswan/crypto/x509.c
+++ b/src/libstrongswan/crypto/x509.c
@@ -24,7 +24,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: x509.c 3301 2007-10-12 21:56:30Z andreas $
+ * RCSID $Id: x509.c 3355 2007-11-20 12:06:40Z martin $
*/
#include <gmp.h>
@@ -1182,7 +1182,7 @@ static void list(private_x509_t *this, FILE *out, bool utc)
fprintf(out, " validity: not before %#T, ", &this->notBefore, utc);
if (now < this->notBefore)
{
- fprintf(out, "not valid yet (valid in %V)\n", &now, &this->notBefore);
+ fprintf(out, "not valid yet (valid in %#V)\n", &now, &this->notBefore);
}
else
{
@@ -1192,14 +1192,14 @@ static void list(private_x509_t *this, FILE *out, bool utc)
fprintf(out, " not after %#T, ", &this->notAfter, utc);
if (now > this->notAfter)
{
- fprintf(out, "expired (%V ago)\n", &now, &this->notAfter);
+ fprintf(out, "expired (%#V ago)\n", &now, &this->notAfter);
}
else
{
fprintf(out, "ok");
if (now > this->notAfter - CERT_WARNING_INTERVAL * 60 * 60 * 24)
{
- fprintf(out, " (expires in %V)", &now, &this->notAfter);
+ fprintf(out, " (expires in %#V)", &now, &this->notAfter);
}
fprintf(out, " \n");
}
diff --git a/src/libstrongswan/library.c b/src/libstrongswan/library.c
index 9f96d119c..f66818bc2 100644
--- a/src/libstrongswan/library.c
+++ b/src/libstrongswan/library.c
@@ -150,11 +150,20 @@ static int print_time(FILE *stream, const struct printf_info *info,
static int print_time_delta(FILE *stream, const struct printf_info *info,
const void *const *args)
{
- time_t *start = *((time_t**)(args[0]));
- time_t *end = *((time_t**)(args[1]));
- u_int delta = abs(*end - *start);
-
char* unit = "second";
+ time_t *arg1, *arg2;
+ time_t delta;
+
+ arg1 = *((time_t**)(args[0]));
+ if (info->alt)
+ {
+ arg2 = *((time_t**)(args[1]));
+ delta = abs(*arg1 - *arg2);
+ }
+ else
+ {
+ delta = *arg1;
+ }
if (delta > 2 * 60 * 60 * 24)
{
@@ -180,5 +189,5 @@ static int print_time_delta(FILE *stream, const struct printf_info *info,
static void __attribute__ ((constructor))print_register()
{
register_printf_function(PRINTF_TIME, print_time, arginfo_ptr_alt_ptr_int);
- register_printf_function(PRINTF_TIME_DELTA, print_time_delta, arginfo_ptr_ptr);
+ register_printf_function(PRINTF_TIME_DELTA, print_time_delta, arginfo_ptr_alt_ptr_ptr);
}
diff --git a/src/libstrongswan/printf_hook.c b/src/libstrongswan/printf_hook.c
index 0407e8c82..baf339640 100644
--- a/src/libstrongswan/printf_hook.c
+++ b/src/libstrongswan/printf_hook.c
@@ -116,3 +116,26 @@ int arginfo_ptr_alt_ptr_int(const struct printf_info *info, size_t n, int *argty
}
return 1;
}
+
+/**
+ * special arginfo handler respecting alt flag
+ */
+int arginfo_ptr_alt_ptr_ptr(const struct printf_info *info, size_t n, int *argtypes)
+{
+ if (info->alt)
+ {
+ if (n > 1)
+ {
+ argtypes[0] = PA_POINTER;
+ argtypes[1] = PA_POINTER;
+ }
+ return 2;
+ }
+
+ if (n > 0)
+ {
+ argtypes[0] = PA_POINTER;
+ }
+ return 1;
+}
+
diff --git a/src/libstrongswan/printf_hook.h b/src/libstrongswan/printf_hook.h
index 03bcf447d..77b228da0 100644
--- a/src/libstrongswan/printf_hook.h
+++ b/src/libstrongswan/printf_hook.h
@@ -44,7 +44,7 @@
#define PRINTF_TRAFFIC_SELECTOR 'R'
/** 1 argument: time_t *time; with #-modifier 2 arguments: time_t *time, bool utc */
#define PRINTF_TIME 'T'
-/** 2 arguments: time_t *begin, time_t *end */
+/** 1 argument: time_t *delta; with #-modifier 2 arguments: time_t *begin, time_t *end */
#define PRINTF_TIME_DELTA 'V'
/**
@@ -55,6 +55,7 @@ int arginfo_ptr_ptr(const struct printf_info *info, size_t n, int *argtypes);
int arginfo_ptr_int(const struct printf_info *info, size_t n, int *argtypes);
int arginfo_int_int(const struct printf_info *info, size_t n, int *argtypes);
int arginfo_ptr_alt_ptr_int(const struct printf_info *info, size_t n, int *argtypes);
+int arginfo_ptr_alt_ptr_ptr(const struct printf_info *info, size_t n, int *argtypes);
int arginfo_int_alt_int_int(const struct printf_info *info, size_t n, int *argtypes);
#endif /* PRINTF_HOOK_H_ */
diff --git a/src/libstrongswan/utils/lexparser.c b/src/libstrongswan/utils/lexparser.c
index 9d3f06593..7cc89fc90 100644
--- a/src/libstrongswan/utils/lexparser.c
+++ b/src/libstrongswan/utils/lexparser.c
@@ -17,8 +17,12 @@
* 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.
+ *
+ * RCSID $Id: lexparser.c 3353 2007-11-19 12:27:08Z martin $
*/
+/* memrchr is a GNU extension */
+#define _GNU_SOURCE
#include <string.h>
#include "lexparser.h"
@@ -45,7 +49,7 @@ bool match(const char *pattern, const chunk_t *ch)
}
/**
- * extracts a token ending with a given termination symbol
+ * extracts a token ending with the first occurrence of a given termination symbol
*/
bool extract_token(chunk_t *token, const char termination, chunk_t *src)
{
@@ -71,6 +75,32 @@ bool extract_token(chunk_t *token, const char termination, chunk_t *src)
}
/**
+ * extracts a token ending with the last occurrence of a given termination symbol
+ */
+bool extract_last_token(chunk_t *token, const char termination, chunk_t *src)
+{
+ u_char *eot = memrchr(src->ptr, termination, src->len);
+
+ /* initialize empty token */
+ *token = chunk_empty;
+
+ if (eot == NULL) /* termination symbol not found */
+ {
+ return FALSE;
+ }
+
+ /* extract token */
+ token->ptr = src->ptr;
+ token->len = (u_int)(eot - src->ptr);
+
+ /* advance src pointer after termination symbol */
+ src->ptr = eot + 1;
+ src->len -= (token->len + 1);
+
+ return TRUE;
+}
+
+/**
* fetches a new line terminated by \n or \r\n
*/
bool fetchline(chunk_t *src, chunk_t *line)
diff --git a/src/libstrongswan/utils/lexparser.h b/src/libstrongswan/utils/lexparser.h
index e3c2c4c70..775898139 100644
--- a/src/libstrongswan/utils/lexparser.h
+++ b/src/libstrongswan/utils/lexparser.h
@@ -17,6 +17,8 @@
* 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.
+ *
+ * RCSID $Id: lexparser.h 3346 2007-11-16 20:23:29Z andreas $
*/
#include <library.h>
@@ -32,11 +34,16 @@ bool eat_whitespace(chunk_t *src);
bool match(const char *pattern, const chunk_t *ch);
/**
- * @brief Extracts a token ending with a given termination symbol
+ * @brief Extracts a token ending with the first occurence a given termination symbol
*/
bool extract_token(chunk_t *token, const char termination, chunk_t *src);
/**
+ * @brief Extracts a token ending with the last occurence a given termination symbol
+ */
+bool extract_last_token(chunk_t *token, const char termination, chunk_t *src);
+
+/**
* @brief Fetches a new text line terminated by \n or \r\n
*/
bool fetchline(chunk_t *src, chunk_t *line);
diff --git a/src/manager/Makefile.am b/src/manager/Makefile.am
index 17eecdbab..7f77d1dba 100644
--- a/src/manager/Makefile.am
+++ b/src/manager/Makefile.am
@@ -3,7 +3,9 @@ ipsec_PROGRAMS = manager.fcgi
manager_fcgi_SOURCES = \
main.c manager.c manager.h gateway.h gateway.c database.h database.c \
controller/auth_controller.c controller/auth_controller.h \
-controller/status_controller.c controller/status_controller.h \
+controller/ikesa_controller.c controller/ikesa_controller.h \
+controller/control_controller.c controller/control_controller.h \
+controller/config_controller.c controller/config_controller.h \
controller/gateway_controller.c controller/gateway_controller.h
manager_fcgi_LDADD = $(top_builddir)/src/manager/libappserv.la -lsqlite3
@@ -34,20 +36,31 @@ ipsec_templates_auth_DATA = templates/auth/login.cs
ipsec_templates_gatewaydir = ${ipsec_templatesdir}/gateway
ipsec_templates_gateway_DATA = templates/gateway/list.cs
-ipsec_templates_statusdir = ${ipsec_templatesdir}/status
-ipsec_templates_status_DATA = templates/status/ikesalist.cs
+ipsec_templates_ikesadir = ${ipsec_templatesdir}/ikesa
+ipsec_templates_ikesa_DATA = templates/ikesa/list.cs
+
+ipsec_templates_controldir = ${ipsec_templatesdir}/control
+ipsec_templates_control_DATA = templates/control/result.cs
+
+ipsec_templates_configdir = ${ipsec_templatesdir}/config
+ipsec_templates_config_DATA = templates/config/list.cs
ipsec_templates_staticdir = ${ipsec_templatesdir}/static
ipsec_templates_static_DATA = templates/static/style.css templates/static/script.js templates/static/jquery.js \
templates/static/pipe.png templates/static/pipe-good.png templates/static/pipe-bad.png \
templates/static/pipe-thin.png templates/static/pipe-thin-left.png templates/static/pipe-thin-right.png \
+templates/static/pipe-thin-green.png templates/static/pipe-thin-left-green.png templates/static/pipe-thin-right-green.png \
templates/static/gateway-left.png templates/static/client-left.png templates/static/strongswan.png \
-templates/static/router.png templates/static/gateway-right.png templates/static/client-right.png
+templates/static/router.png templates/static/gateway-right.png templates/static/client-right.png \
+templates/static/close.png templates/static/initiate.png
EXTRA_DIST = manager.db templates/header.cs templates/footer.cs templates/error.cs \
-templates/auth/login.cs templates/gateway/list.cs templates/status/ikesalist.cs \
+templates/auth/login.cs templates/gateway/list.cs templates/ikesa/list.cs \
+templates/config/list.cs templates/control/result.cs \
templates/static/style.css templates/static/script.js templates/static/jquery.js \
templates/static/pipe.png templates/static/pipe-good.png templates/static/pipe-bad.png \
templates/static/pipe-thin.png templates/static/pipe-thin-left.png templates/static/pipe-thin-right.png \
+templates/static/pipe-thin-green.png templates/static/pipe-thin-left-green.png templates/static/pipe-thin-right-green.png \
templates/static/gateway-left.png templates/static/client-left.png templates/static/strongswan.png \
-templates/static/router.png templates/static/gateway-right.png templates/static/client-right.png
+templates/static/router.png templates/static/gateway-right.png templates/static/client-right.png \
+templates/static/close.png templates/static/initiate.png
diff --git a/src/manager/Makefile.in b/src/manager/Makefile.in
index 5c09c22d4..3830d37fc 100644
--- a/src/manager/Makefile.in
+++ b/src/manager/Makefile.in
@@ -52,9 +52,11 @@ am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(ipsecdir)" \
"$(DESTDIR)$(ipsecdir)" "$(DESTDIR)$(ipsec_templatesdir)" \
"$(DESTDIR)$(ipsec_templates_authdir)" \
+ "$(DESTDIR)$(ipsec_templates_configdir)" \
+ "$(DESTDIR)$(ipsec_templates_controldir)" \
"$(DESTDIR)$(ipsec_templates_gatewaydir)" \
- "$(DESTDIR)$(ipsec_templates_staticdir)" \
- "$(DESTDIR)$(ipsec_templates_statusdir)"
+ "$(DESTDIR)$(ipsec_templates_ikesadir)" \
+ "$(DESTDIR)$(ipsec_templates_staticdir)"
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
am__DEPENDENCIES_1 =
@@ -67,7 +69,8 @@ ipsecPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(ipsec_PROGRAMS)
am_manager_fcgi_OBJECTS = main.$(OBJEXT) manager.$(OBJEXT) \
gateway.$(OBJEXT) database.$(OBJEXT) auth_controller.$(OBJEXT) \
- status_controller.$(OBJEXT) gateway_controller.$(OBJEXT)
+ ikesa_controller.$(OBJEXT) control_controller.$(OBJEXT) \
+ config_controller.$(OBJEXT) gateway_controller.$(OBJEXT)
manager_fcgi_OBJECTS = $(am_manager_fcgi_OBJECTS)
manager_fcgi_DEPENDENCIES = $(top_builddir)/src/manager/libappserv.la
DEFAULT_INCLUDES = -I.@am__isrc@
@@ -87,12 +90,16 @@ DIST_SOURCES = $(libappserv_la_SOURCES) $(manager_fcgi_SOURCES)
ipsecDATA_INSTALL = $(INSTALL_DATA)
ipsec_templatesDATA_INSTALL = $(INSTALL_DATA)
ipsec_templates_authDATA_INSTALL = $(INSTALL_DATA)
+ipsec_templates_configDATA_INSTALL = $(INSTALL_DATA)
+ipsec_templates_controlDATA_INSTALL = $(INSTALL_DATA)
ipsec_templates_gatewayDATA_INSTALL = $(INSTALL_DATA)
+ipsec_templates_ikesaDATA_INSTALL = $(INSTALL_DATA)
ipsec_templates_staticDATA_INSTALL = $(INSTALL_DATA)
-ipsec_templates_statusDATA_INSTALL = $(INSTALL_DATA)
DATA = $(ipsec_DATA) $(ipsec_templates_DATA) \
- $(ipsec_templates_auth_DATA) $(ipsec_templates_gateway_DATA) \
- $(ipsec_templates_static_DATA) $(ipsec_templates_status_DATA)
+ $(ipsec_templates_auth_DATA) $(ipsec_templates_config_DATA) \
+ $(ipsec_templates_control_DATA) \
+ $(ipsec_templates_gateway_DATA) $(ipsec_templates_ikesa_DATA) \
+ $(ipsec_templates_static_DATA)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -229,7 +236,9 @@ xml_LIBS = @xml_LIBS@
manager_fcgi_SOURCES = \
main.c manager.c manager.h gateway.h gateway.c database.h database.c \
controller/auth_controller.c controller/auth_controller.h \
-controller/status_controller.c controller/status_controller.h \
+controller/ikesa_controller.c controller/ikesa_controller.h \
+controller/control_controller.c controller/control_controller.h \
+controller/config_controller.c controller/config_controller.h \
controller/gateway_controller.c controller/gateway_controller.h
manager_fcgi_LDADD = $(top_builddir)/src/manager/libappserv.la -lsqlite3
@@ -251,22 +260,31 @@ ipsec_templates_authdir = ${ipsec_templatesdir}/auth
ipsec_templates_auth_DATA = templates/auth/login.cs
ipsec_templates_gatewaydir = ${ipsec_templatesdir}/gateway
ipsec_templates_gateway_DATA = templates/gateway/list.cs
-ipsec_templates_statusdir = ${ipsec_templatesdir}/status
-ipsec_templates_status_DATA = templates/status/ikesalist.cs
+ipsec_templates_ikesadir = ${ipsec_templatesdir}/ikesa
+ipsec_templates_ikesa_DATA = templates/ikesa/list.cs
+ipsec_templates_controldir = ${ipsec_templatesdir}/control
+ipsec_templates_control_DATA = templates/control/result.cs
+ipsec_templates_configdir = ${ipsec_templatesdir}/config
+ipsec_templates_config_DATA = templates/config/list.cs
ipsec_templates_staticdir = ${ipsec_templatesdir}/static
ipsec_templates_static_DATA = templates/static/style.css templates/static/script.js templates/static/jquery.js \
templates/static/pipe.png templates/static/pipe-good.png templates/static/pipe-bad.png \
templates/static/pipe-thin.png templates/static/pipe-thin-left.png templates/static/pipe-thin-right.png \
+templates/static/pipe-thin-green.png templates/static/pipe-thin-left-green.png templates/static/pipe-thin-right-green.png \
templates/static/gateway-left.png templates/static/client-left.png templates/static/strongswan.png \
-templates/static/router.png templates/static/gateway-right.png templates/static/client-right.png
+templates/static/router.png templates/static/gateway-right.png templates/static/client-right.png \
+templates/static/close.png templates/static/initiate.png
EXTRA_DIST = manager.db templates/header.cs templates/footer.cs templates/error.cs \
-templates/auth/login.cs templates/gateway/list.cs templates/status/ikesalist.cs \
+templates/auth/login.cs templates/gateway/list.cs templates/ikesa/list.cs \
+templates/config/list.cs templates/control/result.cs \
templates/static/style.css templates/static/script.js templates/static/jquery.js \
templates/static/pipe.png templates/static/pipe-good.png templates/static/pipe-bad.png \
templates/static/pipe-thin.png templates/static/pipe-thin-left.png templates/static/pipe-thin-right.png \
+templates/static/pipe-thin-green.png templates/static/pipe-thin-left-green.png templates/static/pipe-thin-right-green.png \
templates/static/gateway-left.png templates/static/client-left.png templates/static/strongswan.png \
-templates/static/router.png templates/static/gateway-right.png templates/static/client-right.png
+templates/static/router.png templates/static/gateway-right.png templates/static/client-right.png \
+templates/static/close.png templates/static/initiate.png
all: all-am
@@ -369,15 +387,17 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_controller.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/config_controller.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/control_controller.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/database.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dispatcher.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gateway.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gateway_controller.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ikesa_controller.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/manager.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/request.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/session.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/status_controller.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml.Plo@am__quote@
.c.o:
@@ -443,19 +463,47 @@ auth_controller.obj: controller/auth_controller.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o auth_controller.obj `if test -f 'controller/auth_controller.c'; then $(CYGPATH_W) 'controller/auth_controller.c'; else $(CYGPATH_W) '$(srcdir)/controller/auth_controller.c'; fi`
-status_controller.o: controller/status_controller.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT status_controller.o -MD -MP -MF $(DEPDIR)/status_controller.Tpo -c -o status_controller.o `test -f 'controller/status_controller.c' || echo '$(srcdir)/'`controller/status_controller.c
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/status_controller.Tpo $(DEPDIR)/status_controller.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='controller/status_controller.c' object='status_controller.o' libtool=no @AMDEPBACKSLASH@
+ikesa_controller.o: controller/ikesa_controller.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ikesa_controller.o -MD -MP -MF $(DEPDIR)/ikesa_controller.Tpo -c -o ikesa_controller.o `test -f 'controller/ikesa_controller.c' || echo '$(srcdir)/'`controller/ikesa_controller.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ikesa_controller.Tpo $(DEPDIR)/ikesa_controller.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='controller/ikesa_controller.c' object='ikesa_controller.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o status_controller.o `test -f 'controller/status_controller.c' || echo '$(srcdir)/'`controller/status_controller.c
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ikesa_controller.o `test -f 'controller/ikesa_controller.c' || echo '$(srcdir)/'`controller/ikesa_controller.c
-status_controller.obj: controller/status_controller.c
-@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT status_controller.obj -MD -MP -MF $(DEPDIR)/status_controller.Tpo -c -o status_controller.obj `if test -f 'controller/status_controller.c'; then $(CYGPATH_W) 'controller/status_controller.c'; else $(CYGPATH_W) '$(srcdir)/controller/status_controller.c'; fi`
-@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/status_controller.Tpo $(DEPDIR)/status_controller.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='controller/status_controller.c' object='status_controller.obj' libtool=no @AMDEPBACKSLASH@
+ikesa_controller.obj: controller/ikesa_controller.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ikesa_controller.obj -MD -MP -MF $(DEPDIR)/ikesa_controller.Tpo -c -o ikesa_controller.obj `if test -f 'controller/ikesa_controller.c'; then $(CYGPATH_W) 'controller/ikesa_controller.c'; else $(CYGPATH_W) '$(srcdir)/controller/ikesa_controller.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ikesa_controller.Tpo $(DEPDIR)/ikesa_controller.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='controller/ikesa_controller.c' object='ikesa_controller.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o status_controller.obj `if test -f 'controller/status_controller.c'; then $(CYGPATH_W) 'controller/status_controller.c'; else $(CYGPATH_W) '$(srcdir)/controller/status_controller.c'; fi`
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ikesa_controller.obj `if test -f 'controller/ikesa_controller.c'; then $(CYGPATH_W) 'controller/ikesa_controller.c'; else $(CYGPATH_W) '$(srcdir)/controller/ikesa_controller.c'; fi`
+
+control_controller.o: controller/control_controller.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT control_controller.o -MD -MP -MF $(DEPDIR)/control_controller.Tpo -c -o control_controller.o `test -f 'controller/control_controller.c' || echo '$(srcdir)/'`controller/control_controller.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/control_controller.Tpo $(DEPDIR)/control_controller.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='controller/control_controller.c' object='control_controller.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o control_controller.o `test -f 'controller/control_controller.c' || echo '$(srcdir)/'`controller/control_controller.c
+
+control_controller.obj: controller/control_controller.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT control_controller.obj -MD -MP -MF $(DEPDIR)/control_controller.Tpo -c -o control_controller.obj `if test -f 'controller/control_controller.c'; then $(CYGPATH_W) 'controller/control_controller.c'; else $(CYGPATH_W) '$(srcdir)/controller/control_controller.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/control_controller.Tpo $(DEPDIR)/control_controller.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='controller/control_controller.c' object='control_controller.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o control_controller.obj `if test -f 'controller/control_controller.c'; then $(CYGPATH_W) 'controller/control_controller.c'; else $(CYGPATH_W) '$(srcdir)/controller/control_controller.c'; fi`
+
+config_controller.o: controller/config_controller.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT config_controller.o -MD -MP -MF $(DEPDIR)/config_controller.Tpo -c -o config_controller.o `test -f 'controller/config_controller.c' || echo '$(srcdir)/'`controller/config_controller.c
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/config_controller.Tpo $(DEPDIR)/config_controller.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='controller/config_controller.c' object='config_controller.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o config_controller.o `test -f 'controller/config_controller.c' || echo '$(srcdir)/'`controller/config_controller.c
+
+config_controller.obj: controller/config_controller.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT config_controller.obj -MD -MP -MF $(DEPDIR)/config_controller.Tpo -c -o config_controller.obj `if test -f 'controller/config_controller.c'; then $(CYGPATH_W) 'controller/config_controller.c'; else $(CYGPATH_W) '$(srcdir)/controller/config_controller.c'; fi`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/config_controller.Tpo $(DEPDIR)/config_controller.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='controller/config_controller.c' object='config_controller.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o config_controller.obj `if test -f 'controller/config_controller.c'; then $(CYGPATH_W) 'controller/config_controller.c'; else $(CYGPATH_W) '$(srcdir)/controller/config_controller.c'; fi`
gateway_controller.o: controller/gateway_controller.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gateway_controller.o -MD -MP -MF $(DEPDIR)/gateway_controller.Tpo -c -o gateway_controller.o `test -f 'controller/gateway_controller.c' || echo '$(srcdir)/'`controller/gateway_controller.c
@@ -527,6 +575,40 @@ uninstall-ipsec_templates_authDATA:
echo " rm -f '$(DESTDIR)$(ipsec_templates_authdir)/$$f'"; \
rm -f "$(DESTDIR)$(ipsec_templates_authdir)/$$f"; \
done
+install-ipsec_templates_configDATA: $(ipsec_templates_config_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(ipsec_templates_configdir)" || $(MKDIR_P) "$(DESTDIR)$(ipsec_templates_configdir)"
+ @list='$(ipsec_templates_config_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(ipsec_templates_configDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(ipsec_templates_configdir)/$$f'"; \
+ $(ipsec_templates_configDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(ipsec_templates_configdir)/$$f"; \
+ done
+
+uninstall-ipsec_templates_configDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(ipsec_templates_config_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(ipsec_templates_configdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(ipsec_templates_configdir)/$$f"; \
+ done
+install-ipsec_templates_controlDATA: $(ipsec_templates_control_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(ipsec_templates_controldir)" || $(MKDIR_P) "$(DESTDIR)$(ipsec_templates_controldir)"
+ @list='$(ipsec_templates_control_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(ipsec_templates_controlDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(ipsec_templates_controldir)/$$f'"; \
+ $(ipsec_templates_controlDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(ipsec_templates_controldir)/$$f"; \
+ done
+
+uninstall-ipsec_templates_controlDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(ipsec_templates_control_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(ipsec_templates_controldir)/$$f'"; \
+ rm -f "$(DESTDIR)$(ipsec_templates_controldir)/$$f"; \
+ done
install-ipsec_templates_gatewayDATA: $(ipsec_templates_gateway_DATA)
@$(NORMAL_INSTALL)
test -z "$(ipsec_templates_gatewaydir)" || $(MKDIR_P) "$(DESTDIR)$(ipsec_templates_gatewaydir)"
@@ -544,6 +626,23 @@ uninstall-ipsec_templates_gatewayDATA:
echo " rm -f '$(DESTDIR)$(ipsec_templates_gatewaydir)/$$f'"; \
rm -f "$(DESTDIR)$(ipsec_templates_gatewaydir)/$$f"; \
done
+install-ipsec_templates_ikesaDATA: $(ipsec_templates_ikesa_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(ipsec_templates_ikesadir)" || $(MKDIR_P) "$(DESTDIR)$(ipsec_templates_ikesadir)"
+ @list='$(ipsec_templates_ikesa_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(ipsec_templates_ikesaDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(ipsec_templates_ikesadir)/$$f'"; \
+ $(ipsec_templates_ikesaDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(ipsec_templates_ikesadir)/$$f"; \
+ done
+
+uninstall-ipsec_templates_ikesaDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(ipsec_templates_ikesa_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(ipsec_templates_ikesadir)/$$f'"; \
+ rm -f "$(DESTDIR)$(ipsec_templates_ikesadir)/$$f"; \
+ done
install-ipsec_templates_staticDATA: $(ipsec_templates_static_DATA)
@$(NORMAL_INSTALL)
test -z "$(ipsec_templates_staticdir)" || $(MKDIR_P) "$(DESTDIR)$(ipsec_templates_staticdir)"
@@ -561,23 +660,6 @@ uninstall-ipsec_templates_staticDATA:
echo " rm -f '$(DESTDIR)$(ipsec_templates_staticdir)/$$f'"; \
rm -f "$(DESTDIR)$(ipsec_templates_staticdir)/$$f"; \
done
-install-ipsec_templates_statusDATA: $(ipsec_templates_status_DATA)
- @$(NORMAL_INSTALL)
- test -z "$(ipsec_templates_statusdir)" || $(MKDIR_P) "$(DESTDIR)$(ipsec_templates_statusdir)"
- @list='$(ipsec_templates_status_DATA)'; for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- f=$(am__strip_dir) \
- echo " $(ipsec_templates_statusDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(ipsec_templates_statusdir)/$$f'"; \
- $(ipsec_templates_statusDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(ipsec_templates_statusdir)/$$f"; \
- done
-
-uninstall-ipsec_templates_statusDATA:
- @$(NORMAL_UNINSTALL)
- @list='$(ipsec_templates_status_DATA)'; for p in $$list; do \
- f=$(am__strip_dir) \
- echo " rm -f '$(DESTDIR)$(ipsec_templates_statusdir)/$$f'"; \
- rm -f "$(DESTDIR)$(ipsec_templates_statusdir)/$$f"; \
- done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
@@ -657,7 +739,7 @@ check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA)
installdirs:
- for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(ipsecdir)" "$(DESTDIR)$(ipsecdir)" "$(DESTDIR)$(ipsec_templatesdir)" "$(DESTDIR)$(ipsec_templates_authdir)" "$(DESTDIR)$(ipsec_templates_gatewaydir)" "$(DESTDIR)$(ipsec_templates_staticdir)" "$(DESTDIR)$(ipsec_templates_statusdir)"; do \
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(ipsecdir)" "$(DESTDIR)$(ipsecdir)" "$(DESTDIR)$(ipsec_templatesdir)" "$(DESTDIR)$(ipsec_templates_authdir)" "$(DESTDIR)$(ipsec_templates_configdir)" "$(DESTDIR)$(ipsec_templates_controldir)" "$(DESTDIR)$(ipsec_templates_gatewaydir)" "$(DESTDIR)$(ipsec_templates_ikesadir)" "$(DESTDIR)$(ipsec_templates_staticdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
@@ -707,9 +789,11 @@ info-am:
install-data-am: install-ipsecDATA install-ipsecPROGRAMS \
install-ipsec_templatesDATA install-ipsec_templates_authDATA \
+ install-ipsec_templates_configDATA \
+ install-ipsec_templates_controlDATA \
install-ipsec_templates_gatewayDATA \
- install-ipsec_templates_staticDATA \
- install-ipsec_templates_statusDATA
+ install-ipsec_templates_ikesaDATA \
+ install-ipsec_templates_staticDATA
install-dvi: install-dvi-am
@@ -748,9 +832,11 @@ ps-am:
uninstall-am: uninstall-ipsecDATA uninstall-ipsecPROGRAMS \
uninstall-ipsec_templatesDATA \
uninstall-ipsec_templates_authDATA \
+ uninstall-ipsec_templates_configDATA \
+ uninstall-ipsec_templates_controlDATA \
uninstall-ipsec_templates_gatewayDATA \
- uninstall-ipsec_templates_staticDATA \
- uninstall-ipsec_templates_statusDATA uninstall-libLTLIBRARIES
+ uninstall-ipsec_templates_ikesaDATA \
+ uninstall-ipsec_templates_staticDATA uninstall-libLTLIBRARIES
.MAKE: install-am install-strip
@@ -763,9 +849,11 @@ uninstall-am: uninstall-ipsecDATA uninstall-ipsecPROGRAMS \
install-exec-am install-html install-html-am install-info \
install-info-am install-ipsecDATA install-ipsecPROGRAMS \
install-ipsec_templatesDATA install-ipsec_templates_authDATA \
+ install-ipsec_templates_configDATA \
+ install-ipsec_templates_controlDATA \
install-ipsec_templates_gatewayDATA \
- install-ipsec_templates_staticDATA \
- install-ipsec_templates_statusDATA install-libLTLIBRARIES \
+ install-ipsec_templates_ikesaDATA \
+ install-ipsec_templates_staticDATA install-libLTLIBRARIES \
install-man install-pdf install-pdf-am install-ps \
install-ps-am install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
@@ -774,9 +862,11 @@ uninstall-am: uninstall-ipsecDATA uninstall-ipsecPROGRAMS \
uninstall-am uninstall-ipsecDATA uninstall-ipsecPROGRAMS \
uninstall-ipsec_templatesDATA \
uninstall-ipsec_templates_authDATA \
+ uninstall-ipsec_templates_configDATA \
+ uninstall-ipsec_templates_controlDATA \
uninstall-ipsec_templates_gatewayDATA \
- uninstall-ipsec_templates_staticDATA \
- uninstall-ipsec_templates_statusDATA uninstall-libLTLIBRARIES
+ uninstall-ipsec_templates_ikesaDATA \
+ uninstall-ipsec_templates_staticDATA uninstall-libLTLIBRARIES
# 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/manager/controller/auth_controller.c b/src/manager/controller/auth_controller.c
index fd4a3c7a5..e9b86941a 100644
--- a/src/manager/controller/auth_controller.c
+++ b/src/manager/controller/auth_controller.c
@@ -60,7 +60,7 @@ static void check(private_auth_controller_t *this, request_t *request)
if (username && password &&
this->manager->login(this->manager, username, password))
{
- request->redirect(request, "status/ikesalist");
+ request->redirect(request, "ikesa/list");
}
else
{
diff --git a/src/manager/controller/config_controller.c b/src/manager/controller/config_controller.c
new file mode 100644
index 000000000..e7941ada4
--- /dev/null
+++ b/src/manager/controller/config_controller.c
@@ -0,0 +1,214 @@
+/**
+ * @file config_controller.c
+ *
+ * @brief Implementation of config_controller_t.
+ *
+ */
+
+/*
+ * 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 "config_controller.h"
+#include "../manager.h"
+#include "../gateway.h"
+
+#include <xml.h>
+
+#include <library.h>
+
+
+typedef struct private_config_controller_t private_config_controller_t;
+
+/**
+ * private data of the task manager
+ */
+struct private_config_controller_t {
+
+ /**
+ * public functions
+ */
+ config_controller_t public;
+
+ /**
+ * manager instance
+ */
+ manager_t *manager;
+};
+
+/**
+ * read XML of a peerconfig element and fill template
+ */
+static void process_peerconfig(private_config_controller_t *this,
+ enumerator_t *e, request_t *r)
+{
+ xml_t *xml;
+ enumerator_t *e1, *e2, *e3;
+ char *name, *value, *config = "", *child = "", *section = "";
+
+ while (e->enumerate(e, &xml, &name, &value))
+ {
+ if (streq(name, "name"))
+ {
+ config = value;
+ }
+ else if (streq(name, "ikeconfig"))
+ {
+ e1 = xml->children(xml);
+ while (e1->enumerate(e1, &xml, &name, &value))
+ {
+ if (streq(name, "local") || streq(name, "remote"))
+ {
+ if (streq(value, "0.0.0.0") || streq(value, "::"))
+ {
+ value = "%any";
+ }
+ r->setf(r, "peercfgs.%s.ikecfg.%s=%s", config, name, value);
+ }
+ }
+ e1->destroy(e1);
+ }
+ else if (streq(name, "childconfiglist"))
+ {
+ e1 = xml->children(xml);
+ while (e1->enumerate(e1, &xml, &name, &value))
+ {
+ if (streq(name, "childconfig"))
+ {
+ int num = 0;
+
+ e2 = xml->children(xml);
+ while (e2->enumerate(e2, &xml, &name, &value))
+ {
+ if (streq(name, "name"))
+ {
+ child = value;
+ }
+ else if (streq(name, "local") || streq(name, "remote"))
+ {
+ section = name;
+ e3 = xml->children(xml);
+ while (e3->enumerate(e3, &xml, &name, &value))
+ {
+ if (streq(name, "network"))
+ {
+ r->setf(r, "peercfgs.%s.childcfgs.%s.%s.networks.%d=%s",
+ config, child, section, ++num, value);
+ }
+ }
+ e3->destroy(e3);
+ }
+ }
+ e2->destroy(e2);
+ }
+ }
+ e1->destroy(e1);
+ }
+ else
+ {
+ r->setf(r, "peercfgs.%s.%s=%s", config, name, value);
+ }
+ }
+}
+
+static void list(private_config_controller_t *this, request_t *r)
+{
+ gateway_t *gateway;
+ xml_t *xml;
+ enumerator_t *e1, *e2;
+ char *name, *value;
+
+ gateway = this->manager->select_gateway(this->manager, 0);
+ e1 = gateway->query_configlist(gateway);
+ if (e1 == NULL)
+ {
+ r->set(r, "title", "Error");
+ r->set(r, "error", "querying the gateway failed");
+ r->render(r, "templates/error.cs");
+ }
+ else
+ {
+ r->set(r, "title", "Configuration overview");
+
+ while (e1->enumerate(e1, &xml, &name, &value))
+ {
+ if (streq(name, "peerconfig"))
+ {
+ e2 = xml->children(xml);
+ process_peerconfig(this, e2, r);
+ e2->destroy(e2);
+ }
+ }
+ e1->destroy(e1);
+
+ r->render(r, "templates/config/list.cs");
+ }
+}
+
+/**
+ * Implementation of controller_t.get_name
+ */
+static char* get_name(private_config_controller_t *this)
+{
+ return "config";
+}
+
+/**
+ * Implementation of controller_t.handle
+ */
+static void handle(private_config_controller_t *this,
+ request_t *request, char *action)
+{
+ if (!this->manager->logged_in(this->manager))
+ {
+ return request->redirect(request, "auth/login");
+ }
+ if (this->manager->select_gateway(this->manager, 0) == NULL)
+ {
+ return request->redirect(request, "gateway/list");
+ }
+ if (action)
+ {
+ if (streq(action, "list"))
+ {
+ return list(this, request);
+ }
+ }
+ return request->redirect(request, "config/list");
+}
+
+/**
+ * Implementation of controller_t.destroy
+ */
+static void destroy(private_config_controller_t *this)
+{
+ free(this);
+}
+
+/*
+ * see header file
+ */
+controller_t *config_controller_create(context_t *context, void *param)
+{
+ private_config_controller_t *this = malloc_thing(private_config_controller_t);
+
+ this->public.controller.get_name = (char*(*)(controller_t*))get_name;
+ this->public.controller.handle = (void(*)(controller_t*,request_t*,char*,char*,char*,char*,char*))handle;
+ this->public.controller.destroy = (void(*)(controller_t*))destroy;
+
+ this->manager = (manager_t*)context;
+
+ return &this->public.controller;
+}
+
diff --git a/src/manager/controller/status_controller.h b/src/manager/controller/config_controller.h
index a736dda83..fcf5f5c49 100644
--- a/src/manager/controller/status_controller.h
+++ b/src/manager/controller/config_controller.h
@@ -1,7 +1,7 @@
/**
- * @file status_controller.h
+ * @file config_controller.h
*
- * @brief Interface of status_controller_t.
+ * @brief Interface of config_controller_t.
*
*/
@@ -20,18 +20,18 @@
* for more details.
*/
-#ifndef STATUS_CONTROLLER_H_
-#define STATUS_CONTROLLER_H_
+#ifndef CONFIG_CONTROLLER_H_
+#define CONFIG_CONTROLLER_H_
#include <controller.h>
-typedef struct status_controller_t status_controller_t;
+typedef struct config_controller_t config_controller_t;
/**
* @brief Status controller.
*/
-struct status_controller_t {
+struct config_controller_t {
/**
* Implements controller_t interface.
@@ -40,8 +40,8 @@ struct status_controller_t {
};
/**
- * @brief Create a status_controller controller instance.
+ * @brief Create a config_controller controller instance.
*/
-controller_t *status_controller_create(context_t *context, void *param);
+controller_t *config_controller_create(context_t *context, void *param);
-#endif /* STATUS_CONTROLLER_H_ */
+#endif /* CONFIG_CONTROLLER_H_ */
diff --git a/src/manager/controller/control_controller.c b/src/manager/controller/control_controller.c
new file mode 100644
index 000000000..12cb5e907
--- /dev/null
+++ b/src/manager/controller/control_controller.c
@@ -0,0 +1,211 @@
+/**
+ * @file control_controller.c
+ *
+ * @brief Implementation of control_controller_t.
+ *
+ */
+
+/*
+ * 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 "control_controller.h"
+#include "../manager.h"
+#include "../gateway.h"
+
+#include <xml.h>
+
+#include <library.h>
+
+
+typedef struct private_control_controller_t private_control_controller_t;
+
+/**
+ * private data of the task manager
+ */
+struct private_control_controller_t {
+
+ /**
+ * public functions
+ */
+ control_controller_t public;
+
+ /**
+ * manager instance
+ */
+ manager_t *manager;
+};
+
+/**
+ * handle the result of a control operation
+ */
+static void handle_result(private_control_controller_t *this, request_t *r,
+ enumerator_t *e)
+{
+ enumerator_t *e1;
+ xml_t *xml;
+ char *name, *value;
+ int num = 0;
+
+ if (e)
+ {
+ while (e->enumerate(e, &xml, &name, &value))
+ {
+ if (streq(name, "status"))
+ {
+ if (value && atoi(value) == 0)
+ {
+ r->set(r, "result", "Operation executed successfully:");
+ }
+ else
+ {
+ r->set(r, "result", "Operation failed:");
+ }
+ }
+ else if (streq(name, "log"))
+ {
+ e1 = xml->children(xml);
+ while (e1->enumerate(e1, &xml, &name, &value))
+ {
+ if (streq(name, "item"))
+ {
+ r->setf(r, "log.%d=%s", ++num, value);
+ }
+ }
+ e1->destroy(e1);
+ }
+ }
+ e->destroy(e);
+ r->render(r, "templates/control/result.cs");
+ }
+ else
+ {
+ r->set(r, "title", "Error");
+ r->set(r, "error", "controlling the gateway failed");
+ r->render(r, "templates/error.cs");
+ }
+}
+
+/**
+ * initiate an IKE or CHILD SA
+ */
+static void initiate(private_control_controller_t *this, request_t *r,
+ bool ike, char *config)
+{
+ gateway_t *gateway;
+ enumerator_t *e;
+
+ r->setf(r, "title=Establishing %s SA %s", ike ? "IKE" : "CHILD", config);
+ gateway = this->manager->select_gateway(this->manager, 0);
+ e = gateway->initiate(gateway, ike, config);
+ handle_result(this, r, e);
+}
+
+/**
+ * terminate an IKE or CHILD SA
+ */
+static void terminate(private_control_controller_t *this, request_t *r,
+ bool ike, u_int32_t id)
+{
+ gateway_t *gateway;
+ enumerator_t *e;
+
+ r->setf(r, "title=Terminate %s SA %d", ike ? "IKE" : "CHILD", id);
+ gateway = this->manager->select_gateway(this->manager, 0);
+ e = gateway->terminate(gateway, ike, id);
+ handle_result(this, r, e);
+}
+
+/**
+ * Implementation of controller_t.get_name
+ */
+static char* get_name(private_control_controller_t *this)
+{
+ return "control";
+}
+
+/**
+ * Implementation of controller_t.handle
+ */
+static void handle(private_control_controller_t *this,
+ request_t *request, char *action, char *str)
+{
+ if (!this->manager->logged_in(this->manager))
+ {
+ return request->redirect(request, "auth/login");
+ }
+ if (this->manager->select_gateway(this->manager, 0) == NULL)
+ {
+ return request->redirect(request, "gateway/list");
+ }
+ if (action)
+ {
+ u_int32_t id;
+
+ if (streq(action, "terminateike"))
+ {
+ if (str && (id = atoi(str)))
+ {
+ return terminate(this, request, TRUE, id);
+ }
+ }
+ if (streq(action, "terminatechild"))
+ {
+ if (str && (id = atoi(str)))
+ {
+ return terminate(this, request, FALSE, id);
+ }
+ }
+ if (streq(action, "initiateike"))
+ {
+ if (str)
+ {
+ return initiate(this, request, TRUE, str);
+ }
+ }
+ if (streq(action, "initiatechild"))
+ {
+ if (str)
+ {
+ return initiate(this, request, FALSE, str);
+ }
+ }
+ }
+ return request->redirect(request, "ikesa/list");
+}
+
+/**
+ * Implementation of controller_t.destroy
+ */
+static void destroy(private_control_controller_t *this)
+{
+ free(this);
+}
+
+/*
+ * see header file
+ */
+controller_t *control_controller_create(context_t *context, void *param)
+{
+ private_control_controller_t *this = malloc_thing(private_control_controller_t);
+
+ this->public.controller.get_name = (char*(*)(controller_t*))get_name;
+ this->public.controller.handle = (void(*)(controller_t*,request_t*,char*,char*,char*,char*,char*))handle;
+ this->public.controller.destroy = (void(*)(controller_t*))destroy;
+
+ this->manager = (manager_t*)context;
+
+ return &this->public.controller;
+}
+
diff --git a/src/manager/controller/control_controller.h b/src/manager/controller/control_controller.h
new file mode 100644
index 000000000..6a55170aa
--- /dev/null
+++ b/src/manager/controller/control_controller.h
@@ -0,0 +1,47 @@
+/**
+ * @file control_controller.h
+ *
+ * @brief Interface of control_controller_t.
+ *
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef CONTROL_CONTROLLER_H_
+#define CONTROL_CONTROLLER_H_
+
+
+#include <controller.h>
+
+typedef struct control_controller_t control_controller_t;
+
+/**
+ * @brief Status controller.
+ */
+struct control_controller_t {
+
+ /**
+ * Implements controller_t interface.
+ */
+ controller_t controller;
+};
+
+/**
+ * @brief Create a control_controller controller instance.
+ */
+controller_t *control_controller_create(context_t *context, void *param);
+
+#endif /* CONTROL_CONTROLLER_H_ */
diff --git a/src/manager/controller/gateway_controller.c b/src/manager/controller/gateway_controller.c
index bdc779256..dff1cf3cf 100644
--- a/src/manager/controller/gateway_controller.c
+++ b/src/manager/controller/gateway_controller.c
@@ -82,7 +82,7 @@ static void _select(private_gateway_controller_t *this, request_t *request)
{
if (this->manager->select_gateway(this->manager, atoi(id)))
{
- request->redirect(request, "status/ikesalist");
+ request->redirect(request, "ikesa/list");
return;
}
}
diff --git a/src/manager/controller/status_controller.c b/src/manager/controller/ikesa_controller.c
index bcdbd26ea..2b282b79c 100644
--- a/src/manager/controller/status_controller.c
+++ b/src/manager/controller/ikesa_controller.c
@@ -1,7 +1,7 @@
/**
- * @file status_controller.c
+ * @file ikesa_controller.c
*
- * @brief Implementation of status_controller_t.
+ * @brief Implementation of ikesa_controller_t.
*
*/
@@ -20,7 +20,7 @@
* for more details.
*/
-#include "status_controller.h"
+#include "ikesa_controller.h"
#include "../manager.h"
#include "../gateway.h"
@@ -29,17 +29,17 @@
#include <library.h>
-typedef struct private_status_controller_t private_status_controller_t;
+typedef struct private_ikesa_controller_t private_ikesa_controller_t;
/**
* private data of the task manager
*/
-struct private_status_controller_t {
+struct private_ikesa_controller_t {
/**
* public functions
*/
- status_controller_t public;
+ ikesa_controller_t public;
/**
* manager instance
@@ -50,7 +50,7 @@ struct private_status_controller_t {
/**
* read XML of a childsa element and fill template
*/
-static void process_childsa(private_status_controller_t *this, char *id,
+static void process_childsa(private_ikesa_controller_t *this, char *id,
enumerator_t *e, request_t *r)
{
xml_t *xml;
@@ -102,7 +102,7 @@ static void process_childsa(private_status_controller_t *this, char *id,
/**
* read XML of a ikesa element and fill template
*/
-static void process_ikesa(private_status_controller_t *this,
+static void process_ikesa(private_ikesa_controller_t *this,
enumerator_t *e, request_t *r)
{
xml_t *xml;
@@ -146,7 +146,7 @@ static void process_ikesa(private_status_controller_t *this,
}
}
-static void ikesalist(private_status_controller_t *this, request_t *r)
+static void list(private_ikesa_controller_t *this, request_t *r)
{
gateway_t *gateway;
xml_t *xml;
@@ -176,22 +176,22 @@ static void ikesalist(private_status_controller_t *this, request_t *r)
}
e1->destroy(e1);
- r->render(r, "templates/status/ikesalist.cs");
+ r->render(r, "templates/ikesa/list.cs");
}
}
/**
* Implementation of controller_t.get_name
*/
-static char* get_name(private_status_controller_t *this)
+static char* get_name(private_ikesa_controller_t *this)
{
- return "status";
+ return "ikesa";
}
/**
* Implementation of controller_t.handle
*/
-static void handle(private_status_controller_t *this,
+static void handle(private_ikesa_controller_t *this,
request_t *request, char *action)
{
if (!this->manager->logged_in(this->manager))
@@ -204,18 +204,18 @@ static void handle(private_status_controller_t *this,
}
if (action)
{
- if (streq(action, "ikesalist"))
+ if (streq(action, "list"))
{
- return ikesalist(this, request);
+ return list(this, request);
}
}
- return request->redirect(request, "status/ikesalist");
+ return request->redirect(request, "ikesa/list");
}
/**
* Implementation of controller_t.destroy
*/
-static void destroy(private_status_controller_t *this)
+static void destroy(private_ikesa_controller_t *this)
{
free(this);
}
@@ -223,9 +223,9 @@ static void destroy(private_status_controller_t *this)
/*
* see header file
*/
-controller_t *status_controller_create(context_t *context, void *param)
+controller_t *ikesa_controller_create(context_t *context, void *param)
{
- private_status_controller_t *this = malloc_thing(private_status_controller_t);
+ private_ikesa_controller_t *this = malloc_thing(private_ikesa_controller_t);
this->public.controller.get_name = (char*(*)(controller_t*))get_name;
this->public.controller.handle = (void(*)(controller_t*,request_t*,char*,char*,char*,char*,char*))handle;
diff --git a/src/manager/controller/ikesa_controller.h b/src/manager/controller/ikesa_controller.h
new file mode 100644
index 000000000..753cccad1
--- /dev/null
+++ b/src/manager/controller/ikesa_controller.h
@@ -0,0 +1,47 @@
+/**
+ * @file ikesa_controller.h
+ *
+ * @brief Interface of ikesa_controller_t.
+ *
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef IKESA_CONTROLLER_H_
+#define IKESA_CONTROLLER_H_
+
+
+#include <controller.h>
+
+typedef struct ikesa_controller_t ikesa_controller_t;
+
+/**
+ * @brief Status controller.
+ */
+struct ikesa_controller_t {
+
+ /**
+ * Implements controller_t interface.
+ */
+ controller_t controller;
+};
+
+/**
+ * @brief Create a ikesa_controller controller instance.
+ */
+controller_t *ikesa_controller_create(context_t *context, void *param);
+
+#endif /* IKESA_CONTROLLER_H_ */
diff --git a/src/manager/gateway.c b/src/manager/gateway.c
index 5f5a4b477..d4eb5279e 100644
--- a/src/manager/gateway.c
+++ b/src/manager/gateway.c
@@ -57,6 +57,11 @@ struct private_gateway_t {
* socket file descriptor, > 0 if connected
*/
int fd;
+
+ /**
+ * unique id assigned to each xml message
+ */
+ int xmlid;
};
struct sockaddr_un unix_addr = { AF_UNIX, IPSEC_PIDDIR "/charon.xml"};
@@ -103,7 +108,7 @@ static bool connect_(private_gateway_t *this)
/**
* Implementation of gateway_t.request.
*/
-static char* request(private_gateway_t *this, char *xml)
+static char* request(private_gateway_t *this, char *xml, ...)
{
if (this->fd < 0)
{
@@ -116,18 +121,25 @@ static char* request(private_gateway_t *this, char *xml)
{
char buf[8096];
ssize_t len;
+ va_list args;
- len = strlen(xml);
- if (send(this->fd, xml, len, 0) != len)
+ va_start(args, xml);
+ len = vsnprintf(buf, sizeof(buf), xml, args);
+ va_end(args);
+ if (len < 0 || len >= sizeof(buf))
{
return NULL;
}
- len = recv(this->fd, buf, sizeof(buf) - 1, 0);
- if (len < 0)
+ if (send(this->fd, buf, len, 0) != len)
{
- return NULL;
+ if (!connect_(this))
+ {
+ return NULL;
+ }
+ continue;
}
- if (len == 0)
+ len = recv(this->fd, buf, sizeof(buf) - 1, 0);
+ if (len <= 0)
{
if (!connect_(this))
{
@@ -149,11 +161,11 @@ static enumerator_t* query_ikesalist(private_gateway_t *this)
xml_t *xml;
enumerator_t *e1, *e2, *e3, *e4 = NULL;
- str = request(this, "<message type=\"request\" id=\"1\">"
+ str = request(this, "<message type=\"request\" id=\"%d\">"
"<query>"
"<ikesalist/>"
"</query>"
- "</message>");
+ "</message>", this->xmlid++);
if (str == NULL)
{
return NULL;
@@ -197,6 +209,152 @@ static enumerator_t* query_ikesalist(private_gateway_t *this)
return NULL;
}
+
+/**
+ * Implementation of gateway_t.query_configlist.
+ */
+static enumerator_t* query_configlist(private_gateway_t *this)
+{
+ char *str, *name, *value;
+ xml_t *xml;
+ enumerator_t *e1, *e2, *e3, *e4 = NULL;
+
+ str = request(this, "<message type=\"request\" id=\"%d\">"
+ "<query>"
+ "<configlist/>"
+ "</query>"
+ "</message>", this->xmlid++);
+ if (str == NULL)
+ {
+ return NULL;
+ }
+ xml = xml_create(str);
+ if (xml == NULL)
+ {
+ return NULL;
+ }
+
+ e1 = xml->children(xml);
+ free(str);
+ while (e1->enumerate(e1, &xml, &name, &value))
+ {
+ if (streq(name, "message"))
+ {
+ e2 = xml->children(xml);
+ while (e2->enumerate(e2, &xml, &name, &value))
+ {
+ if (streq(name, "query"))
+ {
+ e3 = xml->children(xml);
+ while (e3->enumerate(e3, &xml, &name, &value))
+ {
+ if (streq(name, "configlist"))
+ {
+ e4 = xml->children(xml);
+ e1->destroy(e1);
+ e2->destroy(e2);
+ e3->destroy(e3);
+ return e4;
+ }
+ }
+ e3->destroy(e3);
+ }
+ }
+ e2->destroy(e2);
+ }
+ }
+ e1->destroy(e1);
+ return NULL;
+}
+
+/**
+ * create enumerator over control elements children of a control response
+ */
+static enumerator_t* read_result(private_gateway_t *this, char *res)
+{
+ char *name, *value;
+ xml_t *xml;
+ enumerator_t *e1, *e2, *e3;
+
+ if (res == NULL)
+ {
+ return NULL;
+ }
+ xml = xml_create(res);
+ if (xml == NULL)
+ {
+ return NULL;
+ }
+ e1 = xml->children(xml);
+ free(res);
+ while (e1->enumerate(e1, &xml, &name, &value))
+ {
+ if (streq(name, "message"))
+ {
+ e2 = xml->children(xml);
+ while (e2->enumerate(e2, &xml, &name, &value))
+ {
+ if (streq(name, "control"))
+ {
+ e3 = xml->children(xml);
+ e1->destroy(e1);
+ e2->destroy(e2);
+ return e3;
+ }
+ }
+ e2->destroy(e2);
+ }
+ }
+ e1->destroy(e1);
+ return NULL;
+}
+
+/**
+ * Implementation of gateway_t.initiate.
+ */
+static enumerator_t* initiate(private_gateway_t *this, bool ike, char *name)
+{
+ char *str, *kind;
+
+ if (ike)
+ {
+ kind = "ike";
+ }
+ else
+ {
+ kind = "child";
+ }
+ str = request(this, "<message type=\"request\" id=\"%d\">"
+ "<control>"
+ "<%ssainitiate>%s</%ssainitiate>"
+ "</control>"
+ "</message>", this->xmlid++, kind, name, kind);
+ return read_result(this, str);
+}
+
+/**
+ * Implementation of gateway_t.terminate.
+ */
+static enumerator_t* terminate(private_gateway_t *this, bool ike, u_int32_t id)
+{
+ char *str, *kind;
+
+ if (ike)
+ {
+ kind = "ike";
+ }
+ else
+ {
+ kind = "child";
+ }
+ str = request(this, "<message type=\"request\" id=\"%d\">"
+ "<control>"
+ "<%ssaterminate>%d</%ssaterminate>"
+ "</control>"
+ "</message>", this->xmlid++, kind, id, kind);
+ return read_result(this, str);
+}
+
/**
* Implementation of gateway_t.destroy
*/
@@ -220,11 +378,15 @@ static private_gateway_t *gateway_create(char *name)
this->public.request = (char*(*)(gateway_t*, char *xml))request;
this->public.query_ikesalist = (enumerator_t*(*)(gateway_t*))query_ikesalist;
+ this->public.query_configlist = (enumerator_t*(*)(gateway_t*))query_configlist;
+ this->public.initiate = (enumerator_t*(*)(gateway_t*, bool ike, char *name))initiate;
+ this->public.terminate = (enumerator_t*(*)(gateway_t*, bool ike, u_int32_t id))terminate;
this->public.destroy = (void(*)(gateway_t*))destroy;
this->name = strdup(name);
this->host = NULL;
this->fd = -1;
+ this->xmlid = 1;
return this;
}
diff --git a/src/manager/gateway.h b/src/manager/gateway.h
index 1fe2aef4b..81d8b9c3f 100644
--- a/src/manager/gateway.h
+++ b/src/manager/gateway.h
@@ -49,6 +49,31 @@ struct gateway_t {
enumerator_t* (*query_ikesalist)(gateway_t *this);
/**
+ * @brief Query the list of peer configs and its subconfigs.
+ *
+ * @return enumerator over peerconfig XML elements
+ */
+ enumerator_t* (*query_configlist)(gateway_t *this);
+
+ /**
+ * @brief Terminate an IKE or a CHILD SA.
+ *
+ * @param ike TRUE for IKE-, FALSE for a CHILD-SA
+ * @param id ID of the SA to terminate
+ * @return enumerator over control response XML children
+ */
+ enumerator_t* (*terminate)(gateway_t *this, bool ike, u_int32_t id);
+
+ /**
+ * @brief Initiate an IKE or a CHILD SA.
+ *
+ * @param ike TRUE for IKE-, FALSE for CHILD-SA
+ * @param name name of the peer/child config
+ * @return enumerator over control response XML children
+ */
+ enumerator_t* (*initiate)(gateway_t *this, bool ike, char *name);
+
+ /**
* @brief Destroy a gateway instance.
*/
void (*destroy)(gateway_t *this);
diff --git a/src/manager/lib/dispatcher.c b/src/manager/lib/dispatcher.c
index df669ceb6..ce53d39ea 100644
--- a/src/manager/lib/dispatcher.c
+++ b/src/manager/lib/dispatcher.c
@@ -30,6 +30,7 @@
#include <signal.h>
#include <unistd.h>
+#include <debug.h>
#include <utils/linked_list.h>
typedef struct private_dispatcher_t private_dispatcher_t;
@@ -122,8 +123,8 @@ typedef struct {
session_t *session;
/** condvar to wait for session */
pthread_cond_t cond;
- /** number of threads waiting for session */
- int waiting;
+ /** TRUE if session is in use */
+ bool in_use;
/** last use of the session */
time_t used;
} session_entry_t;
@@ -164,7 +165,7 @@ static session_entry_t *session_entry_create(private_dispatcher_t *this)
session_entry_t *entry;
entry = malloc_thing(session_entry_t);
- entry->waiting = 1;
+ entry->in_use = FALSE;
pthread_cond_init(&entry->cond, NULL);
entry->session = load_session(this);
entry->used = time(NULL);
@@ -228,11 +229,12 @@ static void dispatch(private_dispatcher_t *this)
now = time(NULL);
/* find session */
- iterator = this->sessions->create_iterator_locked(this->sessions, &this->mutex);
+ pthread_mutex_lock(&this->mutex);
+ iterator = this->sessions->create_iterator(this->sessions, TRUE);
while (iterator->iterate(iterator, (void**)&current))
{
/* check all sessions for timeout */
- if (current->waiting == 0 &&
+ if (!current->in_use &&
current->used < now - this->timeout)
{
iterator->remove(iterator);
@@ -243,27 +245,24 @@ static void dispatch(private_dispatcher_t *this)
streq(current->session->get_sid(current->session), sid))
{
found = current;
- found->waiting++;
}
}
iterator->destroy(iterator);
if (found)
{ /* wait until session is unused */
- pthread_mutex_lock(&this->mutex);
- while (found->waiting > 1)
+ while (found->in_use)
{
pthread_cond_wait(&found->cond, &this->mutex);
}
- pthread_mutex_unlock(&this->mutex);
}
else
{ /* create a new session if not found */
found = session_entry_create(this);
- pthread_mutex_lock(&this->mutex);
this->sessions->insert_first(this->sessions, found);
- pthread_mutex_unlock(&this->mutex);
}
+ found->in_use = TRUE;
+ pthread_mutex_unlock(&this->mutex);
/* start processing */
found->session->process(found->session, request);
@@ -271,7 +270,7 @@ static void dispatch(private_dispatcher_t *this)
/* release session */
pthread_mutex_lock(&this->mutex);
- found->waiting--;
+ found->in_use = FALSE;
pthread_cond_signal(&found->cond);
pthread_mutex_unlock(&this->mutex);
diff --git a/src/manager/lib/request.c b/src/manager/lib/request.c
index 4623b3860..2e18bded5 100644
--- a/src/manager/lib/request.c
+++ b/src/manager/lib/request.c
@@ -179,12 +179,18 @@ static void add_cookie(private_request_t *this, char *name, char *value)
/**
* Implementation of request_t.redirect.
*/
-static void redirect(private_request_t *this, char *location)
+static void redirect(private_request_t *this, char *fmt, ...)
{
+ va_list args;
+
FCGX_FPrintF(this->req->out, "Status: 303 See Other\n");
- FCGX_FPrintF(this->req->out, "Location: %s%s%s\n\n",
+ FCGX_FPrintF(this->req->out, "Location: %s%s",
FCGX_GetParam("SCRIPT_NAME", this->req->envp),
- *location == '/' ? "" : "/", location);
+ *fmt == '/' ? "" : "/");
+ va_start(args, fmt);
+ FCGX_VFPrintF(this->req->out, fmt, args);
+ va_end(args);
+ FCGX_FPrintF(this->req->out, "\n\n");
}
/**
@@ -196,6 +202,16 @@ static char* get_base(private_request_t *this)
}
/**
+ * Implementation of request_t.serve.
+ */
+static void serve(private_request_t *this, char *headers, chunk_t chunk)
+{
+ FCGX_FPrintF(this->req->out, "%s\n\n", headers);
+
+ FCGX_PutStr(chunk.ptr, chunk.len, this->req->out);
+}
+
+/**
* Implementation of request_t.render.
*/
static void render(private_request_t *this, char *template)
@@ -254,8 +270,9 @@ request_t *request_create(FCGX_Request *request, bool debug)
this->public.add_cookie = (void(*)(request_t*, char *name, char *value))add_cookie;
this->public.get_cookie = (char*(*)(request_t*,char*))get_cookie;
this->public.get_query_data = (char*(*)(request_t*, char *name))get_query_data;
- this->public.redirect = (void(*)(request_t*, char *location))redirect;
+ this->public.redirect = (void(*)(request_t*, char *fmt,...))redirect;
this->public.render = (void(*)(request_t*,char*))render;
+ this->public.serve = (void(*)(request_t*,char*,chunk_t))serve;
this->public.set = (void(*)(request_t*, char *, char*))set;
this->public.setf = (void(*)(request_t*, char *format, ...))setf;
this->public.destroy = (void(*)(request_t*))destroy;
diff --git a/src/manager/lib/request.h b/src/manager/lib/request.h
index e6fd71e71..f78741d37 100644
--- a/src/manager/lib/request.h
+++ b/src/manager/lib/request.h
@@ -75,9 +75,10 @@ struct request_t {
/**
* @brief Redirect the client to another location.
*
- * @param location location to redirect to
+ * @param fmt location format string
+ * @param ... variable argument for fmt
*/
- void (*redirect)(request_t *this, char *location);
+ void (*redirect)(request_t *this, char *fmt, ...);
/**
* @brief Set a template value.
@@ -106,11 +107,18 @@ struct request_t {
* other targets without to worry about path location.
*
* @param template clearsilver template file location
- * @return rendered template string
*/
void (*render)(request_t *this, char *template);
/**
+ * @brief Serve a request with headers and a body.
+ *
+ * @param headers HTTP headers, \n separated
+ * @param chunk body to write to output
+ */
+ void (*serve)(request_t *this, char *headers, chunk_t chunk);
+
+ /**
* @brief Destroy the request_t.
*/
void (*destroy) (request_t *this);
diff --git a/src/manager/main.c b/src/manager/main.c
index bbe07cbf3..eb4654ced 100644
--- a/src/manager/main.c
+++ b/src/manager/main.c
@@ -26,11 +26,13 @@
#include "manager.h"
#include "database.h"
#include "controller/auth_controller.h"
-#include "controller/status_controller.h"
+#include "controller/ikesa_controller.h"
#include "controller/gateway_controller.h"
+#include "controller/control_controller.h"
+#include "controller/config_controller.h"
#define DBFILE IPSECDIR "/manager.db"
-#define SESSION_TIMEOUT 180
+#define SESSION_TIMEOUT 900
#define THREADS 10
int main (int arc, char *argv[])
@@ -52,9 +54,11 @@ int main (int arc, char *argv[])
dispatcher = dispatcher_create(socket, SESSION_TIMEOUT,
(context_constructor_t)manager_create, database);
- dispatcher->add_controller(dispatcher, status_controller_create, NULL);
+ dispatcher->add_controller(dispatcher, ikesa_controller_create, NULL);
dispatcher->add_controller(dispatcher, gateway_controller_create, NULL);
dispatcher->add_controller(dispatcher, auth_controller_create, NULL);
+ dispatcher->add_controller(dispatcher, control_controller_create, NULL);
+ dispatcher->add_controller(dispatcher, config_controller_create, NULL);
dispatcher->run(dispatcher, THREADS, NULL, NULL, NULL, NULL);
diff --git a/src/manager/templates/config/list.cs b/src/manager/templates/config/list.cs
new file mode 100644
index 000000000..e71830d4d
--- /dev/null
+++ b/src/manager/templates/config/list.cs
@@ -0,0 +1,104 @@
+<?cs include:"templates/header.cs" ?>
+<?cs each:peercfg = peercfgs ?>
+ <div class="expand" id="peercfg-<?cs name:peercfg ?>">
+ <h1><?cs name:peercfg ?>:
+ <span><?cs var:peercfg.local ?></span> &lt;-&gt;
+ <span><?cs var:peercfg.remote ?></span>
+ </h1>
+ <div class="controls">
+ <?cs if:peercfg.remote != "%any" ?>
+ <a title="initiate SA" href="<?cs var:base ?>/control/initiateike/<?cs name:peercfg ?>">
+ <img src="<?cs var:base ?>/static/initiate.png"/>
+ </a>
+ <?cs else ?>
+ &nbsp;
+ <?cs /if ?>
+ </div>
+ <div class="expander">
+ <hr/>
+ <table class="drawing">
+ <tr>
+ <td class="left" colspan="3">
+ <?cs var:peercfg.local ?>
+ </td>
+ <td>
+ </td>
+ <td class="right" colspan="3">
+ <?cs var:peercfg.remote ?>
+ </td>
+ </tr>
+ <tr class="images">
+ <td>
+ <?cs if:peercfg.remote != "%any" ?>
+ <img title="Local host can be the initiator" src="<?cs var:base ?>/static/client-left.png"></img>
+ <?cs else ?>
+ <img title="Local host must be the responder" src="<?cs var:base ?>/static/gateway-left.png"></img>
+ <?cs /if ?>
+ </td>
+ <td style="background-image:url(<?cs var:base ?>/static/pipe.png)">
+ <font color="#e5bf5e">0123456789abdcef</font><br/><br/><br/>
+ <?cs var:peercfg.ikecfg.local ?>
+ </td>
+ <td>
+ <img src="<?cs var:base ?>/static/pipe.png"></img>
+ </td>
+ <td>
+ <img title="IKE connection is down" src="<?cs var:base ?>/static/pipe.png"></img>
+ </td>
+ <td>
+ <img src="<?cs var:base ?>/static/pipe.png"></img>
+ </td>
+ <td class="right" style="background-image:url(<?cs var:base ?>/static/pipe.png)">
+ <font color="#e5bf5e">0123456789abcdef</font><br/><br/><br/>
+ <?cs var:peercfg.ikecfg.remote ?>
+ </td>
+ <td>
+ <?cs if:peercfg.remote == "%any" ?>
+ <img title="Remote host must be the initiator" src="<?cs var:base ?>/static/client-right.png"></img>
+ <?cs else ?>
+ <img title="Remote host can be the responder" src="<?cs var:base ?>/static/gateway-right.png"></img>
+ <?cs /if ?>
+ </td>
+ </tr>
+ <?cs each:childcfg = peercfg.childcfgs ?>
+ <tr>
+ <td colspan="6" class="expand">
+ <h1><?cs name:childcfg ?>:</h1>
+ </td>
+ <td class="controls">
+ <?cs if:peercfg.remote != "%any" ?>
+ <a title="initiate SA" href="<?cs var:base ?>/control/initiatechild/<?cs name:childcfg ?>">
+ <img src="<?cs var:base ?>/static/initiate.png"/>
+ </a>
+ <?cs /if ?>
+ </td>
+ </tr>
+ <tr>
+ <td colspan="7"><hr/></td>
+ </tr>
+ <tr class="images">
+ <td colspan="2">
+ <?cs each:net = childcfg.local.networks ?>
+ <p><?cs var:net ?></p>
+ <?cs /each ?>
+ </td>
+ <td style="background-image:url(<?cs var:base ?>/static/pipe-thin-left.png)">
+ <br/><br/><br/>
+ </td>
+ <td style="background-image:url(<?cs var:base ?>/static/pipe-thin.png)">
+ </td>
+ <td class="right" style="background-image:url(<?cs var:base ?>/static/pipe-thin-right.png)">
+ <br/><br/><br/>
+ </td>
+ <td class="right" colspan="2">
+ <?cs each:net = childcfg.remote.networks ?>
+ <p><?cs var:net ?></p>
+ <?cs /each ?>
+ </td>
+ </tr>
+ <?cs /each ?>
+ </table>
+ </div>
+ </div>
+<?cs /each ?>
+<?cs include:"templates/footer.cs" ?>
diff --git a/src/manager/templates/control/result.cs b/src/manager/templates/control/result.cs
new file mode 100644
index 000000000..1d59df65f
--- /dev/null
+++ b/src/manager/templates/control/result.cs
@@ -0,0 +1,14 @@
+<?cs include:"templates/header.cs" ?>
+<div class="expand">
+ <h1><?cs var:result ?></h1>
+ <div class="controls">&nbsp;</div>
+ <div class="expander">
+ <hr/>
+ <ul>
+ <?cs each:item = log ?>
+ <li><?cs var:item ?></li>
+ <?cs /each ?>
+ </ul>
+ </div>
+</div>
+<?cs include:"templates/footer.cs" ?>
diff --git a/src/manager/templates/header.cs b/src/manager/templates/header.cs
index 64a859a9a..bacd833e0 100644
--- a/src/manager/templates/header.cs
+++ b/src/manager/templates/header.cs
@@ -9,13 +9,15 @@
</head>
<body>
<div class="fleft">
- <a href="<?cs var:base ?>/status/ikesalist">
+ <a href="<?cs var:base ?>/ikesa/list">
<img class="fleft" src="<?cs var:base ?>/static/strongswan.png"/>
</a>
<h1>strongSwan Manager</h1>
<h2><?cs var:title ?></h2>
</div>
<div class="menu">
+ | <a href="<?cs var:base ?>/ikesa/list">IKE SAs</a>
+ | <a href="<?cs var:base ?>/config/list">Config</a>
| <a href="<?cs var:base ?>/gateway/list">Select Gateway</a>
| <a href="<?cs var:base ?>/auth/logout">Logout</a>
</div>
diff --git a/src/manager/templates/status/ikesalist.cs b/src/manager/templates/ikesa/list.cs
index 2238aafd3..f9a8e5c68 100644
--- a/src/manager/templates/status/ikesalist.cs
+++ b/src/manager/templates/ikesa/list.cs
@@ -2,11 +2,16 @@
<?cs each:ikesa = ikesas ?>
<div class="expand" id="ikesa-<?cs name:ikesa ?>">
<h1>
- IKE #<?cs name:ikesa ?> [<?cs var:ikesa.peerconfig ?>]:
+ <?cs var:ikesa.peerconfig ?> [IKE #<?cs name:ikesa ?>]:
<span><?cs var:ikesa.local.identification ?></span> &lt;-&gt;
<span><?cs var:ikesa.remote.identification ?></span>
- </h1>
- <div>
+ </h1>
+ <div class="controls">
+ <a title="close IKE_SA" href="<?cs var:base ?>/control/terminateike/<?cs name:ikesa ?>">
+ <img src="<?cs var:base ?>/static/close.png"/>
+ </a>
+ </div>
+ <div class="expander">
<hr/>
<table class="drawing">
<tr>
@@ -66,8 +71,13 @@
</tr>
<?cs each:childsa = ikesa.childsas ?>
<tr>
- <td colspan="7" class="expand">
- <h1>IPsec #<?cs name:childsa ?> [<?cs var:childsa.childconfig ?>]:</h1>
+ <td colspan="6" class="expand">
+ <h1><?cs var:childsa.childconfig ?> [IPsec #<?cs name:childsa ?>]:</h1>
+ </td>
+ <td class="controls">
+ <a title="close CHILD_SA" href="<?cs var:base ?>/control/terminatechild/<?cs name:childsa ?>">
+ <img src="<?cs var:base ?>/static/close.png"/>
+ </a>
</td>
</tr>
<tr>
@@ -79,12 +89,12 @@
<p><?cs var:net ?></p>
<?cs /each ?>
</td>
- <td style="background-image:url(<?cs var:base ?>/static/pipe-thin-left.png)">
+ <td style="background-image:url(<?cs var:base ?>/static/pipe-thin-left-green.png)">
<?cs var:childsa.local.spi ?> &lt;-<br/><br/><br/>
</td>
- <td style="background-image:url(<?cs var:base ?>/static/pipe-thin.png)">
+ <td style="background-image:url(<?cs var:base ?>/static/pipe-thin-green.png)">
</td>
- <td class="right" style="background-image:url(<?cs var:base ?>/static/pipe-thin-right.png)">
+ <td class="right" style="background-image:url(<?cs var:base ?>/static/pipe-thin-right-green.png)">
-&gt; <?cs var:childsa.remote.spi ?><br/><br/><br/>
</td>
<td class="right" colspan="2">
diff --git a/src/manager/templates/static/close.png b/src/manager/templates/static/close.png
new file mode 100644
index 000000000..7cb058d69
--- /dev/null
+++ b/src/manager/templates/static/close.png
Binary files differ
diff --git a/src/manager/templates/static/initiate.png b/src/manager/templates/static/initiate.png
new file mode 100644
index 000000000..4463e3b7a
--- /dev/null
+++ b/src/manager/templates/static/initiate.png
Binary files differ
diff --git a/src/manager/templates/static/pipe-thin-green.png b/src/manager/templates/static/pipe-thin-green.png
new file mode 100644
index 000000000..df3026ec5
--- /dev/null
+++ b/src/manager/templates/static/pipe-thin-green.png
Binary files differ
diff --git a/src/manager/templates/static/pipe-thin-left-green.png b/src/manager/templates/static/pipe-thin-left-green.png
new file mode 100644
index 000000000..b76432a94
--- /dev/null
+++ b/src/manager/templates/static/pipe-thin-left-green.png
Binary files differ
diff --git a/src/manager/templates/static/pipe-thin-right-green.png b/src/manager/templates/static/pipe-thin-right-green.png
new file mode 100644
index 000000000..f193af9cc
--- /dev/null
+++ b/src/manager/templates/static/pipe-thin-right-green.png
Binary files differ
diff --git a/src/manager/templates/static/script.js b/src/manager/templates/static/script.js
index 7b2a5823c..c9105c372 100644
--- a/src/manager/templates/static/script.js
+++ b/src/manager/templates/static/script.js
@@ -1,8 +1,7 @@
$(function(){
- $(".expand > div").hide();
$(".expand > h1").toggle(
- function(){$(this).parent(".expand").find("div").slideDown('fast');},
- function(){$(this).parent(".expand").find("div").slideUp('fast');}
+ function(){$(this).parent(".expand").find(".expander").slideUp('fast');},
+ function(){$(this).parent(".expand").find(".expander").slideDown('fast');}
);
});
diff --git a/src/manager/templates/static/style.css b/src/manager/templates/static/style.css
index 8a7f4960d..9550b8291 100644
--- a/src/manager/templates/static/style.css
+++ b/src/manager/templates/static/style.css
@@ -57,6 +57,8 @@ a img {
font-size: 1em;
cursor: pointer;
margin: 0;
+ float: left;
+ padding-top: 3px;
}
.expand h1 span {
@@ -64,6 +66,15 @@ a img {
margin-right: 2em;
}
+.expander {
+ clear:left;
+}
+
+.controls {
+ margin-top: 3px;
+ text-align: right;
+}
+
.center {
text-align: center;
}
diff --git a/src/pluto/Makefile.am b/src/pluto/Makefile.am
index 4519ef7bb..69902ad8f 100644
--- a/src/pluto/Makefile.am
+++ b/src/pluto/Makefile.am
@@ -132,15 +132,3 @@ if USE_LIBLDAP
pluto_LDADD += -lldap -llber
endif
-install-exec-local :
- mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d
- mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/cacerts
- mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/ocspcerts
- mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/certs
- mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/acerts
- mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/aacerts
- mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/crls
- mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/reqs
- mkdir -p -m 700 $(DESTDIR)$(confdir)/ipsec.d/private
- chown -R $(ipsecuid):$(ipsecgid) $(DESTDIR)$(confdir)/ipsec.d
-
diff --git a/src/pluto/Makefile.in b/src/pluto/Makefile.in
index 8f7a7f31b..77a0a7548 100644
--- a/src/pluto/Makefile.in
+++ b/src/pluto/Makefile.in
@@ -804,7 +804,7 @@ install-data-am: install-ipsecPROGRAMS install-man
install-dvi: install-dvi-am
-install-exec-am: install-exec-local
+install-exec-am:
install-html: install-html-am
@@ -847,8 +847,8 @@ uninstall-man: uninstall-man5 uninstall-man8
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-exec-local \
- install-html install-html-am install-info install-info-am \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am \
install-ipsecPROGRAMS install-man install-man5 install-man8 \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
@@ -861,18 +861,6 @@ uninstall-man: uninstall-man5 uninstall-man8
oid.o : $(LIBSTRONGSWANDIR)/asn1/oid.c $(LIBSTRONGSWANDIR)/asn1/oid.h
$(COMPILE) -c -o $@ $<
-
-install-exec-local :
- mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d
- mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/cacerts
- mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/ocspcerts
- mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/certs
- mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/acerts
- mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/aacerts
- mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/crls
- mkdir -p -m 755 $(DESTDIR)$(confdir)/ipsec.d/reqs
- mkdir -p -m 700 $(DESTDIR)$(confdir)/ipsec.d/private
- chown -R $(ipsecuid):$(ipsecgid) $(DESTDIR)$(confdir)/ipsec.d
# 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/pluto/connections.c b/src/pluto/connections.c
index 952e722d2..8fbf969b6 100644
--- a/src/pluto/connections.c
+++ b/src/pluto/connections.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: connections.c 3252 2007-10-06 21:24:50Z andreas $
+ * RCSID $Id: connections.c 3361 2007-11-21 23:42:27Z andreas $
*/
#include <string.h>
@@ -955,6 +955,7 @@ gen_reqid(void)
} while (reqid != start);
exit_log("unable to allocate reqid");
+ return 0; /* never reached ... */
}
void
diff --git a/src/pluto/vendor.c b/src/pluto/vendor.c
index b54f574f2..0e6e3d9b7 100644
--- a/src/pluto/vendor.c
+++ b/src/pluto/vendor.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: vendor.c 3252 2007-10-06 21:24:50Z andreas $
+ * RCSID $Id: vendor.c 3380 2007-12-04 23:54:32Z andreas $
*/
#include <stdlib.h>
@@ -206,7 +206,9 @@ static struct vid_struct _vid_tab[] = {
/*
* strongSwan
*/
- DEC_MD5_VID(STRONGSWAN, "strongSwan 4.1.8")
+ DEC_MD5_VID(STRONGSWAN, "strongSwan 4.1.10")
+ DEC_MD5_VID(STRONGSWAN_4_1_9, "strongSwan 4.1.9")
+ DEC_MD5_VID(STRONGSWAN_4_1_8, "strongSwan 4.1.8")
DEC_MD5_VID(STRONGSWAN_4_1_7, "strongSwan 4.1.7")
DEC_MD5_VID(STRONGSWAN_4_1_6, "strongSwan 4.1.6")
DEC_MD5_VID(STRONGSWAN_4_1_5, "strongSwan 4.1.5")
diff --git a/src/pluto/vendor.h b/src/pluto/vendor.h
index 4f480df30..d0853b08c 100644
--- a/src/pluto/vendor.h
+++ b/src/pluto/vendor.h
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: vendor.h 3252 2007-10-06 21:24:50Z andreas $
+ * RCSID $Id: vendor.h 3380 2007-12-04 23:54:32Z andreas $
*/
#ifndef _VENDOR_H_
@@ -111,6 +111,8 @@ enum known_vendorid {
VID_STRONGSWAN_4_1_5 = 93,
VID_STRONGSWAN_4_1_6 = 94,
VID_STRONGSWAN_4_1_7 = 95,
+ VID_STRONGSWAN_4_1_8 = 96,
+ VID_STRONGSWAN_4_1_9 = 97,
/* 101 - 200 : NAT-Traversal */
VID_NATT_STENBERG_01 =101,
diff --git a/src/starter/confread.c b/src/starter/confread.c
index e481ff7cf..7a312d893 100644
--- a/src/starter/confread.c
+++ b/src/starter/confread.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: confread.c 3267 2007-10-08 19:57:54Z andreas $
+ * RCSID $Id: confread.c 3405 2007-12-19 00:49:32Z andreas $
*/
#include <stddef.h>
@@ -173,7 +173,7 @@ kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token
goto err;
}
}
- else if (streq(value, "%any"))
+ else if (streq(value, "%any") || streq(value, "%any4"))
{
anyaddr(conn->addr_family, &end->addr);
}
@@ -509,25 +509,46 @@ load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg)
}
break;
case KW_EAP:
- /* TODO: a gperf function for all EAP types */
+ {
+ char *sep;
+
+ /* check for vendor-type format */
+ sep = strchr(kw->value, '-');
+ if (sep)
+ {
+ *(sep++) = '\0';
+ conn->eap_type = atoi(kw->value);
+ conn->eap_vendor = atoi(sep);
+ if (conn->eap_type == 0 || conn->eap_vendor == 0)
+ {
+ plog("# invalid EAP type: %s=%s", kw->entry->name, kw->value);
+ cfg->err++;
+ }
+ break;
+ }
if (streq(kw->value, "aka"))
{
- conn->eap = 23;
+ conn->eap_type = 23;
}
else if (streq(kw->value, "sim"))
{
- conn->eap = 18;
+ conn->eap_type = 18;
+ }
+ else if (streq(kw->value, "md5"))
+ {
+ conn->eap_type = 4;
}
else
{
- conn->eap = atoi(kw->value);
- if (conn->eap == 0)
+ conn->eap_type = atoi(kw->value);
+ if (conn->eap_type == 0)
{
plog("# unknown EAP type: %s=%s", kw->entry->name, kw->value);
cfg->err++;
}
}
break;
+ }
case KW_KEYINGTRIES:
if (streq(kw->value, "%forever"))
{
diff --git a/src/starter/confread.h b/src/starter/confread.h
index 839f73e99..a32e7116d 100644
--- a/src/starter/confread.h
+++ b/src/starter/confread.h
@@ -14,7 +14,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: confread.h 3267 2007-10-08 19:57:54Z andreas $
+ * RCSID $Id: confread.h 3394 2007-12-13 17:31:21Z martin $
*/
#ifndef _IPSEC_CONFREAD_H_
@@ -106,7 +106,8 @@ struct starter_conn {
starter_state_t state;
keyexchange_t keyexchange;
- int eap;
+ u_int32_t eap_type;
+ u_int32_t eap_vendor;
lset_t policy;
time_t sa_ike_life_seconds;
time_t sa_ipsec_life_seconds;
diff --git a/src/starter/invokecharon.c b/src/starter/invokecharon.c
index 1cb0dfb63..111bb9c6f 100644
--- a/src/starter/invokecharon.c
+++ b/src/starter/invokecharon.c
@@ -14,7 +14,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: invokecharon.c 3267 2007-10-08 19:57:54Z andreas $
+ * RCSID $Id: invokecharon.c 3344 2007-11-15 18:34:05Z martin $
*/
#include <sys/types.h>
@@ -78,9 +78,14 @@ starter_stop_charon (void)
kill(pid, SIGINT);
else if (i < 10)
kill(pid, SIGTERM);
+ else if (i == 10)
+ {
+ kill(pid, SIGKILL);
+ plog("starter_stop_charon(): charon does not respond, sending KILL");
+ }
else
kill(pid, SIGKILL);
- usleep(20000);
+ usleep(200000);
}
if (_charon_pid == 0)
return 0;
diff --git a/src/starter/ipsec.conf.5 b/src/starter/ipsec.conf.5
index 1f581bce8..d542af555 100644
--- a/src/starter/ipsec.conf.5
+++ b/src/starter/ipsec.conf.5
@@ -1,5 +1,5 @@
.TH IPSEC.CONF 5 "27 Jun 2007"
-.\" RCSID $Id: ipsec.conf.5 3267 2007-10-08 19:57:54Z andreas $
+.\" RCSID $Id: ipsec.conf.5 3394 2007-12-13 17:31:21Z martin $
.SH NAME
ipsec.conf \- IPsec configuration and connections
.SH DESCRIPTION
@@ -350,13 +350,21 @@ in case of inactivity. This only applies to IKEv1, in IKEv2 the default
retransmission timeout applies, as every exchange is used to detect dead peers.
.TP
.B eap
-defines the EAP type to be used if
+defines the EAP type to propose as server if the client has
.B authby=eap
-is selected. Acceptable values are
+selected. Acceptable values are
.B aka
-for EAP-AKA and
+for EAP-AKA,
.B sim
-for EAP-SIM.
+for EAP-SIM and
+.B md5
+for EAP-MD5.
+Additionally, IANA assigned EAP method numbers are accepted, or a definition
+in the form
+.B eap=type-vendor
+(e.g.
+.B eap=7-12345
+) can be used to specify vendor specific EAP types.
.TP
.B esp
ESP encryption/authentication algorithm to be used
diff --git a/src/starter/starter.c b/src/starter/starter.c
index cc591dc61..bc2e8f1df 100644
--- a/src/starter/starter.c
+++ b/src/starter/starter.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: starter.c 3267 2007-10-08 19:57:54Z andreas $
+ * RCSID $Id: starter.c 3369 2007-11-28 17:02:12Z andreas $
*/
#include <sys/types.h>
@@ -43,6 +43,19 @@
#include "cmp.h"
#include "interfaces.h"
+/**
+ * Return codes defined by Linux Standard Base Core Specification 3.1
+ * in section 20.2. Init Script Actions
+ */
+#define LSB_RC_SUCCESS 0 /* success */
+#define LSB_RC_FAILURE 1 /* generic or unspecified error */
+#define LSB_RC_INVALID_ARGUMENT 2 /* invalid or excess argument(s) */
+#define LSB_RC_NOT_IMPLEMENTED 3 /* unimplemented feature (reload) */
+#define LSB_RC_NOT_ALLOWED 4 /* user had insufficient privilege */
+#define LSB_RC_NOT_INSTALLED 5 /* program is not installed */
+#define LSB_RC_NOT_CONFIGURED 6 /* program is not configured */
+#define LSB_RC_NOT_RUNNING 7 /* program is not running */
+
#define FLAG_ACTION_START_PLUTO 0x01
#define FLAG_ACTION_UPDATE 0x02
#define FLAG_ACTION_RELOAD 0x04
@@ -131,7 +144,7 @@ usage(char *name)
{
fprintf(stderr, "Usage: starter [--nofork] [--auto-update <sec>] "
"[--debug|--debug-more|--debug-all]\n");
- exit(1);
+ exit(LSB_RC_INVALID_ARGUMENT);
}
int main (int argc, char **argv)
@@ -205,7 +218,7 @@ int main (int argc, char **argv)
if (getuid() != 0)
{
plog("permission denied (must be superuser)");
- exit(1);
+ exit(LSB_RC_NOT_ALLOWED);
}
if (stat(PLUTO_PID_FILE, &stb) == 0)
@@ -227,13 +240,13 @@ int main (int argc, char **argv)
if (stat(DEV_RANDOM, &stb) != 0)
{
plog("unable to start strongSwan IPsec -- no %s!", DEV_RANDOM);
- exit(1);
+ exit(LSB_RC_FAILURE);
}
if (stat(DEV_URANDOM, &stb)!= 0)
{
plog("unable to start strongSwan IPsec -- no %s!", DEV_URANDOM);
- exit(1);
+ exit(LSB_RC_FAILURE);
}
cfg = confread_load(CONFIG_FILE);
@@ -244,14 +257,14 @@ int main (int argc, char **argv)
{
confread_free(cfg);
}
- exit(1);
+ exit(LSB_RC_INVALID_ARGUMENT);
}
/* determine if we have a native netkey IPsec stack */
if (!starter_netkey_init())
{
plog("no netkey IPSec stack detected");
- exit(1);
+ exit(LSB_RC_FAILURE);
}
last_reload = time(NULL);
@@ -259,7 +272,7 @@ int main (int argc, char **argv)
if (stat(STARTER_PID_FILE, &stb) == 0)
{
plog("starter is already running (%s exists) -- no fork done", STARTER_PID_FILE);
- exit(0);
+ exit(LSB_RC_SUCCESS);
}
/* fork if we're not debugging stuff */
@@ -287,7 +300,7 @@ int main (int argc, char **argv)
plog("can't fork: %s", strerror(errno));
break;
default:
- exit(0);
+ exit(LSB_RC_SUCCESS);
}
}
@@ -322,7 +335,7 @@ int main (int argc, char **argv)
#endif /* LEAK_DETECTIVE */
close_log();
plog("ipsec starter stopped");
- exit(0);
+ exit(LSB_RC_SUCCESS);
}
/*
@@ -643,7 +656,6 @@ int main (int argc, char **argv)
_action_ |= FLAG_ACTION_UPDATE;
}
}
-
- return 0;
+ exit(LSB_RC_SUCCESS);
}
diff --git a/src/starter/starterstroke.c b/src/starter/starterstroke.c
index eb5d20628..fae895ba0 100644
--- a/src/starter/starterstroke.c
+++ b/src/starter/starterstroke.c
@@ -13,7 +13,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: starterstroke.c 3267 2007-10-08 19:57:54Z andreas $
+ * RCSID $Id: starterstroke.c 3394 2007-12-13 17:31:21Z martin $
*/
#include <sys/types.h>
@@ -197,7 +197,8 @@ int starter_stroke_add_conn(starter_conn_t *conn)
{
msg.add_conn.auth_method = AUTH_EAP;
}
- msg.add_conn.eap_type = conn->eap;
+ msg.add_conn.eap_type = conn->eap_type;
+ msg.add_conn.eap_vendor = conn->eap_vendor;
if (conn->policy & POLICY_TUNNEL)
{
diff --git a/src/starter/starterwhack.c b/src/starter/starterwhack.c
index 19fa9558f..d29b87873 100644
--- a/src/starter/starterwhack.c
+++ b/src/starter/starterwhack.c
@@ -11,7 +11,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: starterwhack.c 3267 2007-10-08 19:57:54Z andreas $
+ * RCSID $Id: starterwhack.c 3405 2007-12-19 00:49:32Z andreas $
*/
#include <sys/types.h>
@@ -148,17 +148,22 @@ connection_name(starter_conn_t *conn)
}
static void
-set_whack_end(whack_end_t *w, starter_end_t *end)
+set_whack_end(whack_end_t *w, starter_end_t *end, sa_family_t family)
{
w->id = end->id;
w->cert = end->cert;
w->ca = end->ca;
w->groups = end->groups;
w->host_addr = end->addr;
- w->host_nexthop = end->nexthop;
w->host_srcip = end->srcip;
w->has_client = end->has_client;
+ if (family == AF_INET6 && isanyaddr(&end->nexthop))
+ {
+ anyaddr(AF_INET6, &end->nexthop);
+ }
+ w->host_nexthop = end->nexthop;
+
if (w->has_client)
w->client = end->subnet;
else
@@ -246,8 +251,8 @@ starter_whack_add_conn(starter_conn_t *conn)
msg.sa_keying_tries = conn->sa_keying_tries;
msg.policy = conn->policy;
- set_whack_end(&msg.left, &conn->left);
- set_whack_end(&msg.right, &conn->right);
+ set_whack_end(&msg.left, &conn->left, conn->addr_family);
+ set_whack_end(&msg.right, &conn->right, conn->addr_family);
msg.esp = conn->esp;
msg.ike = conn->ike;
diff --git a/src/stroke/stroke.h b/src/stroke/stroke.h
index 18db5a894..ca4e397e4 100644
--- a/src/stroke/stroke.h
+++ b/src/stroke/stroke.h
@@ -19,7 +19,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: stroke.h 3271 2007-10-08 20:12:25Z andreas $
+ * RCSID $Id: stroke.h 3394 2007-12-13 17:31:21Z martin $
*/
#ifndef STROKE_H_
@@ -182,7 +182,8 @@ struct stroke_msg_t {
char *name;
int ikev2;
int auth_method;
- int eap_type;
+ u_int32_t eap_type;
+ u_int32_t eap_vendor;
int mode;
int mobike;
int force_encap;
diff --git a/testing/INSTALL b/testing/INSTALL
index 4e55ab633..079bf7f41 100644
--- a/testing/INSTALL
+++ b/testing/INSTALL
@@ -53,7 +53,7 @@ are required for the strongSwan testing environment:
* A vanilla Linux kernel on which the UML kernel will be based on.
We recommend the use of
- http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.23.1.tar.bz2
+ http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.23.11.tar.bz2
* Starting with Linux kernel 2.6.9 no patch must be applied any more in order
to make the vanilla kernel UML-capable. For older kernels you'll find
@@ -67,11 +67,11 @@ are required for the strongSwan testing environment:
* A gentoo-based UML file system (compressed size 130 MBytes) found at
- http://download.strongswan.org/uml/gentoo-fs-20070702.tar.bz2
+ http://download.strongswan.org/uml/gentoo-fs-20071108.tar.bz2
* The latest strongSwan distribution
- http://download.strongswan.org/strongswan-4.1.8.tar.gz
+ http://download.strongswan.org/strongswan-4.1.10.tar.gz
3. Creating the environment
@@ -146,5 +146,5 @@ README document.
-----------------------------------------------------------------------------
-This file is RCSID $Id: INSTALL 3308 2007-10-17 03:39:16Z andreas $
+This file is RCSID $Id: INSTALL 3410 2007-12-19 21:01:19Z andreas $
diff --git a/testing/do-tests.in b/testing/do-tests.in
index 2b26d4517..7aadafd6a 100755
--- a/testing/do-tests.in
+++ b/testing/do-tests.in
@@ -14,7 +14,7 @@
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
-# RCSID $Id: do-tests.in 3273 2007-10-08 20:18:34Z andreas $
+# RCSID $Id: do-tests.in 3323 2007-11-07 12:22:44Z andreas $
DIR=`dirname $0`
@@ -233,6 +233,13 @@ do
@EOF
fi
+ if [ $SUBDIR = "ipv6" ]
+ then
+ IPTABLES="ip6tables"
+ else
+ IPTABLES="iptables"
+ fi
+
for name in $SUBTESTS
do
let "testnumber += 1"
@@ -464,7 +471,7 @@ do
ssh $HOSTLOGIN ip route list table $SOURCEIP_ROUTING_TABLE \
> $TESTRESULTDIR/${host}.iproute 2>/dev/null
- ssh $HOSTLOGIN iptables -v -n -L \
+ ssh $HOSTLOGIN $IPTABLES -v -n -L \
> $TESTRESULTDIR/${host}.iptables 2>/dev/null
cat >> $TESTRESULTDIR/index.html <<@EOF
<h3>$host</h3>
@@ -483,7 +490,7 @@ do
<li><a href="$host.auth.log">auth.log</a></li>
<li><a href="$host.daemon.log">daemon.log</a></li>
<li><a href="$host.iproute">ip route list table $SOURCEIP_ROUTING_TABLE</a></li>
- <li><a href="$host.iptables">iptables -L</a></li>
+ <li><a href="$host.iptables">$IPTABLES -L</a></li>
</ul>
</td>
</tr>
diff --git a/testing/hosts/winnetou/etc/apache2/httpd.conf b/testing/hosts/winnetou/etc/apache2/httpd.conf
deleted file mode 100644
index 41c74453a..000000000
--- a/testing/hosts/winnetou/etc/apache2/httpd.conf
+++ /dev/null
@@ -1,1103 +0,0 @@
-#
-# This is a modification of the default Apache 2 configuration
-# file by Gentoo Linux. .... [insert more]
-#
-# Support:
-# http://www.gentoo.org/main/en/lists.xml [mailing lists]
-# http://forums.gentoo.org/ [web forums]
-#
-# Bug Reports:
-# http://bugs.gentoo.org/ [gentoo related bugs]
-# http://bugs.apache.org/ [apache httpd related bugs]
-
-#
-#
-#
-# Based upon the NCSA server configuration files originally by Rob McCool.
-#
-# This is the main Apache server configuration file. It contains the
-# configuration directives that give the server its instructions.
-# See <URL:http://httpd.apache.org/docs/2.0/> for detailed information about
-# the directives.
-#
-# Do NOT simply read the instructions in here without understanding
-# what they do. They're here only as hints or reminders. If you are unsure
-# consult the online docs. You have been warned.
-#
-# The configuration directives are grouped into three basic sections:
-# 1. Directives that control the operation of the Apache server process as a
-# whole (the 'global environment').
-# 2. Directives that define the parameters of the 'main' or 'default' server,
-# which responds to requests that aren't handled by a virtual host.
-# These directives also provide default values for the settings
-# of all virtual hosts.
-# 3. Settings for virtual hosts, which allow Web requests to be sent to
-# different IP addresses or hostnames and have them handled by the
-# same Apache server process.
-#
-# Configuration and logfile names: If the filenames you specify for many
-# of the server's control files begin with "/" (or "drive:/" for Win32), the
-# server will use that explicit path. If the filenames do *not* begin
-# with "/", the value of ServerRoot is prepended -- so "logs/foo.log"
-# with ServerRoot set to "/usr/lib/apache2" will be interpreted by the
-# server as "/usr/lib/apache2/logs/foo.log".
-#
-
-### Section 1: Global Environment
-#
-# The directives in this section affect the overall operation of Apache,
-# such as the number of concurrent requests it can handle or where it
-# can find its configuration files.
-#
-
-#
-# ServerRoot: The top of the directory tree under which the server's
-# configuration, error, and log files are kept.
-#
-# NOTE! If you intend to place this on an NFS (or otherwise network)
-# mounted filesystem then please read the LockFile documentation (available
-# at <URL:http://httpd.apache.org/docs/2.0/mod/mpm_common.html#lockfile>);
-# you will save yourself a lot of trouble.
-#
-# Do NOT add a slash at the end of the directory path.
-#
-ServerRoot "/usr/lib/apache2"
-
-#
-# The accept serialization lock file MUST BE STORED ON A LOCAL DISK.
-#
-#LockFile "/var/run/apache2.lock"
-
-#
-# ScoreBoardFile: File used to store internal server process information.
-# If unspecified (the default), the scoreboard will be stored in an
-# anonymous shared memory segment, and will be unavailable to third-party
-# applications.
-# If specified, ensure that no two invocations of Apache share the same
-# scoreboard file. The scoreboard file MUST BE STORED ON A LOCAL DISK.
-#
-<IfModule !perchild.c>
- #ScoreBoardFile /var/run/apache2_runtime_status
-</IfModule>
-
-
-#
-# PidFile: The file in which the server should record its process
-# identification number when it starts.
-#
-PidFile "/var/run/apache2.pid"
-
-#
-# Timeout: The number of seconds before receives and sends time out.
-#
-Timeout 300
-
-#
-# KeepAlive: Whether or not to allow persistent connections (more than
-# one request per connection). Set to "Off" to deactivate.
-#
-KeepAlive On
-
-#
-# MaxKeepAliveRequests: The maximum number of requests to allow
-# during a persistent connection. Set to 0 to allow an unlimited amount.
-# We recommend you leave this number high, for maximum performance.
-#
-MaxKeepAliveRequests 100
-
-#
-# KeepAliveTimeout: Number of seconds to wait for the next request from the
-# same client on the same connection.
-#
-KeepAliveTimeout 15
-
-##
-## Server-Pool Size Regulation (MPM specific)
-##
-
-# prefork MPM [DEFAULT IF USE=-threads]
-# StartServers: number of server processes to start
-# MinSpareServers: minimum number of server processes which are kept spare
-# MaxSpareServers: maximum number of server processes which are kept spare
-# MaxClients: maximum number of server processes allowed to start
-# MaxRequestsPerChild: maximum number of requests a server process serves
-<IfModule prefork.c>
- StartServers 5
- MinSpareServers 5
- MaxSpareServers 10
- MaxClients 150
- MaxRequestsPerChild 0
-</IfModule>
-
-# worker MPM [DEFAULT IF USE=threads]
-# StartServers: initial number of server processes to start
-# MaxClients: maximum number of simultaneous client connections
-# MinSpareThreads: minimum number of worker threads which are kept spare
-# MaxSpareThreads: maximum number of worker threads which are kept spare
-# ThreadsPerChild: constant number of worker threads in each server process
-# MaxRequestsPerChild: maximum number of requests a server process serves
-<IfModule worker.c>
- StartServers 2
- MaxClients 150
- MinSpareThreads 25
- MaxSpareThreads 75
- ThreadsPerChild 25
- MaxRequestsPerChild 0
-</IfModule>
-
-# perchild MPM [THIS MPM IS NOT SUPPORTED]
-# NumServers: constant number of server processes
-# StartThreads: initial number of worker threads in each server process
-# MinSpareThreads: minimum number of worker threads which are kept spare
-# MaxSpareThreads: maximum number of worker threads which are kept spare
-# MaxThreadsPerChild: maximum number of worker threads in each server process
-# MaxRequestsPerChild: maximum number of connections per server process
-<IfModule perchild.c>
- NumServers 5
- StartThreads 5
- MinSpareThreads 5
- MaxSpareThreads 10
- MaxThreadsPerChild 20
- MaxRequestsPerChild 0
-</IfModule>
-
-# peruser MPM [THIS MPM IS NOT SUPPORTED]
-# MinSpareServers - Minimum number of idle children, to handle request spikes
-# MaxClients - Maximum number of children alive at the same time
-# MaxProcessors - Maximum number of processors per vhost
-# Multiplexer - Specify an Multiplexer Child configuration.
-# Processor - Specify a User and Group for a specific child process.
-# ServerEnvironment - Specify the server environment for this virtual host.
-<IfModule peruser.c>
- ServerLimit 256
- MaxClients 256
- MinSpareProcessors 2
- MaxProcessors 10
- MaxRequestsPerChild 1000
-
- # kill off idle processors after this many seconds
- # set to 0 to disable
- ExpireTimeout 1800
-
- Multiplexer nobody nobody
-
- Processor apache apache
-
- # chroot dir is optional:
- # Processor user group /path/to/chroot
-</IfModule>
-
-# itk MPM [THIS MPM IS NOT SUPPORTED]
-# StartServers: number of server processes to start
-# MinSpareServers: minimum number of server processes which are kept spare
-# MaxSpareServers: maximum number of server processes which are kept spare
-# MaxClients: maximum number of server processes allowed to start
-# MaxRequestsPerChild: maximum number of requests a server process serves
-<IfModule itk.c>
- StartServers 5
- MinSpareServers 2
- MaxSpareServers 10
- MaxClients 150
- MaxRequestsPerChild 1000
-</IfModule>
-
-#
-# Listen: Allows you to bind Apache to specific IP addresses and/or
-# ports, instead of the default. See also the <VirtualHost>
-# directive.
-#
-# Change this to Listen on specific IP addresses as shown below to
-# prevent Apache from glomming onto all bound IP addresses (0.0.0.0)
-#
-#Listen 12.34.56.78:80
-Listen 80
-Listen 8880
-Listen 8881
-Listen 8882
-
-#
-# Dynamic Shared Object (DSO) Support
-#
-# To be able to use the functionality of a module which was built as a DSO you
-# have to place corresponding `LoadModule' lines at this location so the
-# directives contained in it are actually available _before_ they are used.
-# Statically compiled modules (those listed by `httpd -l') do not need
-# to be loaded here.
-#
-# The following modules are considered as the default configuration.
-# If you wish to disable one of them, you may have to alter other
-# configuration directives.
-#
-# You should always leave these three, as they are needed for normal use.
-# mod_access (Order, Allow, etc..)
-# mod_log_config (Transferlog, etc..)
-# mod_mime (AddType, etc...)
-#
-# Example:
-# LoadModule foo_module modules/mod_foo.so
-
-
-# Authentication Modules
-#
-# These modules provide authentication and authorization for
-# clients. They should not normally be disabled.
-#
-LoadModule access_module modules/mod_access.so
-LoadModule auth_module modules/mod_auth.so
-LoadModule auth_anon_module modules/mod_auth_anon.so
-LoadModule auth_dbm_module modules/mod_auth_dbm.so
-LoadModule auth_digest_module modules/mod_auth_digest.so
-
-#
-# Metadata Modules
-#
-# These modules provide extra data to clients about
-# a file, such as the mime-type or charset.
-#
-LoadModule charset_lite_module modules/mod_charset_lite.so
-LoadModule env_module modules/mod_env.so
-LoadModule expires_module modules/mod_expires.so
-LoadModule headers_module modules/mod_headers.so
-LoadModule mime_module modules/mod_mime.so
-LoadModule negotiation_module modules/mod_negotiation.so
-LoadModule setenvif_module modules/mod_setenvif.so
-
-#
-# Logging Modules
-#
-# These modules provide logging services for Apache
-#
-LoadModule log_config_module modules/mod_log_config.so
-LoadModule logio_module modules/mod_logio.so
-
-
-#
-# CGI Modules
-#
-# These modules provide the ability to execute CGI Scripts.
-#
-LoadModule cgi_module modules/mod_cgi.so
-LoadModule cgid_module modules/mod_cgid.so
-
-
-#
-# This `suexec` module provides the ability to exeucte CGI scripts under
-# a different user than apache is run.
-#
-LoadModule suexec_module modules/mod_suexec.so
-
-
-#
-# Mappers
-#
-# These Modules provide URL mappings or translations.
-LoadModule alias_module modules/mod_alias.so
-LoadModule rewrite_module modules/mod_rewrite.so
-<IfDefine USERDIR>
- LoadModule userdir_module modules/mod_userdir.so
-</IfDefine>
-
-
-#
-# Handlers
-#
-# These modules create content for a client.
-#
-<IfDefine INFO>
- LoadModule info_module modules/mod_info.so
- LoadModule status_module modules/mod_status.so
-</IfDefine>
-LoadModule actions_module modules/mod_actions.so
-LoadModule autoindex_module modules/mod_autoindex.so
-LoadModule dir_module modules/mod_dir.so
-
-#
-# Filters
-#
-# These modules provide filters for Apache.
-# They preform common tasks like gzip encoding or SSI
-#
-#
-LoadModule ext_filter_module modules/mod_ext_filter.so
-LoadModule deflate_module modules/mod_deflate.so
-LoadModule include_module modules/mod_include.so
-
-
-#
-# Cache Modules
-#
-# The following modules are used for storing a cache of
-# generated or proxied content.
-#
-#LoadModule cache_module modules/mod_cache.so
-#LoadModule disk_cache_module modules/mod_disk_cache.so
-#LoadModule mem_cache_module modules/mod_mem_cache.so
-#LoadModule file_cache_module modules/mod_file_cache.so
-
-#
-# Proxy Modules
-#
-# The following modules are only needed if you are running
-# Apache as a Forward or Reverse Proxy.
-#
-# WARNING: Enabling these modules can be dangerous!
-# READ THE DOCUMENTATION FIRST:
-# http://httpd.apache.org/docs/2.0/mod/mod_proxy.html
-<IfDefine PROXY>
- LoadModule proxy_module modules/mod_proxy.so
- LoadModule proxy_connect_module modules/mod_proxy_connect.so
- LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
- LoadModule proxy_http_module modules/mod_proxy_http.so
-</IfDefine>
-
-#
-# Uncommon Modules
-#
-# The following Modules are not commonly loaded for Apache
-#
-#LoadModule case_filter_module modules/mod_case_filter.so
-#LoadModule case_filter_in_module modules/mod_case_filter_in.so
-#LoadModule echo_module modules/mod_echo.so
-#LoadModule mime_magic_module modules/mod_mime_magic.so
-#LoadModule speling_module modules/mod_speling.so
-#LoadModule unique_id_module modules/mod_unique_id.so
-#LoadModule vhost_alias_module modules/mod_vhost_alias.so
-
-#
-# Obsolete Modules
-#
-# The Following modules are not commonly needed and use
-# obsolete technologies.
-#
-#LoadModule cern_meta_module modules/mod_cern_meta.so
-#LoadModule imap_module modules/mod_imap.so
-#LoadModule usertrack_module modules/mod_usertrack.so
-#LoadModule asis_module modules/mod_asis.so
-
-
-#
-# Extra Modules
-#
-# We Include extra .conf files from /etc/apache2/modules.d
-# This is used to load things like PHP and mod_ssl.
-#
-Include /etc/apache2/modules.d/*.conf
-
-### Section 2: 'Main' server configuration
-#
-# The directives in this section set up the values used by the 'main'
-# server, which responds to any requests that aren't handled by a
-# <VirtualHost> definition. These values also provide defaults for
-# any <VirtualHost> containers you may define later in the file.
-#
-# All of these directives may appear inside <VirtualHost> containers,
-# in which case these default settings will be overridden for the
-# virtual host being defined.
-#
-
-#
-# If you wish httpd to run as a different user or group, you must run
-# httpd as root initially and it will switch.
-#
-# User/Group: The name (or #number) of the user/group to run httpd as.
-# . On SCO (ODT 3) use "User nouser" and "Group nogroup".
-# . On HPUX you may not be able to use shared memory as nobody, and the
-# suggested workaround is to create a user www and use that user.
-# NOTE that some kernels refuse to setgid(Group) or semctl(IPC_SET)
-# when the value of (unsigned)Group is above 60000;
-# don't use Group #-1 on these systems!
-#
-User apache
-Group apache
-
-#
-# ServerAdmin: Your address, where problems with the server should be
-# e-mailed. This address appears on some server-generated pages, such
-# as error documents. e.g. admin@your-domain.com
-#
-ServerAdmin root@localhost
-
-#
-# ServerName gives the name and port that the server uses to identify itself.
-# This can often be determined automatically, but we recommend you specify
-# it explicitly to prevent problems during startup.
-#
-# If this is not set to valid DNS name for your host, server-generated
-# redirections will not work. See also the UseCanonicalName directive.
-#
-# If your host doesn't have a registered DNS name, enter its IP address here.
-# You will have to access it by its address anyway, and this will make
-# redirections work in a sensible way.
-#
-#ServerName localhost
-
-#
-# UseCanonicalName: Determines how Apache constructs self-referencing
-# URLs and the SERVER_NAME and SERVER_PORT variables.
-# When set "Off", Apache will use the Hostname and Port supplied
-# by the client. When set "On", Apache will use the value of the
-# ServerName directive.
-#
-UseCanonicalName Off
-
-
-#
-# Each directory to which Apache has access can be configured with respect
-# to which services and features are allowed and/or disabled in that
-# directory (and its subdirectories).
-#
-# First, we configure the "default" to be a very restrictive set of
-# features.
-#
-<Directory />
- Options FollowSymLinks
- AllowOverride None
-</Directory>
-
-#
-# Note that from this point forward you must specifically allow
-# particular features to be enabled - so if something's not working as
-# you might expect, make sure that you have specifically enabled it
-# below.
-#
-
-#
-# UserDir: The name of the directory that is appended onto a user's home
-# directory if a ~user request is received.
-# enable by adding -D USERDIR to /etc/conf.d/apache2
-#
-<IfModule mod_userdir.c>
- UserDir public_html
-
-#
-# Control access to UserDir directories. The following is an example
-# for a site where these directories are restricted to read-only.
-#
- <Directory /home/*/public_html>
- AllowOverride FileInfo AuthConfig Limit Indexes
- Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
- <Limit GET POST OPTIONS PROPFIND>
- Order allow,deny
- Allow from all
- </Limit>
- <LimitExcept GET POST OPTIONS PROPFIND>
- Order deny,allow
- Deny from all
- </LimitExcept>
- </Directory>
-
-
-# Enable this additional section if you would like to make use of a
-# suexec-enabled cgi-bin directory on a per-user basis.
-#
-#<Directory /home/*/public_html/cgi-bin>
-# Options ExecCGI
-# SetHandler cgi-script
-#</Directory>
-
-</IfModule>
-
-
-#
-# DirectoryIndex: sets the file that Apache will serve if a directory
-# is requested.
-#
-# The index.html.var file (a type-map) is used to deliver content-
-# negotiated documents. The MultiViews Option can be used for the
-# same purpose, but it is much slower.
-#
-DirectoryIndex index.html ocsp.cgi
-
-#
-# AccessFileName: The name of the file to look for in each directory
-# for additional configuration directives. See also the AllowOverride
-# directive.
-#
-AccessFileName .htaccess
-
-#
-# The following lines prevent .htaccess and .htpasswd files from being
-# viewed by Web clients.
-#
-<FilesMatch "^\.ht">
- Order allow,deny
- Deny from all
-</FilesMatch>
-
-#
-# TypesConfig describes where the mime.types file (or equivalent) is
-# to be found.
-#
-TypesConfig /etc/mime.types
-
-#
-# DefaultType is the default MIME type the server will use for a document
-# if it cannot otherwise determine one, such as from filename extensions.
-# If your server contains mostly text or HTML documents, "text/plain" is
-# a good value. If most of your content is binary, such as applications
-# or images, you may want to use "application/octet-stream" instead to
-# keep browsers from trying to display binary files as though they are
-# text.
-#
-DefaultType text/plain
-
-#
-# The mod_mime_magic module allows the server to use various hints from the
-# contents of the file itself to determine its type. The MIMEMagicFile
-# directive tells the module where the hint definitions are located.
-#
-<IfModule mod_mime_magic.c>
- MIMEMagicFile /etc/apache2/magic
-</IfModule>
-
-#
-# HostnameLookups: Log the names of clients or just their IP addresses
-# e.g., www.apache.org (on) or 204.62.129.132 (off).
-# The default is off because it'd be overall better for the net if people
-# had to knowingly turn this feature on, since enabling it means that
-# each client request will result in AT LEAST one lookup request to the
-# nameserver.
-#
-HostnameLookups Off
-
-#
-# EnableMMAP: Control whether memory-mapping is used to deliver
-# files (assuming that the underlying OS supports it).
-# The default is on; turn this off if you serve from NFS-mounted
-# filesystems. On some systems, turning it off (regardless of
-# filesystem) can improve performance; for details, please see
-# http://httpd.apache.org/docs/2.0/mod/core.html#enablemmap
-#
-#EnableMMAP off
-
-#
-# EnableSendfile: Control whether the sendfile kernel support is
-# used to deliver files (assuming that the OS supports it).
-# The default is on; turn this off if you serve from NFS-mounted
-# filesystems. Please see
-# http://httpd.apache.org/docs/2.0/mod/core.html#enablesendfile
-#
-#EnableSendfile off
-
-#
-# ErrorLog: The location of the error log file.
-# If you do not specify an ErrorLog directive within a <VirtualHost>
-# container, error messages relating to that virtual host will be
-# logged here. If you *do* define an error logfile for a <VirtualHost>
-# container, that host's errors will be logged there and not here.
-#
-ErrorLog logs/error_log
-
-#
-# LogLevel: Control the number of messages logged to the error_log.
-# Possible values include: debug, info, notice, warn, error, crit,
-# alert, emerg.
-#
-LogLevel warn
-
-#
-# The following directives define some format nicknames for use with
-# a CustomLog directive (see below).
-#
-LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
-LogFormat "%h %l %u %t \"%r\" %>s %b" common
-LogFormat "%{Referer}i -> %U" referer
-LogFormat "%{User-agent}i" agent
-LogFormat "%v %h %l %u %t \"%r\" %>s %b %T" script
-LogFormat "%v %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" VLOG=%{VLOG}e" vhost
-
-# You need to enable mod_logio.c to use %I and %O
-#LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
-
-#
-# The location and format of the access logfile (Common Logfile Format).
-# If you do not define any access logfiles within a <VirtualHost>
-# container, they will be logged here. Contrariwise, if you *do*
-# define per-<VirtualHost> access logfiles, transactions will be
-# logged therein and *not* in this file.
-#
-CustomLog logs/access_log common
-
-#
-# If you would like to have agent and referer logfiles, uncomment the
-# following directives.
-#
-#CustomLog logs/referer_log referer
-#CustomLog logs/agent_log agent
-
-#
-# If you prefer a single logfile with access, agent, and referer information
-# (Combined Logfile Format) you can use the following directive.
-#
-#CustomLog logs/access_log combined
-
-#
-# ServerTokens
-# This directive configures what you return as the Server HTTP response
-# Header. The default is 'Full' which sends information about the OS-Type
-# and compiled in modules.
-# Set to one of: Full | OS | Minor | Minimal | Major | Prod
-# where Full conveys the most information, and Prod the least.
-#
-ServerTokens Prod
-
-#
-# Optionally add a line containing the server version and virtual host
-# name to server-generated pages (internal error documents, FTP directory
-# listings, mod_status and mod_info output etc., but not CGI generated
-# documents or custom error documents).
-# Set to "EMail" to also include a mailto: link to the ServerAdmin.
-# Set to one of: On | Off | EMail
-#
-ServerSignature On
-
-#
-# Aliases: Add here as many aliases as you need (with no limit). The format is
-# Alias fakename realname
-#
-# Note that if you include a trailing / on fakename then the server will
-# require it to be present in the URL. So "/icons" isn't aliased in this
-# example, only "/icons/". If the fakename is slash-terminated, then the
-# realname must also be slash terminated, and if the fakename omits the
-# trailing slash, the realname must also omit it.
-#
-# We include the /icons/ alias for FancyIndexed directory listings. If you
-# do not use FancyIndexing, you may comment this out.
-#
-Alias /icons/ "/var/www/localhost/icons/"
-
-<Directory "/var/www/localhost/icons/">
- Options Indexes MultiViews
- AllowOverride None
- Order allow,deny
- Allow from all
-</Directory>
-
-#
-# ScriptAlias: This controls which directories contain server scripts.
-# ScriptAliases are essentially the same as Aliases, except that
-# documents in the realname directory are treated as applications and
-# run by the server when requested rather than as documents sent to the client.
-# The same rules about trailing "/" apply to ScriptAlias directives as to
-# Alias.
-#
-ScriptAlias /cgi-bin/ /var/www/localhost/cgi-bin/
-
-<IfModule mod_cgid.c>
- #
- # Additional to mod_cgid.c settings, mod_cgid has Scriptsock <path>
- # for setting UNIX socket for communicating with cgid.
- #
- #Scriptsock /var/run/cgisock
-</IfModule>
-
-#
-# "/var/www/localhost/cgi-bin/" should be changed to whatever your ScriptAliased
-# CGI directory exists, if you have that configured.
-#
-<Directory "/var/www/localhost/cgi-bin/">
- AllowOverride None
- Options None
- Order allow,deny
- Allow from all
-</Directory>
-
-#
-# Redirect allows you to tell clients about documents which used to exist in
-# your server's namespace, but do not anymore. This allows you to tell the
-# clients where to look for the relocated document.
-# Example:
-# Redirect permanent /foo http://www.example.com/bar
-
-#
-# Directives controlling the display of server-generated directory listings.
-#
-<IfModule mod_autoindex.c>
- #
- # IndexOptions: Controls the appearance of server-generated directory
- # listings.
- #
- IndexOptions FancyIndexing VersionSort
-
- #
- # AddIcon* directives tell the server which icon to show for different
- # files or filename extensions. These are only displayed for
- # FancyIndexed directories.
- #
- AddIconByEncoding (CMP,/icons/compressed.gif) x-compress x-gzip
-
- AddIconByType (TXT,/icons/text.gif) text/*
- AddIconByType (IMG,/icons/image2.gif) image/*
- AddIconByType (SND,/icons/sound2.gif) audio/*
- AddIconByType (VID,/icons/movie.gif) video/*
-
- AddIcon /icons/binary.gif .bin .exe
- AddIcon /icons/binhex.gif .hqx
- AddIcon /icons/tar.gif .tar
- AddIcon /icons/world2.gif .wrl .wrl.gz .vrml .vrm .iv
- AddIcon /icons/compressed.gif .Z .z .tgz .gz .zip
- AddIcon /icons/a.gif .ps .ai .eps
- AddIcon /icons/layout.gif .html .shtml .htm .pdf
- AddIcon /icons/text.gif .txt
- AddIcon /icons/c.gif .c
- AddIcon /icons/p.gif .pl .py
- AddIcon /icons/f.gif .for
- AddIcon /icons/dvi.gif .dvi
- AddIcon /icons/uuencoded.gif .uu
- AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl
- AddIcon /icons/tex.gif .tex
- AddIcon /icons/bomb.gif core
-
- AddIcon /icons/back.gif ..
- AddIcon /icons/hand.right.gif README
- AddIcon /icons/folder.gif ^^DIRECTORY^^
- AddIcon /icons/blank.gif ^^BLANKICON^^
-
- #
- # DefaultIcon is which icon to show for files which do not have an icon
- # explicitly set.
- #
- DefaultIcon /icons/unknown.gif
-
- #
- # AddDescription allows you to place a short description after a file in
- # server-generated indexes. These are only displayed for FancyIndexed
- # directories.
- # Format: AddDescription "description" filename
- #
- #AddDescription "GZIP compressed document" .gz
- #AddDescription "tar archive" .tar
- #AddDescription "GZIP compressed tar archive" .tgz
-
- #
- # ReadmeName is the name of the README file the server will look for by
- # default, and append to directory listings.
- #
- # HeaderName is the name of a file which should be prepended to
- # directory indexes.
- ReadmeName README.html
- HeaderName HEADER.html
-
- #
- # IndexIgnore is a set of filenames which directory indexing should ignore
- # and not include in the listing. Shell-style wildcarding is permitted.
- #
- IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t .svn
-</IfModule>
-
-#
-# DefaultLanguage and AddLanguage allows you to specify the language of
-# a document. You can then use content negotiation to give a browser a
-# file in a language the user can understand.
-#
-# Specify a default language. This means that all data
-# going out without a specific language tag (see below) will
-# be marked with this one. You probably do NOT want to set
-# this unless you are sure it is correct for all cases.
-#
-# * It is generally better to not mark a page as
-# * being a certain language than marking it with the wrong
-# * language!
-#
-# DefaultLanguage nl
-#
-# Note 1: The suffix does not have to be the same as the language
-# keyword --- those with documents in Polish (whose net-standard
-# language code is pl) may wish to use "AddLanguage pl .po" to
-# avoid the ambiguity with the common suffix for perl scripts.
-#
-# Note 2: The example entries below illustrate that in some cases
-# the two character 'Language' abbreviation is not identical to
-# the two character 'Country' code for its country,
-# E.g. 'Danmark/dk' versus 'Danish/da'.
-#
-# Note 3: In the case of 'ltz' we violate the RFC by using a three char
-# specifier. There is 'work in progress' to fix this and get
-# the reference data for rfc1766 cleaned up.
-#
-# Catalan (ca) - Croatian (hr) - Czech (cs) - Danish (da) - Dutch (nl)
-# English (en) - Esperanto (eo) - Estonian (et) - French (fr) - German (de)
-# Greek-Modern (el) - Hebrew (he) - Italian (it) - Japanese (ja)
-# Korean (ko) - Luxembourgeois* (ltz) - Norwegian Nynorsk (nn)
-# Norwegian (no) - Polish (pl) - Portugese (pt)
-# Brazilian Portuguese (pt-BR) - Russian (ru) - Swedish (sv)
-# Simplified Chinese (zh-CN) - Spanish (es) - Traditional Chinese (zh-TW)
-#
-AddLanguage ca .ca
-AddLanguage cs .cz .cs
-AddLanguage da .dk
-AddLanguage de .de
-AddLanguage el .el
-AddLanguage en .en
-AddLanguage eo .eo
-AddLanguage es .es
-AddLanguage et .et
-AddLanguage fr .fr
-AddLanguage he .he
-AddLanguage hr .hr
-AddLanguage it .it
-AddLanguage ja .ja
-AddLanguage ko .ko
-AddLanguage ltz .ltz
-AddLanguage nl .nl
-AddLanguage nn .nn
-AddLanguage no .no
-AddLanguage pl .po
-AddLanguage pt .pt
-AddLanguage pt-BR .pt-br
-AddLanguage ru .ru
-AddLanguage sv .sv
-AddLanguage zh-CN .zh-cn
-AddLanguage zh-TW .zh-tw
-
-#
-# LanguagePriority allows you to give precedence to some languages
-# in case of a tie during content negotiation.
-#
-# Just list the languages in decreasing order of preference. We have
-# more or less alphabetized them here. You probably want to change this.
-#
-LanguagePriority en ca cs da de el eo es et fr he hr it ja ko ltz nl nn no pl pt pt-BR ru sv zh-CN zh-TW
-
-#
-# ForceLanguagePriority allows you to serve a result page rather than
-# MULTIPLE CHOICES (Prefer) [in case of a tie] or NOT ACCEPTABLE (Fallback)
-# [in case no accepted languages matched the available variants]
-#
-ForceLanguagePriority Prefer Fallback
-
-#
-# Commonly used filename extensions to character sets. You probably
-# want to avoid clashes with the language extensions, unless you
-# are good at carefully testing your setup after each change.
-# See http://www.iana.org/assignments/character-sets for the
-# official list of charset names and their respective RFCs.
-#
-AddCharset ISO-8859-1 .iso8859-1 .latin1
-AddCharset ISO-8859-2 .iso8859-2 .latin2 .cen
-AddCharset ISO-8859-3 .iso8859-3 .latin3
-AddCharset ISO-8859-4 .iso8859-4 .latin4
-AddCharset ISO-8859-5 .iso8859-5 .latin5 .cyr .iso-ru
-AddCharset ISO-8859-6 .iso8859-6 .latin6 .arb
-AddCharset ISO-8859-7 .iso8859-7 .latin7 .grk
-AddCharset ISO-8859-8 .iso8859-8 .latin8 .heb
-AddCharset ISO-8859-9 .iso8859-9 .latin9 .trk
-AddCharset ISO-2022-JP .iso2022-jp .jis
-AddCharset ISO-2022-KR .iso2022-kr .kis
-AddCharset ISO-2022-CN .iso2022-cn .cis
-AddCharset Big5 .Big5 .big5
-# For russian, more than one charset is used (depends on client, mostly):
-AddCharset WINDOWS-1251 .cp-1251 .win-1251
-AddCharset CP866 .cp866
-AddCharset KOI8-r .koi8-r .koi8-ru
-AddCharset KOI8-ru .koi8-uk .ua
-AddCharset ISO-10646-UCS-2 .ucs2
-AddCharset ISO-10646-UCS-4 .ucs4
-AddCharset UTF-8 .utf8
-
-# The set below does not map to a specific (iso) standard
-# but works on a fairly wide range of browsers. Note that
-# capitalization actually matters (it should not, but it
-# does for some browsers).
-#
-# See http://www.iana.org/assignments/character-sets
-# for a list of sorts. But browsers support few.
-#
-AddCharset GB2312 .gb2312 .gb
-AddCharset utf-7 .utf7
-AddCharset utf-8 .utf8
-AddCharset big5 .big5 .b5
-AddCharset EUC-TW .euc-tw
-AddCharset EUC-JP .euc-jp
-AddCharset EUC-KR .euc-kr
-AddCharset shift_jis .sjis
-
-#
-# AddType allows you to add to or override the MIME configuration
-# file mime.types for specific file types.
-#
-#AddType application/x-tar .tgz
-#
-# AddEncoding allows you to have certain browsers uncompress
-# information on the fly. Note: Not all browsers support this.
-# Despite the name similarity, the following Add* directives have nothing
-# to do with the FancyIndexing customization directives above.
-#
-#AddEncoding x-compress .Z
-#AddEncoding x-gzip .gz .tgz
-#
-# If the AddEncoding directives above are commented-out, then you
-# probably should define those extensions to indicate media types:
-#
-AddType application/x-compress .Z
-AddType application/x-gzip .gz .tgz
-
-#
-# AddHandler allows you to map certain file extensions to "handlers":
-# actions unrelated to filetype. These can be either built into the server
-# or added with the Action directive (see below)
-#
-# To use CGI scripts outside of ScriptAliased directories:
-# (You will also need to add "ExecCGI" to the "Options" directive.)
-#
-AddHandler cgi-script .cgi
-
-#
-# For files that include their own HTTP headers:
-#
-#AddHandler send-as-is asis
-
-#
-# For server-parsed imagemap files:
-#
-#AddHandler imap-file map
-
-#
-# For type maps (negotiated resources):
-# (This is enabled by default to allow the Apache "It Worked" page
-# to be distributed in multiple languages.)
-#
-AddHandler type-map var
-
-#
-# Filters allow you to process content before it is sent to the client.
-#
-# To parse .shtml files for server-side includes (SSI):
-# (You will also need to add "Includes" to the "Options" directive.)
-#
-#AddType text/html .shtml
-#AddOutputFilter INCLUDES .shtml
-
-#
-# Action lets you define media types that will execute a script whenever
-# a matching file is called. This eliminates the need for repeated URL
-# pathnames for oft-used CGI file processors.
-# Format: Action media/type /cgi-script/location
-# Format: Action handler-name /cgi-script/location
-#
-
-#
-# Customizable error responses come in three flavors:
-# 1) plain text 2) local redirects 3) external redirects
-#
-# Some examples:
-#ErrorDocument 500 "The server made a boo boo."
-#ErrorDocument 404 /missing.html
-#ErrorDocument 404 "/cgi-bin/missing_handler.pl"
-#ErrorDocument 402 http://www.example.com/subscription_info.html
-#
-
-#
-# Putting this all together, we can internationalize error responses.
-#
-# We use Alias to redirect any /error/HTTP_<error>.html.var response to
-# our collection of by-error message multi-language collections. We use
-# includes to substitute the appropriate text.
-#
-# You can modify the messages' appearance without changing any of the
-# default HTTP_<error>.html.var files by adding the line:
-#
-# Alias /error/include/ "/your/include/path/"
-#
-# which allows you to create your own set of files by starting with the
-# /var/www/localhost/error/include files and copying them to /your/includepath/
-# even on a per-VirtualHost basis. The default include files will display
-# your Apache version number and your ServerAdmin email address regardless
-# of the setting of ServerSignature.
-#
-# The internationalized error documents require mod_alias, mod_include
-# and mod_negotiation. To activate them, uncomment the following 30 lines.
-
-# Alias /error/ "/var/www/localhost/error/"
-#
-# <Directory "/var/www/localhost/error">
-# AllowOverride None
-# Options IncludesNoExec
-# AddOutputFilter Includes html
-# AddHandler type-map var
-# Order allow,deny
-# Allow from all
-# LanguagePriority en cs de es fr it nl sv pt-br ro
-# ForceLanguagePriority Prefer Fallback
-# </Directory>
-#
-# ErrorDocument 400 /error/HTTP_BAD_REQUEST.html.var
-# ErrorDocument 401 /error/HTTP_UNAUTHORIZED.html.var
-# ErrorDocument 403 /error/HTTP_FORBIDDEN.html.var
-# ErrorDocument 404 /error/HTTP_NOT_FOUND.html.var
-# ErrorDocument 405 /error/HTTP_METHOD_NOT_ALLOWED.html.var
-# ErrorDocument 408 /error/HTTP_REQUEST_TIME_OUT.html.var
-# ErrorDocument 410 /error/HTTP_GONE.html.var
-# ErrorDocument 411 /error/HTTP_LENGTH_REQUIRED.html.var
-# ErrorDocument 412 /error/HTTP_PRECONDITION_FAILED.html.var
-# ErrorDocument 413 /error/HTTP_REQUEST_ENTITY_TOO_LARGE.html.var
-# ErrorDocument 414 /error/HTTP_REQUEST_URI_TOO_LARGE.html.var
-# ErrorDocument 415 /error/HTTP_UNSUPPORTED_MEDIA_TYPE.html.var
-# ErrorDocument 500 /error/HTTP_INTERNAL_SERVER_ERROR.html.var
-# ErrorDocument 501 /error/HTTP_NOT_IMPLEMENTED.html.var
-# ErrorDocument 502 /error/HTTP_BAD_GATEWAY.html.var
-# ErrorDocument 503 /error/HTTP_SERVICE_UNAVAILABLE.html.var
-# ErrorDocument 506 /error/HTTP_VARIANT_ALSO_VARIES.html.var
-
-
-#
-# The following directives modify normal HTTP response behavior to
-# handle known problems with browser implementations.
-#
-BrowserMatch "Mozilla/2" nokeepalive
-BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0
-BrowserMatch "RealPlayer 4\.0" force-response-1.0
-BrowserMatch "Java/1\.0" force-response-1.0
-BrowserMatch "JDK/1\.0" force-response-1.0
-
-#
-# The following directive disables redirects on non-GET requests for
-# a directory that does not include the trailing slash. This fixes a
-# problem with Microsoft WebFolders which does not appropriately handle
-# redirects for folders with DAV methods.
-# Same deal with Apple's DAV filesystem and Gnome VFS support for DAV.
-#
-BrowserMatch "Microsoft Data Access Internet Publishing Provider" redirect-carefully
-BrowserMatch "MS FrontPage" redirect-carefully
-BrowserMatch "^WebDrive" redirect-carefully
-BrowserMatch "^WebDAVFS/1.[0123]" redirect-carefully
-BrowserMatch "^gnome-vfs" redirect-carefully
-BrowserMatch "^XML Spy" redirect-carefully
-BrowserMatch "^Dreamweaver-WebDAV-SCM1" redirect-carefully
-
-#
-# Allow server status reports generated by mod_status,
-# with the URL of http://servername/server-status
-# Change the ".example.com" to match your domain to enable.
-#
-<IfDefine INFO>
- ExtendedStatus On
- <Location /server-status>
- SetHandler server-status
- Order deny,allow
- Deny from all
- Allow from localhost
- </Location>
-</IfDefine>
-
-#
-# Allow remote server configuration reports, with the URL of
-# http://localhost/server-info (This is useful for debugging)
-#
-<IfDefine INFO>
- <Location /server-info>
- SetHandler server-info
- Order deny,allow
- Deny from all
- Allow from localhost
- </Location>
-</IfDefine>
-
-
-#
-# Gentoo VHosts
-#
-# For Gentoo we include External Virtual Hosts Files.
-# Please see vhosts.d/00_default_vhost.conf for the default virtual host.
-#
-Include /etc/apache2/vhosts.d/*.conf
diff --git a/testing/hosts/winnetou/etc/apache2/modules.d/00_mod_mime.conf b/testing/hosts/winnetou/etc/apache2/modules.d/00_mod_mime.conf
new file mode 100644
index 000000000..72b7e0ea4
--- /dev/null
+++ b/testing/hosts/winnetou/etc/apache2/modules.d/00_mod_mime.conf
@@ -0,0 +1,61 @@
+# DefaultType: the default MIME type the server will use for a document
+# if it cannot otherwise determine one, such as from filename extensions.
+# If your server contains mostly text or HTML documents, "text/plain" is
+# a good value. If most of your content is binary, such as applications
+# or images, you may want to use "application/octet-stream" instead to
+# keep browsers from trying to display binary files as though they are
+# text.
+DefaultType text/plain
+
+<IfModule mime_module>
+# TypesConfig points to the file containing the list of mappings from
+# filename extension to MIME-type.
+TypesConfig /etc/mime.types
+
+# AddType allows you to add to or override the MIME configuration
+# file specified in TypesConfig for specific file types.
+#AddType application/x-gzip .tgz
+
+# AddEncoding allows you to have certain browsers uncompress
+# information on the fly. Note: Not all browsers support this.
+#AddEncoding x-compress .Z
+#AddEncoding x-gzip .gz .tgz
+
+# If the AddEncoding directives above are commented-out, then you
+# probably should define those extensions to indicate media types:
+AddType application/x-compress .Z
+AddType application/x-gzip .gz .tgz
+
+# AddHandler allows you to map certain file extensions to "handlers":
+# actions unrelated to filetype. These can be either built into the server
+# or added with the Action directive (see below)
+
+# To use CGI scripts outside of ScriptAliased directories:
+# (You will also need to add "ExecCGI" to the "Options" directive.)
+AddHandler cgi-script .cgi
+
+# For files that include their own HTTP headers:
+#AddHandler send-as-is asis
+
+# For server-parsed imagemap files:
+#AddHandler imap-file map
+
+# For type maps (negotiated resources):
+AddHandler type-map var
+
+# Filters allow you to process content before it is sent to the client.
+#
+# To parse .shtml files for server-side includes (SSI):
+# (You will also need to add "Includes" to the "Options" directive.)
+#AddType text/html .shtml
+#AddOutputFilter INCLUDES .shtml
+</IfModule>
+
+<IfModule mime_magic_module>
+# The mod_mime_magic module allows the server to use various hints from the
+# contents of the file itself to determine its type. The MIMEMagicFile
+# directive tells the module where the hint definitions are located.
+MIMEMagicFile /etc/apache2/magic
+</IfModule>
+
+# vim: ts=4 filetype=apache
diff --git a/testing/hosts/winnetou/etc/apache2/vhosts.d/01_ocsp_vhost.conf b/testing/hosts/winnetou/etc/apache2/vhosts.d/01_ocsp_vhost.conf
index c97c30936..9a32412db 100644
--- a/testing/hosts/winnetou/etc/apache2/vhosts.d/01_ocsp_vhost.conf
+++ b/testing/hosts/winnetou/etc/apache2/vhosts.d/01_ocsp_vhost.conf
@@ -1,36 +1,51 @@
# OCSP Server
+Listen 8880
+
<VirtualHost *:8880>
ServerAdmin root@strongswan.org
DocumentRoot /etc/openssl/ocsp
ServerName ocsp.strongswan.org
ServerAlias 192.168.0.150
+ DirectoryIndex ocsp.cgi
<Directory "/etc/openssl/ocsp">
- Options +ExecCGI
+ Options +ExecCGI
+ Order allow,deny
+ Allow from all
</Directory>
ErrorLog /var/log/apache2/ocsp/error_log
CustomLog /var/log/apache2/ocsp/access_log combined
</VirtualHost>
+Listen 8881
+
<VirtualHost *:8881>
ServerAdmin root@research.strongswan.org
DocumentRoot /etc/openssl/research/ocsp
ServerName ocsp.research.strongswan.org
ServerAlias ocsp.strongswan.org 192.168.0.150
+ DirectoryIndex ocsp.cgi
<Directory "/etc/openssl/research/ocsp">
- Options +ExecCGI
+ Options +ExecCGI
+ Order allow,deny
+ Allow from all
</Directory>
ErrorLog /var/log/apache2/ocsp/error_log
CustomLog /var/log/apache2/ocsp/access_log combined
</VirtualHost>
+Listen 8882
+
<VirtualHost *:8882>
ServerAdmin root@sales.strongswan.org
DocumentRoot /etc/openssl/sales/ocsp
ServerName ocsp.sales.strongswan.org
ServerAlias ocsp.strongswan.org 192.168.0.150
+ DirectoryIndex ocsp.cgi
<Directory "/etc/openssl/sales/ocsp">
- Options +ExecCGI
+ Options +ExecCGI
+ Order allow,deny
+ Allow from all
</Directory>
ErrorLog /var/log/apache2/ocsp/error_log
CustomLog /var/log/apache2/ocsp/access_log combined
diff --git a/testing/hosts/winnetou/etc/conf.d/apache2 b/testing/hosts/winnetou/etc/conf.d/apache2
deleted file mode 100644
index cfb80a7d9..000000000
--- a/testing/hosts/winnetou/etc/conf.d/apache2
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright 1999-2004 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/strongswan/testing/hosts/winnetou/etc/conf.d/apache2,v 1.2 2006/01/06 12:21:21 as Exp $
-
-# Config file for /etc/init.d/apache2
-
-# An example from /etc/apache2/conf/modules.d/40_mod_ssl.conf:
-#
-# <IfDefine SSL>
-# <IfModule !mod_ssl.c>
-# LoadModule ssl_module extramodules/mod_ssl.so
-# </IfModule>
-# </IfDefine>
-#
-# This means that the mod_ssl.so DSO module is only loaded
-# into the server when you pass "-D SSL" at startup. To
-# enable WebDAV, add "-D DAV -D DAV_FS". If you installed
-# mod_php then add "-D PHP4". For more options, please
-# read the files in the /etc/apache2/conf/modules.d directory.
-
-APACHE2_OPTS="-D SSL -D DEFAULT_VHOST"
-
-# Extended options for advanced uses of Apache ONLY
-# You don't need to edit these unless you are doing crazy Apache stuff
-# As not having them set correctly, or feeding in an incorrect configuration
-# via them will result in Apache failing to start
-# YOU HAVE BEEN WARNED.
-
-# ServerRoot setting
-#SERVERROOT=/etc/apache2
-
-# Configuration file location
-# - If this does NOT start with a '/', then it is treated relative to
-# $SERVERROOT by Apache
-#CONFIGFILE=conf/apache2.conf
-
-# Location to log startup errors to
-# They are normally dumped to your terminal.
-#STARTUPERRORLOG="/var/log/apache2/startuperror.log"
-
-# PID file location
-# Note that this MUST match the setting in your configuration file!
-PIDFILE=/var/run/apache2.pid
-
-# Restart style
-# see http://httpd.apache.org/docs-2.0/stopping.html for more details
-# the default is 'graceful', the other possible value is 'restart'
-# If you use 'graceful', completion of the command does NOT imply that the system
-# has finished restarting. Restart is finished only when all child processes
-# have finished serving their current request sets. Read the URL for details.
-#RESTARTSTYLE="restart"
-RESTARTSTYLE="graceful"
diff --git a/testing/hosts/winnetou/etc/init.d/apache2 b/testing/hosts/winnetou/etc/init.d/apache2
index f54f3444a..5f72d3090 100755
--- a/testing/hosts/winnetou/etc/init.d/apache2
+++ b/testing/hosts/winnetou/etc/init.d/apache2
@@ -1,78 +1,121 @@
#!/sbin/runscript
-# Copyright 1999-2004 Gentoo Foundation
+# Copyright 1999-2007 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-opts="${opts} reload"
+opts="configtest fullstatus graceful gracefulstop modules reload"
-[ "x${SERVERROOT}" != "x" ] && APACHE2_OPTS="${APACHE2_OPTS} -d ${SERVERROOT}"
-[ "x${CONFIGFILE}" != "x" ] && APACHE2_OPTS="${APACHE2_OPTS} -f ${CONFIGFILE}"
-[ "x${STARTUPERRORLOG}" != "x" ] && APACHE2_OPTS="${APACHE2_OPTS} -E ${STARTUPERRORLOG}"
-# set a default for PIDFILE/RESTARTSTYLE for those that FAILED to follow
-# instructiosn and update the conf.d/apache2 file.
-# (bug #38787)
-[ -z "${PIDFILE}" ] && PIDFILE=/var/run/apache2.pid
-[ -z "${RESTARTSTYLE}" ] && RESTARTSTYLE="graceful"
+depend() {
+ need net
+ use mysql dns logger netmount postgresql
+ after sshd
+}
+
+configtest() {
+ ebegin "Checking Apache Configuration"
+ checkconfig
+ eend $?
+}
checkconfig() {
- local myconf="/etc/apache2/conf/apache2.conf"
- if [ "x${CONFIGFILE}" != "x" ]; then
- if [ ${CONFIGFILE:0:1} = "/" ]; then
- myconf="${CONFIGFILE}"
- else
- myconf="${SERVERROOT:-/usr/lib/apache2}/${CONFIGFILE}"
- fi
+ SERVERROOT="${SERVERROOT:-/usr/lib/apache2}"
+ if [ ! -d ${SERVERROOT} ]; then
+ eerror "SERVERROOT does not exist: ${SERVERROOT}"
+ return 1
fi
- if [ ! -r "${myconf}" ]; then
- eerror "Unable to read configuration file: ${myconf}"
+
+ CONFIGFILE="${CONFIGFILE:-/etc/apache2/httpd.conf}"
+ [ "${CONFIGFILE#/}" = "${CONFIGFILE}" ] && CONFIGFILE="${SERVERROOT}/${CONFIGFILE}"
+ if [ ! -r "${CONFIGFILE}" ]; then
+ eerror "Unable to read configuration file: ${CONFIGFILE}"
return 1
fi
- if [ -z "${PIDFILE}" ]; then
- eerror "\$PIDFILE is not set!"
- eerror "Did you etc-update /etc/conf.d/apache2?"
- return 1
- fi
- if [ -z "${RESTARTSTYLE}" ]; then
- eerror "\$RESTARTSTYLE is not set!"
- eerror "Did you etc-update /etc/conf.d/apache2?"
- return 1
- fi
- /usr/sbin/apache2 -t ${APACHE2_OPTS} 1>/dev/null 2>&1
+
+ APACHE2_OPTS="${APACHE2_OPTS} -d ${SERVERROOT}"
+ APACHE2_OPTS="${APACHE2_OPTS} -f ${CONFIGFILE}"
+ [ -n "${STARTUPERRORLOG}" ] && APACHE2_OPTS="${APACHE2_OPTS} -E ${STARTUPERRORLOG}"
+
+ APACHE2="/usr/sbin/apache2"
+
+ ${APACHE2} ${APACHE2_OPTS} -t 1>/dev/null 2>&1
ret=$?
if [ $ret -ne 0 ]; then
eerror "Apache2 has detected a syntax error in your configuration files:"
- /usr/sbin/apache2 -t ${APACHE2_OPTS}
+ ${APACHE2} ${APACHE2_OPTS} -t
fi
- return $ret
-}
-depend() {
- need net
- use mysql dns logger netmount postgres
- after sshd
+ return $ret
}
start() {
checkconfig || return 1
ebegin "Starting apache2"
[ -f /var/log/apache2/ssl_scache ] && rm /var/log/apache2/ssl_scache
- [ -f /usr/lib/apache2/build/envvars ] && . /usr/lib/apache2/build/envvars
- env -i PATH=$PATH /sbin/start-stop-daemon --quiet \
- --start --startas /usr/sbin/apache2 \
- --pidfile ${PIDFILE} -- -k start ${APACHE2_OPTS}
+
+ start-stop-daemon --start --exec ${APACHE2} -- ${APACHE2_OPTS} -k start
eend $?
}
stop() {
+ checkconfig || return 1
ebegin "Stopping apache2"
- /usr/sbin/apache2ctl stop >/dev/null
- start-stop-daemon -o --quiet --stop --pidfile ${PIDFILE}
+ start-stop-daemon --stop --retry -TERM/5/-KILL/5 --exec ${APACHE2} --pidfile /var/run/apache2.pid
eend $?
}
reload() {
- # restarting apache2 is much easier than apache1. The server handles most of the work for us.
- # see http://httpd.apache.org/docs-2.0/stopping.html for more details
- ebegin "Restarting apache2"
- /usr/sbin/apache2 ${APACHE2_OPTS} -k ${RESTARTSTYLE}
+ RELOAD_TYPE="${RELOAD_TYPE:-graceful}"
+
+ checkconfig || return 1
+ if [ "${RELOAD_TYPE}" = "restart" ]; then
+ ebegin "Restarting apache2"
+ start-stop-daemon --stop --oknodo --signal HUP --exec ${APACHE2} --pidfile /var/run/apache2.pid
+ eend $?
+ elif [ "${RELOAD_TYPE}" = "graceful" ]; then
+ ebegin "Gracefully restarting apache2"
+ start-stop-daemon --stop --oknodo --signal USR1 --exec ${APACHE2} --pidfile /var/run/apache2.pid
+ eend $?
+ else
+ eerror "${RELOAD_TYPE} is not a valid RELOAD_TYPE. Please edit /etc/conf.d/apache2"
+ fi
+}
+
+graceful() {
+ checkconfig || return 1
+ ebegin "Gracefully restarting apache2"
+ start-stop-daemon --stop --signal USR1 --exec ${APACHE2} --pidfile /var/run/apache2.pid
+ eend $?
+}
+
+gracefulstop() {
+ checkconfig || return 1
+
+ # zap!
+ if service_started "${myservice}"; then
+ mark_service_stopped "${myservice}"
+ fi
+
+ ebegin "Gracefully stopping apache2"
+ # 28 is SIGWINCH
+ start-stop-daemon --stop --signal 28 --exec ${APACHE2} --pidfile /var/run/apache2.pid
eend $?
}
+
+modules() {
+ checkconfig || return 1
+
+ ${APACHE2} ${APACHE2_OPTS} -M 2>&1
+}
+
+status() {
+ LYNX="${LYNX:-lynx -dump}"
+ STATUSURL="${STATUSURL:-http://localhost/server-status}"
+
+ ${LYNX} ${STATUSURL} | awk ' /process$/ { print; exit } { print } '
+}
+
+fullstatus() {
+ LYNX="${LYNX:-lynx -dump}"
+ STATUSURL="${STATUSURL:-http://localhost/server-status}"
+
+ ${LYNX} ${STATUSURL}
+}
diff --git a/testing/hosts/winnetou/etc/runlevels/default/apache2 b/testing/hosts/winnetou/etc/runlevels/default/apache2
index f54f3444a..5f72d3090 100755
--- a/testing/hosts/winnetou/etc/runlevels/default/apache2
+++ b/testing/hosts/winnetou/etc/runlevels/default/apache2
@@ -1,78 +1,121 @@
#!/sbin/runscript
-# Copyright 1999-2004 Gentoo Foundation
+# Copyright 1999-2007 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-opts="${opts} reload"
+opts="configtest fullstatus graceful gracefulstop modules reload"
-[ "x${SERVERROOT}" != "x" ] && APACHE2_OPTS="${APACHE2_OPTS} -d ${SERVERROOT}"
-[ "x${CONFIGFILE}" != "x" ] && APACHE2_OPTS="${APACHE2_OPTS} -f ${CONFIGFILE}"
-[ "x${STARTUPERRORLOG}" != "x" ] && APACHE2_OPTS="${APACHE2_OPTS} -E ${STARTUPERRORLOG}"
-# set a default for PIDFILE/RESTARTSTYLE for those that FAILED to follow
-# instructiosn and update the conf.d/apache2 file.
-# (bug #38787)
-[ -z "${PIDFILE}" ] && PIDFILE=/var/run/apache2.pid
-[ -z "${RESTARTSTYLE}" ] && RESTARTSTYLE="graceful"
+depend() {
+ need net
+ use mysql dns logger netmount postgresql
+ after sshd
+}
+
+configtest() {
+ ebegin "Checking Apache Configuration"
+ checkconfig
+ eend $?
+}
checkconfig() {
- local myconf="/etc/apache2/conf/apache2.conf"
- if [ "x${CONFIGFILE}" != "x" ]; then
- if [ ${CONFIGFILE:0:1} = "/" ]; then
- myconf="${CONFIGFILE}"
- else
- myconf="${SERVERROOT:-/usr/lib/apache2}/${CONFIGFILE}"
- fi
+ SERVERROOT="${SERVERROOT:-/usr/lib/apache2}"
+ if [ ! -d ${SERVERROOT} ]; then
+ eerror "SERVERROOT does not exist: ${SERVERROOT}"
+ return 1
fi
- if [ ! -r "${myconf}" ]; then
- eerror "Unable to read configuration file: ${myconf}"
+
+ CONFIGFILE="${CONFIGFILE:-/etc/apache2/httpd.conf}"
+ [ "${CONFIGFILE#/}" = "${CONFIGFILE}" ] && CONFIGFILE="${SERVERROOT}/${CONFIGFILE}"
+ if [ ! -r "${CONFIGFILE}" ]; then
+ eerror "Unable to read configuration file: ${CONFIGFILE}"
return 1
fi
- if [ -z "${PIDFILE}" ]; then
- eerror "\$PIDFILE is not set!"
- eerror "Did you etc-update /etc/conf.d/apache2?"
- return 1
- fi
- if [ -z "${RESTARTSTYLE}" ]; then
- eerror "\$RESTARTSTYLE is not set!"
- eerror "Did you etc-update /etc/conf.d/apache2?"
- return 1
- fi
- /usr/sbin/apache2 -t ${APACHE2_OPTS} 1>/dev/null 2>&1
+
+ APACHE2_OPTS="${APACHE2_OPTS} -d ${SERVERROOT}"
+ APACHE2_OPTS="${APACHE2_OPTS} -f ${CONFIGFILE}"
+ [ -n "${STARTUPERRORLOG}" ] && APACHE2_OPTS="${APACHE2_OPTS} -E ${STARTUPERRORLOG}"
+
+ APACHE2="/usr/sbin/apache2"
+
+ ${APACHE2} ${APACHE2_OPTS} -t 1>/dev/null 2>&1
ret=$?
if [ $ret -ne 0 ]; then
eerror "Apache2 has detected a syntax error in your configuration files:"
- /usr/sbin/apache2 -t ${APACHE2_OPTS}
+ ${APACHE2} ${APACHE2_OPTS} -t
fi
- return $ret
-}
-depend() {
- need net
- use mysql dns logger netmount postgres
- after sshd
+ return $ret
}
start() {
checkconfig || return 1
ebegin "Starting apache2"
[ -f /var/log/apache2/ssl_scache ] && rm /var/log/apache2/ssl_scache
- [ -f /usr/lib/apache2/build/envvars ] && . /usr/lib/apache2/build/envvars
- env -i PATH=$PATH /sbin/start-stop-daemon --quiet \
- --start --startas /usr/sbin/apache2 \
- --pidfile ${PIDFILE} -- -k start ${APACHE2_OPTS}
+
+ start-stop-daemon --start --exec ${APACHE2} -- ${APACHE2_OPTS} -k start
eend $?
}
stop() {
+ checkconfig || return 1
ebegin "Stopping apache2"
- /usr/sbin/apache2ctl stop >/dev/null
- start-stop-daemon -o --quiet --stop --pidfile ${PIDFILE}
+ start-stop-daemon --stop --retry -TERM/5/-KILL/5 --exec ${APACHE2} --pidfile /var/run/apache2.pid
eend $?
}
reload() {
- # restarting apache2 is much easier than apache1. The server handles most of the work for us.
- # see http://httpd.apache.org/docs-2.0/stopping.html for more details
- ebegin "Restarting apache2"
- /usr/sbin/apache2 ${APACHE2_OPTS} -k ${RESTARTSTYLE}
+ RELOAD_TYPE="${RELOAD_TYPE:-graceful}"
+
+ checkconfig || return 1
+ if [ "${RELOAD_TYPE}" = "restart" ]; then
+ ebegin "Restarting apache2"
+ start-stop-daemon --stop --oknodo --signal HUP --exec ${APACHE2} --pidfile /var/run/apache2.pid
+ eend $?
+ elif [ "${RELOAD_TYPE}" = "graceful" ]; then
+ ebegin "Gracefully restarting apache2"
+ start-stop-daemon --stop --oknodo --signal USR1 --exec ${APACHE2} --pidfile /var/run/apache2.pid
+ eend $?
+ else
+ eerror "${RELOAD_TYPE} is not a valid RELOAD_TYPE. Please edit /etc/conf.d/apache2"
+ fi
+}
+
+graceful() {
+ checkconfig || return 1
+ ebegin "Gracefully restarting apache2"
+ start-stop-daemon --stop --signal USR1 --exec ${APACHE2} --pidfile /var/run/apache2.pid
+ eend $?
+}
+
+gracefulstop() {
+ checkconfig || return 1
+
+ # zap!
+ if service_started "${myservice}"; then
+ mark_service_stopped "${myservice}"
+ fi
+
+ ebegin "Gracefully stopping apache2"
+ # 28 is SIGWINCH
+ start-stop-daemon --stop --signal 28 --exec ${APACHE2} --pidfile /var/run/apache2.pid
eend $?
}
+
+modules() {
+ checkconfig || return 1
+
+ ${APACHE2} ${APACHE2_OPTS} -M 2>&1
+}
+
+status() {
+ LYNX="${LYNX:-lynx -dump}"
+ STATUSURL="${STATUSURL:-http://localhost/server-status}"
+
+ ${LYNX} ${STATUSURL} | awk ' /process$/ { print; exit } { print } '
+}
+
+fullstatus() {
+ LYNX="${LYNX:-lynx -dump}"
+ STATUSURL="${STATUSURL:-http://localhost/server-status}"
+
+ ${LYNX} ${STATUSURL}
+}
diff --git a/testing/images/a-m-c-w-d-ip6.png b/testing/images/a-m-c-w-d-ip6.png
new file mode 100644
index 000000000..2b81d5c2b
--- /dev/null
+++ b/testing/images/a-m-c-w-d-ip6.png
Binary files differ
diff --git a/testing/images/a-m-c-w-ip6.png b/testing/images/a-m-c-w-ip6.png
new file mode 100644
index 000000000..374ca8069
--- /dev/null
+++ b/testing/images/a-m-c-w-ip6.png
Binary files differ
diff --git a/testing/images/a-m-c-w-s-b-med.png b/testing/images/a-m-c-w-s-b-med.png
new file mode 100644
index 000000000..5b31fa120
--- /dev/null
+++ b/testing/images/a-m-c-w-s-b-med.png
Binary files differ
diff --git a/testing/images/a-m-w-s-b-ip6.png b/testing/images/a-m-w-s-b-ip6.png
new file mode 100644
index 000000000..fbce9793e
--- /dev/null
+++ b/testing/images/a-m-w-s-b-ip6.png
Binary files differ
diff --git a/testing/images/a-v-m-c-w-med.png b/testing/images/a-v-m-c-w-med.png
new file mode 100644
index 000000000..9a47aa360
--- /dev/null
+++ b/testing/images/a-v-m-c-w-med.png
Binary files differ
diff --git a/testing/images/m-w-s-ip6.png b/testing/images/m-w-s-ip6.png
new file mode 100644
index 000000000..50d05b70e
--- /dev/null
+++ b/testing/images/m-w-s-ip6.png
Binary files differ
diff --git a/testing/images/m-w-s.png b/testing/images/m-w-s.png
index 5f1aee2aa..14115c1f3 100755
--- a/testing/images/m-w-s.png
+++ b/testing/images/m-w-s.png
Binary files differ
diff --git a/testing/scripts/build-umlrootfs b/testing/scripts/build-umlrootfs
index 3498f216e..b205f62a6 100755
--- a/testing/scripts/build-umlrootfs
+++ b/testing/scripts/build-umlrootfs
@@ -14,7 +14,7 @@
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
-# RCSID $Id: build-umlrootfs 3273 2007-10-08 20:18:34Z andreas $
+# RCSID $Id: build-umlrootfs 3404 2007-12-19 00:47:56Z andreas $
DIR=`dirname $0`
@@ -141,10 +141,21 @@ then
echo -n " --enable-ldap" >> $INSTALLSHELL
fi
+if [ "$USE_EAP_AKA" = "yes" ]
+then
+ echo -n " --enable-eap-aka" >> $INSTALLSHELL
+fi
+
+if [ "$USE_P2P" = "yes" ]
+then
+ echo -n " --enable-p2p" >> $INSTALLSHELL
+fi
+
if [ "$USE_LEAK_DETECTIVE" = "yes" ]
then
echo -n " --enable-leak-detective" >> $INSTALLSHELL
fi
+
echo "" >> $INSTALLSHELL
echo "make" >> $INSTALLSHELL
echo "make install" >> $INSTALLSHELL
diff --git a/testing/testing.conf b/testing/testing.conf
index aecedd7ae..7665f877a 100755
--- a/testing/testing.conf
+++ b/testing/testing.conf
@@ -21,28 +21,30 @@ UMLTESTDIR=~/strongswan-testing
# Bzipped kernel sources
# (file extension .tar.bz2 required)
-KERNEL=$UMLTESTDIR/linux-2.6.22.1.tar.bz2
+KERNEL=$UMLTESTDIR/linux-2.6.23.11.tar.bz2
# Extract kernel version
KERNELVERSION=`basename $KERNEL .tar.bz2 | sed -e 's/linux-//'`
# Kernel configuration file
-KERNELCONFIG=$UMLTESTDIR/.config-2.6.22
+KERNELCONFIG=$UMLTESTDIR/.config-2.6.23
# Bzipped uml patch for kernel
# (not needed anymore for 2.6.9 kernel or higher)
#UMLPATCH=$UMLTESTDIR/uml_jmpbuf-2.6.18.patch.bz2
# Bzipped source of strongSwan
-STRONGSWAN=$UMLTESTDIR/strongswan-4.1.7.tar.bz2
+STRONGSWAN=$UMLTESTDIR/strongswan-4.1.10.tar.bz2
# strongSwan compile options (use "yes" or "no")
USE_LIBCURL="yes"
USE_LDAP="yes"
+USE_EAP_AKA="yes"
+USE_P2P="yes"
USE_LEAK_DETECTIVE="no"
# Gentoo linux root filesystem
-ROOTFS=$UMLTESTDIR/gentoo-fs-20070702.tar.bz2
+ROOTFS=$UMLTESTDIR/gentoo-fs-20071108.tar.bz2
# Size of the finished root filesystem in MB
ROOTFSSIZE=544
diff --git a/testing/tests/ikev1/host2host-transport/evaltest.dat b/testing/tests/ikev1/host2host-transport/evaltest.dat
index d19f970f2..04c0eb3a2 100644
--- a/testing/tests/ikev1/host2host-transport/evaltest.dat
+++ b/testing/tests/ikev1/host2host-transport/evaltest.dat
@@ -1,5 +1,7 @@
moon::ipsec status::host-host.*STATE_QUICK_I2.*IPsec SA established::YES
sun::ipsec status::host-host.*STATE_QUICK_R2.*IPsec SA established::YES
+moon::ip xfrm state::mode transport::YES
+sun::ip xfrm state::mode transport::YES
moon::ping -c 1 PH_IP_SUN::64 bytes from PH_IP_SUN: icmp_seq=1::YES
sun::tcpdump::IP moon.strongswan.org > sun.strongswan.org: ESP::YES
sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: ESP::YES
diff --git a/testing/tests/ikev2/host2host-transport/evaltest.dat b/testing/tests/ikev2/host2host-transport/evaltest.dat
index a46e4e4e4..2dd58c9d7 100644
--- a/testing/tests/ikev2/host2host-transport/evaltest.dat
+++ b/testing/tests/ikev2/host2host-transport/evaltest.dat
@@ -1,5 +1,8 @@
+moon::cat /var/log/daemon.log::received USE_TRANSPORT_MODE notify::YES
moon::ipsec status::host-host.*INSTALLED.*TRANSPORT::YES
sun::ipsec status::host-host.*INSTALLED.*TRANSPORT::YES
+moon::ip xfrm state::mode transport::YES
+sun::ip xfrm state::mode transport::YES
moon::ping -c 1 PH_IP_SUN::64 bytes from PH_IP_SUN: icmp_seq=1::YES
sun::tcpdump::IP moon.strongswan.org > sun.strongswan.org: ESP::YES
sun::tcpdump::IP sun.strongswan.org > moon.strongswan.org: ESP::YES
diff --git a/testing/tests/ikev2/host2host-transport/hosts/moon/etc/ipsec.conf b/testing/tests/ikev2/host2host-transport/hosts/moon/etc/ipsec.conf
index b80aa80c4..7f6c5a58a 100755
--- a/testing/tests/ikev2/host2host-transport/hosts/moon/etc/ipsec.conf
+++ b/testing/tests/ikev2/host2host-transport/hosts/moon/etc/ipsec.conf
@@ -10,6 +10,7 @@ conn %default
keylife=20m
rekeymargin=3m
keyingtries=1
+ mobike=no
keyexchange=ikev2
conn host-host
diff --git a/testing/tests/ikev2/host2host-transport/hosts/sun/etc/ipsec.conf b/testing/tests/ikev2/host2host-transport/hosts/sun/etc/ipsec.conf
index dd1811083..af52fb22b 100755
--- a/testing/tests/ikev2/host2host-transport/hosts/sun/etc/ipsec.conf
+++ b/testing/tests/ikev2/host2host-transport/hosts/sun/etc/ipsec.conf
@@ -10,6 +10,7 @@ conn %default
keylife=20m
rekeymargin=3m
keyingtries=1
+ mobike=no
keyexchange=ikev2
conn host-host
diff --git a/testing/tests/ikev2/reauth-early/description.txt b/testing/tests/ikev2/reauth-early/description.txt
new file mode 100644
index 000000000..130d08d28
--- /dev/null
+++ b/testing/tests/ikev2/reauth-early/description.txt
@@ -0,0 +1,7 @@
+This scenario tests <b>repeated authentication</b> according to RFC 4478.
+The iniator <b>carol</b> sets a large <b>ikelifetime=20m</b> but the responder
+<b>moon</b> defining a much shorter <b>ikelifetime=30s</b> proposes this
+value via an AUTH_LIFETIME notification to the initiator. Thus the
+IKE reauthentication takes places after less than 30s. A ping from
+<b>carol</b> to client <b>alice</b> hiding in the subnet behind <b>moon</b>
+tests if the CHILD_SA has been inherited by the new IKE_SA.
diff --git a/testing/tests/ikev2/reauth-early/evaltest.dat b/testing/tests/ikev2/reauth-early/evaltest.dat
new file mode 100644
index 000000000..b4cbe2f41
--- /dev/null
+++ b/testing/tests/ikev2/reauth-early/evaltest.dat
@@ -0,0 +1,6 @@
+moon::ipsec statusall::rw\[2\].*ESTABLISHED::YES
+carol::ipsec statusall::home\[2\].*ESTABLISHED::YES
+carol::cat /var/log/daemon.log::received AUTH_LIFETIME of 30s, scheduling reauthentication in 25s::YES
+carol::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_seq=1::YES
+moon::tcpdump::IP carol.strongswan.org > moon.strongswan.org: ESP::YES
+moon::tcpdump::IP moon.strongswan.org > carol.strongswan.org: ESP::YES
diff --git a/testing/tests/ikev2/reauth-early/hosts/carol/etc/ipsec.conf b/testing/tests/ikev2/reauth-early/hosts/carol/etc/ipsec.conf
new file mode 100755
index 000000000..311dc3dc5
--- /dev/null
+++ b/testing/tests/ikev2/reauth-early/hosts/carol/etc/ipsec.conf
@@ -0,0 +1,23 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ crlcheckinterval=180
+ strictcrlpolicy=no
+ plutostart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=5s
+ keyingtries=1
+
+conn home
+ left=PH_IP_CAROL
+ leftcert=carolCert.pem
+ leftid=carol@strongswan.org
+ leftfirewall=yes
+ right=PH_IP_MOON
+ rightid=@moon.strongswan.org
+ rightsubnet=10.1.0.0/16
+ keyexchange=ikev2
+ auto=add
diff --git a/testing/tests/ikev2/reauth-early/hosts/moon/etc/ipsec.conf b/testing/tests/ikev2/reauth-early/hosts/moon/etc/ipsec.conf
new file mode 100755
index 000000000..64a7aef6d
--- /dev/null
+++ b/testing/tests/ikev2/reauth-early/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,22 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ crlcheckinterval=180
+ strictcrlpolicy=no
+ plutostart=no
+
+conn %default
+ ikelifetime=30s
+ keylife=20m
+ rekeymargin=0s
+ keyingtries=1
+
+conn rw
+ left=PH_IP_MOON
+ leftcert=moonCert.pem
+ leftid=@moon.strongswan.org
+ leftsubnet=10.1.0.0/16
+ leftfirewall=yes
+ right=%any
+ keyexchange=ikev2
+ auto=add
diff --git a/testing/tests/ikev2/reauth-early/posttest.dat b/testing/tests/ikev2/reauth-early/posttest.dat
new file mode 100644
index 000000000..94a400606
--- /dev/null
+++ b/testing/tests/ikev2/reauth-early/posttest.dat
@@ -0,0 +1,4 @@
+moon::ipsec stop
+carol::ipsec stop
+moon::/etc/init.d/iptables stop 2> /dev/null
+carol::/etc/init.d/iptables stop 2> /dev/null
diff --git a/testing/tests/ikev2/reauth-early/pretest.dat b/testing/tests/ikev2/reauth-early/pretest.dat
new file mode 100644
index 000000000..7ed2423be
--- /dev/null
+++ b/testing/tests/ikev2/reauth-early/pretest.dat
@@ -0,0 +1,7 @@
+moon::/etc/init.d/iptables start 2> /dev/null
+carol::/etc/init.d/iptables start 2> /dev/null
+moon::ipsec start
+carol::ipsec start
+carol::sleep 1
+carol::ipsec up home
+carol::sleep 30
diff --git a/testing/tests/ikev2/reauth-early/test.conf b/testing/tests/ikev2/reauth-early/test.conf
new file mode 100644
index 000000000..9cd583b16
--- /dev/null
+++ b/testing/tests/ikev2/reauth-early/test.conf
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# UML instances used for this test
+
+# All UML instances that are required for this test
+#
+UMLHOSTS="alice moon carol winnetou"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-c-w.png"
+
+# UML instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="moon"
+
+# UML instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon carol"
diff --git a/testing/tests/ikev2/reauth-late/description.txt b/testing/tests/ikev2/reauth-late/description.txt
new file mode 100644
index 000000000..e4f05e1d4
--- /dev/null
+++ b/testing/tests/ikev2/reauth-late/description.txt
@@ -0,0 +1,8 @@
+This scenario tests <b>repeated authentication</b> according to RFC 4478.
+The iniator <b>carol</b> sets a short <b>ikelifetime=20m</b> but the responder
+<b>moon</b> defining a much larger <b>ikelifetime=30s</b> proposes this
+value via an AUTH_LIFETIME notification to the initiator. The initatior
+ignores this notification and schedules the IKE reauthentication within
+the shorter interval of 30s. A ping from <b>carol</b> to client <b>alice</b>
+hiding in the subnet behind <b>moon</b> tests if the CHILD_SA has been
+inherited by the new IKE_SA.
diff --git a/testing/tests/ikev2/reauth-late/evaltest.dat b/testing/tests/ikev2/reauth-late/evaltest.dat
new file mode 100644
index 000000000..7ce2bf147
--- /dev/null
+++ b/testing/tests/ikev2/reauth-late/evaltest.dat
@@ -0,0 +1,7 @@
+moon::ipsec statusall::rw\[2\].*ESTABLISHED::YES
+carol::ipsec statusall::home\[2\].*ESTABLISHED::YES
+carol::cat /var/log/daemon.log::received AUTH_LIFETIME of 3600s, scheduling reauthentication in 3595s::YES
+carol::cat /var/log/daemon.log::scheduling reauthentication in 2[0-5]s::YES
+carol::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_seq=1::YES
+moon::tcpdump::IP carol.strongswan.org > moon.strongswan.org: ESP::YES
+moon::tcpdump::IP moon.strongswan.org > carol.strongswan.org: ESP::YES
diff --git a/testing/tests/ikev2/reauth-late/hosts/carol/etc/ipsec.conf b/testing/tests/ikev2/reauth-late/hosts/carol/etc/ipsec.conf
new file mode 100755
index 000000000..32a43efac
--- /dev/null
+++ b/testing/tests/ikev2/reauth-late/hosts/carol/etc/ipsec.conf
@@ -0,0 +1,23 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ crlcheckinterval=180
+ strictcrlpolicy=no
+ plutostart=no
+
+conn %default
+ ikelifetime=30s
+ keylife=20m
+ rekeymargin=5s
+ keyingtries=1
+
+conn home
+ left=PH_IP_CAROL
+ leftcert=carolCert.pem
+ leftid=carol@strongswan.org
+ leftfirewall=yes
+ right=PH_IP_MOON
+ rightid=@moon.strongswan.org
+ rightsubnet=10.1.0.0/16
+ keyexchange=ikev2
+ auto=add
diff --git a/testing/tests/ikev2/reauth-late/hosts/moon/etc/ipsec.conf b/testing/tests/ikev2/reauth-late/hosts/moon/etc/ipsec.conf
new file mode 100755
index 000000000..bdd186a04
--- /dev/null
+++ b/testing/tests/ikev2/reauth-late/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,22 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ crlcheckinterval=180
+ strictcrlpolicy=no
+ plutostart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=0s
+ keyingtries=1
+
+conn rw
+ left=PH_IP_MOON
+ leftcert=moonCert.pem
+ leftid=@moon.strongswan.org
+ leftsubnet=10.1.0.0/16
+ leftfirewall=yes
+ right=%any
+ keyexchange=ikev2
+ auto=add
diff --git a/testing/tests/ikev2/reauth-late/posttest.dat b/testing/tests/ikev2/reauth-late/posttest.dat
new file mode 100644
index 000000000..94a400606
--- /dev/null
+++ b/testing/tests/ikev2/reauth-late/posttest.dat
@@ -0,0 +1,4 @@
+moon::ipsec stop
+carol::ipsec stop
+moon::/etc/init.d/iptables stop 2> /dev/null
+carol::/etc/init.d/iptables stop 2> /dev/null
diff --git a/testing/tests/ikev2/reauth-late/pretest.dat b/testing/tests/ikev2/reauth-late/pretest.dat
new file mode 100644
index 000000000..7ed2423be
--- /dev/null
+++ b/testing/tests/ikev2/reauth-late/pretest.dat
@@ -0,0 +1,7 @@
+moon::/etc/init.d/iptables start 2> /dev/null
+carol::/etc/init.d/iptables start 2> /dev/null
+moon::ipsec start
+carol::ipsec start
+carol::sleep 1
+carol::ipsec up home
+carol::sleep 30
diff --git a/testing/tests/ikev2/reauth-late/test.conf b/testing/tests/ikev2/reauth-late/test.conf
new file mode 100644
index 000000000..9cd583b16
--- /dev/null
+++ b/testing/tests/ikev2/reauth-late/test.conf
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# UML instances used for this test
+
+# All UML instances that are required for this test
+#
+UMLHOSTS="alice moon carol winnetou"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-c-w.png"
+
+# UML instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="moon"
+
+# UML instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon carol"
diff --git a/testing/tests/ikev2/rw-eap-aka-rsa/description.txt b/testing/tests/ikev2/rw-eap-aka-rsa/description.txt
new file mode 100644
index 000000000..b4f766d6f
--- /dev/null
+++ b/testing/tests/ikev2/rw-eap-aka-rsa/description.txt
@@ -0,0 +1,7 @@
+The roadwarrior <b>carol</b> sets up a connection to gateway <b>moon</b>.
+<b>carol</b> uses the <i>Extensible Authentication Protocol</i>
+in association with the <i>Authentication and Key Agreement</i> protocol
+(<b>EAP-AKA</b>) to authenticate against the gateway. This protocol is used
+in UMTS, but here a secret from <b>ipsec.secrets</b> is used instead of a USIM/(R)UIM.
+Gateway <b>moon</b> additionaly uses an <b>RSA signature</b> to authenticate itself
+against <b>carol</b>.
diff --git a/testing/tests/ikev2/rw-eap-aka-rsa/evaltest.dat b/testing/tests/ikev2/rw-eap-aka-rsa/evaltest.dat
new file mode 100644
index 000000000..5de841c03
--- /dev/null
+++ b/testing/tests/ikev2/rw-eap-aka-rsa/evaltest.dat
@@ -0,0 +1,10 @@
+carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with EAP successful::YES
+moon::cat /var/log/daemon.log::authentication of 'carol@strongswan.org' with EAP successful::YES
+moon::ipsec statusall::rw-eapaka.*ESTABLISHED::YES
+carol::ipsec statusall::home.*ESTABLISHED::YES
+carol::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_seq=1::YES
+moon::tcpdump::IP carol.strongswan.org > moon.strongswan.org: ESP::YES
+moon::tcpdump::IP moon.strongswan.org > carol.strongswan.org: ESP::YES
+
+
diff --git a/testing/tests/ikev2/rw-eap-aka-rsa/hosts/carol/etc/ipsec.conf b/testing/tests/ikev2/rw-eap-aka-rsa/hosts/carol/etc/ipsec.conf
new file mode 100755
index 000000000..c2fe02639
--- /dev/null
+++ b/testing/tests/ikev2/rw-eap-aka-rsa/hosts/carol/etc/ipsec.conf
@@ -0,0 +1,23 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutostart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ keyexchange=ikev2
+ authby=eap
+
+conn home
+ left=PH_IP_CAROL
+ leftnexthop=%direct
+ leftid=carol@strongswan.org
+ leftfirewall=yes
+ right=PH_IP_MOON
+ rightid=@moon.strongswan.org
+ rightsubnet=10.1.0.0/16
+ rightsendcert=never
+ auto=add
diff --git a/testing/tests/ikev2/rw-eap-aka-rsa/hosts/carol/etc/ipsec.secrets b/testing/tests/ikev2/rw-eap-aka-rsa/hosts/carol/etc/ipsec.secrets
new file mode 100644
index 000000000..e03e89a0f
--- /dev/null
+++ b/testing/tests/ikev2/rw-eap-aka-rsa/hosts/carol/etc/ipsec.secrets
@@ -0,0 +1,3 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+carol@strongswan.org : EAP "Ar3etTnp01qlpOgb"
diff --git a/testing/tests/ikev2/rw-eap-aka-rsa/hosts/moon/etc/ipsec.conf b/testing/tests/ikev2/rw-eap-aka-rsa/hosts/moon/etc/ipsec.conf
new file mode 100755
index 000000000..dbf38160f
--- /dev/null
+++ b/testing/tests/ikev2/rw-eap-aka-rsa/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,24 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ strictcrlpolicy=no
+ plutostart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ keyexchange=ikev2
+
+conn rw-eapaka
+ authby=rsasig
+ eap=aka
+ left=PH_IP_MOON
+ leftsubnet=10.1.0.0/16
+ leftid=@moon.strongswan.org
+ leftcert=moonCert.pem
+ leftfirewall=yes
+ rightid=*@strongswan.org
+ right=%any
+ auto=add
diff --git a/testing/tests/ikev2/rw-eap-aka-rsa/hosts/moon/etc/ipsec.secrets b/testing/tests/ikev2/rw-eap-aka-rsa/hosts/moon/etc/ipsec.secrets
new file mode 100644
index 000000000..aa3838385
--- /dev/null
+++ b/testing/tests/ikev2/rw-eap-aka-rsa/hosts/moon/etc/ipsec.secrets
@@ -0,0 +1,5 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: RSA moonKey.pem
+
+carol@strongswan.org : EAP "Ar3etTnp01qlpOgb"
diff --git a/testing/tests/ikev2/rw-eap-aka-rsa/posttest.dat b/testing/tests/ikev2/rw-eap-aka-rsa/posttest.dat
new file mode 100644
index 000000000..94a400606
--- /dev/null
+++ b/testing/tests/ikev2/rw-eap-aka-rsa/posttest.dat
@@ -0,0 +1,4 @@
+moon::ipsec stop
+carol::ipsec stop
+moon::/etc/init.d/iptables stop 2> /dev/null
+carol::/etc/init.d/iptables stop 2> /dev/null
diff --git a/testing/tests/ikev2/rw-eap-aka-rsa/pretest.dat b/testing/tests/ikev2/rw-eap-aka-rsa/pretest.dat
new file mode 100644
index 000000000..ed5498bfe
--- /dev/null
+++ b/testing/tests/ikev2/rw-eap-aka-rsa/pretest.dat
@@ -0,0 +1,7 @@
+moon::/etc/init.d/iptables start 2> /dev/null
+carol::/etc/init.d/iptables start 2> /dev/null
+moon::ipsec start
+carol::ipsec start
+carol::sleep 1
+carol::ipsec up home
+carol::sleep 1
diff --git a/testing/tests/ikev2/rw-eap-aka-rsa/test.conf b/testing/tests/ikev2/rw-eap-aka-rsa/test.conf
new file mode 100644
index 000000000..2bd21499b
--- /dev/null
+++ b/testing/tests/ikev2/rw-eap-aka-rsa/test.conf
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# UML instances used for this test
+
+# All UML instances that are required for this test
+#
+UMLHOSTS="alice carol moon"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-c.png"
+
+# UML instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="moon"
+
+# UML instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon carol"
diff --git a/testing/tests/ipv6/host2host-ikev1/description.txt b/testing/tests/ipv6/host2host-ikev1/description.txt
index c59b32acb..b52c4caf8 100644
--- a/testing/tests/ipv6/host2host-ikev1/description.txt
+++ b/testing/tests/ipv6/host2host-ikev1/description.txt
@@ -1,3 +1,5 @@
An IPv6 ESP connection between the hosts <b>moon</b> and <b>sun</b> is successfully set up.
-The authentication is based on X.509 certificates. In order to test the host-to-host tunnel
-<b>moon</b> sends an IPv6 ICMP request to <b>sun</b> using the ping6 command.
+The authentication is based on X.509 certificates. Upon the successful establishment of
+the IPsec tunnel, <b>leftfirewall=yes</b> automatically inserts ip6tables-based firewall
+rules that let pass the tunneled traffic. In order to test both the host-to-host tunnel
+and the firewall rules, <b>moon</b> sends an IPv6 ICMP request to <b>sun</b> using the ping6 command.
diff --git a/testing/tests/ipv6/host2host-ikev1/hosts/moon/etc/init.d/iptables b/testing/tests/ipv6/host2host-ikev1/hosts/moon/etc/init.d/iptables
new file mode 100755
index 000000000..521d1ce31
--- /dev/null
+++ b/testing/tests/ipv6/host2host-ikev1/hosts/moon/etc/init.d/iptables
@@ -0,0 +1,100 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # enable IP forwarding
+ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ /sbin/ip6tables -P INPUT DROP
+ /sbin/ip6tables -P OUTPUT DROP
+ /sbin/ip6tables -P FORWARD DROP
+
+ # allow esp
+ ip6tables -A INPUT -i eth0 -p 50 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow MobIKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 4500 --sport 4500 -j ACCEPT
+
+ # allow ICMPv6 neighbor-solicitations
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+
+ # allow ICMPv6 neighbor-advertisements
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/ip6tables -t filter -P INPUT ACCEPT
+ /sbin/ip6tables -t filter -P FORWARD ACCEPT
+ /sbin/ip6tables -t filter -P OUTPUT ACCEPT
+
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/ipv6/host2host-ikev1/hosts/moon/etc/ipsec.conf b/testing/tests/ipv6/host2host-ikev1/hosts/moon/etc/ipsec.conf
index 9499140c5..2814e881f 100755
--- a/testing/tests/ipv6/host2host-ikev1/hosts/moon/etc/ipsec.conf
+++ b/testing/tests/ipv6/host2host-ikev1/hosts/moon/etc/ipsec.conf
@@ -19,12 +19,9 @@ conn net-net
conn host-host
left=PH_IP6_MOON
- leftnexthop=0::0
leftcert=moonCert.pem
leftid=@moon.strongswan.org
leftfirewall=yes
right=PH_IP6_SUN
- rightnexthop=0::0
rightid=@sun.strongswan.org
auto=add
-
diff --git a/testing/tests/ipv6/host2host-ikev1/hosts/sun/etc/init.d/iptables b/testing/tests/ipv6/host2host-ikev1/hosts/sun/etc/init.d/iptables
new file mode 100755
index 000000000..521d1ce31
--- /dev/null
+++ b/testing/tests/ipv6/host2host-ikev1/hosts/sun/etc/init.d/iptables
@@ -0,0 +1,100 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # enable IP forwarding
+ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ /sbin/ip6tables -P INPUT DROP
+ /sbin/ip6tables -P OUTPUT DROP
+ /sbin/ip6tables -P FORWARD DROP
+
+ # allow esp
+ ip6tables -A INPUT -i eth0 -p 50 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow MobIKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 4500 --sport 4500 -j ACCEPT
+
+ # allow ICMPv6 neighbor-solicitations
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+
+ # allow ICMPv6 neighbor-advertisements
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/ip6tables -t filter -P INPUT ACCEPT
+ /sbin/ip6tables -t filter -P FORWARD ACCEPT
+ /sbin/ip6tables -t filter -P OUTPUT ACCEPT
+
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/ipv6/host2host-ikev1/hosts/sun/etc/ipsec.conf b/testing/tests/ipv6/host2host-ikev1/hosts/sun/etc/ipsec.conf
index c64904a6e..4cf027ad5 100755
--- a/testing/tests/ipv6/host2host-ikev1/hosts/sun/etc/ipsec.conf
+++ b/testing/tests/ipv6/host2host-ikev1/hosts/sun/etc/ipsec.conf
@@ -19,11 +19,9 @@ conn net-net
conn host-host
left=PH_IP6_SUN
- leftnexthop=0::0
leftcert=sunCert.pem
leftid=@sun.strongswan.org
leftfirewall=yes
right=PH_IP6_MOON
- rightnexthop=0::0
rightid=@moon.strongswan.org
auto=add
diff --git a/testing/tests/ipv6/host2host-ikev1/posttest.dat b/testing/tests/ipv6/host2host-ikev1/posttest.dat
index dff181797..5a9150bc8 100644
--- a/testing/tests/ipv6/host2host-ikev1/posttest.dat
+++ b/testing/tests/ipv6/host2host-ikev1/posttest.dat
@@ -1,2 +1,4 @@
moon::ipsec stop
sun::ipsec stop
+moon::/etc/init.d/iptables stop 2> /dev/null
+sun::/etc/init.d/iptables stop 2> /dev/null
diff --git a/testing/tests/ipv6/host2host-ikev1/pretest.dat b/testing/tests/ipv6/host2host-ikev1/pretest.dat
index 4707af077..3536fd886 100644
--- a/testing/tests/ipv6/host2host-ikev1/pretest.dat
+++ b/testing/tests/ipv6/host2host-ikev1/pretest.dat
@@ -1,3 +1,5 @@
+moon::/etc/init.d/iptables start 2> /dev/null
+sun::/etc/init.d/iptables start 2> /dev/null
moon::ipsec start
sun::ipsec start
moon::sleep 2
diff --git a/testing/tests/ipv6/host2host-ikev1/test.conf b/testing/tests/ipv6/host2host-ikev1/test.conf
index cf2e704fd..6ab5b8a96 100644
--- a/testing/tests/ipv6/host2host-ikev1/test.conf
+++ b/testing/tests/ipv6/host2host-ikev1/test.conf
@@ -9,7 +9,7 @@ UMLHOSTS="moon winnetou sun"
# Corresponding block diagram
#
-DIAGRAM="m-w-s.png"
+DIAGRAM="m-w-s-ip6.png"
# UML instances on which tcpdump is to be started
#
diff --git a/testing/tests/ipv6/host2host-ikev2/description.txt b/testing/tests/ipv6/host2host-ikev2/description.txt
index c59b32acb..b52c4caf8 100644
--- a/testing/tests/ipv6/host2host-ikev2/description.txt
+++ b/testing/tests/ipv6/host2host-ikev2/description.txt
@@ -1,3 +1,5 @@
An IPv6 ESP connection between the hosts <b>moon</b> and <b>sun</b> is successfully set up.
-The authentication is based on X.509 certificates. In order to test the host-to-host tunnel
-<b>moon</b> sends an IPv6 ICMP request to <b>sun</b> using the ping6 command.
+The authentication is based on X.509 certificates. Upon the successful establishment of
+the IPsec tunnel, <b>leftfirewall=yes</b> automatically inserts ip6tables-based firewall
+rules that let pass the tunneled traffic. In order to test both the host-to-host tunnel
+and the firewall rules, <b>moon</b> sends an IPv6 ICMP request to <b>sun</b> using the ping6 command.
diff --git a/testing/tests/ipv6/host2host-ikev2/hosts/moon/etc/init.d/iptables b/testing/tests/ipv6/host2host-ikev2/hosts/moon/etc/init.d/iptables
new file mode 100755
index 000000000..25074a0f1
--- /dev/null
+++ b/testing/tests/ipv6/host2host-ikev2/hosts/moon/etc/init.d/iptables
@@ -0,0 +1,107 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # enable IP forwarding
+ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ /sbin/ip6tables -P INPUT DROP
+ /sbin/ip6tables -P OUTPUT DROP
+ /sbin/ip6tables -P FORWARD DROP
+
+ # allow esp
+ ip6tables -A INPUT -i eth0 -p 50 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow MobIKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 4500 --sport 4500 -j ACCEPT
+
+ # allow last UDP fragment
+ ip6tables -A INPUT -i eth0 -p udp -m frag --fraglast -j ACCEPT
+
+ # allow ICMPv6 neighbor-solicitations
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+
+ # allow ICMPv6 neighbor-advertisements
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ # log dropped packets
+ ip6tables -A INPUT -j LOG --log-prefix " IN: "
+ ip6tables -A OUTPUT -j LOG --log-prefix " OUT: "
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/ip6tables -t filter -P INPUT ACCEPT
+ /sbin/ip6tables -t filter -P FORWARD ACCEPT
+ /sbin/ip6tables -t filter -P OUTPUT ACCEPT
+
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/ipv6/host2host-ikev2/hosts/moon/etc/ipsec.conf b/testing/tests/ipv6/host2host-ikev2/hosts/moon/etc/ipsec.conf
index 44c85068e..ccc8037b5 100755
--- a/testing/tests/ipv6/host2host-ikev2/hosts/moon/etc/ipsec.conf
+++ b/testing/tests/ipv6/host2host-ikev2/hosts/moon/etc/ipsec.conf
@@ -2,6 +2,7 @@
config setup
strictcrlpolicy=no
+ crlcheckinterval=180
plutostart=no
conn %default
@@ -18,12 +19,10 @@ conn net-net
conn host-host
left=PH_IP6_MOON
- leftnexthop=0::0
leftcert=moonCert.pem
leftid=@moon.strongswan.org
leftfirewall=yes
right=PH_IP6_SUN
- rightnexthop=0::0
rightid=@sun.strongswan.org
auto=add
diff --git a/testing/tests/ipv6/host2host-ikev2/hosts/sun/etc/init.d/iptables b/testing/tests/ipv6/host2host-ikev2/hosts/sun/etc/init.d/iptables
new file mode 100755
index 000000000..25074a0f1
--- /dev/null
+++ b/testing/tests/ipv6/host2host-ikev2/hosts/sun/etc/init.d/iptables
@@ -0,0 +1,107 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # enable IP forwarding
+ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ /sbin/ip6tables -P INPUT DROP
+ /sbin/ip6tables -P OUTPUT DROP
+ /sbin/ip6tables -P FORWARD DROP
+
+ # allow esp
+ ip6tables -A INPUT -i eth0 -p 50 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow MobIKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 4500 --sport 4500 -j ACCEPT
+
+ # allow last UDP fragment
+ ip6tables -A INPUT -i eth0 -p udp -m frag --fraglast -j ACCEPT
+
+ # allow ICMPv6 neighbor-solicitations
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+
+ # allow ICMPv6 neighbor-advertisements
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ # log dropped packets
+ ip6tables -A INPUT -j LOG --log-prefix " IN: "
+ ip6tables -A OUTPUT -j LOG --log-prefix " OUT: "
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/ip6tables -t filter -P INPUT ACCEPT
+ /sbin/ip6tables -t filter -P FORWARD ACCEPT
+ /sbin/ip6tables -t filter -P OUTPUT ACCEPT
+
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/ipv6/host2host-ikev2/hosts/sun/etc/ipsec.conf b/testing/tests/ipv6/host2host-ikev2/hosts/sun/etc/ipsec.conf
index 8b3858b30..1ec8b49d6 100755
--- a/testing/tests/ipv6/host2host-ikev2/hosts/sun/etc/ipsec.conf
+++ b/testing/tests/ipv6/host2host-ikev2/hosts/sun/etc/ipsec.conf
@@ -2,6 +2,7 @@
config setup
strictcrlpolicy=no
+ crlcheckinterval=180
plutostart=no
conn %default
@@ -18,11 +19,9 @@ conn net-net
conn host-host
left=PH_IP6_SUN
- leftnexthop=0::0
leftcert=sunCert.pem
leftid=@sun.strongswan.org
leftfirewall=yes
right=PH_IP6_MOON
- rightnexthop=0::0
rightid=@moon.strongswan.org
auto=add
diff --git a/testing/tests/ipv6/host2host-ikev2/posttest.dat b/testing/tests/ipv6/host2host-ikev2/posttest.dat
index dff181797..5a9150bc8 100644
--- a/testing/tests/ipv6/host2host-ikev2/posttest.dat
+++ b/testing/tests/ipv6/host2host-ikev2/posttest.dat
@@ -1,2 +1,4 @@
moon::ipsec stop
sun::ipsec stop
+moon::/etc/init.d/iptables stop 2> /dev/null
+sun::/etc/init.d/iptables stop 2> /dev/null
diff --git a/testing/tests/ipv6/host2host-ikev2/pretest.dat b/testing/tests/ipv6/host2host-ikev2/pretest.dat
index 4707af077..3536fd886 100644
--- a/testing/tests/ipv6/host2host-ikev2/pretest.dat
+++ b/testing/tests/ipv6/host2host-ikev2/pretest.dat
@@ -1,3 +1,5 @@
+moon::/etc/init.d/iptables start 2> /dev/null
+sun::/etc/init.d/iptables start 2> /dev/null
moon::ipsec start
sun::ipsec start
moon::sleep 2
diff --git a/testing/tests/ipv6/host2host-ikev2/test.conf b/testing/tests/ipv6/host2host-ikev2/test.conf
index cf2e704fd..6ab5b8a96 100644
--- a/testing/tests/ipv6/host2host-ikev2/test.conf
+++ b/testing/tests/ipv6/host2host-ikev2/test.conf
@@ -9,7 +9,7 @@ UMLHOSTS="moon winnetou sun"
# Corresponding block diagram
#
-DIAGRAM="m-w-s.png"
+DIAGRAM="m-w-s-ip6.png"
# UML instances on which tcpdump is to be started
#
diff --git a/testing/tests/ipv6/net2net-ikev1/description.txt b/testing/tests/ipv6/net2net-ikev1/description.txt
new file mode 100644
index 000000000..5952ecc2d
--- /dev/null
+++ b/testing/tests/ipv6/net2net-ikev1/description.txt
@@ -0,0 +1,6 @@
+An IPv6 ESP tunnel connection between the gateways <b>moon</b> and <b>sun</b> is successfully set up.
+It connects the two subnets hiding behind their respective gateways. The authentication is based on
+X.509 certificates. Upon the successful establishment of the IPsec tunnel, <b>leftfirewall=yes</b>
+automatically inserts ip6tables-based firewall rules that let pass the tunneled traffic.
+In order to test both the net-to-net tunnel and the firewall rules, client <b>alice</b> behind <b>moon</b>
+sends an IPv6 ICMP request to client <b>bob</b> behind <b>sun</b> using the ping6 command.
diff --git a/testing/tests/ipv6/net2net-ikev1/evaltest.dat b/testing/tests/ipv6/net2net-ikev1/evaltest.dat
new file mode 100644
index 000000000..459b0a630
--- /dev/null
+++ b/testing/tests/ipv6/net2net-ikev1/evaltest.dat
@@ -0,0 +1,5 @@
+moon::ipsec status::net-net.*STATE_QUICK_I2.*IPsec SA established::YES
+sun::ipsec status::net-net.*STATE_QUICK_R2.*IPsec SA established::YES
+alice::ping6 -c 1 -p deadbeef ip6-bob.strongswan.org::64 bytes from ip6-bob.strongswan.org: icmp_seq=1::YES
+sun::tcpdump::IP6 ip6-moon.strongswan.org > ip6-sun.strongswan.org: ESP::YES
+sun::tcpdump::IP6 ip6-sun.strongswan.org > ip6-moon.strongswan.org: ESP::YES
diff --git a/testing/tests/ipv6/net2net-ikev1/hosts/moon/etc/init.d/iptables b/testing/tests/ipv6/net2net-ikev1/hosts/moon/etc/init.d/iptables
new file mode 100755
index 000000000..521d1ce31
--- /dev/null
+++ b/testing/tests/ipv6/net2net-ikev1/hosts/moon/etc/init.d/iptables
@@ -0,0 +1,100 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # enable IP forwarding
+ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ /sbin/ip6tables -P INPUT DROP
+ /sbin/ip6tables -P OUTPUT DROP
+ /sbin/ip6tables -P FORWARD DROP
+
+ # allow esp
+ ip6tables -A INPUT -i eth0 -p 50 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow MobIKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 4500 --sport 4500 -j ACCEPT
+
+ # allow ICMPv6 neighbor-solicitations
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+
+ # allow ICMPv6 neighbor-advertisements
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/ip6tables -t filter -P INPUT ACCEPT
+ /sbin/ip6tables -t filter -P FORWARD ACCEPT
+ /sbin/ip6tables -t filter -P OUTPUT ACCEPT
+
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/ipv6/net2net-ikev1/hosts/moon/etc/ipsec.conf b/testing/tests/ipv6/net2net-ikev1/hosts/moon/etc/ipsec.conf
new file mode 100755
index 000000000..84abbb07a
--- /dev/null
+++ b/testing/tests/ipv6/net2net-ikev1/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,28 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutodebug=control
+ crlcheckinterval=180
+ strictcrlpolicy=no
+ charonstart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+
+conn net-net
+ also=host-host
+ leftsubnet=fec1::0/16
+ rightsubnet=fec2::0/16
+
+conn host-host
+ left=PH_IP6_MOON
+ leftcert=moonCert.pem
+ leftid=@moon.strongswan.org
+ leftfirewall=yes
+ right=PH_IP6_SUN
+ rightid=@sun.strongswan.org
+ auto=add
+
diff --git a/testing/tests/ipv6/net2net-ikev1/hosts/sun/etc/init.d/iptables b/testing/tests/ipv6/net2net-ikev1/hosts/sun/etc/init.d/iptables
new file mode 100755
index 000000000..521d1ce31
--- /dev/null
+++ b/testing/tests/ipv6/net2net-ikev1/hosts/sun/etc/init.d/iptables
@@ -0,0 +1,100 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # enable IP forwarding
+ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ /sbin/ip6tables -P INPUT DROP
+ /sbin/ip6tables -P OUTPUT DROP
+ /sbin/ip6tables -P FORWARD DROP
+
+ # allow esp
+ ip6tables -A INPUT -i eth0 -p 50 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow MobIKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 4500 --sport 4500 -j ACCEPT
+
+ # allow ICMPv6 neighbor-solicitations
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+
+ # allow ICMPv6 neighbor-advertisements
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/ip6tables -t filter -P INPUT ACCEPT
+ /sbin/ip6tables -t filter -P FORWARD ACCEPT
+ /sbin/ip6tables -t filter -P OUTPUT ACCEPT
+
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/ipv6/net2net-ikev1/hosts/sun/etc/ipsec.conf b/testing/tests/ipv6/net2net-ikev1/hosts/sun/etc/ipsec.conf
new file mode 100755
index 000000000..4cf027ad5
--- /dev/null
+++ b/testing/tests/ipv6/net2net-ikev1/hosts/sun/etc/ipsec.conf
@@ -0,0 +1,27 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutodebug=control
+ crlcheckinterval=180
+ strictcrlpolicy=no
+ charonstart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+
+conn net-net
+ also=host-host
+ leftsubnet=fec2::0/16
+ rightsubnet=fec1::0/16
+
+conn host-host
+ left=PH_IP6_SUN
+ leftcert=sunCert.pem
+ leftid=@sun.strongswan.org
+ leftfirewall=yes
+ right=PH_IP6_MOON
+ rightid=@moon.strongswan.org
+ auto=add
diff --git a/testing/tests/ipv6/net2net-ikev1/posttest.dat b/testing/tests/ipv6/net2net-ikev1/posttest.dat
new file mode 100644
index 000000000..4c95e2afe
--- /dev/null
+++ b/testing/tests/ipv6/net2net-ikev1/posttest.dat
@@ -0,0 +1,8 @@
+moon::ipsec stop
+sun::ipsec stop
+alice::"ip route del fec2:\:/16 via fec1:\:1"
+moon::"ip route del fec2:\:/16 via fec0:\:2"
+sun::"ip route del fec1:\:/16 via fec0:\:1"
+bob::"ip route del fec1:\:/16 via fec2:\:1"
+moon::/etc/init.d/iptables stop 2> /dev/null
+sun::/etc/init.d/iptables stop 2> /dev/null
diff --git a/testing/tests/ipv6/net2net-ikev1/pretest.dat b/testing/tests/ipv6/net2net-ikev1/pretest.dat
new file mode 100644
index 000000000..e360bfbaa
--- /dev/null
+++ b/testing/tests/ipv6/net2net-ikev1/pretest.dat
@@ -0,0 +1,10 @@
+moon::/etc/init.d/iptables start 2> /dev/null
+sun::/etc/init.d/iptables start 2> /dev/null
+alice::"ip route add fec2:\:/16 via fec1:\:1"
+moon::"ip route add fec2:\:/16 via fec0:\:2"
+sun::"ip route add fec1:\:/16 via fec0:\:1"
+bob::"ip route add fec1:\:/16 via fec2:\:1"
+moon::ipsec start
+sun::ipsec start
+moon::sleep 2
+moon::ipsec up net-net
diff --git a/testing/tests/ipv6/net2net-ikev1/test.conf b/testing/tests/ipv6/net2net-ikev1/test.conf
new file mode 100644
index 000000000..991d884db
--- /dev/null
+++ b/testing/tests/ipv6/net2net-ikev1/test.conf
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# UML instances used for this test
+
+# All UML instances that are required for this test
+#
+UMLHOSTS="alice moon winnetou sun bob"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-w-s-b-ip6.png"
+
+# UML instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="sun"
+
+# UML instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon sun"
diff --git a/testing/tests/ipv6/net2net-ikev2/description.txt b/testing/tests/ipv6/net2net-ikev2/description.txt
new file mode 100644
index 000000000..5952ecc2d
--- /dev/null
+++ b/testing/tests/ipv6/net2net-ikev2/description.txt
@@ -0,0 +1,6 @@
+An IPv6 ESP tunnel connection between the gateways <b>moon</b> and <b>sun</b> is successfully set up.
+It connects the two subnets hiding behind their respective gateways. The authentication is based on
+X.509 certificates. Upon the successful establishment of the IPsec tunnel, <b>leftfirewall=yes</b>
+automatically inserts ip6tables-based firewall rules that let pass the tunneled traffic.
+In order to test both the net-to-net tunnel and the firewall rules, client <b>alice</b> behind <b>moon</b>
+sends an IPv6 ICMP request to client <b>bob</b> behind <b>sun</b> using the ping6 command.
diff --git a/testing/tests/ipv6/net2net-ikev2/evaltest.dat b/testing/tests/ipv6/net2net-ikev2/evaltest.dat
new file mode 100644
index 000000000..1b4e7c88a
--- /dev/null
+++ b/testing/tests/ipv6/net2net-ikev2/evaltest.dat
@@ -0,0 +1,5 @@
+moon::ipsec status::net-net.*INSTALLED::YES
+sun::ipsec status::net.net.*INSTALLED::YES
+alice::ping6 -c 1 -p deadbeef ip6-bob.strongswan.org::64 bytes from ip6-bob.strongswan.org: icmp_seq=1::YES
+sun::tcpdump::IP6 ip6-moon.strongswan.org > ip6-sun.strongswan.org: ESP::YES
+sun::tcpdump::IP6 ip6-sun.strongswan.org > ip6-moon.strongswan.org: ESP::YES
diff --git a/testing/tests/ipv6/net2net-ikev2/hosts/moon/etc/init.d/iptables b/testing/tests/ipv6/net2net-ikev2/hosts/moon/etc/init.d/iptables
new file mode 100755
index 000000000..25074a0f1
--- /dev/null
+++ b/testing/tests/ipv6/net2net-ikev2/hosts/moon/etc/init.d/iptables
@@ -0,0 +1,107 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # enable IP forwarding
+ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ /sbin/ip6tables -P INPUT DROP
+ /sbin/ip6tables -P OUTPUT DROP
+ /sbin/ip6tables -P FORWARD DROP
+
+ # allow esp
+ ip6tables -A INPUT -i eth0 -p 50 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow MobIKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 4500 --sport 4500 -j ACCEPT
+
+ # allow last UDP fragment
+ ip6tables -A INPUT -i eth0 -p udp -m frag --fraglast -j ACCEPT
+
+ # allow ICMPv6 neighbor-solicitations
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+
+ # allow ICMPv6 neighbor-advertisements
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ # log dropped packets
+ ip6tables -A INPUT -j LOG --log-prefix " IN: "
+ ip6tables -A OUTPUT -j LOG --log-prefix " OUT: "
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/ip6tables -t filter -P INPUT ACCEPT
+ /sbin/ip6tables -t filter -P FORWARD ACCEPT
+ /sbin/ip6tables -t filter -P OUTPUT ACCEPT
+
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/ipv6/net2net-ikev2/hosts/moon/etc/ipsec.conf b/testing/tests/ipv6/net2net-ikev2/hosts/moon/etc/ipsec.conf
new file mode 100755
index 000000000..651e17e90
--- /dev/null
+++ b/testing/tests/ipv6/net2net-ikev2/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,28 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ strictcrlpolicy=no
+ crlcheckinterval=180
+ plutostart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ keyexchange=ikev2
+ mobike=no
+
+conn net-net
+ also=host-host
+ leftsubnet=fec1::0/16
+ rightsubnet=fec2::0/16
+
+conn host-host
+ left=PH_IP6_MOON
+ leftcert=moonCert.pem
+ leftid=@moon.strongswan.org
+ leftfirewall=yes
+ right=PH_IP6_SUN
+ rightid=@sun.strongswan.org
+ auto=add
diff --git a/testing/tests/ipv6/net2net-ikev2/hosts/sun/etc/init.d/iptables b/testing/tests/ipv6/net2net-ikev2/hosts/sun/etc/init.d/iptables
new file mode 100755
index 000000000..25074a0f1
--- /dev/null
+++ b/testing/tests/ipv6/net2net-ikev2/hosts/sun/etc/init.d/iptables
@@ -0,0 +1,107 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # enable IP forwarding
+ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ /sbin/ip6tables -P INPUT DROP
+ /sbin/ip6tables -P OUTPUT DROP
+ /sbin/ip6tables -P FORWARD DROP
+
+ # allow esp
+ ip6tables -A INPUT -i eth0 -p 50 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow MobIKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 4500 --sport 4500 -j ACCEPT
+
+ # allow last UDP fragment
+ ip6tables -A INPUT -i eth0 -p udp -m frag --fraglast -j ACCEPT
+
+ # allow ICMPv6 neighbor-solicitations
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+
+ # allow ICMPv6 neighbor-advertisements
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ # log dropped packets
+ ip6tables -A INPUT -j LOG --log-prefix " IN: "
+ ip6tables -A OUTPUT -j LOG --log-prefix " OUT: "
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/ip6tables -t filter -P INPUT ACCEPT
+ /sbin/ip6tables -t filter -P FORWARD ACCEPT
+ /sbin/ip6tables -t filter -P OUTPUT ACCEPT
+
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/ipv6/net2net-ikev2/hosts/sun/etc/ipsec.conf b/testing/tests/ipv6/net2net-ikev2/hosts/sun/etc/ipsec.conf
new file mode 100755
index 000000000..4ba0bcbc0
--- /dev/null
+++ b/testing/tests/ipv6/net2net-ikev2/hosts/sun/etc/ipsec.conf
@@ -0,0 +1,28 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ strictcrlpolicy=no
+ crlcheckinterval=180
+ plutostart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ keyexchange=ikev2
+ mobike=no
+
+conn net-net
+ also=host-host
+ leftsubnet=fec2::0/16
+ rightsubnet=fec1::0/16
+
+conn host-host
+ left=PH_IP6_SUN
+ leftcert=sunCert.pem
+ leftid=@sun.strongswan.org
+ leftfirewall=yes
+ right=PH_IP6_MOON
+ rightid=@moon.strongswan.org
+ auto=add
diff --git a/testing/tests/ipv6/net2net-ikev2/posttest.dat b/testing/tests/ipv6/net2net-ikev2/posttest.dat
new file mode 100644
index 000000000..4c95e2afe
--- /dev/null
+++ b/testing/tests/ipv6/net2net-ikev2/posttest.dat
@@ -0,0 +1,8 @@
+moon::ipsec stop
+sun::ipsec stop
+alice::"ip route del fec2:\:/16 via fec1:\:1"
+moon::"ip route del fec2:\:/16 via fec0:\:2"
+sun::"ip route del fec1:\:/16 via fec0:\:1"
+bob::"ip route del fec1:\:/16 via fec2:\:1"
+moon::/etc/init.d/iptables stop 2> /dev/null
+sun::/etc/init.d/iptables stop 2> /dev/null
diff --git a/testing/tests/ipv6/net2net-ikev2/pretest.dat b/testing/tests/ipv6/net2net-ikev2/pretest.dat
new file mode 100644
index 000000000..e360bfbaa
--- /dev/null
+++ b/testing/tests/ipv6/net2net-ikev2/pretest.dat
@@ -0,0 +1,10 @@
+moon::/etc/init.d/iptables start 2> /dev/null
+sun::/etc/init.d/iptables start 2> /dev/null
+alice::"ip route add fec2:\:/16 via fec1:\:1"
+moon::"ip route add fec2:\:/16 via fec0:\:2"
+sun::"ip route add fec1:\:/16 via fec0:\:1"
+bob::"ip route add fec1:\:/16 via fec2:\:1"
+moon::ipsec start
+sun::ipsec start
+moon::sleep 2
+moon::ipsec up net-net
diff --git a/testing/tests/ipv6/net2net-ikev2/test.conf b/testing/tests/ipv6/net2net-ikev2/test.conf
new file mode 100644
index 000000000..991d884db
--- /dev/null
+++ b/testing/tests/ipv6/net2net-ikev2/test.conf
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# UML instances used for this test
+
+# All UML instances that are required for this test
+#
+UMLHOSTS="alice moon winnetou sun bob"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-w-s-b-ip6.png"
+
+# UML instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="sun"
+
+# UML instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon sun"
diff --git a/testing/tests/ipv6/rw-ikev1/description.txt b/testing/tests/ipv6/rw-ikev1/description.txt
new file mode 100644
index 000000000..046c4b50c
--- /dev/null
+++ b/testing/tests/ipv6/rw-ikev1/description.txt
@@ -0,0 +1,7 @@
+The roadwarrior <b>carol</b> sets up a connection to gateway <b>moon</b>.
+The authentication is based on <b>X.509 certificates</b>. Upon the successful
+establishment of the IPsec tunnel, <b>leftfirewall=yes</b> automatically inserts
+ip6tables-based firewall rules that let pass the tunneled traffic.
+In order to test both the IPv6 ESP tunnel and the firewall rules, <b>carol</b>
+sends an IPv6 ICMP request to the client <b>alice</b> behind the gateway <b>moon</b>
+using the ping6 command.
diff --git a/testing/tests/ipv6/rw-ikev1/evaltest.dat b/testing/tests/ipv6/rw-ikev1/evaltest.dat
new file mode 100644
index 000000000..894e9118e
--- /dev/null
+++ b/testing/tests/ipv6/rw-ikev1/evaltest.dat
@@ -0,0 +1,5 @@
+carol::ipsec status::home.*STATE_QUICK_I2.*IPsec SA established::YES
+moon::ipsec status::rw.*STATE_QUICK_R2.*IPsec SA established::YES
+carol::ping6 -c 1 ip6-alice.strongswan.org::64 bytes from ip6-alice.strongswan.org: icmp_seq=1::YES
+moon::tcpdump::IP6 ip6-carol.strongswan.org > ip6-moon.strongswan.org: ESP::YES
+moon::tcpdump::IP6 ip6-moon.strongswan.org > ip6-carol.strongswan.org: ESP::YES
diff --git a/testing/tests/ipv6/rw-ikev1/hosts/carol/etc/init.d/iptables b/testing/tests/ipv6/rw-ikev1/hosts/carol/etc/init.d/iptables
new file mode 100755
index 000000000..521d1ce31
--- /dev/null
+++ b/testing/tests/ipv6/rw-ikev1/hosts/carol/etc/init.d/iptables
@@ -0,0 +1,100 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # enable IP forwarding
+ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ /sbin/ip6tables -P INPUT DROP
+ /sbin/ip6tables -P OUTPUT DROP
+ /sbin/ip6tables -P FORWARD DROP
+
+ # allow esp
+ ip6tables -A INPUT -i eth0 -p 50 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow MobIKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 4500 --sport 4500 -j ACCEPT
+
+ # allow ICMPv6 neighbor-solicitations
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+
+ # allow ICMPv6 neighbor-advertisements
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/ip6tables -t filter -P INPUT ACCEPT
+ /sbin/ip6tables -t filter -P FORWARD ACCEPT
+ /sbin/ip6tables -t filter -P OUTPUT ACCEPT
+
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/ipv6/rw-ikev1/hosts/carol/etc/ipsec.conf b/testing/tests/ipv6/rw-ikev1/hosts/carol/etc/ipsec.conf
new file mode 100755
index 000000000..b27609917
--- /dev/null
+++ b/testing/tests/ipv6/rw-ikev1/hosts/carol/etc/ipsec.conf
@@ -0,0 +1,27 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutodebug=control
+ crlcheckinterval=180
+ strictcrlpolicy=no
+ charonstart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+
+conn home
+ left=PH_IP6_CAROL
+ leftcert=carolCert.pem
+ leftid=carol@strongswan.org
+ leftfirewall=yes
+ right=PH_IP6_MOON
+ rightsubnet=fec1::/16
+ rightid=@moon.strongswan.org
+ auto=add
+
+
+
+
diff --git a/testing/tests/ipv6/rw-ikev1/hosts/moon/etc/init.d/iptables b/testing/tests/ipv6/rw-ikev1/hosts/moon/etc/init.d/iptables
new file mode 100755
index 000000000..521d1ce31
--- /dev/null
+++ b/testing/tests/ipv6/rw-ikev1/hosts/moon/etc/init.d/iptables
@@ -0,0 +1,100 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # enable IP forwarding
+ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ /sbin/ip6tables -P INPUT DROP
+ /sbin/ip6tables -P OUTPUT DROP
+ /sbin/ip6tables -P FORWARD DROP
+
+ # allow esp
+ ip6tables -A INPUT -i eth0 -p 50 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow MobIKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 4500 --sport 4500 -j ACCEPT
+
+ # allow ICMPv6 neighbor-solicitations
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+
+ # allow ICMPv6 neighbor-advertisements
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/ip6tables -t filter -P INPUT ACCEPT
+ /sbin/ip6tables -t filter -P FORWARD ACCEPT
+ /sbin/ip6tables -t filter -P OUTPUT ACCEPT
+
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/ipv6/rw-ikev1/hosts/moon/etc/ipsec.conf b/testing/tests/ipv6/rw-ikev1/hosts/moon/etc/ipsec.conf
new file mode 100755
index 000000000..0129ef744
--- /dev/null
+++ b/testing/tests/ipv6/rw-ikev1/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,22 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutodebug=control
+ crlcheckinterval=180
+ strictcrlpolicy=no
+ charonstart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+
+conn rw
+ left=PH_IP6_MOON
+ leftcert=moonCert.pem
+ leftid=@moon.strongswan.org
+ leftsubnet=fec1::/16
+ leftfirewall=yes
+ right=%any6
+ auto=add
diff --git a/testing/tests/ipv6/rw-ikev1/posttest.dat b/testing/tests/ipv6/rw-ikev1/posttest.dat
new file mode 100644
index 000000000..d37b96f9c
--- /dev/null
+++ b/testing/tests/ipv6/rw-ikev1/posttest.dat
@@ -0,0 +1,6 @@
+moon::ipsec stop
+carol::ipsec stop
+alice::"ip route del fec0:\:/16 via fec1:\:1"
+carol::"ip route del fec1:\:/16 via fec0:\:1"
+moon::/etc/init.d/iptables stop 2> /dev/null
+carol::/etc/init.d/iptables stop 2> /dev/null
diff --git a/testing/tests/ipv6/rw-ikev1/pretest.dat b/testing/tests/ipv6/rw-ikev1/pretest.dat
new file mode 100644
index 000000000..2b3bf90a7
--- /dev/null
+++ b/testing/tests/ipv6/rw-ikev1/pretest.dat
@@ -0,0 +1,8 @@
+moon::/etc/init.d/iptables start 2> /dev/null
+carol::/etc/init.d/iptables start 2> /dev/null
+alice::"ip route add fec0:\:/16 via fec1:\:1"
+carol::"ip route add fec1:\:/16 via fec0:\:1"
+carol::ipsec start
+moon::ipsec start
+carol::sleep 2
+carol::ipsec up home
diff --git a/testing/tests/ipv6/rw-ikev1/test.conf b/testing/tests/ipv6/rw-ikev1/test.conf
new file mode 100644
index 000000000..bce9814db
--- /dev/null
+++ b/testing/tests/ipv6/rw-ikev1/test.conf
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# UML instances used for this test
+
+# All UML instances that are required for this test
+#
+UMLHOSTS="alice moon carol winnetou"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-c-w-ip6.png"
+
+# UML instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="moon"
+
+# UML instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon carol"
diff --git a/testing/tests/ipv6/rw-ikev2/description.txt b/testing/tests/ipv6/rw-ikev2/description.txt
new file mode 100644
index 000000000..17461370e
--- /dev/null
+++ b/testing/tests/ipv6/rw-ikev2/description.txt
@@ -0,0 +1,7 @@
+The roadwarriors <b>carol</b> and <b>dave</b> set up an IPv6 connection each
+to gateway <b>moon</b>. The authentication is based on <b>X.509 certificates</b>.
+Upon the successful establishment of the IPv6 ESP tunnels, <b>leftfirewall=yes</b>
+automatically inserts ip6tables-based firewall rules that let pass the tunneled traffic.
+In order to test both tunnel and firewall, both <b>carol</b> and <b>dave</b> send
+an IPv6 ICMP request to the client <b>alice</b> behind the gateway <b>moon</b>
+using the ping6 command.
diff --git a/testing/tests/ipv6/rw-ikev2/evaltest.dat b/testing/tests/ipv6/rw-ikev2/evaltest.dat
new file mode 100644
index 000000000..cee1853c4
--- /dev/null
+++ b/testing/tests/ipv6/rw-ikev2/evaltest.dat
@@ -0,0 +1,10 @@
+moon::ipsec statusall::rw.*ESTABLISHED::YES
+carol::ipsec statusall::home.*ESTABLISHED::YES
+dave::ipsec statusall::home.*ESTABLISHED::YES
+carol::ping6 -c 1 ip6-alice.strongswan.org::64 bytes from ip6-alice.strongswan.org: icmp_seq=1::YES
+dave::ping6 -c 1 ip6-alice.strongswan.org::64 bytes from ip6-alice.strongswan.org: icmp_seq=1::YES
+moon::tcpdump::IP6 ip6-carol.strongswan.org > ip6-moon.strongswan.org: ESP::YES
+moon::tcpdump::IP6 ip6-moon.strongswan.org > ip6-carol.strongswan.org: ESP::YES
+moon::tcpdump::IP6 ip6-dave.strongswan.org > ip6-moon.strongswan.org: ESP::YES
+moon::tcpdump::IP6 ip6-moon.strongswan.org > ip6-dave.strongswan.org: ESP::YES
+
diff --git a/testing/tests/ipv6/rw-ikev2/hosts/carol/etc/init.d/iptables b/testing/tests/ipv6/rw-ikev2/hosts/carol/etc/init.d/iptables
new file mode 100755
index 000000000..25074a0f1
--- /dev/null
+++ b/testing/tests/ipv6/rw-ikev2/hosts/carol/etc/init.d/iptables
@@ -0,0 +1,107 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # enable IP forwarding
+ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ /sbin/ip6tables -P INPUT DROP
+ /sbin/ip6tables -P OUTPUT DROP
+ /sbin/ip6tables -P FORWARD DROP
+
+ # allow esp
+ ip6tables -A INPUT -i eth0 -p 50 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow MobIKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 4500 --sport 4500 -j ACCEPT
+
+ # allow last UDP fragment
+ ip6tables -A INPUT -i eth0 -p udp -m frag --fraglast -j ACCEPT
+
+ # allow ICMPv6 neighbor-solicitations
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+
+ # allow ICMPv6 neighbor-advertisements
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ # log dropped packets
+ ip6tables -A INPUT -j LOG --log-prefix " IN: "
+ ip6tables -A OUTPUT -j LOG --log-prefix " OUT: "
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/ip6tables -t filter -P INPUT ACCEPT
+ /sbin/ip6tables -t filter -P FORWARD ACCEPT
+ /sbin/ip6tables -t filter -P OUTPUT ACCEPT
+
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/ipv6/rw-ikev2/hosts/carol/etc/ipsec.conf b/testing/tests/ipv6/rw-ikev2/hosts/carol/etc/ipsec.conf
new file mode 100755
index 000000000..92388586a
--- /dev/null
+++ b/testing/tests/ipv6/rw-ikev2/hosts/carol/etc/ipsec.conf
@@ -0,0 +1,23 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ crlcheckinterval=180
+ strictcrlpolicy=no
+ plutostart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+
+conn home
+ left=PH_IP6_CAROL
+ leftcert=carolCert.pem
+ leftid=carol@strongswan.org
+ leftfirewall=yes
+ right=PH_IP6_MOON
+ rightid=@moon.strongswan.org
+ rightsubnet=fec1::/16
+ keyexchange=ikev2
+ auto=add
diff --git a/testing/tests/ipv6/rw-ikev2/hosts/dave/etc/init.d/iptables b/testing/tests/ipv6/rw-ikev2/hosts/dave/etc/init.d/iptables
new file mode 100755
index 000000000..25074a0f1
--- /dev/null
+++ b/testing/tests/ipv6/rw-ikev2/hosts/dave/etc/init.d/iptables
@@ -0,0 +1,107 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # enable IP forwarding
+ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ /sbin/ip6tables -P INPUT DROP
+ /sbin/ip6tables -P OUTPUT DROP
+ /sbin/ip6tables -P FORWARD DROP
+
+ # allow esp
+ ip6tables -A INPUT -i eth0 -p 50 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow MobIKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 4500 --sport 4500 -j ACCEPT
+
+ # allow last UDP fragment
+ ip6tables -A INPUT -i eth0 -p udp -m frag --fraglast -j ACCEPT
+
+ # allow ICMPv6 neighbor-solicitations
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+
+ # allow ICMPv6 neighbor-advertisements
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ # log dropped packets
+ ip6tables -A INPUT -j LOG --log-prefix " IN: "
+ ip6tables -A OUTPUT -j LOG --log-prefix " OUT: "
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/ip6tables -t filter -P INPUT ACCEPT
+ /sbin/ip6tables -t filter -P FORWARD ACCEPT
+ /sbin/ip6tables -t filter -P OUTPUT ACCEPT
+
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/ipv6/rw-ikev2/hosts/dave/etc/ipsec.conf b/testing/tests/ipv6/rw-ikev2/hosts/dave/etc/ipsec.conf
new file mode 100755
index 000000000..ed1eb39ca
--- /dev/null
+++ b/testing/tests/ipv6/rw-ikev2/hosts/dave/etc/ipsec.conf
@@ -0,0 +1,23 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ crlcheckinterval=180
+ strictcrlpolicy=no
+ plutostart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+
+conn home
+ left=PH_IP6_DAVE
+ leftcert=daveCert.pem
+ leftid=dave@strongswan.org
+ leftfirewall=yes
+ right=PH_IP6_MOON
+ rightid=@moon.strongswan.org
+ rightsubnet=fec1::/16
+ keyexchange=ikev2
+ auto=add
diff --git a/testing/tests/ipv6/rw-ikev2/hosts/moon/etc/init.d/iptables b/testing/tests/ipv6/rw-ikev2/hosts/moon/etc/init.d/iptables
new file mode 100755
index 000000000..25074a0f1
--- /dev/null
+++ b/testing/tests/ipv6/rw-ikev2/hosts/moon/etc/init.d/iptables
@@ -0,0 +1,107 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # enable IP forwarding
+ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ /sbin/ip6tables -P INPUT DROP
+ /sbin/ip6tables -P OUTPUT DROP
+ /sbin/ip6tables -P FORWARD DROP
+
+ # allow esp
+ ip6tables -A INPUT -i eth0 -p 50 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow MobIKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 4500 --sport 4500 -j ACCEPT
+
+ # allow last UDP fragment
+ ip6tables -A INPUT -i eth0 -p udp -m frag --fraglast -j ACCEPT
+
+ # allow ICMPv6 neighbor-solicitations
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+
+ # allow ICMPv6 neighbor-advertisements
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ # log dropped packets
+ ip6tables -A INPUT -j LOG --log-prefix " IN: "
+ ip6tables -A OUTPUT -j LOG --log-prefix " OUT: "
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/ip6tables -t filter -P INPUT ACCEPT
+ /sbin/ip6tables -t filter -P FORWARD ACCEPT
+ /sbin/ip6tables -t filter -P OUTPUT ACCEPT
+
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/ipv6/rw-ikev2/hosts/moon/etc/ipsec.conf b/testing/tests/ipv6/rw-ikev2/hosts/moon/etc/ipsec.conf
new file mode 100755
index 000000000..f78ba45e0
--- /dev/null
+++ b/testing/tests/ipv6/rw-ikev2/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,22 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ crlcheckinterval=180
+ strictcrlpolicy=no
+ plutostart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+
+conn rw
+ left=PH_IP6_MOON
+ leftcert=moonCert.pem
+ leftid=@moon.strongswan.org
+ leftsubnet=fec1::/16
+ leftfirewall=yes
+ right=%any
+ keyexchange=ikev2
+ auto=add
diff --git a/testing/tests/ipv6/rw-ikev2/posttest.dat b/testing/tests/ipv6/rw-ikev2/posttest.dat
new file mode 100644
index 000000000..07e89d7da
--- /dev/null
+++ b/testing/tests/ipv6/rw-ikev2/posttest.dat
@@ -0,0 +1,9 @@
+moon::ipsec stop
+carol::ipsec stop
+dave::ipsec stop
+moon::/etc/init.d/iptables stop 2> /dev/null
+carol::/etc/init.d/iptables stop 2> /dev/null
+dave::/etc/init.d/iptables stop 2> /dev/null
+alice::"ip route del fec0:\:/16 via fec1:\:1"
+carol::"ip route del fec1:\:/16 via fec0:\:1"
+dave::"ip route del fec1:\:/16 via fec0:\:1"
diff --git a/testing/tests/ipv6/rw-ikev2/pretest.dat b/testing/tests/ipv6/rw-ikev2/pretest.dat
new file mode 100644
index 000000000..dea60a040
--- /dev/null
+++ b/testing/tests/ipv6/rw-ikev2/pretest.dat
@@ -0,0 +1,12 @@
+moon::/etc/init.d/iptables start 2> /dev/null
+carol::/etc/init.d/iptables start 2> /dev/null
+dave::/etc/init.d/iptables start 2> /dev/null
+alice::"ip route add fec0:\:/16 via fec1:\:1"
+carol::"ip route add fec1:\:/16 via fec0:\:1"
+dave::"ip route add fec1:\:/16 via fec0:\:1"
+moon::ipsec start
+carol::ipsec start
+dave::ipsec start
+carol::sleep 1
+carol::ipsec up home
+dave::ipsec up home
diff --git a/testing/tests/ipv6/rw-ikev2/test.conf b/testing/tests/ipv6/rw-ikev2/test.conf
new file mode 100644
index 000000000..80cf5e3a1
--- /dev/null
+++ b/testing/tests/ipv6/rw-ikev2/test.conf
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# UML instances used for this test
+
+# All UML instances that are required for this test
+#
+UMLHOSTS="alice moon carol winnetou dave"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-c-w-d-ip6.png"
+
+# UML instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="moon"
+
+# UML instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon carol dave"
diff --git a/testing/tests/ipv6/rw-psk-ikev1/description.txt b/testing/tests/ipv6/rw-psk-ikev1/description.txt
new file mode 100644
index 000000000..81072ebf6
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev1/description.txt
@@ -0,0 +1,5 @@
+The roadwarrior <b>carol</b> sets up an IPv6 tunnel connection to gateway <b>moon</b>.
+The authentication is based on <b>Preshared Keys</b> (PSK) and <b>IPv6 addresses</b> (ID_IPV6_ADDR).
+<b>firewall=yes</b> automatically inserts ip6tables-based firewall rules that let pass
+the tunneled traffic. In order to test the tunnel <b>carol</b> sends an IPv6
+ICMP request to client <b>alice</b> behind the gateway <b>moon</b> using the ping6 command.
diff --git a/testing/tests/ipv6/rw-psk-ikev1/evaltest.dat b/testing/tests/ipv6/rw-psk-ikev1/evaltest.dat
new file mode 100644
index 000000000..4046d0bbc
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev1/evaltest.dat
@@ -0,0 +1,5 @@
+carol::ipsec status::home.*STATE_QUICK_I2.*IPsec SA established::YES
+moon::ipsec status::rw.*STATE_QUICK_R2.*IPsec SA established::YES
+carol::ping6 -c 1 ip6-alice.strongswan.org::64 bytes from ip6-alice.strongswan.org: icmp_seq=1::YES
+moon::tcpdump::IP6 ip6-carol.strongswan.org > ip6-moon.strongswan.org: ESP::YES
+moon::tcpdump::IP6 ip6-moon.strongswan.org > ip6-carol.strongswan.org: ESP::YES
diff --git a/testing/tests/ipv6/rw-psk-ikev1/hosts/carol/etc/init.d/iptables b/testing/tests/ipv6/rw-psk-ikev1/hosts/carol/etc/init.d/iptables
new file mode 100755
index 000000000..521d1ce31
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev1/hosts/carol/etc/init.d/iptables
@@ -0,0 +1,100 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # enable IP forwarding
+ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ /sbin/ip6tables -P INPUT DROP
+ /sbin/ip6tables -P OUTPUT DROP
+ /sbin/ip6tables -P FORWARD DROP
+
+ # allow esp
+ ip6tables -A INPUT -i eth0 -p 50 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow MobIKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 4500 --sport 4500 -j ACCEPT
+
+ # allow ICMPv6 neighbor-solicitations
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+
+ # allow ICMPv6 neighbor-advertisements
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/ip6tables -t filter -P INPUT ACCEPT
+ /sbin/ip6tables -t filter -P FORWARD ACCEPT
+ /sbin/ip6tables -t filter -P OUTPUT ACCEPT
+
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/ipv6/rw-psk-ikev1/hosts/carol/etc/ipsec.conf b/testing/tests/ipv6/rw-psk-ikev1/hosts/carol/etc/ipsec.conf
new file mode 100755
index 000000000..5d77c2dd5
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev1/hosts/carol/etc/ipsec.conf
@@ -0,0 +1,19 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutodebug=control
+ charonstart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ authby=secret
+
+conn home
+ left=PH_IP6_CAROL
+ leftfirewall=yes
+ right=PH_IP6_MOON
+ rightsubnet=fec1::/16
+ auto=add
diff --git a/testing/tests/ipv6/rw-psk-ikev1/hosts/carol/etc/ipsec.secrets b/testing/tests/ipv6/rw-psk-ikev1/hosts/carol/etc/ipsec.secrets
new file mode 100644
index 000000000..42c84fc49
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev1/hosts/carol/etc/ipsec.secrets
@@ -0,0 +1,3 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+PH_IP6_CAROL PH_IP6_MOON : PSK 0sv+NkxY9LLZvwj4qCC2o/gGrWDF2d21jL
diff --git a/testing/tests/ipv6/rw-psk-ikev1/hosts/moon/etc/init.d/iptables b/testing/tests/ipv6/rw-psk-ikev1/hosts/moon/etc/init.d/iptables
new file mode 100755
index 000000000..521d1ce31
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev1/hosts/moon/etc/init.d/iptables
@@ -0,0 +1,100 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # enable IP forwarding
+ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ /sbin/ip6tables -P INPUT DROP
+ /sbin/ip6tables -P OUTPUT DROP
+ /sbin/ip6tables -P FORWARD DROP
+
+ # allow esp
+ ip6tables -A INPUT -i eth0 -p 50 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow MobIKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 4500 --sport 4500 -j ACCEPT
+
+ # allow ICMPv6 neighbor-solicitations
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+
+ # allow ICMPv6 neighbor-advertisements
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/ip6tables -t filter -P INPUT ACCEPT
+ /sbin/ip6tables -t filter -P FORWARD ACCEPT
+ /sbin/ip6tables -t filter -P OUTPUT ACCEPT
+
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/ipv6/rw-psk-ikev1/hosts/moon/etc/ipsec.conf b/testing/tests/ipv6/rw-psk-ikev1/hosts/moon/etc/ipsec.conf
new file mode 100755
index 000000000..78f674026
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev1/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,19 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutodebug=control
+ charonstart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ authby=secret
+
+conn rw
+ left=PH_IP6_MOON
+ leftsubnet=fec1::/16
+ leftfirewall=yes
+ right=%any6
+ auto=add
diff --git a/testing/tests/ipv6/rw-psk-ikev1/hosts/moon/etc/ipsec.secrets b/testing/tests/ipv6/rw-psk-ikev1/hosts/moon/etc/ipsec.secrets
new file mode 100644
index 000000000..ac738c1aa
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev1/hosts/moon/etc/ipsec.secrets
@@ -0,0 +1,3 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+PH_IP6_MOON %any6 : PSK 0sv+NkxY9LLZvwj4qCC2o/gGrWDF2d21jL
diff --git a/testing/tests/ipv6/rw-psk-ikev1/posttest.dat b/testing/tests/ipv6/rw-psk-ikev1/posttest.dat
new file mode 100644
index 000000000..d37b96f9c
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev1/posttest.dat
@@ -0,0 +1,6 @@
+moon::ipsec stop
+carol::ipsec stop
+alice::"ip route del fec0:\:/16 via fec1:\:1"
+carol::"ip route del fec1:\:/16 via fec0:\:1"
+moon::/etc/init.d/iptables stop 2> /dev/null
+carol::/etc/init.d/iptables stop 2> /dev/null
diff --git a/testing/tests/ipv6/rw-psk-ikev1/pretest.dat b/testing/tests/ipv6/rw-psk-ikev1/pretest.dat
new file mode 100644
index 000000000..6fbbccaae
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev1/pretest.dat
@@ -0,0 +1,10 @@
+moon::/etc/init.d/iptables start 2> /dev/null
+carol::/etc/init.d/iptables start 2> /dev/null
+alice::"ip route add fec0:\:/16 via fec1:\:1"
+carol::"ip route add fec1:\:/16 via fec0:\:1"
+moon::rm /etc/ipsec.d/cacerts/*
+carol::rm /etc/ipsec.d/cacerts/*
+carol::ipsec start
+moon::ipsec start
+carol::sleep 2
+carol::ipsec up home
diff --git a/testing/tests/ipv6/rw-psk-ikev1/test.conf b/testing/tests/ipv6/rw-psk-ikev1/test.conf
new file mode 100644
index 000000000..bce9814db
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev1/test.conf
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# UML instances used for this test
+
+# All UML instances that are required for this test
+#
+UMLHOSTS="alice moon carol winnetou"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-c-w-ip6.png"
+
+# UML instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="moon"
+
+# UML instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon carol"
diff --git a/testing/tests/ipv6/rw-psk-ikev2/description.txt b/testing/tests/ipv6/rw-psk-ikev2/description.txt
new file mode 100644
index 000000000..66fc09053
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev2/description.txt
@@ -0,0 +1,7 @@
+The roadwarriors <b>carol</b> and <b>dave</b> set up an IPv6 tunnel connection each
+to gateway <b>moon</b>. The authentication is based on distinct <b>pre-shared keys</b>
+and IPv6 addresses. Upon the successful establishment of the IPsec tunnels,
+<b>leftfirewall=yes</b> automatically inserts ip6tables-based firewall rules that
+let pass the tunneled traffic. In order to test both tunnel and firewall, both
+<b>carol</b> and <b>dave</b> send an IPv6 ICMP request to client <b>alice</b>
+behind the gateway <b>moon</b> using the ping6 command.
diff --git a/testing/tests/ipv6/rw-psk-ikev2/evaltest.dat b/testing/tests/ipv6/rw-psk-ikev2/evaltest.dat
new file mode 100644
index 000000000..cee1853c4
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev2/evaltest.dat
@@ -0,0 +1,10 @@
+moon::ipsec statusall::rw.*ESTABLISHED::YES
+carol::ipsec statusall::home.*ESTABLISHED::YES
+dave::ipsec statusall::home.*ESTABLISHED::YES
+carol::ping6 -c 1 ip6-alice.strongswan.org::64 bytes from ip6-alice.strongswan.org: icmp_seq=1::YES
+dave::ping6 -c 1 ip6-alice.strongswan.org::64 bytes from ip6-alice.strongswan.org: icmp_seq=1::YES
+moon::tcpdump::IP6 ip6-carol.strongswan.org > ip6-moon.strongswan.org: ESP::YES
+moon::tcpdump::IP6 ip6-moon.strongswan.org > ip6-carol.strongswan.org: ESP::YES
+moon::tcpdump::IP6 ip6-dave.strongswan.org > ip6-moon.strongswan.org: ESP::YES
+moon::tcpdump::IP6 ip6-moon.strongswan.org > ip6-dave.strongswan.org: ESP::YES
+
diff --git a/testing/tests/ipv6/rw-psk-ikev2/hosts/carol/etc/init.d/iptables b/testing/tests/ipv6/rw-psk-ikev2/hosts/carol/etc/init.d/iptables
new file mode 100755
index 000000000..25074a0f1
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev2/hosts/carol/etc/init.d/iptables
@@ -0,0 +1,107 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # enable IP forwarding
+ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ /sbin/ip6tables -P INPUT DROP
+ /sbin/ip6tables -P OUTPUT DROP
+ /sbin/ip6tables -P FORWARD DROP
+
+ # allow esp
+ ip6tables -A INPUT -i eth0 -p 50 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow MobIKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 4500 --sport 4500 -j ACCEPT
+
+ # allow last UDP fragment
+ ip6tables -A INPUT -i eth0 -p udp -m frag --fraglast -j ACCEPT
+
+ # allow ICMPv6 neighbor-solicitations
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+
+ # allow ICMPv6 neighbor-advertisements
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ # log dropped packets
+ ip6tables -A INPUT -j LOG --log-prefix " IN: "
+ ip6tables -A OUTPUT -j LOG --log-prefix " OUT: "
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/ip6tables -t filter -P INPUT ACCEPT
+ /sbin/ip6tables -t filter -P FORWARD ACCEPT
+ /sbin/ip6tables -t filter -P OUTPUT ACCEPT
+
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/ipv6/rw-psk-ikev2/hosts/carol/etc/ipsec.conf b/testing/tests/ipv6/rw-psk-ikev2/hosts/carol/etc/ipsec.conf
new file mode 100755
index 000000000..b656b9ec7
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev2/hosts/carol/etc/ipsec.conf
@@ -0,0 +1,19 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutostart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ keyexchange=ikev2
+ authby=secret
+
+conn home
+ left=PH_IP6_CAROL
+ leftfirewall=yes
+ right=PH_IP6_MOON
+ rightsubnet=fec1::/16
+ auto=add
diff --git a/testing/tests/ipv6/rw-psk-ikev2/hosts/carol/etc/ipsec.secrets b/testing/tests/ipv6/rw-psk-ikev2/hosts/carol/etc/ipsec.secrets
new file mode 100644
index 000000000..2abcb4e0a
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev2/hosts/carol/etc/ipsec.secrets
@@ -0,0 +1,3 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+PH_IP6_CAROL : PSK 0sFpZAZqEN6Ti9sqt4ZP5EWcqx
diff --git a/testing/tests/ipv6/rw-psk-ikev2/hosts/dave/etc/init.d/iptables b/testing/tests/ipv6/rw-psk-ikev2/hosts/dave/etc/init.d/iptables
new file mode 100755
index 000000000..25074a0f1
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev2/hosts/dave/etc/init.d/iptables
@@ -0,0 +1,107 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # enable IP forwarding
+ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ /sbin/ip6tables -P INPUT DROP
+ /sbin/ip6tables -P OUTPUT DROP
+ /sbin/ip6tables -P FORWARD DROP
+
+ # allow esp
+ ip6tables -A INPUT -i eth0 -p 50 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow MobIKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 4500 --sport 4500 -j ACCEPT
+
+ # allow last UDP fragment
+ ip6tables -A INPUT -i eth0 -p udp -m frag --fraglast -j ACCEPT
+
+ # allow ICMPv6 neighbor-solicitations
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+
+ # allow ICMPv6 neighbor-advertisements
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ # log dropped packets
+ ip6tables -A INPUT -j LOG --log-prefix " IN: "
+ ip6tables -A OUTPUT -j LOG --log-prefix " OUT: "
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/ip6tables -t filter -P INPUT ACCEPT
+ /sbin/ip6tables -t filter -P FORWARD ACCEPT
+ /sbin/ip6tables -t filter -P OUTPUT ACCEPT
+
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/ipv6/rw-psk-ikev2/hosts/dave/etc/ipsec.conf b/testing/tests/ipv6/rw-psk-ikev2/hosts/dave/etc/ipsec.conf
new file mode 100755
index 000000000..c62f4ff07
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev2/hosts/dave/etc/ipsec.conf
@@ -0,0 +1,20 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ strictcrlpolicy=no
+ plutostart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ keyexchange=ikev2
+ authby=secret
+
+conn home
+ left=PH_IP6_DAVE
+ leftfirewall=yes
+ right=PH_IP6_MOON
+ rightsubnet=fec1::/16
+ auto=add
diff --git a/testing/tests/ipv6/rw-psk-ikev2/hosts/dave/etc/ipsec.secrets b/testing/tests/ipv6/rw-psk-ikev2/hosts/dave/etc/ipsec.secrets
new file mode 100644
index 000000000..2375cd559
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev2/hosts/dave/etc/ipsec.secrets
@@ -0,0 +1,3 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+PH_IP6_DAVE : PSK 0sjVzONCF02ncsgiSlmIXeqhGN
diff --git a/testing/tests/ipv6/rw-psk-ikev2/hosts/moon/etc/init.d/iptables b/testing/tests/ipv6/rw-psk-ikev2/hosts/moon/etc/init.d/iptables
new file mode 100755
index 000000000..25074a0f1
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev2/hosts/moon/etc/init.d/iptables
@@ -0,0 +1,107 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # enable IP forwarding
+ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ /sbin/ip6tables -P INPUT DROP
+ /sbin/ip6tables -P OUTPUT DROP
+ /sbin/ip6tables -P FORWARD DROP
+
+ # allow esp
+ ip6tables -A INPUT -i eth0 -p 50 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow MobIKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 4500 --sport 4500 -j ACCEPT
+
+ # allow last UDP fragment
+ ip6tables -A INPUT -i eth0 -p udp -m frag --fraglast -j ACCEPT
+
+ # allow ICMPv6 neighbor-solicitations
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+
+ # allow ICMPv6 neighbor-advertisements
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ # log dropped packets
+ ip6tables -A INPUT -j LOG --log-prefix " IN: "
+ ip6tables -A OUTPUT -j LOG --log-prefix " OUT: "
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/ip6tables -t filter -P INPUT ACCEPT
+ /sbin/ip6tables -t filter -P FORWARD ACCEPT
+ /sbin/ip6tables -t filter -P OUTPUT ACCEPT
+
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/ipv6/rw-psk-ikev2/hosts/moon/etc/ipsec.conf b/testing/tests/ipv6/rw-psk-ikev2/hosts/moon/etc/ipsec.conf
new file mode 100755
index 000000000..0cf988768
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev2/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,19 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutostart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ keyexchange=ikev2
+ authby=secret
+
+conn rw
+ left=PH_IP6_MOON
+ leftsubnet=fec1::/16
+ leftfirewall=yes
+ right=%any
+ auto=add
diff --git a/testing/tests/ipv6/rw-psk-ikev2/hosts/moon/etc/ipsec.secrets b/testing/tests/ipv6/rw-psk-ikev2/hosts/moon/etc/ipsec.secrets
new file mode 100644
index 000000000..88c418353
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev2/hosts/moon/etc/ipsec.secrets
@@ -0,0 +1,5 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+PH_IP6_CAROL : PSK 0sFpZAZqEN6Ti9sqt4ZP5EWcqx
+
+PH_IP6_DAVE : PSK 0sjVzONCF02ncsgiSlmIXeqhGN
diff --git a/testing/tests/ipv6/rw-psk-ikev2/posttest.dat b/testing/tests/ipv6/rw-psk-ikev2/posttest.dat
new file mode 100644
index 000000000..07e89d7da
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev2/posttest.dat
@@ -0,0 +1,9 @@
+moon::ipsec stop
+carol::ipsec stop
+dave::ipsec stop
+moon::/etc/init.d/iptables stop 2> /dev/null
+carol::/etc/init.d/iptables stop 2> /dev/null
+dave::/etc/init.d/iptables stop 2> /dev/null
+alice::"ip route del fec0:\:/16 via fec1:\:1"
+carol::"ip route del fec1:\:/16 via fec0:\:1"
+dave::"ip route del fec1:\:/16 via fec0:\:1"
diff --git a/testing/tests/ipv6/rw-psk-ikev2/pretest.dat b/testing/tests/ipv6/rw-psk-ikev2/pretest.dat
new file mode 100644
index 000000000..07b0ebd7d
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev2/pretest.dat
@@ -0,0 +1,15 @@
+moon::/etc/init.d/iptables start 2> /dev/null
+carol::/etc/init.d/iptables start 2> /dev/null
+dave::/etc/init.d/iptables start 2> /dev/null
+alice::"ip route add fec0:\:/16 via fec1:\:1"
+carol::"ip route add fec1:\:/16 via fec0:\:1"
+dave::"ip route add fec1:\:/16 via fec0:\:1"
+moon::rm /etc/ipsec.d/cacerts/*
+carol::rm /etc/ipsec.d/cacerts/*
+dave::rm /etc/ipsec.d/cacerts/*
+moon::ipsec start
+carol::ipsec start
+dave::ipsec start
+carol::sleep 1
+carol::ipsec up home
+dave::ipsec up home
diff --git a/testing/tests/ipv6/rw-psk-ikev2/test.conf b/testing/tests/ipv6/rw-psk-ikev2/test.conf
new file mode 100644
index 000000000..80cf5e3a1
--- /dev/null
+++ b/testing/tests/ipv6/rw-psk-ikev2/test.conf
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# UML instances used for this test
+
+# All UML instances that are required for this test
+#
+UMLHOSTS="alice moon carol winnetou dave"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-c-w-d-ip6.png"
+
+# UML instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="moon"
+
+# UML instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon carol dave"
diff --git a/testing/tests/ipv6/transport-ikev1/description.txt b/testing/tests/ipv6/transport-ikev1/description.txt
new file mode 100644
index 000000000..2d54790aa
--- /dev/null
+++ b/testing/tests/ipv6/transport-ikev1/description.txt
@@ -0,0 +1,5 @@
+An IPv6 ESP transport connection between the hosts <b>moon</b> and <b>sun</b> is successfully set up.
+The authentication is based on X.509 certificates. Upon the successful establishment of
+the IPsec SA, <b>leftfirewall=yes</b> automatically inserts ip6tables-based firewall
+rules that let pass the protected traffic. In order to test both the transport connection
+and the firewall rules, <b>moon</b> sends an IPv6 ICMP request to <b>sun</b> using the ping6 command.
diff --git a/testing/tests/ipv6/transport-ikev1/evaltest.dat b/testing/tests/ipv6/transport-ikev1/evaltest.dat
new file mode 100644
index 000000000..2010557c1
--- /dev/null
+++ b/testing/tests/ipv6/transport-ikev1/evaltest.dat
@@ -0,0 +1,7 @@
+moon::ipsec status::host-host.*STATE_QUICK_I2.*IPsec SA established::YES
+sun::ipsec status::host-host.*STATE_QUICK_R2.*IPsec SA established::YES
+moon::ip xfrm state::mode transport::YES
+sun::ip xfrm state::mode transport::YES
+moon::ping6 -c 1 -p deadbeef ip6-sun.strongswan.org::64 bytes from ip6-sun.strongswan.org: icmp_seq=1::YES
+sun::tcpdump::IP6 ip6-moon.strongswan.org > ip6-sun.strongswan.org: ESP::YES
+sun::tcpdump::IP6 ip6-sun.strongswan.org > ip6-moon.strongswan.org: ESP::YES
diff --git a/testing/tests/ipv6/transport-ikev1/hosts/moon/etc/init.d/iptables b/testing/tests/ipv6/transport-ikev1/hosts/moon/etc/init.d/iptables
new file mode 100755
index 000000000..521d1ce31
--- /dev/null
+++ b/testing/tests/ipv6/transport-ikev1/hosts/moon/etc/init.d/iptables
@@ -0,0 +1,100 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # enable IP forwarding
+ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ /sbin/ip6tables -P INPUT DROP
+ /sbin/ip6tables -P OUTPUT DROP
+ /sbin/ip6tables -P FORWARD DROP
+
+ # allow esp
+ ip6tables -A INPUT -i eth0 -p 50 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow MobIKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 4500 --sport 4500 -j ACCEPT
+
+ # allow ICMPv6 neighbor-solicitations
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+
+ # allow ICMPv6 neighbor-advertisements
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/ip6tables -t filter -P INPUT ACCEPT
+ /sbin/ip6tables -t filter -P FORWARD ACCEPT
+ /sbin/ip6tables -t filter -P OUTPUT ACCEPT
+
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/ipv6/transport-ikev1/hosts/moon/etc/ipsec.conf b/testing/tests/ipv6/transport-ikev1/hosts/moon/etc/ipsec.conf
new file mode 100755
index 000000000..8bc0deba8
--- /dev/null
+++ b/testing/tests/ipv6/transport-ikev1/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,23 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutodebug=control
+ crlcheckinterval=180
+ strictcrlpolicy=no
+ charonstart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+
+conn host-host
+ left=PH_IP6_MOON
+ leftcert=moonCert.pem
+ leftid=@moon.strongswan.org
+ leftfirewall=yes
+ right=PH_IP6_SUN
+ rightid=@sun.strongswan.org
+ type=transport
+ auto=add
diff --git a/testing/tests/ipv6/transport-ikev1/hosts/sun/etc/init.d/iptables b/testing/tests/ipv6/transport-ikev1/hosts/sun/etc/init.d/iptables
new file mode 100755
index 000000000..521d1ce31
--- /dev/null
+++ b/testing/tests/ipv6/transport-ikev1/hosts/sun/etc/init.d/iptables
@@ -0,0 +1,100 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # enable IP forwarding
+ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ /sbin/ip6tables -P INPUT DROP
+ /sbin/ip6tables -P OUTPUT DROP
+ /sbin/ip6tables -P FORWARD DROP
+
+ # allow esp
+ ip6tables -A INPUT -i eth0 -p 50 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow MobIKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 4500 --sport 4500 -j ACCEPT
+
+ # allow ICMPv6 neighbor-solicitations
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+
+ # allow ICMPv6 neighbor-advertisements
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/ip6tables -t filter -P INPUT ACCEPT
+ /sbin/ip6tables -t filter -P FORWARD ACCEPT
+ /sbin/ip6tables -t filter -P OUTPUT ACCEPT
+
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/ipv6/transport-ikev1/hosts/sun/etc/ipsec.conf b/testing/tests/ipv6/transport-ikev1/hosts/sun/etc/ipsec.conf
new file mode 100755
index 000000000..b68082dd9
--- /dev/null
+++ b/testing/tests/ipv6/transport-ikev1/hosts/sun/etc/ipsec.conf
@@ -0,0 +1,23 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ plutodebug=control
+ crlcheckinterval=180
+ strictcrlpolicy=no
+ charonstart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+
+conn host-host
+ left=PH_IP6_SUN
+ leftcert=sunCert.pem
+ leftid=@sun.strongswan.org
+ leftfirewall=yes
+ right=PH_IP6_MOON
+ rightid=@moon.strongswan.org
+ type=transport
+ auto=add
diff --git a/testing/tests/ipv6/transport-ikev1/posttest.dat b/testing/tests/ipv6/transport-ikev1/posttest.dat
new file mode 100644
index 000000000..5a9150bc8
--- /dev/null
+++ b/testing/tests/ipv6/transport-ikev1/posttest.dat
@@ -0,0 +1,4 @@
+moon::ipsec stop
+sun::ipsec stop
+moon::/etc/init.d/iptables stop 2> /dev/null
+sun::/etc/init.d/iptables stop 2> /dev/null
diff --git a/testing/tests/ipv6/transport-ikev1/pretest.dat b/testing/tests/ipv6/transport-ikev1/pretest.dat
new file mode 100644
index 000000000..3536fd886
--- /dev/null
+++ b/testing/tests/ipv6/transport-ikev1/pretest.dat
@@ -0,0 +1,6 @@
+moon::/etc/init.d/iptables start 2> /dev/null
+sun::/etc/init.d/iptables start 2> /dev/null
+moon::ipsec start
+sun::ipsec start
+moon::sleep 2
+moon::ipsec up host-host
diff --git a/testing/tests/ipv6/transport-ikev1/test.conf b/testing/tests/ipv6/transport-ikev1/test.conf
new file mode 100644
index 000000000..6ab5b8a96
--- /dev/null
+++ b/testing/tests/ipv6/transport-ikev1/test.conf
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# UML instances used for this test
+
+# All UML instances that are required for this test
+#
+UMLHOSTS="moon winnetou sun"
+
+# Corresponding block diagram
+#
+DIAGRAM="m-w-s-ip6.png"
+
+# UML instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="sun"
+
+# UML instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon sun"
diff --git a/testing/tests/ipv6/transport-ikev2/description.txt b/testing/tests/ipv6/transport-ikev2/description.txt
new file mode 100644
index 000000000..2d54790aa
--- /dev/null
+++ b/testing/tests/ipv6/transport-ikev2/description.txt
@@ -0,0 +1,5 @@
+An IPv6 ESP transport connection between the hosts <b>moon</b> and <b>sun</b> is successfully set up.
+The authentication is based on X.509 certificates. Upon the successful establishment of
+the IPsec SA, <b>leftfirewall=yes</b> automatically inserts ip6tables-based firewall
+rules that let pass the protected traffic. In order to test both the transport connection
+and the firewall rules, <b>moon</b> sends an IPv6 ICMP request to <b>sun</b> using the ping6 command.
diff --git a/testing/tests/ipv6/transport-ikev2/evaltest.dat b/testing/tests/ipv6/transport-ikev2/evaltest.dat
new file mode 100644
index 000000000..1ea5bcebe
--- /dev/null
+++ b/testing/tests/ipv6/transport-ikev2/evaltest.dat
@@ -0,0 +1,8 @@
+moon::cat /var/log/daemon.log::received USE_TRANSPORT_MODE notify::YES
+moon::ipsec status::host-host.*INSTALLED.*TRANSPORT::YES
+sun::ipsec status::host-host.*INSTALLED.*TRANSPORT::YES
+moon::ip xfrm state::mode transport::YES
+sun::ip xfrm state::mode transport::YES
+moon::ping6 -c 1 -p deadbeef ip6-sun.strongswan.org::64 bytes from ip6-sun.strongswan.org: icmp_seq=1::YES
+sun::tcpdump::IP6 ip6-moon.strongswan.org > ip6-sun.strongswan.org: ESP::YES
+sun::tcpdump::IP6 ip6-sun.strongswan.org > ip6-moon.strongswan.org: ESP::YES
diff --git a/testing/tests/ipv6/transport-ikev2/hosts/moon/etc/init.d/iptables b/testing/tests/ipv6/transport-ikev2/hosts/moon/etc/init.d/iptables
new file mode 100755
index 000000000..25074a0f1
--- /dev/null
+++ b/testing/tests/ipv6/transport-ikev2/hosts/moon/etc/init.d/iptables
@@ -0,0 +1,107 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # enable IP forwarding
+ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ /sbin/ip6tables -P INPUT DROP
+ /sbin/ip6tables -P OUTPUT DROP
+ /sbin/ip6tables -P FORWARD DROP
+
+ # allow esp
+ ip6tables -A INPUT -i eth0 -p 50 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow MobIKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 4500 --sport 4500 -j ACCEPT
+
+ # allow last UDP fragment
+ ip6tables -A INPUT -i eth0 -p udp -m frag --fraglast -j ACCEPT
+
+ # allow ICMPv6 neighbor-solicitations
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+
+ # allow ICMPv6 neighbor-advertisements
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ # log dropped packets
+ ip6tables -A INPUT -j LOG --log-prefix " IN: "
+ ip6tables -A OUTPUT -j LOG --log-prefix " OUT: "
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/ip6tables -t filter -P INPUT ACCEPT
+ /sbin/ip6tables -t filter -P FORWARD ACCEPT
+ /sbin/ip6tables -t filter -P OUTPUT ACCEPT
+
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/ipv6/transport-ikev2/hosts/moon/etc/ipsec.conf b/testing/tests/ipv6/transport-ikev2/hosts/moon/etc/ipsec.conf
new file mode 100755
index 000000000..7df72bd4f
--- /dev/null
+++ b/testing/tests/ipv6/transport-ikev2/hosts/moon/etc/ipsec.conf
@@ -0,0 +1,24 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ strictcrlpolicy=no
+ crlcheckinterval=180
+ plutostart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ mobike=no
+ keyexchange=ikev2
+
+conn host-host
+ left=PH_IP6_MOON
+ leftcert=moonCert.pem
+ leftid=@moon.strongswan.org
+ leftfirewall=yes
+ right=PH_IP6_SUN
+ rightid=@sun.strongswan.org
+ type=transport
+ auto=add
diff --git a/testing/tests/ipv6/transport-ikev2/hosts/sun/etc/init.d/iptables b/testing/tests/ipv6/transport-ikev2/hosts/sun/etc/init.d/iptables
new file mode 100755
index 000000000..25074a0f1
--- /dev/null
+++ b/testing/tests/ipv6/transport-ikev2/hosts/sun/etc/init.d/iptables
@@ -0,0 +1,107 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # enable IP forwarding
+ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ /sbin/ip6tables -P INPUT DROP
+ /sbin/ip6tables -P OUTPUT DROP
+ /sbin/ip6tables -P FORWARD DROP
+
+ # allow esp
+ ip6tables -A INPUT -i eth0 -p 50 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow MobIKE
+ ip6tables -A INPUT -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+ ip6tables -A OUTPUT -o eth0 -p udp --dport 4500 --sport 4500 -j ACCEPT
+
+ # allow last UDP fragment
+ ip6tables -A INPUT -i eth0 -p udp -m frag --fraglast -j ACCEPT
+
+ # allow ICMPv6 neighbor-solicitations
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-solicitation -j ACCEPT
+
+ # allow ICMPv6 neighbor-advertisements
+ ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+ ip6tables -A OUTPUT -p icmpv6 --icmpv6-type neighbor-advertisement -j ACCEPT
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ # log dropped packets
+ ip6tables -A INPUT -j LOG --log-prefix " IN: "
+ ip6tables -A OUTPUT -j LOG --log-prefix " OUT: "
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/ip6tables -t filter -P INPUT ACCEPT
+ /sbin/ip6tables -t filter -P FORWARD ACCEPT
+ /sbin/ip6tables -t filter -P OUTPUT ACCEPT
+
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/ip6tables -F -t $a
+ /sbin/ip6tables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/ipv6/transport-ikev2/hosts/sun/etc/ipsec.conf b/testing/tests/ipv6/transport-ikev2/hosts/sun/etc/ipsec.conf
new file mode 100755
index 000000000..b306ec666
--- /dev/null
+++ b/testing/tests/ipv6/transport-ikev2/hosts/sun/etc/ipsec.conf
@@ -0,0 +1,24 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ strictcrlpolicy=no
+ crlcheckinterval=180
+ plutostart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ mobike=no
+ keyexchange=ikev2
+
+conn host-host
+ left=PH_IP6_SUN
+ leftcert=sunCert.pem
+ leftid=@sun.strongswan.org
+ leftfirewall=yes
+ right=PH_IP6_MOON
+ rightid=@moon.strongswan.org
+ type=transport
+ auto=add
diff --git a/testing/tests/ipv6/transport-ikev2/posttest.dat b/testing/tests/ipv6/transport-ikev2/posttest.dat
new file mode 100644
index 000000000..5a9150bc8
--- /dev/null
+++ b/testing/tests/ipv6/transport-ikev2/posttest.dat
@@ -0,0 +1,4 @@
+moon::ipsec stop
+sun::ipsec stop
+moon::/etc/init.d/iptables stop 2> /dev/null
+sun::/etc/init.d/iptables stop 2> /dev/null
diff --git a/testing/tests/ipv6/transport-ikev2/pretest.dat b/testing/tests/ipv6/transport-ikev2/pretest.dat
new file mode 100644
index 000000000..3536fd886
--- /dev/null
+++ b/testing/tests/ipv6/transport-ikev2/pretest.dat
@@ -0,0 +1,6 @@
+moon::/etc/init.d/iptables start 2> /dev/null
+sun::/etc/init.d/iptables start 2> /dev/null
+moon::ipsec start
+sun::ipsec start
+moon::sleep 2
+moon::ipsec up host-host
diff --git a/testing/tests/ipv6/transport-ikev2/test.conf b/testing/tests/ipv6/transport-ikev2/test.conf
new file mode 100644
index 000000000..6ab5b8a96
--- /dev/null
+++ b/testing/tests/ipv6/transport-ikev2/test.conf
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# UML instances used for this test
+
+# All UML instances that are required for this test
+#
+UMLHOSTS="moon winnetou sun"
+
+# Corresponding block diagram
+#
+DIAGRAM="m-w-s-ip6.png"
+
+# UML instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="sun"
+
+# UML instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="moon sun"
diff --git a/testing/tests/p2pnat/behind-same-nat/description.txt b/testing/tests/p2pnat/behind-same-nat/description.txt
new file mode 100644
index 000000000..1d06ca3b5
--- /dev/null
+++ b/testing/tests/p2pnat/behind-same-nat/description.txt
@@ -0,0 +1,6 @@
+The peers <b>alice</b> and <b>venus</b> are hidden behind the same NAT router <b>moon</b>
+but both are not aware of this fact. Thus they try to resolve the apparent double-NAT
+situation with the help of the mediation server <b>carol</b> where they register under
+the pseudonyms <b>6cu1UTVw@medsrv.org</b> and <b>F1ubAio8@medsrv.org</b>, respectively.
+Based on the set of endpoints relayed to them by the mediation server, the peers find out
+that they can communicate directly with each other without a NAT router in between.
diff --git a/testing/tests/p2pnat/behind-same-nat/evaltest.dat b/testing/tests/p2pnat/behind-same-nat/evaltest.dat
new file mode 100644
index 000000000..0036e073f
--- /dev/null
+++ b/testing/tests/p2pnat/behind-same-nat/evaltest.dat
@@ -0,0 +1,11 @@
+alice::ipsec statusall::medsrv.*ESTABLISHED::YES
+venus::ipsec statusall::medsrv.*ESTABLISHED::YES
+carol::ipsec statusall::medsrv.*ESTABLISHED.*PH_IP_MOON.*6cu1UTVw@medsrv.org::YES
+carol::ipsec statusall::medsrv.*ESTABLISHED.*PH_IP_MOON.*F1ubAio8@medsrv.org::YES
+alice::cat /var/log/daemon.log::received P2P_CALLBACK::YES
+alice::ipsec statusall::p2p.*ESTABLISHED::YES
+venus::ipsec statusall::p2p.*ESTABLISHED::YES
+alice::ipsec statusall::p2p.*INSTALLED::YES
+venus::ipsec statusall::p2p.*INSTALLED::YES
+alice::ping -c 1 PH_IP_VENUS::64 bytes from PH_IP_VENUS: icmp_seq=1::YES
+venus::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_seq=1::YES
diff --git a/testing/tests/p2pnat/behind-same-nat/hosts/alice/etc/init.d/iptables b/testing/tests/p2pnat/behind-same-nat/hosts/alice/etc/init.d/iptables
new file mode 100755
index 000000000..937486984
--- /dev/null
+++ b/testing/tests/p2pnat/behind-same-nat/hosts/alice/etc/init.d/iptables
@@ -0,0 +1,78 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ # allow esp
+ iptables -A INPUT -i eth0 -p 50 -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE
+ iptables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow NAT-T including P2P
+ iptables -A INPUT -i eth0 -p udp --dport 4500 -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p udp --sport 4500 -j ACCEPT
+
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/p2pnat/behind-same-nat/hosts/alice/etc/ipsec.conf b/testing/tests/p2pnat/behind-same-nat/hosts/alice/etc/ipsec.conf
new file mode 100755
index 000000000..e481996f7
--- /dev/null
+++ b/testing/tests/p2pnat/behind-same-nat/hosts/alice/etc/ipsec.conf
@@ -0,0 +1,36 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ crlcheckinterval=180
+ strictcrlpolicy=no
+ plutostart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ keyexchange=ikev2
+ mobike=no
+ dpdaction=restart
+ dpddelay=60s
+ left=%defaultroute
+ leftfirewall=yes
+
+conn medsrv
+ leftid=6cu1UTVw@medsrv.org
+ right=PH_IP_CAROL
+ rightid=carol@strongswan.org
+ p2p_mediation=yes
+ authby=psk
+ auto=add
+
+conn p2p
+ leftcert=aliceCert.pem
+ leftid=alice@strongswan.org
+ right=%any
+ rightid=@venus.strongswan.org
+ rightsubnet=PH_IP_VENUS/32
+ p2p_mediated_by=medsrv
+ p2p_peerid=F1ubAio8@medsrv.org
+ auto=start
diff --git a/testing/tests/p2pnat/behind-same-nat/hosts/alice/etc/ipsec.secrets b/testing/tests/p2pnat/behind-same-nat/hosts/alice/etc/ipsec.secrets
new file mode 100644
index 000000000..59396bbeb
--- /dev/null
+++ b/testing/tests/p2pnat/behind-same-nat/hosts/alice/etc/ipsec.secrets
@@ -0,0 +1,7 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: RSA aliceKey.pem
+
+# secret used for mediation connection
+
+6cu1UTVw@medsrv.org : PSK "BAXz/6cSITttd0CzF9799p859Pi4LPnP"
diff --git a/testing/tests/p2pnat/behind-same-nat/hosts/carol/etc/init.d/iptables b/testing/tests/p2pnat/behind-same-nat/hosts/carol/etc/init.d/iptables
new file mode 100755
index 000000000..40510ce60
--- /dev/null
+++ b/testing/tests/p2pnat/behind-same-nat/hosts/carol/etc/init.d/iptables
@@ -0,0 +1,77 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ # allow esp
+ iptables -A INPUT -i eth0 -p 50 -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE behind NAT
+ iptables -A INPUT -i eth0 -p udp --dport 500 -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p udp --sport 500 -j ACCEPT
+
+ # allow NAT-T
+ iptables -A INPUT -i eth0 -p udp --dport 4500 -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p udp --sport 4500 -j ACCEPT
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/p2pnat/behind-same-nat/hosts/carol/etc/ipsec.conf b/testing/tests/p2pnat/behind-same-nat/hosts/carol/etc/ipsec.conf
new file mode 100755
index 000000000..712d888b1
--- /dev/null
+++ b/testing/tests/p2pnat/behind-same-nat/hosts/carol/etc/ipsec.conf
@@ -0,0 +1,25 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ crlcheckinterval=180
+ strictcrlpolicy=no
+ plutostart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ keyexchange=ikev2
+ mobike=no
+ dpdaction=clear
+ dpddelay=60s
+
+conn medsrv
+ left=PH_IP_CAROL
+ leftcert=carolCert.pem
+ leftid=carol@strongswan.org
+ leftfirewall=yes
+ right=%any
+ p2p_mediation=yes
+ auto=add
diff --git a/testing/tests/p2pnat/behind-same-nat/hosts/carol/etc/ipsec.secrets b/testing/tests/p2pnat/behind-same-nat/hosts/carol/etc/ipsec.secrets
new file mode 100644
index 000000000..f1b30db72
--- /dev/null
+++ b/testing/tests/p2pnat/behind-same-nat/hosts/carol/etc/ipsec.secrets
@@ -0,0 +1,11 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: RSA carolKey.pem "nH5ZQEWtku0RJEZ6"
+
+# Mediation clients with random IDs
+
+6cu1UTVw@medsrv.org : PSK "BAXz/6cSITttd0CzF9799p859Pi4LPnP"
+
+F1ubAio8@medsrv.org : PSK "9tb3wiUGqUwCSRIRAwLFWfkdA8u6hHA8"
+
+av9oEPMz@medsrv.org : PSK "ZVm3FLOiweS1ywUDpR/L9FvpwNYp9svt"
diff --git a/testing/tests/p2pnat/behind-same-nat/hosts/venus/etc/init.d/iptables b/testing/tests/p2pnat/behind-same-nat/hosts/venus/etc/init.d/iptables
new file mode 100755
index 000000000..06d0ebca8
--- /dev/null
+++ b/testing/tests/p2pnat/behind-same-nat/hosts/venus/etc/init.d/iptables
@@ -0,0 +1,78 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ # allow esp
+ iptables -A INPUT -i eth0 -p 50 -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE
+ iptables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow NAT-T including P2P
+ iptables -A INPUT -i eth0 -p udp --dport 4500 -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p udp --sport 4500 -j ACCEPT
+
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/p2pnat/behind-same-nat/hosts/venus/etc/ipsec.conf b/testing/tests/p2pnat/behind-same-nat/hosts/venus/etc/ipsec.conf
new file mode 100755
index 000000000..d21009353
--- /dev/null
+++ b/testing/tests/p2pnat/behind-same-nat/hosts/venus/etc/ipsec.conf
@@ -0,0 +1,36 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ crlcheckinterval=180
+ strictcrlpolicy=no
+ plutostart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ keyexchange=ikev2
+ mobike=no
+ dpdaction=restart
+ dpddelay=60s
+ left=%defaultroute
+ leftfirewall=yes
+
+conn medsrv
+ leftid=F1ubAio8@medsrv.org
+ right=PH_IP_CAROL
+ rightid=carol@strongswan.org
+ authby=psk
+ p2p_mediation=yes
+ auto=start
+
+conn p2p
+ leftcert=venusCert.pem
+ leftid=@venus.strongswan.org
+ right=%any
+ rightid=alice@strongswan.org
+ rightsubnet=PH_IP_ALICE/32
+ p2p_mediated_by=medsrv
+ p2p_peerid=6cu1UTVw@medsrv.org
+ auto=add
diff --git a/testing/tests/p2pnat/behind-same-nat/hosts/venus/etc/ipsec.secrets b/testing/tests/p2pnat/behind-same-nat/hosts/venus/etc/ipsec.secrets
new file mode 100644
index 000000000..0032a6d3a
--- /dev/null
+++ b/testing/tests/p2pnat/behind-same-nat/hosts/venus/etc/ipsec.secrets
@@ -0,0 +1,7 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: RSA venusKey.pem
+
+# secret used for mediation connection
+
+F1ubAio8@medsrv.org : PSK "9tb3wiUGqUwCSRIRAwLFWfkdA8u6hHA8"
diff --git a/testing/tests/p2pnat/behind-same-nat/posttest.dat b/testing/tests/p2pnat/behind-same-nat/posttest.dat
new file mode 100644
index 000000000..36cd0f36d
--- /dev/null
+++ b/testing/tests/p2pnat/behind-same-nat/posttest.dat
@@ -0,0 +1,8 @@
+venus::ipsec stop
+alice::ipsec stop
+carol::ipsec stop
+alice::/etc/init.d/iptables stop 2> /dev/null
+moon::/etc/init.d/iptables stop 2> /dev/null
+carol::/etc/init.d/iptables stop 2> /dev/null
+venus::/etc/init.d/iptables stop 2> /dev/null
+moon::conntrack -F
diff --git a/testing/tests/p2pnat/behind-same-nat/pretest.dat b/testing/tests/p2pnat/behind-same-nat/pretest.dat
new file mode 100644
index 000000000..912222eef
--- /dev/null
+++ b/testing/tests/p2pnat/behind-same-nat/pretest.dat
@@ -0,0 +1,14 @@
+alice::/etc/init.d/iptables start 2> /dev/null
+venus::/etc/init.d/iptables start 2> /dev/null
+moon::/etc/init.d/iptables start 2> /dev/null
+carol::/etc/init.d/iptables start 2> /dev/null
+moon::iptables -t nat -A POSTROUTING -o eth0 -s 10.1.0.0/16 -p udp -j SNAT --to-source PH_IP_MOON:1100-1200
+moon::iptables -t nat -A POSTROUTING -o eth0 -s 10.1.0.0/16 -p tcp -j SNAT --to-source PH_IP_MOON:2000-2100
+moon::iptables -A FORWARD -i eth1 -o eth0 -s 10.1.0.0/16 -j ACCEPT
+moon::iptables -A FORWARD -i eth0 -o eth1 -d 10.1.0.0/16 -j ACCEPT
+carol::ipsec start
+carol::sleep 1
+alice::ipsec start
+alice::sleep 1
+venus::ipsec start
+venus::sleep 2
diff --git a/testing/tests/p2pnat/behind-same-nat/test.conf b/testing/tests/p2pnat/behind-same-nat/test.conf
new file mode 100644
index 000000000..f98a0ab1b
--- /dev/null
+++ b/testing/tests/p2pnat/behind-same-nat/test.conf
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# UML instances used for this test
+
+# All UML instances that are required for this test
+#
+UMLHOSTS="alice venus moon carol winnetou"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-v-m-c-w-med.png"
+
+# UML instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="moon"
+
+# UML instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="alice venus carol"
diff --git a/testing/tests/p2pnat/medsrv-psk/description.txt b/testing/tests/p2pnat/medsrv-psk/description.txt
new file mode 100644
index 000000000..16b3735bf
--- /dev/null
+++ b/testing/tests/p2pnat/medsrv-psk/description.txt
@@ -0,0 +1,7 @@
+The peers <b>alice</b> and <b>bob</b> are hidden behind the NAT routers <b>moon</b> and <b>sun</b>,
+respectively. Due to this double-NAT situation they cannot set up an IPsec tunnel directly
+but need the assistance from the mediation server <b>carol</b> with which they register under
+the pseudonyms <b>6cu1UTVw@medsrv.org</b> and <b>av9oEPMz@medsrv.org</b>, respectively,
+authenticating by means of individual pre-shared keys. Using the set of endpoints relayed
+to them by the mediation server, the peers are able to set up a direct IPsec connection..
+In order to test the double NAT-ed IPsec tunnel both peers ping each other.
diff --git a/testing/tests/p2pnat/medsrv-psk/evaltest.dat b/testing/tests/p2pnat/medsrv-psk/evaltest.dat
new file mode 100644
index 000000000..b8280c325
--- /dev/null
+++ b/testing/tests/p2pnat/medsrv-psk/evaltest.dat
@@ -0,0 +1,12 @@
+alice::ipsec statusall::medsrv.*ESTABLISHED::YES
+bob::ipsec statusall::medsrv.*ESTABLISHED::YES
+carol::ipsec statusall::medsrv.*ESTABLISHED.*PH_IP_MOON.*6cu1UTVw@medsrv.org::YES
+carol::ipsec statusall::medsrv.*ESTABLISHED.*PH_IP_SUN.*v9oEPMz@medsrv.org::YES
+alice::ipsec statusall::p2p.*ESTABLISHED::YES
+bob::ipsec statusall::p2p.*ESTABLISHED::YES
+alice::ipsec statusall::p2p.*INSTALLED::YES
+bob::ipsec statusall::p2p.*INSTALLED::YES
+alice::ping -c 1 PH_IP_BOB::64 bytes from PH_IP_BOB: icmp_seq=1::YES
+bob::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_seq=1::YES
+moon::tcpdump::IP moon.strongswan.org.* > sun.strongswan.org.*: UDP::YES
+moon::tcpdump::IP sun.strongswan.org.* > moon.strongswan.org.*: UDP::YES
diff --git a/testing/tests/p2pnat/medsrv-psk/hosts/alice/etc/init.d/iptables b/testing/tests/p2pnat/medsrv-psk/hosts/alice/etc/init.d/iptables
new file mode 100755
index 000000000..09b4cabfa
--- /dev/null
+++ b/testing/tests/p2pnat/medsrv-psk/hosts/alice/etc/init.d/iptables
@@ -0,0 +1,74 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ # allow IKE
+ iptables -A INPUT -i eth0 -p udp --sport 500 --dport 500 -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p udp --dport 500 --sport 500 -j ACCEPT
+
+ # allow NAT-T including P2P
+ iptables -A INPUT -i eth0 -p udp --dport 4500 -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p udp --sport 4500 -j ACCEPT
+
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/p2pnat/medsrv-psk/hosts/alice/etc/ipsec.conf b/testing/tests/p2pnat/medsrv-psk/hosts/alice/etc/ipsec.conf
new file mode 100755
index 000000000..370934ce7
--- /dev/null
+++ b/testing/tests/p2pnat/medsrv-psk/hosts/alice/etc/ipsec.conf
@@ -0,0 +1,36 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ crlcheckinterval=180
+ strictcrlpolicy=no
+ plutostart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ keyexchange=ikev2
+ mobike=no
+ dpdaction=restart
+ dpddelay=60s
+ left=%defaultroute
+ leftfirewall=yes
+
+conn medsrv
+ leftid=6cu1UTVw@medsrv.org
+ right=PH_IP_CAROL
+ rightid=carol@strongswan.org
+ p2p_mediation=yes
+ authby=psk
+ auto=add
+
+conn p2p
+ leftcert=aliceCert.pem
+ leftid=alice@strongswan.org
+ right=%any
+ rightid=bob@strongswan.org
+ rightsubnet=PH_IP_BOB/32
+ p2p_mediated_by=medsrv
+ p2p_peerid=av9oEPMz@medsrv.org
+ auto=start
diff --git a/testing/tests/p2pnat/medsrv-psk/hosts/alice/etc/ipsec.secrets b/testing/tests/p2pnat/medsrv-psk/hosts/alice/etc/ipsec.secrets
new file mode 100644
index 000000000..59396bbeb
--- /dev/null
+++ b/testing/tests/p2pnat/medsrv-psk/hosts/alice/etc/ipsec.secrets
@@ -0,0 +1,7 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: RSA aliceKey.pem
+
+# secret used for mediation connection
+
+6cu1UTVw@medsrv.org : PSK "BAXz/6cSITttd0CzF9799p859Pi4LPnP"
diff --git a/testing/tests/p2pnat/medsrv-psk/hosts/bob/etc/ipsec.conf b/testing/tests/p2pnat/medsrv-psk/hosts/bob/etc/ipsec.conf
new file mode 100755
index 000000000..8d8d9391f
--- /dev/null
+++ b/testing/tests/p2pnat/medsrv-psk/hosts/bob/etc/ipsec.conf
@@ -0,0 +1,36 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ crlcheckinterval=180
+ strictcrlpolicy=no
+ plutostart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ keyexchange=ikev2
+ mobike=no
+ dpdaction=restart
+ dpddelay=60s
+ left=%defaultroute
+ leftfirewall=yes
+
+conn medsrv
+ leftid=av9oEPMz@medsrv.org
+ right=PH_IP_CAROL
+ rightid=carol@strongswan.org
+ authby=psk
+ p2p_mediation=yes
+ auto=start
+
+conn p2p
+ leftcert=bobCert.pem
+ leftid=bob@strongswan.org
+ right=%any
+ rightid=alice@strongswan.org
+ rightsubnet=PH_IP_ALICE/32
+ p2p_mediated_by=medsrv
+ p2p_peerid=6cu1UTVw@medsrv.org
+ auto=add
diff --git a/testing/tests/p2pnat/medsrv-psk/hosts/bob/etc/ipsec.secrets b/testing/tests/p2pnat/medsrv-psk/hosts/bob/etc/ipsec.secrets
new file mode 100644
index 000000000..0dc3958da
--- /dev/null
+++ b/testing/tests/p2pnat/medsrv-psk/hosts/bob/etc/ipsec.secrets
@@ -0,0 +1,7 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: RSA bobKey.pem
+
+# secret used for mediation connection
+
+av9oEPMz@medsrv.org : PSK "ZVm3FLOiweS1ywUDpR/L9FvpwNYp9svt"
diff --git a/testing/tests/p2pnat/medsrv-psk/hosts/carol/etc/init.d/iptables b/testing/tests/p2pnat/medsrv-psk/hosts/carol/etc/init.d/iptables
new file mode 100755
index 000000000..40510ce60
--- /dev/null
+++ b/testing/tests/p2pnat/medsrv-psk/hosts/carol/etc/init.d/iptables
@@ -0,0 +1,77 @@
+#!/sbin/runscript
+# Copyright 1999-2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+opts="start stop reload"
+
+depend() {
+ before net
+ need logger
+}
+
+start() {
+ ebegin "Starting firewall"
+
+ # default policy is DROP
+ /sbin/iptables -P INPUT DROP
+ /sbin/iptables -P OUTPUT DROP
+ /sbin/iptables -P FORWARD DROP
+
+ # allow esp
+ iptables -A INPUT -i eth0 -p 50 -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p 50 -j ACCEPT
+
+ # allow IKE behind NAT
+ iptables -A INPUT -i eth0 -p udp --dport 500 -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p udp --sport 500 -j ACCEPT
+
+ # allow NAT-T
+ iptables -A INPUT -i eth0 -p udp --dport 4500 -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p udp --sport 4500 -j ACCEPT
+
+ # allow crl fetch from winnetou
+ iptables -A INPUT -i eth0 -p tcp --sport 80 -s PH_IP_WINNETOU -j ACCEPT
+ iptables -A OUTPUT -o eth0 -p tcp --dport 80 -d PH_IP_WINNETOU -j ACCEPT
+
+ # allow ssh
+ iptables -A INPUT -p tcp --dport 22 -j ACCEPT
+ iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
+
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+
+ if [ $a == nat ]; then
+ /sbin/iptables -t nat -P PREROUTING ACCEPT
+ /sbin/iptables -t nat -P POSTROUTING ACCEPT
+ /sbin/iptables -t nat -P OUTPUT ACCEPT
+ elif [ $a == mangle ]; then
+ /sbin/iptables -t mangle -P PREROUTING ACCEPT
+ /sbin/iptables -t mangle -P INPUT ACCEPT
+ /sbin/iptables -t mangle -P FORWARD ACCEPT
+ /sbin/iptables -t mangle -P OUTPUT ACCEPT
+ /sbin/iptables -t mangle -P POSTROUTING ACCEPT
+ elif [ $a == filter ]; then
+ /sbin/iptables -t filter -P INPUT ACCEPT
+ /sbin/iptables -t filter -P FORWARD ACCEPT
+ /sbin/iptables -t filter -P OUTPUT ACCEPT
+ fi
+ done
+ eend $?
+}
+
+reload() {
+ ebegin "Flushing firewall"
+ for a in `cat /proc/net/ip_tables_names`; do
+ /sbin/iptables -F -t $a
+ /sbin/iptables -X -t $a
+ done;
+ eend $?
+ start
+}
+
diff --git a/testing/tests/p2pnat/medsrv-psk/hosts/carol/etc/ipsec.conf b/testing/tests/p2pnat/medsrv-psk/hosts/carol/etc/ipsec.conf
new file mode 100755
index 000000000..712d888b1
--- /dev/null
+++ b/testing/tests/p2pnat/medsrv-psk/hosts/carol/etc/ipsec.conf
@@ -0,0 +1,25 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+ crlcheckinterval=180
+ strictcrlpolicy=no
+ plutostart=no
+
+conn %default
+ ikelifetime=60m
+ keylife=20m
+ rekeymargin=3m
+ keyingtries=1
+ keyexchange=ikev2
+ mobike=no
+ dpdaction=clear
+ dpddelay=60s
+
+conn medsrv
+ left=PH_IP_CAROL
+ leftcert=carolCert.pem
+ leftid=carol@strongswan.org
+ leftfirewall=yes
+ right=%any
+ p2p_mediation=yes
+ auto=add
diff --git a/testing/tests/p2pnat/medsrv-psk/hosts/carol/etc/ipsec.secrets b/testing/tests/p2pnat/medsrv-psk/hosts/carol/etc/ipsec.secrets
new file mode 100644
index 000000000..64089431a
--- /dev/null
+++ b/testing/tests/p2pnat/medsrv-psk/hosts/carol/etc/ipsec.secrets
@@ -0,0 +1,9 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: RSA carolKey.pem "nH5ZQEWtku0RJEZ6"
+
+# Mediation clients with random IDs
+
+6cu1UTVw@medsrv.org : PSK "BAXz/6cSITttd0CzF9799p859Pi4LPnP"
+
+av9oEPMz@medsrv.org : PSK "ZVm3FLOiweS1ywUDpR/L9FvpwNYp9svt"
diff --git a/testing/tests/p2pnat/medsrv-psk/posttest.dat b/testing/tests/p2pnat/medsrv-psk/posttest.dat
new file mode 100644
index 000000000..ca3cebc0a
--- /dev/null
+++ b/testing/tests/p2pnat/medsrv-psk/posttest.dat
@@ -0,0 +1,10 @@
+bob::ipsec stop
+alice::ipsec stop
+carol::ipsec stop
+alice::/etc/init.d/iptables stop 2> /dev/null
+moon::/etc/init.d/iptables stop 2> /dev/null
+carol::/etc/init.d/iptables stop 2> /dev/null
+sun::/etc/init.d/iptables stop 2> /dev/null
+bob::/etc/init.d/iptables stop 2> /dev/null
+moon::conntrack -F
+sun::conntrack -F
diff --git a/testing/tests/p2pnat/medsrv-psk/pretest.dat b/testing/tests/p2pnat/medsrv-psk/pretest.dat
new file mode 100644
index 000000000..a5c9a2fbb
--- /dev/null
+++ b/testing/tests/p2pnat/medsrv-psk/pretest.dat
@@ -0,0 +1,19 @@
+alice::/etc/init.d/iptables start 2> /dev/null
+moon::/etc/init.d/iptables start 2> /dev/null
+carol::/etc/init.d/iptables start 2> /dev/null
+sun::/etc/init.d/iptables start 2> /dev/null
+bob::/etc/init.d/iptables start 2> /dev/null
+moon::iptables -t nat -A POSTROUTING -o eth0 -s 10.1.0.0/16 -p udp -j SNAT --to-source PH_IP_MOON:1100-1200
+moon::iptables -t nat -A POSTROUTING -o eth0 -s 10.1.0.0/16 -p tcp -j SNAT --to-source PH_IP_MOON:2000-2100
+moon::iptables -A FORWARD -i eth1 -o eth0 -s 10.1.0.0/16 -j ACCEPT
+moon::iptables -A FORWARD -i eth0 -o eth1 -d 10.1.0.0/16 -j ACCEPT
+sun::iptables -t nat -A POSTROUTING -o eth0 -s 10.2.0.0/16 -p udp -j SNAT --to-source PH_IP_SUN:1200-1300
+sun::iptables -t nat -A POSTROUTING -o eth0 -s 10.2.0.0/16 -p tcp -j SNAT --to-source PH_IP_SUN:2000-2100
+sun::iptables -A FORWARD -i eth1 -o eth0 -s 10.2.0.0/16 -j ACCEPT
+sun::iptables -A FORWARD -i eth0 -o eth1 -d 10.2.0.0/16 -j ACCEPT
+carol::ipsec start
+carol::sleep 1
+bob::ipsec start
+bob::sleep 1
+alice::ipsec start
+alice::sleep 2
diff --git a/testing/tests/p2pnat/medsrv-psk/test.conf b/testing/tests/p2pnat/medsrv-psk/test.conf
new file mode 100644
index 000000000..2dc4cd8c1
--- /dev/null
+++ b/testing/tests/p2pnat/medsrv-psk/test.conf
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# This configuration file provides information on the
+# UML instances used for this test
+
+# All UML instances that are required for this test
+#
+UMLHOSTS="alice moon carol winnetou sun bob"
+
+# Corresponding block diagram
+#
+DIAGRAM="a-m-c-w-s-b-med.png"
+
+# UML instances on which tcpdump is to be started
+#
+TCPDUMPHOSTS="moon"
+
+# UML instances on which IPsec is started
+# Used for IPsec logging purposes
+#
+IPSECHOSTS="alice carol bob"