]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
merged multi-auth branch back into trunk
authorMartin Willi <martin@strongswan.org>
Tue, 14 Apr 2009 10:34:24 +0000 (10:34 -0000)
committerMartin Willi <martin@strongswan.org>
Tue, 14 Apr 2009 10:34:24 +0000 (10:34 -0000)
230 files changed:
src/_copyright/Makefile.am
src/charon/Makefile.am
src/charon/bus/bus.c
src/charon/bus/bus.h
src/charon/config/attributes/attribute_manager.c
src/charon/config/attributes/attribute_manager.h
src/charon/config/attributes/attribute_provider.h
src/charon/config/auth_cfg.c [new file with mode: 0644]
src/charon/config/auth_cfg.h [new file with mode: 0644]
src/charon/config/backend.h
src/charon/config/backend_manager.c
src/charon/config/backend_manager.h
src/charon/config/peer_cfg.c
src/charon/config/peer_cfg.h
src/charon/config/proposal.c
src/charon/config/proposal_keywords.h [new file with mode: 0644]
src/charon/config/proposal_keywords.txt [new file with mode: 0644]
src/charon/credentials/auth_info.c [deleted file]
src/charon/credentials/auth_info.h [deleted file]
src/charon/credentials/credential_manager.c
src/charon/credentials/credential_manager.h
src/charon/credentials/sets/auth_cfg_wrapper.c [moved from src/charon/credentials/sets/auth_info_wrapper.c with 67% similarity]
src/charon/credentials/sets/auth_cfg_wrapper.h [moved from src/charon/credentials/sets/auth_info_wrapper.h with 60% similarity]
src/charon/encoding/generator.c
src/charon/encoding/message.c
src/charon/encoding/message.h
src/charon/plugins/eap_mschapv2/eap_mschapv2.c
src/charon/plugins/eap_sim_file/eap_sim_file_card.c
src/charon/plugins/eap_sim_file/eap_sim_file_triplets.c
src/charon/plugins/load_tester/load_tester_config.c
src/charon/plugins/nm/nm_creds.c
src/charon/plugins/nm/nm_service.c
src/charon/plugins/smp/smp.c
src/charon/plugins/sql/pool.c
src/charon/plugins/sql/sql_attribute.c
src/charon/plugins/sql/sql_config.c
src/charon/plugins/stroke/stroke_attribute.c
src/charon/plugins/stroke/stroke_config.c
src/charon/plugins/stroke/stroke_cred.c
src/charon/plugins/stroke/stroke_list.c
src/charon/plugins/stroke/stroke_socket.c
src/charon/plugins/uci/uci_config.c
src/charon/plugins/uci/uci_control.c
src/charon/plugins/uci/uci_creds.c
src/charon/plugins/unit_tester/tests/test_auth_info.c
src/charon/plugins/unit_tester/tests/test_med_db.c
src/charon/plugins/unit_tester/tests/test_pool.c
src/charon/processing/jobs/initiate_mediation_job.c
src/charon/sa/authenticators/authenticator.c
src/charon/sa/authenticators/authenticator.h
src/charon/sa/authenticators/eap/eap_manager.c
src/charon/sa/authenticators/eap/eap_method.c
src/charon/sa/authenticators/eap/eap_method.h
src/charon/sa/authenticators/eap/sim_manager.h
src/charon/sa/authenticators/eap_authenticator.c
src/charon/sa/authenticators/eap_authenticator.h
src/charon/sa/authenticators/psk_authenticator.c
src/charon/sa/authenticators/psk_authenticator.h
src/charon/sa/authenticators/pubkey_authenticator.c
src/charon/sa/authenticators/pubkey_authenticator.h
src/charon/sa/connect_manager.c
src/charon/sa/ike_sa.c
src/charon/sa/ike_sa.h
src/charon/sa/ike_sa_manager.c
src/charon/sa/task_manager.c
src/charon/sa/tasks/child_create.c
src/charon/sa/tasks/child_delete.c
src/charon/sa/tasks/child_rekey.c
src/charon/sa/tasks/ike_auth.c
src/charon/sa/tasks/ike_auth_lifetime.c
src/charon/sa/tasks/ike_cert_post.c
src/charon/sa/tasks/ike_cert_pre.c
src/charon/sa/tasks/ike_config.c
src/charon/sa/tasks/ike_init.c
src/charon/sa/tasks/ike_me.c
src/charon/sa/tasks/ike_mobike.c
src/charon/sa/tasks/ike_natd.c
src/charon/sa/tasks/ike_rekey.c
src/libfreeswan/Makefile.am
src/libfreeswan/freeswan.h
src/libstrongswan/credentials/certificates/certificate.c
src/libstrongswan/credentials/certificates/certificate.h
src/libstrongswan/plugins/curl/curl_fetcher.c
src/libstrongswan/settings.h
src/libstrongswan/utils/enumerator.h
src/libstrongswan/utils/identification.c
src/libstrongswan/utils/identification.h
src/libstrongswan/utils/linked_list.h
src/pluto/Makefile.am
src/pluto/ac.c
src/pluto/alg_info.c
src/pluto/constants.c
src/pluto/constants.h
src/pluto/crl.c
src/pluto/defs.h
src/pluto/demux.c
src/pluto/fetch.c
src/pluto/id.c
src/pluto/ike_alg.c
src/pluto/kernel.c
src/pluto/keys.c
src/pluto/modecfg.c
src/pluto/nat_traversal.c
src/pluto/pem.c
src/pluto/pgp.c
src/pluto/plutomain.c
src/pluto/server.c
src/pluto/smartcard.c
src/pluto/state.c
src/pluto/vendor.c
src/pluto/virtual.c
src/pluto/x509.c
src/starter/Makefile.am
src/starter/args.c
src/starter/confread.h
src/starter/invokecharon.c
src/starter/invokecharon.h
src/starter/invokepluto.c
src/starter/invokepluto.h
src/starter/ipsec.conf.5
src/starter/keywords.h
src/starter/keywords.txt
src/starter/starter.c
src/starter/starterstroke.c
src/stroke/stroke_msg.h
src/whack/Makefile.am
testing/hosts/winnetou/etc/openssl/index.txt
testing/hosts/winnetou/etc/openssl/index.txt.old
testing/hosts/winnetou/etc/openssl/newcerts/15.pem [new file with mode: 0644]
testing/hosts/winnetou/etc/openssl/serial
testing/hosts/winnetou/etc/openssl/serial.old
testing/scripts/function.sh
testing/scripts/start-bridges [new file with mode: 0755]
testing/scripts/start-switches [deleted file]
testing/scripts/stop-bridges [new file with mode: 0755]
testing/start-testing
testing/stop-testing
testing/testing.conf
testing/tests/ikev1/dpd-restart/evaltest.dat
testing/tests/ikev1/protoport-route/evaltest.dat
testing/tests/ikev1/protoport-route/pretest.dat
testing/tests/ikev2/any-interface/hosts/alice/etc/strongswan.conf
testing/tests/ikev2/any-interface/hosts/bob/etc/strongswan.conf
testing/tests/ikev2/any-interface/hosts/moon/etc/strongswan.conf
testing/tests/ikev2/any-interface/hosts/sun/etc/strongswan.conf
testing/tests/ikev2/crl-revoked/evaltest.dat
testing/tests/ikev2/host2host-transport/hosts/moon/etc/strongswan.conf
testing/tests/ikev2/host2host-transport/hosts/sun/etc/strongswan.conf
testing/tests/ikev2/mult-auth-rsa-eap-sim-id/description.txt [new file with mode: 0644]
testing/tests/ikev2/mult-auth-rsa-eap-sim-id/evaltest.dat [new file with mode: 0644]
testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/alice/etc/raddb/clients.conf [new file with mode: 0644]
testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/alice/etc/raddb/eap.conf [new file with mode: 0644]
testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/alice/etc/raddb/proxy.conf [new file with mode: 0644]
testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/alice/etc/raddb/radiusd.conf [new file with mode: 0644]
testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/alice/etc/raddb/sites-available/default [new file with mode: 0644]
testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/alice/etc/raddb/triplets.dat [new file with mode: 0644]
testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/alice/etc/raddb/users [new file with mode: 0644]
testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/carol/etc/ipsec.conf [new file with mode: 0755]
testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/carol/etc/ipsec.d/triplets.dat [new file with mode: 0644]
testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/carol/etc/ipsec.secrets [new file with mode: 0644]
testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/carol/etc/strongswan.conf [moved from testing/tests/ikev2/two-certs/hosts/dave/etc/strongswan.conf with 63% similarity]
testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/dave/etc/ipsec.conf [new file with mode: 0755]
testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/dave/etc/ipsec.d/triplets.dat [new file with mode: 0644]
testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/dave/etc/ipsec.secrets [new file with mode: 0644]
testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/dave/etc/strongswan.conf [new file with mode: 0644]
testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/moon/etc/init.d/iptables [new file with mode: 0755]
testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/moon/etc/ipsec.conf [new file with mode: 0755]
testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/moon/etc/ipsec.secrets [new file with mode: 0644]
testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/moon/etc/strongswan.conf [new file with mode: 0644]
testing/tests/ikev2/mult-auth-rsa-eap-sim-id/posttest.dat [new file with mode: 0644]
testing/tests/ikev2/mult-auth-rsa-eap-sim-id/pretest.dat [new file with mode: 0644]
testing/tests/ikev2/mult-auth-rsa-eap-sim-id/test.conf [new file with mode: 0644]
testing/tests/ikev2/multi-level-ca-cr-init/description.txt
testing/tests/ikev2/multi-level-ca-cr-init/hosts/moon/etc/ipsec.conf
testing/tests/ikev2/multi-level-ca-cr-resp/description.txt
testing/tests/ikev2/multi-level-ca-cr-resp/evaltest.dat
testing/tests/ikev2/multi-level-ca-cr-resp/hosts/moon/etc/ipsec.conf
testing/tests/ikev2/multi-level-ca-ldap/evaltest.dat
testing/tests/ikev2/multi-level-ca-loop/evaltest.dat
testing/tests/ikev2/multi-level-ca-revoked/evaltest.dat
testing/tests/ikev2/multi-level-ca-strict/description.txt
testing/tests/ikev2/multi-level-ca/evaltest.dat
testing/tests/ikev2/net2net-cert/hosts/moon/etc/strongswan.conf
testing/tests/ikev2/net2net-cert/hosts/sun/etc/strongswan.conf
testing/tests/ikev2/net2net-psk/hosts/moon/etc/strongswan.conf
testing/tests/ikev2/net2net-psk/hosts/sun/etc/strongswan.conf
testing/tests/ikev2/net2net-route/hosts/moon/etc/strongswan.conf
testing/tests/ikev2/net2net-route/hosts/sun/etc/strongswan.conf
testing/tests/ikev2/net2net-start/hosts/moon/etc/strongswan.conf
testing/tests/ikev2/net2net-start/hosts/sun/etc/strongswan.conf
testing/tests/ikev2/ocsp-no-signer-cert/evaltest.dat
testing/tests/ikev2/ocsp-strict-ifuri/evaltest.dat
testing/tests/ikev2/ocsp-untrusted-cert/evaltest.dat
testing/tests/ikev2/reauth-late/evaltest.dat
testing/tests/ikev2/rw-eap-aka-id-rsa/evaltest.dat
testing/tests/ikev2/rw-eap-aka-rsa/evaltest.dat
testing/tests/ikev2/rw-eap-md5-id-radius/evaltest.dat
testing/tests/ikev2/rw-eap-md5-radius/evaltest.dat
testing/tests/ikev2/rw-eap-mschapv2-id-rsa/evaltest.dat
testing/tests/ikev2/rw-eap-sim-id-radius/description.txt
testing/tests/ikev2/rw-eap-sim-id-radius/evaltest.dat
testing/tests/ikev2/rw-eap-sim-id-radius/hosts/alice/etc/raddb/triplets.dat
testing/tests/ikev2/rw-eap-sim-id-radius/hosts/carol/etc/ipsec.conf
testing/tests/ikev2/rw-eap-sim-radius/evaltest.dat
testing/tests/ikev2/two-certs/description.txt
testing/tests/ikev2/two-certs/evaltest.dat
testing/tests/ikev2/two-certs/hosts/carol/etc/ipsec.conf
testing/tests/ikev2/two-certs/hosts/carol/etc/ipsec.d/certs/carolCert-002.pem [new file with mode: 0644]
testing/tests/ikev2/two-certs/hosts/carol/etc/ipsec.d/private/carolKey-002.pem [new file with mode: 0644]
testing/tests/ikev2/two-certs/hosts/carol/etc/ipsec.secrets [new file with mode: 0644]
testing/tests/ikev2/two-certs/hosts/moon/etc/ipsec.conf
testing/tests/ikev2/two-certs/hosts/moon/etc/ipsec.d/certs/carolRevokedCert.pem [deleted file]
testing/tests/ikev2/two-certs/hosts/moon/etc/ipsec.d/certs/daveCert.der [deleted file]
testing/tests/ikev2/two-certs/posttest.dat
testing/tests/ikev2/two-certs/pretest.dat
testing/tests/ikev2/two-certs/test.conf
testing/tests/openssl/alg-blowfish/description.txt [new file with mode: 0644]
testing/tests/openssl/alg-blowfish/evaltest.dat [new file with mode: 0644]
testing/tests/openssl/alg-blowfish/hosts/carol/etc/ipsec.conf [new file with mode: 0755]
testing/tests/openssl/alg-blowfish/hosts/carol/etc/strongswan.conf [new file with mode: 0644]
testing/tests/openssl/alg-blowfish/hosts/dave/etc/ipsec.conf [moved from testing/tests/ikev2/two-certs/hosts/dave/etc/ipsec.conf with 87% similarity]
testing/tests/openssl/alg-blowfish/hosts/dave/etc/strongswan.conf [new file with mode: 0644]
testing/tests/openssl/alg-blowfish/hosts/moon/etc/ipsec.conf [new file with mode: 0755]
testing/tests/openssl/alg-blowfish/hosts/moon/etc/strongswan.conf [new file with mode: 0644]
testing/tests/openssl/alg-blowfish/posttest.dat [new file with mode: 0644]
testing/tests/openssl/alg-blowfish/pretest.dat [new file with mode: 0644]
testing/tests/openssl/alg-blowfish/test.conf [new file with mode: 0644]
testing/tests/openssl/rw-cert/hosts/moon/etc/strongswan.conf
testing/tests/sql/rw-eap-aka-rsa/hosts/carol/etc/ipsec.d/data.sql
testing/tests/sql/rw-eap-aka-rsa/hosts/moon/etc/ipsec.d/data.sql

index 00d5fb2ffbe1d3b0d49a2c0d2aa601e9f8f5b296..8b46f11a49470135d469616a2284defd7a50dbdd 100644 (file)
@@ -2,5 +2,8 @@ ipsec_PROGRAMS = _copyright
 _copyright_SOURCES = _copyright.c
 dist_man8_MANS = _copyright.8
 
-INCLUDES = -I$(top_srcdir)/src/libfreeswan
+INCLUDES = \
+-I$(top_srcdir)/src/libfreeswan \
+-I$(top_srcdir)/src/libstrongswan
+
 _copyright_LDADD = $(top_builddir)/src/libfreeswan/libfreeswan.a
index 9da2b238add1f60e80d93e67989ef4fbff40f9ec..cc1cffdaa4e94b0915330f018c531abf09469303 100644 (file)
@@ -8,7 +8,8 @@ config/backend_manager.c config/backend_manager.h config/backend.h \
 config/child_cfg.c config/child_cfg.h \
 config/ike_cfg.c config/ike_cfg.h \
 config/peer_cfg.c config/peer_cfg.h \
-config/proposal.c config/proposal.h \
+config/proposal.c config/proposal.h config/proposal_keywords.c config/proposal_keywords.h \
+config/auth_cfg.c config/auth_cfg.h \
 config/traffic_selector.c config/traffic_selector.h \
 config/attributes/attribute_provider.h \
 config/attributes/attribute_manager.c config/attributes/attribute_manager.h \
@@ -93,8 +94,7 @@ 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 \
 credentials/credential_manager.c credentials/credential_manager.h \
-credentials/auth_info.c credentials/auth_info.h \
-credentials/sets/auth_info_wrapper.c credentials/sets/auth_info_wrapper.h \
+credentials/sets/auth_cfg_wrapper.c credentials/sets/auth_cfg_wrapper.h \
 credentials/sets/ocsp_response_wrapper.c credentials/sets/ocsp_response_wrapper.h \
 credentials/sets/cert_cache.c credentials/sets/cert_cache.h \
 credentials/credential_set.h
@@ -108,6 +108,12 @@ AM_CFLAGS = -rdynamic \
   -DRESOLV_CONF=\"${resolv_conf}\"
 charon_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lpthread -lm -ldl
 
+EXTRA_DIST = config/proposal_keywords.txt
+MAINTAINERCLEANFILES = config/proposal_keywords.c
+
+config/proposal_keywords.c:    config/proposal_keywords.txt config/proposal_keywords.h
+               $(GPERF) -C -G -c -t < $< > $@
+
 # compile options
 #################
 
index 670c535b01e1a9b88dfb3d24f548f13447cf163d..c0b8e45e19fa4aab67dd25e748493c64f5477b49 100644 (file)
@@ -520,6 +520,45 @@ static void child_keys(private_bus_t *this, child_sa_t *child_sa,
        this->mutex->unlock(this->mutex);
 }
 
+/**
+ * Implementation of bus_t.authorize
+ */
+static bool authorize(private_bus_t *this, linked_list_t *auth, bool final)
+{
+       enumerator_t *enumerator;
+       ike_sa_t *ike_sa;
+       entry_t *entry;
+       bool keep, success = TRUE;
+       
+       ike_sa = pthread_getspecific(this->thread_sa);
+       
+       this->mutex->lock(this->mutex);
+       enumerator = this->listeners->create_enumerator(this->listeners);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               if (entry->calling || !entry->listener->authorize)
+               {
+                       continue;
+               }
+               entry->calling++;
+               keep = entry->listener->authorize(entry->listener, ike_sa,
+                                                                                 auth, final, &success);
+               entry->calling--;
+               if (!keep)
+               {
+                       unregister_listener(this, entry, enumerator);
+                       break;
+               }
+               if (!success)
+               {
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+       return success;
+}
+
 /**
  * Implementation of bus_t.destroy.
  */
@@ -548,6 +587,7 @@ bus_t *bus_create()
        this->public.message = (void(*)(bus_t*, message_t *message, bool incoming))message;
        this->public.ike_keys = (void(*)(bus_t*, ike_sa_t *ike_sa, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey))ike_keys;
        this->public.child_keys = (void(*)(bus_t*, child_sa_t *child_sa, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r))child_keys;
+       this->public.authorize = (bool(*)(bus_t*, linked_list_t *auth, bool final))authorize;
        this->public.destroy = (void(*)(bus_t*)) destroy;
        
        this->listeners = linked_list_create();
index 90ad2017f9c469f6dbe8edd50a267cdad2a47886..5c479b6cb527495789b176315a389e8b55f5001b 100644 (file)
@@ -210,6 +210,23 @@ struct listener_t {
         */
        bool (*child_keys)(listener_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa,
                                           diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r);
+       
+       /**
+        * Hook called to invoke additional authorization rules.
+        *
+        * An authorization hook gets invoked several times: After each
+        * authentication round, the hook gets invoked with with final = FALSE.
+        * After authentication is complete and the peer configuration is selected,
+        * it is invoked again, but with final = TRUE.
+        *
+        * @param ike_sa        IKE_SA to authorize
+        * @param auth          list of auth_cfg_t, done in peers authentication rounds
+        * @param final         TRUE if this is the final hook invocation
+        * @param success       set to TRUE to complete IKE_SA, FALSE abort
+        * @return                      TRUE to stay registered, FALSE to unregister
+        */
+       bool (*authorize)(listener_t *this, ike_sa_t *ike_sa, linked_list_t *auth,
+                                         bool final, bool *success);
 };
 
 /**
@@ -316,6 +333,15 @@ struct bus_t {
         */
        void (*message)(bus_t *this, message_t *message, bool incoming);
        
+       /**
+        * IKE_SA authorization hook.
+        *
+        * @param auth          list of auth_cfg_t, containing peers authentication info
+        * @param final         TRUE if this is the final invocation
+        * @return                      TRUE to establish IKE_SA, FALSE to send AUTH_FAILED
+        */
+       bool (*authorize)(bus_t *this, linked_list_t *auth, bool final);
+       
        /**
         * IKE_SA keymat hook.
         *
index a069c954a327eb0d2d6121bc0f05c30876f2a0a1..f0ae4ffa0192d8993c2d165ec63db6e19153fc1c 100644 (file)
@@ -49,7 +49,7 @@ struct private_attribute_manager_t {
  */
 static host_t* acquire_address(private_attribute_manager_t *this,
                                                           char *pool, identification_t *id,
-                                                          auth_info_t *auth, host_t *requested)
+                                                          host_t *requested)
 {
        enumerator_t *enumerator;
        attribute_provider_t *current;
@@ -59,7 +59,7 @@ static host_t* acquire_address(private_attribute_manager_t *this,
        enumerator = this->providers->create_enumerator(this->providers);
        while (enumerator->enumerate(enumerator, &current))
        {
-               host = current->acquire_address(current, pool, id, auth, requested);
+               host = current->acquire_address(current, pool, id, requested);
                if (host)
                {
                        break;
@@ -143,7 +143,7 @@ attribute_manager_t *attribute_manager_create()
 {
        private_attribute_manager_t *this = malloc_thing(private_attribute_manager_t);
        
-       this->public.acquire_address = (host_t*(*)(attribute_manager_t*, char*, identification_t*,auth_info_t*,host_t*))acquire_address;
+       this->public.acquire_address = (host_t*(*)(attribute_manager_t*, char*, identification_t*,host_t*))acquire_address;
        this->public.release_address = (void(*)(attribute_manager_t*, char *, host_t*, identification_t*))release_address;
        this->public.add_provider = (void(*)(attribute_manager_t*, attribute_provider_t *provider))add_provider;
        this->public.remove_provider = (void(*)(attribute_manager_t*, attribute_provider_t *provider))remove_provider;
index aef6e7b6e833d0be200cc27caece11986cc9f129..0ac37e78a6bc9415e45ec3a6a12a172cd410ad4d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2008-2009 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -36,14 +36,13 @@ struct attribute_manager_t {
         * Acquire a virtual IP address to assign to a peer.
         *
         * @param pool                  pool name to acquire address from
-        * @param id                    peer identity to get address for
-        * @param auth                  authorization infos of peer
+        * @param id                    peer identity to get address forua
         * @param requested             IP in configuration request
         * @return                              allocated address, NULL to serve none
         */
        host_t* (*acquire_address)(attribute_manager_t *this,
                                                           char *pool, identification_t *id,
-                                                          auth_info_t *auth, host_t *requested);
+                                                          host_t *requested);
        
        /**
         * Release a previously acquired address.
index 5d563e86b9fd71069f1882ecc87d8d03de40e2ed..cbd0075ad676b87b240f3f2974af6f13aacd0b2a 100644 (file)
@@ -25,7 +25,6 @@
 
 #include <library.h>
 #include <utils/host.h>
-#include <credentials/auth_info.h>
 
 typedef struct attribute_provider_t attribute_provider_t;
 
@@ -39,13 +38,12 @@ struct attribute_provider_t {
         *
         * @param pool                  name of the pool to acquire address from
         * @param id                    peer ID
-        * @param auth                  authorization infos
         * @param requested             IP in configuration request
         * @return                              allocated address, NULL to serve none
         */
        host_t* (*acquire_address)(attribute_provider_t *this,
                                                           char *pool, identification_t *id, 
-                                                          auth_info_t *auth, host_t *requested);
+                                                          host_t *requested);
        /**
         * Release a previously acquired address.
         *
diff --git a/src/charon/config/auth_cfg.c b/src/charon/config/auth_cfg.c
new file mode 100644 (file)
index 0000000..90fe987
--- /dev/null
@@ -0,0 +1,770 @@
+/*
+ * Copyright (C) 2007-2009 Martin Willi
+ * Copyright (C) 2008 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * $Id$
+ */
+
+#include "auth_cfg.h"
+
+#include <daemon.h>
+#include <utils/linked_list.h>
+#include <utils/identification.h>
+#include <credentials/certificates/certificate.h>
+
+ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_SUBJECT_HASH_URL,
+       "RULE_IDENTITY",
+       "RULE_AUTH_CLASS",
+       "RULE_EAP_IDENTITY",
+       "RULE_EAP_TYPE",
+       "RULE_EAP_VENDOR",
+       "RULE_CA_CERT",
+       "RULE_IM_CERT",
+       "RULE_SUBJECT_CERT",
+       "RULE_CRL_VALIDATION",
+       "RULE_OCSP_VALIDATION",
+       "RULE_AC_GROUP",
+       "HELPER_IM_CERT",
+       "HELPER_SUBJECT_CERT",
+       "HELPER_IM_HASH_URL",
+       "HELPER_SUBJECT_HASH_URL",
+);
+
+typedef struct private_auth_cfg_t private_auth_cfg_t;
+
+/**
+ * private data of item_set
+ */
+struct private_auth_cfg_t {
+       
+       /**
+        * public functions
+        */
+       auth_cfg_t public;
+       
+       /**
+        * list of entry_t
+        */
+       linked_list_t *entries;
+};
+
+typedef struct entry_t entry_t;
+
+struct entry_t {
+       /** rule type */
+       auth_rule_t type;
+       /** associated value */
+       void *value;
+};
+
+/**
+ * enumerator for auth_cfg_t.create_enumerator()
+ */
+typedef struct {
+       /** implements enumerator_t */
+       enumerator_t public;
+       /** inner enumerator from linked_list_t */
+       enumerator_t *inner;
+       /** current entry */
+       entry_t *current;
+} entry_enumerator_t;
+
+/**
+ * enumerate function for item_enumerator_t
+ */
+static bool enumerate(entry_enumerator_t *this, auth_rule_t *type, void **value)
+{
+       entry_t *entry;
+       
+       if (this->inner->enumerate(this->inner, &entry))
+       {
+               this->current = entry;
+               *type = entry->type;
+               *value = entry->value;
+               return TRUE;
+       }
+       return FALSE;
+}
+
+/**
+ * destroy function for item_enumerator_t
+ */
+static void entry_enumerator_destroy(entry_enumerator_t *this)
+{
+       this->inner->destroy(this->inner);
+       free(this);
+}
+
+/**
+ * Implementation of auth_cfg_t.create_enumerator.
+ */
+static enumerator_t* create_enumerator(private_auth_cfg_t *this)
+{
+       entry_enumerator_t *enumerator;
+       
+       enumerator = malloc_thing(entry_enumerator_t);
+       enumerator->inner = this->entries->create_enumerator(this->entries);
+       enumerator->public.enumerate = (void*)enumerate;
+       enumerator->public.destroy = (void*)entry_enumerator_destroy;
+       enumerator->current = NULL;
+       return &enumerator->public;
+}
+
+/**
+ * Destroy the value associated with an entry
+ */
+static void destroy_entry_value(entry_t *entry)
+{
+       switch (entry->type)
+       {
+               case AUTH_RULE_IDENTITY:
+               case AUTH_RULE_EAP_IDENTITY:
+               case AUTH_RULE_AC_GROUP:
+               {
+                       identification_t *id = (identification_t*)entry->value;
+                       id->destroy(id);
+                       break;
+               }
+               case AUTH_RULE_CA_CERT:
+               case AUTH_RULE_IM_CERT:
+               case AUTH_RULE_SUBJECT_CERT:
+               case AUTH_HELPER_IM_CERT:
+               case AUTH_HELPER_SUBJECT_CERT:
+               {
+                       certificate_t *cert = (certificate_t*)entry->value;
+                       cert->destroy(cert);
+                       break;
+               }
+               case AUTH_HELPER_IM_HASH_URL:
+               case AUTH_HELPER_SUBJECT_HASH_URL:
+               {
+                       free(entry->value);
+                       break;
+               }
+               case AUTH_RULE_AUTH_CLASS:
+               case AUTH_RULE_EAP_TYPE:
+               case AUTH_RULE_EAP_VENDOR:
+               case AUTH_RULE_CRL_VALIDATION:
+               case AUTH_RULE_OCSP_VALIDATION:
+                       break;
+       }
+}
+
+/**
+ * Implementation of auth_cfg_t.replace.
+ */
+static void replace(auth_cfg_t *this, entry_enumerator_t *enumerator,
+                                       auth_rule_t type, ...)
+{
+       if (enumerator->current)
+       {
+               va_list args;
+               
+               va_start(args, type);
+               
+               destroy_entry_value(enumerator->current);
+               enumerator->current->type = type;
+               switch (type)
+               {
+                       case AUTH_RULE_AUTH_CLASS:
+                       case AUTH_RULE_EAP_TYPE:
+                       case AUTH_RULE_EAP_VENDOR:
+                       case AUTH_RULE_CRL_VALIDATION:
+                       case AUTH_RULE_OCSP_VALIDATION:
+                               /* integer type */
+                               enumerator->current->value = (void*)va_arg(args, u_int);
+                               break;
+                       case AUTH_RULE_IDENTITY:
+                       case AUTH_RULE_EAP_IDENTITY:
+                       case AUTH_RULE_AC_GROUP:
+                       case AUTH_RULE_CA_CERT:
+                       case AUTH_RULE_IM_CERT:
+                       case AUTH_RULE_SUBJECT_CERT:
+                       case AUTH_HELPER_IM_CERT:
+                       case AUTH_HELPER_SUBJECT_CERT:
+                       case AUTH_HELPER_IM_HASH_URL:
+                       case AUTH_HELPER_SUBJECT_HASH_URL:
+                               /* pointer type */
+                               enumerator->current->value = va_arg(args, void*);
+                               break;
+               }
+               va_end(args);
+       }
+}
+
+/**
+ * Implementation of auth_cfg_t.get.
+ */
+static void* get(private_auth_cfg_t *this, auth_rule_t type)
+{
+       enumerator_t *enumerator;
+       void *current_value, *best_value = NULL;
+       auth_rule_t current_type;
+       bool found = FALSE;
+       
+       enumerator = create_enumerator(this);
+       while (enumerator->enumerate(enumerator, &current_type, &current_value))
+       {
+               if (type == current_type)
+               {
+                       if (type == AUTH_RULE_CRL_VALIDATION ||
+                               type == AUTH_RULE_OCSP_VALIDATION)
+                       {       /* for CRL/OCSP validation, always get() the highest value */
+                               if (!found || current_value > best_value)
+                               {
+                                       best_value = current_value;
+                               }
+                               found = TRUE;
+                               continue;
+                       }
+                       best_value = current_value;
+                       found = TRUE;
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+       if (found)
+       {
+               return best_value;
+       }
+       switch (type)
+       {
+               /* use some sane defaults if we don't find an entry */
+               case AUTH_RULE_AUTH_CLASS:
+                       return (void*)AUTH_CLASS_ANY;
+               case AUTH_RULE_EAP_TYPE:
+                       return (void*)EAP_NAK;
+               case AUTH_RULE_EAP_VENDOR:
+                       return (void*)0;
+               case AUTH_RULE_CRL_VALIDATION:
+               case AUTH_RULE_OCSP_VALIDATION:
+                       return (void*)VALIDATION_FAILED;
+               case AUTH_RULE_IDENTITY:
+               case AUTH_RULE_EAP_IDENTITY:
+               case AUTH_RULE_AC_GROUP:
+               case AUTH_RULE_CA_CERT:
+               case AUTH_RULE_IM_CERT:
+               case AUTH_RULE_SUBJECT_CERT:
+               case AUTH_HELPER_IM_CERT:
+               case AUTH_HELPER_SUBJECT_CERT:
+               case AUTH_HELPER_IM_HASH_URL:
+               case AUTH_HELPER_SUBJECT_HASH_URL:
+               default:
+                       return NULL;
+       }
+}
+
+/**
+ * Implementation of auth_cfg_t.add.
+ */
+static void add(private_auth_cfg_t *this, auth_rule_t type, ...)
+{
+       entry_t *entry = malloc_thing(entry_t);
+       va_list args;
+       
+       va_start(args, type);
+       entry->type = type;
+       switch (type)
+       {
+               case AUTH_RULE_AUTH_CLASS:
+               case AUTH_RULE_EAP_TYPE:
+               case AUTH_RULE_EAP_VENDOR:
+               case AUTH_RULE_CRL_VALIDATION:
+               case AUTH_RULE_OCSP_VALIDATION:
+                       /* integer type */
+                       entry->value = (void*)va_arg(args, u_int);
+                       break;
+               case AUTH_RULE_IDENTITY:
+               case AUTH_RULE_EAP_IDENTITY:
+               case AUTH_RULE_AC_GROUP:
+               case AUTH_RULE_CA_CERT:
+               case AUTH_RULE_IM_CERT:
+               case AUTH_RULE_SUBJECT_CERT:
+               case AUTH_HELPER_IM_CERT:
+               case AUTH_HELPER_SUBJECT_CERT:
+               case AUTH_HELPER_IM_HASH_URL:
+               case AUTH_HELPER_SUBJECT_HASH_URL:
+                       /* pointer type */
+                       entry->value = va_arg(args, void*);
+                       break;
+       }
+       va_end(args);
+       this->entries->insert_last(this->entries, entry);
+}
+
+/**
+ * Implementation of auth_cfg_t.complies.
+ */
+static bool complies(private_auth_cfg_t *this, auth_cfg_t *constraints,
+                                        bool log_error)
+{
+       enumerator_t *e1, *e2;
+       bool success = TRUE;
+       auth_rule_t t1, t2;
+       void *value;
+       
+       e1 = constraints->create_enumerator(constraints);
+       while (e1->enumerate(e1, &t1, &value))
+       {
+               switch (t1)
+               {
+                       case AUTH_RULE_CA_CERT:
+                       case AUTH_RULE_IM_CERT:
+                       {
+                               certificate_t *c1, *c2;
+                               
+                               c1 = (certificate_t*)value;
+                               
+                               success = FALSE;
+                               e2 = create_enumerator(this);
+                               while (e2->enumerate(e2, &t2, &c2))
+                               {
+                                       if ((t2 == AUTH_RULE_CA_CERT || t2 == AUTH_RULE_IM_CERT) &&
+                                               c1->equals(c1, c2))
+                                       {
+                                               success = TRUE;
+                                       }
+                               }
+                               e2->destroy(e2);
+                               if (!success && log_error)
+                               {
+                                       DBG1(DBG_CFG, "constraint check failed: peer not "
+                                                "authenticated by CA '%D'.", c1->get_subject(c1));
+                               }
+                               break;
+                       }
+                       case AUTH_RULE_SUBJECT_CERT:
+                       {
+                               certificate_t *c1, *c2;
+                               
+                               c1 = (certificate_t*)value;
+                               c2 = get(this, AUTH_RULE_SUBJECT_CERT);
+                               if (!c2 || !c1->equals(c1, c2))
+                               {
+                                       success = FALSE;
+                                       if (log_error)
+                                       {
+                                               DBG1(DBG_CFG, "constraint check failed: peer not "
+                                                        "authenticated with peer cert '%D'.",
+                                                        c1->get_subject(c1));
+                                       }
+                               }
+                               break;
+                       }
+                       case AUTH_RULE_CRL_VALIDATION:
+                       case AUTH_RULE_OCSP_VALIDATION:
+                       {
+                               cert_validation_t validated, required;
+                               
+                               required = (uintptr_t)value;
+                               validated = (uintptr_t)get(this, t1);
+                               switch (required)
+                               {
+                                       case VALIDATION_FAILED:
+                                               /* no constraint */
+                                               break;
+                                       case VALIDATION_SKIPPED:
+                                               if (validated == VALIDATION_SKIPPED)
+                                               {
+                                                       break;
+                                               }
+                                               /* FALL */
+                                       case VALIDATION_GOOD:
+                                               if (validated == VALIDATION_GOOD)
+                                               {
+                                                       break;
+                                               }
+                                               /* FALL */
+                                       default:
+                                               success = FALSE;
+                                               if (log_error)
+                                               {
+                                                       DBG1(DBG_CFG, "constraint check failed: %N is %N, "
+                                                                "but requires at least %N", auth_rule_names,
+                                                                t1, cert_validation_names, validated,
+                                                                cert_validation_names, required);
+                                               }
+                                               break;
+                               }
+                               break;
+                       }
+                       case AUTH_RULE_IDENTITY:
+                       case AUTH_RULE_EAP_IDENTITY:
+                       {
+                               identification_t *id1, *id2;
+                               
+                               id1 = (identification_t*)value;
+                               id2 = get(this, t1);
+                               if (!id2 || !id2->matches(id2, id1))
+                               {
+                                       success = FALSE;
+                                       if (log_error)
+                                       {
+                                               DBG1(DBG_CFG, "constraint check failed: %sidentity '%D'"
+                                                        " required ", t1 == AUTH_RULE_IDENTITY ? "" :
+                                                        "EAP ", id1);
+                                       }
+                               }
+                               break;
+                       }
+                       case AUTH_RULE_AUTH_CLASS:
+                       {
+                               if ((uintptr_t)value != AUTH_CLASS_ANY &&
+                                       (uintptr_t)value != (uintptr_t)get(this, t1))
+                               {
+                                       success = FALSE;
+                                       if (log_error)
+                                       {
+                                               DBG1(DBG_CFG, "constraint requires %N authentication, "
+                                                        "but %N was used", auth_class_names, (uintptr_t)value,
+                                                        auth_class_names, (uintptr_t)get(this, t1));
+                                       }
+                               }
+                               break;
+                       }
+                       case AUTH_RULE_EAP_TYPE:
+                       {
+                               if ((uintptr_t)value != (uintptr_t)get(this, t1))
+                               {
+                                       success = FALSE;
+                                       if (log_error)
+                                       {
+                                               DBG1(DBG_CFG, "constraint requires %N, "
+                                                        "but %N was used", eap_type_names, (uintptr_t)value,
+                                                        eap_type_names,  (uintptr_t)get(this, t1));
+                                       }
+                               }
+                               break;
+                       }
+                       case AUTH_RULE_EAP_VENDOR:
+                       {
+                               if ((uintptr_t)value != (uintptr_t)get(this, t1))
+                               {
+                                       success = FALSE;
+                                       if (log_error)
+                                       {
+                                               DBG1(DBG_CFG, "constraint requires EAP vendor %d, "
+                                                        "but %d was used", (uintptr_t)value,
+                                                        (uintptr_t)get(this, t1));
+                                       }
+                               }
+                               break;
+                       }
+                       case AUTH_RULE_AC_GROUP:
+                       {
+                               success = FALSE;
+                               if (log_error)
+                               {
+                                       DBG1(DBG_CFG, "constraint check %N not implemented!",
+                                                auth_rule_names, t1);
+                               }
+                               break;
+                       }
+                       case AUTH_HELPER_IM_CERT:
+                       case AUTH_HELPER_SUBJECT_CERT:
+                       case AUTH_HELPER_IM_HASH_URL:
+                       case AUTH_HELPER_SUBJECT_HASH_URL:
+                               /* skip helpers */
+                               continue;
+               }
+               if (!success)
+               {
+                       break;
+               }
+       }
+       e1->destroy(e1);
+       return success;
+}
+
+/**
+ * Implementation of auth_cfg_t.merge.
+ */
+static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy)
+{
+       if (!other)
+       {       /* nothing to merge */
+               return;
+       }
+       if (copy)
+       {
+               enumerator_t *enumerator;
+               auth_rule_t type;
+               void *value;
+               
+               enumerator = create_enumerator(other);
+               while (enumerator->enumerate(enumerator, &type, &value))
+               {
+                       switch (type)
+                       {
+                               case AUTH_RULE_CA_CERT:
+                               case AUTH_RULE_IM_CERT:
+                               case AUTH_RULE_SUBJECT_CERT:
+                               case AUTH_HELPER_IM_CERT:
+                               case AUTH_HELPER_SUBJECT_CERT:
+                               {
+                                       certificate_t *cert = (certificate_t*)value;
+                                       
+                                       add(this, type, cert->get_ref(cert));
+                                       break;
+                               }
+                               case AUTH_RULE_CRL_VALIDATION:
+                               case AUTH_RULE_OCSP_VALIDATION:
+                               case AUTH_RULE_AUTH_CLASS:
+                               case AUTH_RULE_EAP_TYPE:
+                               case AUTH_RULE_EAP_VENDOR:
+                               {
+                                       add(this, type, (uintptr_t)value);
+                                       break;
+                               }
+                               case AUTH_RULE_IDENTITY:
+                               case AUTH_RULE_EAP_IDENTITY:
+                               case AUTH_RULE_AC_GROUP:
+                               {
+                                       identification_t *id = (identification_t*)value;
+                                       
+                                       add(this, type, id->clone(id));
+                                       break;
+                               }
+                               case AUTH_HELPER_IM_HASH_URL:
+                               case AUTH_HELPER_SUBJECT_HASH_URL:
+                               {
+                                       add(this, type, strdup((char*)value));
+                                       break;
+                               }
+                       }
+               }
+               enumerator->destroy(enumerator);
+       }
+       else
+       {
+               entry_t *entry;
+               
+               while (other->entries->remove_first(other->entries,
+                                                                                       (void**)&entry) == SUCCESS)
+               {
+                       this->entries->insert_last(this->entries, entry);
+               }
+       }
+}
+
+/**
+ * Implementation of auth_cfg_t.equals.
+ */
+static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other)
+{
+       enumerator_t *e1, *e2;
+       entry_t *i1, *i2;
+       bool equal = TRUE, found;
+       
+       if (this->entries->get_count(this->entries) !=
+               other->entries->get_count(other->entries))
+       {
+               return FALSE;
+       }
+       e1 = this->entries->create_enumerator(this->entries);
+       while (e1->enumerate(e1, &i1))
+       {
+               found = FALSE;
+               e2 = other->entries->create_enumerator(other->entries);
+               while (e2->enumerate(e2, &i2))
+               {
+                       if (i1->type == i2->type)
+                       {
+                               switch (i1->type)
+                               {
+                                       case AUTH_RULE_AUTH_CLASS:
+                                       case AUTH_RULE_EAP_TYPE:
+                                       case AUTH_RULE_EAP_VENDOR:
+                                       case AUTH_RULE_CRL_VALIDATION:
+                                       case AUTH_RULE_OCSP_VALIDATION:
+                                       {
+                                               if (i1->value == i2->value)
+                                               {
+                                                       found = TRUE;
+                                                       break;
+                                               }
+                                               continue;
+                                       }
+                                       case AUTH_RULE_CA_CERT:
+                                       case AUTH_RULE_IM_CERT:
+                                       case AUTH_RULE_SUBJECT_CERT:
+                                       case AUTH_HELPER_IM_CERT:
+                                       case AUTH_HELPER_SUBJECT_CERT:
+                                       {
+                                               certificate_t *c1, *c2;
+                                               
+                                               c1 = (certificate_t*)i1->value;
+                                               c2 = (certificate_t*)i2->value;
+                                               
+                                               if (c1->equals(c1, c2))
+                                               {
+                                                       found = TRUE;
+                                                       break;
+                                               }
+                                               continue;
+                                       }
+                                       case AUTH_RULE_IDENTITY:
+                                       case AUTH_RULE_EAP_IDENTITY:
+                                       case AUTH_RULE_AC_GROUP:
+                                       {
+                                               identification_t *id1, *id2;
+                                               
+                                               id1 = (identification_t*)i1->value;
+                                               id2 = (identification_t*)i2->value;
+                                               
+                                               if (id1->equals(id1, id2))
+                                               {
+                                                       found = TRUE;
+                                                       break;
+                                               }
+                                               continue;
+                                       }
+                                       case AUTH_HELPER_IM_HASH_URL:
+                                       case AUTH_HELPER_SUBJECT_HASH_URL:
+                                       {
+                                               if (streq(i1->value, i2->value))
+                                               {
+                                                       found = TRUE;
+                                                       break;
+                                               }
+                                               continue;
+                                       }
+                               }
+                               break;
+                       }
+               }
+               e2->destroy(e2);
+               if (!found)
+               {
+                       equal = FALSE;
+                       break;
+               }
+       }
+       e1->destroy(e1);
+       return equal;
+}
+
+/**
+ * Implementation of auth_cfg_t.purge
+ */
+static void purge(private_auth_cfg_t *this, bool keep_ca)
+{
+       entry_t *entry;
+       linked_list_t *cas;
+       
+       cas = linked_list_create();
+       while (this->entries->remove_last(this->entries, (void**)&entry) == SUCCESS)
+       {
+               if (keep_ca && entry->type == AUTH_RULE_CA_CERT)
+               {
+                       cas->insert_first(cas, entry);
+               }
+               else
+               {
+                       destroy_entry_value(entry);
+                       free(entry);
+               }
+       }
+       while (cas->remove_last(cas, (void**)&entry) == SUCCESS)
+       {
+               this->entries->insert_first(this->entries, entry);
+       }
+       cas->destroy(cas);
+}
+
+/**
+ * Implementation of auth_cfg_t.clone
+ */
+static auth_cfg_t* clone_(private_auth_cfg_t *this)
+{
+       enumerator_t *enumerator;
+       auth_cfg_t *clone;
+       entry_t *entry;
+       
+       clone = auth_cfg_create();
+       enumerator = this->entries->create_enumerator(this->entries);
+       while (enumerator->enumerate(enumerator, &entry))
+       {
+               switch (entry->type)
+               {
+                       case AUTH_RULE_IDENTITY:
+                       case AUTH_RULE_EAP_IDENTITY:
+                       case AUTH_RULE_AC_GROUP:
+                       {
+                               identification_t *id = (identification_t*)entry->value;
+                               clone->add(clone, entry->type, id->clone(id));
+                               break;
+                       }
+                       case AUTH_RULE_CA_CERT:
+                       case AUTH_RULE_IM_CERT:
+                       case AUTH_RULE_SUBJECT_CERT:
+                       case AUTH_HELPER_IM_CERT:
+                       case AUTH_HELPER_SUBJECT_CERT:
+                       {
+                               certificate_t *cert = (certificate_t*)entry->value;
+                               clone->add(clone, entry->type, cert->get_ref(cert));
+                               break;
+                       }
+                       case AUTH_HELPER_IM_HASH_URL:
+                       case AUTH_HELPER_SUBJECT_HASH_URL:
+                       {
+                               clone->add(clone, entry->type, strdup(entry->value));
+                               break;
+                       }
+                       case AUTH_RULE_AUTH_CLASS:
+                       case AUTH_RULE_EAP_TYPE:
+                       case AUTH_RULE_EAP_VENDOR:
+                       case AUTH_RULE_CRL_VALIDATION:
+                       case AUTH_RULE_OCSP_VALIDATION:
+                               clone->add(clone, entry->type, (uintptr_t)entry->value);
+                               break;
+               }
+       }
+       enumerator->destroy(enumerator);
+       return clone;
+}
+
+/**
+ * Implementation of auth_cfg_t.destroy
+ */
+static void destroy(private_auth_cfg_t *this)
+{
+       purge(this, FALSE);
+       this->entries->destroy(this->entries);
+       free(this);
+}
+
+/*
+ * see header file
+ */
+auth_cfg_t *auth_cfg_create()
+{
+       private_auth_cfg_t *this = malloc_thing(private_auth_cfg_t);
+       
+       this->public.add = (void(*)(auth_cfg_t*, auth_rule_t type, ...))add;
+       this->public.get = (void*(*)(auth_cfg_t*, auth_rule_t type))get;
+       this->public.create_enumerator = (enumerator_t*(*)(auth_cfg_t*))create_enumerator;
+       this->public.replace = (void(*)(auth_cfg_t*,enumerator_t*,auth_rule_t,...))replace;
+       this->public.complies = (bool(*)(auth_cfg_t*, auth_cfg_t *,bool))complies;
+       this->public.merge = (void(*)(auth_cfg_t*, auth_cfg_t *other,bool))merge;
+       this->public.purge = (void(*)(auth_cfg_t*,bool))purge;
+       this->public.equals = (bool(*)(auth_cfg_t*, auth_cfg_t *other))equals;
+       this->public.clone = (auth_cfg_t*(*)(auth_cfg_t*))clone_;
+       this->public.destroy = (void(*)(auth_cfg_t*))destroy;
+       
+       this->entries = linked_list_create();
+       
+       return &this->public;
+}
+
diff --git a/src/charon/config/auth_cfg.h b/src/charon/config/auth_cfg.h
new file mode 100644 (file)
index 0000000..c6bc195
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2007-2009 Martin Willi
+ * Copyright (C) 2008 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup auth_cfg auth_cfg
+ * @{ @ingroup config
+ */
+
+#ifndef AUTH_CFG_H_
+#define AUTH_CFG_H_
+
+#include <utils/enumerator.h>
+
+typedef struct auth_cfg_t auth_cfg_t;
+typedef enum auth_rule_t auth_rule_t;
+
+/**
+ * Authentication config to use during authentication process.
+ *
+ * Each authentication config contains a set of rules. These rule-sets are used
+ * in two ways:
+ * - For configs specifying local authentication behavior, the rules define
+ *   which authentication method in which way.
+ * - For configs specifying remote peer authentication, the rules define
+ *   constraints the peer has to fullfill.
+ *
+ * Additionally to the rules, there is a set of helper items. These are used
+ * to transport credentials during the authentication process.
+ */
+enum auth_rule_t {
+       
+       /** identity to use for IKEv2 authentication exchange, identification_t* */
+       AUTH_RULE_IDENTITY,
+       /** authentication class, auth_class_t */
+       AUTH_RULE_AUTH_CLASS,
+       /** EAP identity to use within EAP-Identity exchange, identification_t* */
+       AUTH_RULE_EAP_IDENTITY,
+       /** EAP type to propose for peer authentication, eap_type_t */
+       AUTH_RULE_EAP_TYPE,
+       /** EAP vendor for vendor specific type, u_int32_t */
+       AUTH_RULE_EAP_VENDOR,
+       /** certificate authority, certificate_t* */
+       AUTH_RULE_CA_CERT,
+       /** intermediate certificate in trustchain, certificate_t* */
+       AUTH_RULE_IM_CERT,
+       /** subject certificate, certificate_t* */
+       AUTH_RULE_SUBJECT_CERT,
+       /** result of a CRL validation, cert_validation_t */
+       AUTH_RULE_CRL_VALIDATION,
+       /** result of a OCSP validation, cert_validation_t */
+       AUTH_RULE_OCSP_VALIDATION,
+       /** subject is in attribute certificate group, identification_t* */
+       AUTH_RULE_AC_GROUP,
+       
+       /** intermediate certificate, certificate_t* */
+       AUTH_HELPER_IM_CERT,
+       /** subject certificate, certificate_t* */
+       AUTH_HELPER_SUBJECT_CERT,
+       /** Hash and URL of a intermediate certificate, char* */
+       AUTH_HELPER_IM_HASH_URL,
+       /** Hash and URL of a end-entity certificate, char* */
+       AUTH_HELPER_SUBJECT_HASH_URL,
+};
+
+/**
+ * enum name for auth_rule_t.
+ */
+extern enum_name_t *auth_rule_names;
+
+/**
+ * Authentication/Authorization round.
+ *
+ * RFC4739 defines multiple authentication rounds. This class defines such
+ * a round from a configuration perspective, either for the local or the remote
+ * peer. Local config are called "rulesets", as they define how we authenticate.
+ * Remote peer configs are called "constraits", they define what is needed to 
+ * complete the authentication round successfully.
+ *
+ * @verbatim
+
+   [Repeat for each configuration]
+   +--------------------------------------------------+
+   |                                                  |
+   |                                                  |
+   |   +----------+     IKE_AUTH       +--------- +   |
+   |   |  config  |   ----------->     |          |   |
+   |   |  ruleset |                    |          |   |
+   |   +----------+ [ <----------- ]   |          |   |
+   |                [ optional EAP ]   |   Peer   |   |
+   |   +----------+ [ -----------> ]   |          |   |
+   |   |  config  |                    |          |   |
+   |   |  constr. |   <-----------     |          |   |
+   |   +----------+     IKE_AUTH       +--------- +   |
+   |                                                  |
+   |                                                  |
+   +--------------------------------------------------+
+
+   @endverbatim
+ *
+ * Values for each items are either pointers (casted to void*) or short
+ * integers (use uintptr_t cast).
+ */
+struct auth_cfg_t {
+
+       /**
+        * Add an rule to the set.
+        *
+        * @param rule          rule type
+        * @param ...           associated value to rule
+        */
+       void (*add)(auth_cfg_t *this, auth_rule_t rule, ...);
+       
+       /**
+        * Get an rule value.
+        *
+        * @param rule          rule type
+        * @return                      bool if item has been found
+        */
+       void* (*get)(auth_cfg_t *this, auth_rule_t rule);
+       
+       /**
+        * Create an enumerator over added rules.
+        *
+        * @return                      enumerator over (auth_rule_t, union{void*,uintpr_t})
+        */
+       enumerator_t* (*create_enumerator)(auth_cfg_t *this);
+       
+       /**
+        * Replace an rule at enumerator position.
+        *
+        * @param pos           enumerator position position
+        * @param rule          rule type
+        * @param ...           associated value to rule
+        */
+       void (*replace)(auth_cfg_t *this, enumerator_t *pos,
+                                       auth_rule_t rule, ...);
+       
+       /**
+        * Check if a used config fulfills a set of configured constraints.
+        *
+        * @param constraints   required authorization rules
+        * @param log_error             wheter to log compliance errors
+        * @return                              TRUE if this complies with constraints
+        */
+       bool (*complies)(auth_cfg_t *this, auth_cfg_t *constraints, bool log_error);
+       
+       /**
+        * Merge items from other into this.
+        *
+        * @param other         items to read for merge
+        * @param copy          TRUE to copy items, FALSE to move them
+        */
+       void (*merge)(auth_cfg_t *this, auth_cfg_t *other, bool copy);
+       
+       /**
+        * Purge all rules in a config.
+        *
+        * @param keep_ca       wheter to keep AUTH_RULE_CA_CERT entries
+        */
+       void (*purge)(auth_cfg_t *this, bool keep_ca);
+       
+       /**
+        * Check two configs for equality.
+        *
+        * @param other         other config to compaire against this
+        * @return                      TRUE if auth infos identical
+        */
+       bool (*equals)(auth_cfg_t *this, auth_cfg_t *other);
+       
+       /**
+        * Clone a authentication config, including all rules.
+        *
+        * @return                      cloned configuration
+        */
+       auth_cfg_t* (*clone)(auth_cfg_t *this);
+       
+       /**
+        * Destroy a config with all associated rules/values.
+        */
+       void (*destroy)(auth_cfg_t *this);
+};
+
+/**
+ * Create a authentication config.
+ */
+auth_cfg_t *auth_cfg_create();
+
+#endif /** AUTH_CFG_H_ @}*/
index 4673d3984ff13680d6dd073da3a6254ec05932c4..42633f73b1d77bfe2888c25e406fb691051f3e40 100644 (file)
@@ -28,7 +28,6 @@ typedef struct backend_t backend_t;
 #include <library.h>
 #include <config/ike_cfg.h>
 #include <config/peer_cfg.h>
-#include <credentials/auth_info.h>
 #include <utils/linked_list.h>
 
 /**
@@ -45,6 +44,10 @@ struct backend_t {
         *
         * Hosts may be NULL to get all.
         *
+        * There is no requirement for the backend to filter the configurations
+        * using the supplied hosts; but it may do so if it increases lookup times
+        * (e.g. include hosts in SQL query).
+        *
         * @param me            address of local host
         * @param other         address of remote host
         * @return                      enumerator over ike_cfg_t's
@@ -52,10 +55,17 @@ struct backend_t {
        enumerator_t* (*create_ike_cfg_enumerator)(backend_t *this,
                                                                                           host_t *me, host_t *other);
        /**
-        * Create an enumerator over all Peer configs matching two IDs.
+        * Create an enumerator over all peer configs matching two identities.
         *
         * IDs may be NULL to get all.
         *
+        * As configurations are looked up in the first authentication round (when
+        * multiple authentication), the backend implementation should compare
+        * the identities to the first auth_cfgs only.
+        * There is no requirement for the backend to filter the configurations
+        * using the supplied identities; but it may do so if it increases lookup
+        * times (e.g. include hosts in SQL query).
+        *
         * @param me            identity of ourself
         * @param other         identity of remote host
         * @return                      enumerator over peer_cfg_t
@@ -64,7 +74,7 @@ struct backend_t {
                                                                                                identification_t *me,
                                                                                                identification_t *other);
        /**
-        * Get a peer_cfg identified by it's name, or a name of its child.
+        * Get a peer_cfg identified by it's name, or a name of its children.
         *
         * @param name                          name of peer/child cfg
         * @return                                      matching peer_config, or NULL if none found
index c31df8d04a63e0317ad0e98b25027a660f860b4e..28e50ef0a1c0c8b3e1592233d770dfdafec370e7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007 Martin Willi
+ * Copyright (C) 2007-2009 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -67,15 +67,6 @@ typedef struct {
        host_t *other;
 } ike_data_t;
 
-/**
- * data to pass nested peer enumerator
- */
-typedef struct {
-       private_backend_manager_t *this;
-       identification_t *me;
-       identification_t *other;
-} peer_data_t;
-
 /**
  * inner enumerator constructor for IKE cfgs
  */
@@ -84,60 +75,59 @@ static enumerator_t *ike_enum_create(backend_t *backend, ike_data_t *data)
        return backend->create_ike_cfg_enumerator(backend, data->me, data->other);
 }
 
-/**
- * inner enumerator constructor for Peer cfgs
- */
-static enumerator_t *peer_enum_create(backend_t *backend, peer_data_t *data)
-{
-       return backend->create_peer_cfg_enumerator(backend, data->me, data->other);
-}
-/**
- * inner enumerator constructor for all Peer cfgs
- */
-static enumerator_t *peer_enum_create_all(backend_t *backend)
-{
-       return backend->create_peer_cfg_enumerator(backend, NULL, NULL);
-}
-
 /**
  * get a match of a candidate ike_cfg for two hosts
  */
-static ike_cfg_match_t get_match(ike_cfg_t *cand, host_t *me, host_t *other)
+static ike_cfg_match_t get_ike_match(ike_cfg_t *cand, host_t *me, host_t *other)
 {
        host_t *me_cand, *other_cand;
        ike_cfg_match_t match = MATCH_NONE;
        
-       me_cand = host_create_from_dns(cand->get_my_addr(cand),
-                                                                  me->get_family(me), 0);
-       if (!me_cand)
-       {
-               return MATCH_NONE;
-       }
-       if (me_cand->ip_equals(me_cand, me))
+       if (me)
        {
-               match += MATCH_ME;
+               me_cand = host_create_from_dns(cand->get_my_addr(cand),
+                                                                          me->get_family(me), 0);
+               if (!me_cand)
+               {
+                       return MATCH_NONE;
+               }
+               if (me_cand->ip_equals(me_cand, me))
+               {
+                       match += MATCH_ME;
+               }
+               else if (me_cand->is_anyaddr(me_cand))
+               {
+                       match += MATCH_ANY;
+               }
+               me_cand->destroy(me_cand);
        }
-       else if (me_cand->is_anyaddr(me_cand))
+       else
        {
                match += MATCH_ANY;
        }
-       me_cand->destroy(me_cand);
        
-       other_cand = host_create_from_dns(cand->get_other_addr(cand),
-                                                                         other->get_family(other), 0);
-       if (!other_cand)
-       {
-               return MATCH_NONE;
-       }
-       if (other_cand->ip_equals(other_cand, other))
+       if (other)
        {
-               match += MATCH_OTHER;
+               other_cand = host_create_from_dns(cand->get_other_addr(cand),
+                                                                                 other->get_family(other), 0);
+               if (!other_cand)
+               {
+                       return MATCH_NONE;
+               }
+               if (other_cand->ip_equals(other_cand, other))
+               {
+                       match += MATCH_OTHER;
+               }
+               else if (other_cand->is_anyaddr(other_cand))
+               {
+                       match += MATCH_ANY;
+               }
+               other_cand->destroy(other_cand);
        }
-       else if (other_cand->is_anyaddr(other_cand))
+       else
        {
                match += MATCH_ANY;
        }
-       other_cand->destroy(other_cand);
        return match;
 }
 
@@ -165,7 +155,7 @@ static ike_cfg_t *get_ike_cfg(private_backend_manager_t *this,
                                                (void*)ike_enum_create, data, (void*)free);
        while (enumerator->enumerate(enumerator, (void**)&current))
        {
-               match = get_match(current, me, other);
+               match = get_ike_match(current, me, other);
                
                if (match)
                {
@@ -191,87 +181,198 @@ static ike_cfg_t *get_ike_cfg(private_backend_manager_t *this,
        return found;
 }
 
+/**
+ * Get the best ID match in one of the configs auth_cfg
+ */
+static id_match_t get_peer_match(identification_t *id,
+                                                                peer_cfg_t *cfg, bool local)
+{
+       enumerator_t *enumerator;
+       auth_cfg_t *auth;
+       identification_t *candidate;
+       id_match_t match = ID_MATCH_NONE;
+       
+       if (!id)
+       {
+               return ID_MATCH_ANY;
+       }
+       
+       /* compare first auth config only */
+       enumerator = cfg->create_auth_cfg_enumerator(cfg, local);
+       if (enumerator->enumerate(enumerator, &auth))
+       {
+               candidate = auth->get(auth, AUTH_RULE_IDENTITY);
+               if (candidate)
+               {
+                       match = id->matches(id, candidate);
+                       /* match vice-versa, as the proposed IDr might be ANY */
+                       if (!match)
+                       {
+                               match = candidate->matches(candidate, id);
+                       }
+               }
+               else
+               {
+                       match = ID_MATCH_ANY;
+               }
+       }
+       enumerator->destroy(enumerator);
+       return match;
+}
+
+/**
+ * data to pass nested peer enumerator
+ */
+typedef struct {
+       rwlock_t *lock;
+       identification_t *me;
+       identification_t *other;
+} peer_data_t;
 
-static enumerator_t *create_peer_cfg_enumerator(private_backend_manager_t *this)
+/**
+ * list element to help sorting
+ */
+typedef struct {
+       id_match_t match_peer;
+       ike_cfg_match_t match_ike;
+       peer_cfg_t *cfg;
+} match_entry_t;
+
+/**
+ * inner enumerator constructor for peer cfgs
+ */
+static enumerator_t *peer_enum_create(backend_t *backend, peer_data_t *data)
 {
-       this->lock->read_lock(this->lock);
-       return enumerator_create_nested(
-                                                       this->backends->create_enumerator(this->backends),
-                                                       (void*)peer_enum_create_all, this->lock,
-                                                       (void*)this->lock->unlock);
+       return backend->create_peer_cfg_enumerator(backend, data->me, data->other);
+}
+
+/**
+ * unlock/cleanup peer enumerator
+ */
+static void peer_enum_destroy(peer_data_t *data)
+{
+       data->lock->unlock(data->lock);
+       free(data);
+}
+
+/**
+ * convert enumerator value from match_entry to config
+ */
+static bool peer_enum_filter(linked_list_t *configs,
+                                                        match_entry_t **in, peer_cfg_t **out)
+{
+       *out = (*in)->cfg;
+       return TRUE;
+}
+
+/**
+ * Clean up temporary config list
+ */
+static void peer_enum_filter_destroy(linked_list_t *configs)
+{
+       match_entry_t *entry;
+       
+       while (configs->remove_last(configs, (void**)&entry) == SUCCESS)
+       {
+               entry->cfg->destroy(entry->cfg);
+               free(entry);
+       }
+       configs->destroy(configs);
+}
+
+/**
+ * Insert entry into match-sorted list, using helper
+ */
+static void insert_sorted(match_entry_t *entry, linked_list_t *list,
+                                                 linked_list_t *helper)
+{
+       match_entry_t *current;
+       
+       while (list->remove_first(list, (void**)&current) == SUCCESS)
+       {
+               helper->insert_last(helper, current);
+       }
+       while (helper->remove_first(helper, (void**)&current) == SUCCESS)
+       {
+               if (entry && (
+                        (entry->match_ike > current->match_ike &&
+                         entry->match_peer >= current->match_peer) ||
+                        (entry->match_ike >= current->match_ike &&
+                         entry->match_peer > current->match_peer)))
+               {
+                       list->insert_last(list, entry);
+                       entry = NULL;
+               }
+               list->insert_last(list, current);
+       }
+       if (entry)
+       {
+               list->insert_last(list, entry);
+       }
 }
 
 /**
- * implements backend_manager_t.get_peer_cfg.
+ * Implements backend_manager_t.create_peer_cfg_enumerator.
  */                    
-static peer_cfg_t *get_peer_cfg(private_backend_manager_t *this, host_t *me,
-                                                               host_t *other, identification_t *my_id,
-                                                               identification_t *other_id, auth_info_t *auth)
+static enumerator_t *create_peer_cfg_enumerator(private_backend_manager_t *this,
+                                                       host_t *me, host_t *other, identification_t *my_id,
+                                                       identification_t *other_id)
 {
-       peer_cfg_t *current, *found = NULL;
        enumerator_t *enumerator;
-       id_match_t best_peer = ID_MATCH_NONE;
-       ike_cfg_match_t best_ike = MATCH_NONE;
        peer_data_t *data;
-       
-       DBG2(DBG_CFG, "looking for a peer config for %H[%D]...%H[%D]",
-                me, my_id, other, other_id);
+       peer_cfg_t *cfg;
+       linked_list_t *configs, *helper;
        
        data = malloc_thing(peer_data_t);
-       data->this = this;
+       data->lock = this->lock;
        data->me = my_id;
        data->other = other_id;
        
+       /* create a sorted list with all matches */
        this->lock->read_lock(this->lock);
        enumerator = enumerator_create_nested(
-                                               this->backends->create_enumerator(this->backends),
-                                               (void*)peer_enum_create, data, (void*)free);
-       while (enumerator->enumerate(enumerator, &current))
+                                       this->backends->create_enumerator(this->backends),
+                                       (void*)peer_enum_create, data, (void*)peer_enum_destroy);
+       
+       if (!me && !other && !my_id && !other_id)
+       {       /* shortcut if we are doing a "listall" */
+               return enumerator;
+       }
+       
+       DBG1(DBG_CFG, "looking for peer configs matching %H[%D]...%H[%D]",
+                me, my_id, other, other_id);
+       
+       configs = linked_list_create();
+       /* only once allocated helper list for sorting */
+       helper = linked_list_create();
+       while (enumerator->enumerate(enumerator, &cfg))
        {
-               identification_t *my_cand, *other_cand;
-               id_match_t m1, m2, match_peer;
+               id_match_t match_peer_me, match_peer_other;
                ike_cfg_match_t match_ike;
+               match_entry_t *entry;
                
-               my_cand = current->get_my_id(current);
-               other_cand = current->get_other_id(current);
-               
-               /* own ID may have wildcards in both, config and request (missing IDr) */
-               m1 = my_cand->matches(my_cand, my_id);
-               if (!m1)
-               {
-                       m1 = my_id->matches(my_id, my_cand);
-               }
-               m2 = other_id->matches(other_id, other_cand);
-               
-               match_peer = m1 + m2;
-               match_ike = get_match(current->get_ike_cfg(current), me, other);
+               match_peer_me = get_peer_match(my_id, cfg, TRUE);
+               match_peer_other = get_peer_match(other_id, cfg, FALSE);
+               match_ike = get_ike_match(cfg->get_ike_cfg(cfg), me, other);
                
-               if (m1 && m2 && match_ike && 
-                       auth->complies(auth, current->get_auth(current)))
+               if (match_peer_me && match_peer_other && match_ike)
                {
-                       DBG2(DBG_CFG, "  candidate \"%s\": %D...%D with prio %d.%d",
-                                current->get_name(current), my_cand, other_cand,
-                                match_peer, match_ike);
-                       if ((match_peer > best_peer && match_ike >= best_ike) ||
-                               (match_peer >= best_peer && match_ike > best_ike))
-                       {
-                               DESTROY_IF(found);
-                               found = current;
-                               found->get_ref(found);
-                               best_peer = match_peer;
-                               best_ike = match_ike;
-                       }
+                       DBG2(DBG_CFG, "  candidate \"%s\", match: %d/%d/%d (me/other/ike)",
+                                cfg->get_name(cfg), match_peer_me, match_peer_other, match_ike);
+                       
+                       entry = malloc_thing(match_entry_t);
+                       entry->match_peer = match_peer_me + match_peer_other;
+                       entry->match_ike = match_ike;
+                       entry->cfg = cfg->get_ref(cfg);
+                       insert_sorted(entry, configs, helper);
                }
        }
-       if (found)
-       {
-               DBG1(DBG_CFG, "found matching peer config \"%s\": %D...%D with prio %d.%d",
-                        found->get_name(found), found->get_my_id(found),
-                        found->get_other_id(found), best_peer, best_ike);
-       }
        enumerator->destroy(enumerator);
-       this->lock->unlock(this->lock);
-       return found;
+       helper->destroy(helper);
+       
+       return enumerator_create_filter(configs->create_enumerator(configs),
+                                                                       (void*)peer_enum_filter, configs,
+                                                                       (void*)peer_enum_filter_destroy);
 }
 
 /**
@@ -332,9 +433,8 @@ backend_manager_t *backend_manager_create()
        private_backend_manager_t *this = malloc_thing(private_backend_manager_t);
        
        this->public.get_ike_cfg = (ike_cfg_t* (*)(backend_manager_t*, host_t*, host_t*))get_ike_cfg;
-       this->public.get_peer_cfg = (peer_cfg_t* (*)(backend_manager_t*,host_t*,host_t*,identification_t*,identification_t*,auth_info_t*))get_peer_cfg;
        this->public.get_peer_cfg_by_name = (peer_cfg_t* (*)(backend_manager_t*,char*))get_peer_cfg_by_name;
-       this->public.create_peer_cfg_enumerator = (enumerator_t* (*)(backend_manager_t*))create_peer_cfg_enumerator;
+       this->public.create_peer_cfg_enumerator = (enumerator_t* (*)(backend_manager_t*,host_t*,host_t*,identification_t*,identification_t*))create_peer_cfg_enumerator;
        this->public.add_backend = (void(*)(backend_manager_t*, backend_t *backend))add_backend;
        this->public.remove_backend = (void(*)(backend_manager_t*, backend_t *backend))remove_backend;
        this->public.destroy = (void (*)(backend_manager_t*))destroy;
index 1fd921c488f1524843193cf751b7e5fbc86f8c0d..b3c74fb7b592091e81e6ab63372cc5e0d042b748 100644 (file)
@@ -63,20 +63,6 @@ struct backend_manager_t {
        ike_cfg_t* (*get_ike_cfg)(backend_manager_t *this, 
                                                          host_t *my_host, host_t *other_host);
        
-       /**
-        * Get a peer_config identified by two IDs and authorization info.
-        *
-        * @param me                            own address
-        * @param other                         peer address
-        * @param my_id                         own ID
-        * @param other_id                      peer ID
-        * @param auth_info                     authorization info
-        * @return                                      matching peer_config, or NULL if none found
-        */
-       peer_cfg_t* (*get_peer_cfg)(backend_manager_t *this, host_t *me,
-                                                               host_t *other, identification_t *my_id,
-                                                               identification_t *other_id, auth_info_t *auth);
-       
        /**
         * Get a peer_config identified by it's name.
         *
@@ -86,12 +72,20 @@ struct backend_manager_t {
        peer_cfg_t* (*get_peer_cfg_by_name)(backend_manager_t *this, char *name);
        
        /**
-        * Create an enumerator over all peer configs.
+        * Create an enumerator over all matching peer configs.
+        *
+        * Pass NULL as parameters to match any. The enumerator enumerates over
+        * peer_cfgs, ordered by priority (best match first).
         *
-        * @return                                      enumerator over peer configs
+        * @param me                            local address
+        * @param other                         remote address
+        * @param my_id                         IDr in first authentication round
+        * @param other_id                      IDi in first authentication round
+        * @return                                      enumerator over peer_cfg_t
         */
-       enumerator_t* (*create_peer_cfg_enumerator)(backend_manager_t *this);
-       
+       enumerator_t* (*create_peer_cfg_enumerator)(backend_manager_t *this,
+                                                       host_t *me, host_t *other, identification_t *my_id,
+                                                       identification_t *other_id);
        /**
         * Register a backend on the manager.
         *
index 398244f6df360f62b1aa3746026d27e859557de5..5d9db1b227f0603af1fd0d1dbedc4eddeb19949d 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007-2008 Tobias Brunner
- * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005-2009 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
@@ -81,16 +81,6 @@ struct private_peer_cfg_t {
         */
        mutex_t *mutex;
        
-       /**
-        * id to use to identify us
-        */
-       identification_t *my_id;
-       
-       /**
-        * allowed id for other
-        */
-       identification_t *other_id;
-       
        /**
         * should we send a certificate
         */
@@ -147,10 +137,15 @@ struct private_peer_cfg_t {
        char *pool;
        
        /**
-        * required authorization constraints
+        * local authentication configs (rulesets)
         */
-       auth_info_t *auth;
-
+       linked_list_t *local_auth;
+       
+       /**
+        * remote authentication configs (constraints)
+        */
+       linked_list_t *remote_auth;
+       
 #ifdef ME      
        /**
         * Is this a mediation connection?
@@ -286,22 +281,6 @@ static child_cfg_t* select_child_cfg(private_peer_cfg_t *this,
        return found;
 }
 
-/**
- * Implementation of peer_cfg_t.get_my_id
- */
-static identification_t *get_my_id(private_peer_cfg_t *this)
-{
-       return this->my_id;
-}
-
-/**
- * Implementation of peer_cfg_t.get_other_id
- */
-static identification_t *get_other_id(private_peer_cfg_t *this)
-{
-       return this->other_id;
-}
-
 /**
  * Implementation of peer_cfg_t.get_cert_policy.
  */
@@ -397,13 +376,34 @@ static char* get_pool(private_peer_cfg_t *this)
 {
        return this->pool;
 }
-       
+
 /**
- * Implementation of peer_cfg_t.get_auth.
+ * Implementation of peer_cfg_t.add_auth_cfg
  */
-static auth_info_t* get_auth(private_peer_cfg_t *this)
+static void add_auth_cfg(private_peer_cfg_t *this,
+                                                auth_cfg_t *cfg, bool local)
 {
-       return this->auth;
+       if (local)
+       {
+               this->local_auth->insert_last(this->local_auth, cfg);
+       }
+       else
+       {
+               this->remote_auth->insert_last(this->remote_auth, cfg);
+       }
+}
+
+/**
+ * Implementation of peer_cfg_t.create_auth_cfg_enumerator
+ */
+static enumerator_t* create_auth_cfg_enumerator(private_peer_cfg_t *this,
+                                                                                                bool local)
+{
+       if (local)
+       {
+               return this->local_auth->create_enumerator(this->local_auth);
+       }
+       return this->remote_auth->create_enumerator(this->remote_auth);
 }
 
 #ifdef ME
@@ -432,6 +432,60 @@ static identification_t* get_peer_id(private_peer_cfg_t *this)
 }
 #endif /* ME */
 
+/**
+ * check auth configs for equality
+ */
+static bool auth_cfg_equal(private_peer_cfg_t *this, private_peer_cfg_t *other)
+{
+       enumerator_t *e1, *e2;
+       auth_cfg_t *cfg1, *cfg2;
+       bool equal = TRUE;
+       
+       if (this->local_auth->get_count(this->local_auth) !=
+               other->local_auth->get_count(other->local_auth))
+       {
+               return FALSE;
+       }
+       if (this->remote_auth->get_count(this->remote_auth) !=
+               other->remote_auth->get_count(other->remote_auth))
+       {
+               return FALSE;
+       }
+       
+       e1 = this->local_auth->create_enumerator(this->local_auth);
+       e2 = other->local_auth->create_enumerator(other->local_auth);
+       while (e1->enumerate(e1, &cfg1) && e2->enumerate(e2, &cfg2))
+       {
+               if (!cfg1->equals(cfg1, cfg2))
+               {
+                       equal = FALSE;
+                       break;
+               }
+       }
+       e1->destroy(e1);
+       e2->destroy(e2);
+       
+       if (!equal)
+       {
+               return FALSE;
+       }
+       
+       e1 = this->remote_auth->create_enumerator(this->remote_auth);
+       e2 = other->remote_auth->create_enumerator(other->remote_auth);
+       while (e1->enumerate(e1, &cfg1) && e2->enumerate(e2, &cfg2))
+       {
+               if (!cfg1->equals(cfg1, cfg2))
+               {
+                       equal = FALSE;
+                       break;
+               }
+       }
+       e1->destroy(e1);
+       e2->destroy(e2);
+       
+       return equal;
+}
+
 /**
  * Implementation of peer_cfg_t.equals.
  */
@@ -448,8 +502,6 @@ static bool equals(private_peer_cfg_t *this, private_peer_cfg_t *other)
        
        return (
                this->ike_version == other->ike_version &&
-               this->my_id->equals(this->my_id, other->my_id) &&
-               this->other_id->equals(this->other_id, other->other_id) &&
                this->cert_policy == other->cert_policy &&
                this->unique == other->unique &&
                this->keyingtries == other->keyingtries &&
@@ -464,7 +516,7 @@ static bool equals(private_peer_cfg_t *this, private_peer_cfg_t *other)
                  this->virtual_ip->equals(this->virtual_ip, other->virtual_ip))) &&
                (this->pool == other->pool || 
                 (this->pool && other->pool && streq(this->pool, other->pool))) &&
-               this->auth->equals(this->auth, other->auth) 
+               auth_cfg_equal(this, other)
 #ifdef ME
                && this->mediation == other->mediation &&
                this->mediated_by == other->mediated_by &&
@@ -492,11 +544,13 @@ static void destroy(private_peer_cfg_t *this)
        if (ref_put(&this->refcount))
        {
                this->ike_cfg->destroy(this->ike_cfg);
-               this->child_cfgs->destroy_offset(this->child_cfgs, offsetof(child_cfg_t, destroy));
-               this->my_id->destroy(this->my_id);
-               this->other_id->destroy(this->other_id);
+               this->child_cfgs->destroy_offset(this->child_cfgs,
+                                                                               offsetof(child_cfg_t, destroy));
                DESTROY_IF(this->virtual_ip);
-               this->auth->destroy(this->auth);
+               this->local_auth->destroy_offset(this->local_auth,
+                                                                               offsetof(auth_cfg_t, destroy));
+               this->remote_auth->destroy_offset(this->remote_auth,
+                                                                               offsetof(auth_cfg_t, destroy));
 #ifdef ME
                DESTROY_IF(this->mediated_by);
                DESTROY_IF(this->peer_id);
@@ -512,7 +566,6 @@ static void destroy(private_peer_cfg_t *this)
  * Described in header-file
  */
 peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
-                                                       identification_t *my_id, identification_t *other_id,
                                                        cert_policy_t cert_policy, unique_policy_t unique,
                                                        u_int32_t keyingtries, u_int32_t rekey_time,
                                                        u_int32_t reauth_time, u_int32_t jitter_time,
@@ -531,8 +584,6 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
        this->public.remove_child_cfg = (void(*)(peer_cfg_t*, enumerator_t*))remove_child_cfg;
        this->public.create_child_cfg_enumerator = (enumerator_t* (*) (peer_cfg_t *))create_child_cfg_enumerator;
        this->public.select_child_cfg = (child_cfg_t* (*) (peer_cfg_t *,linked_list_t*,linked_list_t*,host_t*,host_t*))select_child_cfg;
-       this->public.get_my_id = (identification_t* (*)(peer_cfg_t*))get_my_id;
-       this->public.get_other_id = (identification_t* (*)(peer_cfg_t *))get_other_id;
        this->public.get_cert_policy = (cert_policy_t (*) (peer_cfg_t *))get_cert_policy;
        this->public.get_unique_policy = (unique_policy_t (*) (peer_cfg_t *))get_unique_policy;
        this->public.get_keyingtries = (u_int32_t (*) (peer_cfg_t *))get_keyingtries;
@@ -543,7 +594,8 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
        this->public.get_dpd = (u_int32_t (*) (peer_cfg_t *))get_dpd;
        this->public.get_virtual_ip = (host_t* (*) (peer_cfg_t *))get_virtual_ip;
        this->public.get_pool = (char*(*)(peer_cfg_t*))get_pool;
-       this->public.get_auth = (auth_info_t*(*)(peer_cfg_t*))get_auth;
+       this->public.add_auth_cfg = (void(*)(peer_cfg_t*, auth_cfg_t *cfg, bool local))add_auth_cfg;
+       this->public.create_auth_cfg_enumerator = (enumerator_t*(*)(peer_cfg_t*, bool local))create_auth_cfg_enumerator;
        this->public.equals = (bool(*)(peer_cfg_t*, peer_cfg_t *other))equals;
        this->public.get_ref = (peer_cfg_t*(*)(peer_cfg_t *))get_ref;
        this->public.destroy = (void(*)(peer_cfg_t *))destroy;
@@ -559,8 +611,6 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
        this->ike_cfg = ike_cfg;
        this->child_cfgs = linked_list_create();
        this->mutex = mutex_create(MUTEX_DEFAULT);
-       this->my_id = my_id;
-       this->other_id = other_id;
        this->cert_policy = cert_policy;
        this->unique = unique;
        this->keyingtries = keyingtries;
@@ -580,7 +630,8 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
        this->dpd = dpd;
        this->virtual_ip = virtual_ip;
        this->pool = pool ? strdup(pool) : NULL;
-       this->auth = auth_info_create();
+       this->local_auth = linked_list_create();
+       this->remote_auth = linked_list_create();
        this->refcount = 1;
 #ifdef ME
        this->mediation = mediation;
index 3a776927e61a0d163aa7464d3c5aa7e42f2391b9..7cfe61207062b8b0eb7d2da269b0308e7f33463d 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2007-2008 Tobias Brunner
- * Copyright (C) 2005-2007 Martin Willi
+ * Copyright (C) 2005-2009 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
@@ -38,7 +38,7 @@ typedef struct peer_cfg_t peer_cfg_t;
 #include <config/child_cfg.h>
 #include <sa/authenticators/authenticator.h>
 #include <sa/authenticators/eap/eap_method.h>
-#include <credentials/auth_info.h>
+#include <config/auth_cfg.h>
 
 /**
  * Certificate sending policy. This is also used for certificate
@@ -87,27 +87,33 @@ extern enum_name_t *unique_policy_names;
  * exactly one ike_cfg_t, which is use for initiation. Additionally, it contains
  * multiple child_cfg_t defining which CHILD_SAs are allowed for this peer.
  * @verbatim
-
-                           +-------------------+           +---------------+
-   +---------------+       |     peer_cfg      |         +---------------+ |
-   |    ike_cfg    |       +-------------------+         |   child_cfg   | |
-   +---------------+       | - ids             |         +---------------+ |
-   | - hosts       | 1   1 | - cas             | 1     n | - proposals   | |
-   | - proposals   |<------| - auth info       |-------->| - traffic sel | |
-   | - ...         |       | - dpd config      |         | - ...         |-+
-   +---------------+       | - ...             |         +---------------+
-                           +-------------------+
-                                     ^
-                                     |
-                           +-------------------+
-                           |     auth_info     |
-                           +-------------------+
-                           |     auth_items    |
-                           +-------------------+
+                          +-------------------+        +---------------+
+   +---------------+      |     peer_cfg      |      +---------------+ |
+   |    ike_cfg    |      +-------------------+      |   child_cfg   | |
+   +---------------+      | - ids             |      +---------------+ |
+   | - hosts       | 1  1 | - cas             | 1  n | - proposals   | |
+   | - proposals   |<-----| - auth info       |----->| - traffic sel | |
+   | - ...         |      | - dpd config      |      | - ...         |-+
+   +---------------+      | - ...             |      +---------------+
+                          +-------------------+
+                             | 1         0 |
+                             |             |
+                             v n         n V
+             +-------------------+     +-------------------+
+           +-------------------+ |   +-------------------+ |
+           |     auth_cfg      | |   |     auth_cfg      | |
+           +-------------------+ |   +-------------------+ |
+           | - local rules     |-+   | - remote constr.  |-+
+           +-------------------+     +-------------------+
    @endverbatim
- * The auth_info_t object associated to the peer_cfg holds additional
- * authorization constraints. A peer who wants to use a config needs to fullfil
- * the requirements defined in auth_info.
+ *
+ * Each peer_cfg has two lists of authentication config attached. Local
+ * authentication configs define how to authenticate ourself against the remote
+ * peer. Each config is enforced using the multiple authentication extension
+ * (RFC4739). 
+ * The remote authentication configs are handled as constraints. The peer has
+ * to fullfill each of these rules (using multiple authentication, in any order)
+ * to gain access to the configuration.
  */
 struct peer_cfg_t {
        
@@ -169,25 +175,20 @@ struct peer_cfg_t {
                                                                          host_t *other_host);
        
        /**
-        * Get the authentication constraint items.
+        * Add an authentication config to the peer configuration.
         *
-        * @return                              auth_info object to manipulate requirements
+        * @param config                config to add
+        * @param local                 TRUE for local rules, FALSE for remote constraints
         */
-       auth_info_t* (*get_auth)(peer_cfg_t *this);
-               
-       /**
-        * Get own ID.
-        * 
-        * @return                              own id
-        */
-       identification_t* (*get_my_id)(peer_cfg_t *this);
+       void (*add_auth_cfg)(peer_cfg_t *this, auth_cfg_t *cfg, bool local);
        
        /**
-        * Get peers ID.
-        * 
-        * @return                              other id
+        * Create an enumerator over registered authentication configs.
+        *
+        * @param local                 TRUE for local rules, FALSE for remote constraints
+        * @return                              enumerator over auth_cfg_t*
         */
-       identification_t* (*get_other_id)(peer_cfg_t *this);
+       enumerator_t* (*create_auth_cfg_enumerator)(peer_cfg_t *this, bool local);
 
        /**
         * Should be sent a certificate for this connection?
@@ -331,8 +332,6 @@ struct peer_cfg_t {
  * @param name                         name of the peer_cfg
  * @param ike_version          which IKE version we sould use for this peer
  * @param ike_cfg                      IKE config to use when acting as initiator
- * @param my_id                        identification_t for ourselves
- * @param other_id                     identification_t for the remote guy
  * @param cert_policy          should we send a certificate payload?
  * @param unique                       uniqueness of an IKE_SA
  * @param keyingtries          how many keying tries should be done before giving up
@@ -350,7 +349,6 @@ struct peer_cfg_t {
  * @return                                     peer_cfg_t object
  */
 peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
-                                                       identification_t *my_id, identification_t *other_id,
                                                        cert_policy_t cert_policy, unique_policy_t unique,
                                                        u_int32_t keyingtries, u_int32_t rekey_time,
                                                        u_int32_t reauth_time, u_int32_t jitter_time,
index da697392548903b00308ed0e514ddc130f69e2f0..7bddff1745bead5e1c8d3824c8105081f85162c0 100644 (file)
@@ -19,6 +19,7 @@
 #include <string.h>
 
 #include "proposal.h"
+#include "proposal_keywords.h"
 
 #include <daemon.h>
 #include <utils/linked_list.h>
@@ -583,222 +584,59 @@ static void check_proposal(private_proposal_t *this)
        }
 }
 
+struct proposal_token {
+       char             *name;
+       transform_type_t  type;
+       u_int16_t         algorithm;
+       u_int16_t         keysize;  
+};
+
 /**
  * add a algorithm identified by a string to the proposal.
- * TODO: we could use gperf here.
  */
 static status_t add_string_algo(private_proposal_t *this, chunk_t alg)
 {
-       if (strncmp(alg.ptr, "null", alg.len) == 0)
-       {
-               add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_NULL, 0);
-       }
-       else if (strncmp(alg.ptr, "aes128", alg.len) == 0)
-       {
-               add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 128);
-       }
-       else if (strncmp(alg.ptr, "aes192", alg.len) == 0)
-       {
-               add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 192);
-       }
-       else if (strncmp(alg.ptr, "aes256", alg.len) == 0)
+       const proposal_token_t *token = in_word_set(alg.ptr, alg.len);
+
+       if (token == NULL)
        {
-               add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 256);
+               return FAILED;
        }
-       else if (strstr(alg.ptr, "ccm"))
-       {
-               u_int16_t key_size, icv_size;
 
-               if (sscanf(alg.ptr, "aes%huccm%hu", &key_size, &icv_size) == 2)
-               {
-                       if (key_size == 128 || key_size == 192 || key_size == 256)
-                       {
-                               switch (icv_size)
-                               {
-                                       case   8: /* octets */
-                                       case  64: /* bits */
-                                               add_algorithm(this, ENCRYPTION_ALGORITHM,
-                                                                         ENCR_AES_CCM_ICV8, key_size);
-                                               break;
-                                       case  12: /* octets */
-                                       case  96: /* bits */
-                                               add_algorithm(this, ENCRYPTION_ALGORITHM,
-                                                                         ENCR_AES_CCM_ICV12, key_size);
-                                               break;
-                                       case  16: /* octets */
-                                       case 128: /* bits */
-                                               add_algorithm(this, ENCRYPTION_ALGORITHM,
-                                                                         ENCR_AES_CCM_ICV16, key_size);
-                                               break;
-                                       default:
-                                               /* invalid ICV size */
-                                               break;
-                               }
-                       }
-               }
-       }
-       else if (strstr(alg.ptr, "gcm"))
-       {
-               u_int16_t key_size, icv_size;
+       add_algorithm(this, token->type, token->algorithm, token->keysize);
 
-               if (sscanf(alg.ptr, "aes%hugcm%hu", &key_size, &icv_size) == 2)
-               {
-                       if (key_size == 128 || key_size == 192 || key_size == 256)
-                       {
-                               switch (icv_size)
-                               {
-                                       case   8: /* octets */
-                                       case  64: /* bits */
-                                               add_algorithm(this, ENCRYPTION_ALGORITHM,
-                                                                         ENCR_AES_GCM_ICV8, key_size);
-                                               break;
-                                       case  12: /* octets */
-                                       case  96: /* bits */
-                                               add_algorithm(this, ENCRYPTION_ALGORITHM,
-                                                                         ENCR_AES_GCM_ICV12, key_size);
-                                               break;
-                                       case  16: /* octets */
-                                       case 128: /* bits */
-                                               add_algorithm(this, ENCRYPTION_ALGORITHM,
-                                                                         ENCR_AES_GCM_ICV16, key_size);
-                                               break;
-                                       default:
-                                               /* invalid ICV size */
-                                               break;
-                               }
-                       }
-               }
-       }
-       else if (strncmp(alg.ptr, "3des", alg.len) == 0)
-       {
-               add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_3DES, 0);
-       }
-       /* blowfish only uses some predefined key sizes yet */
-       else if (strncmp(alg.ptr, "blowfish128", alg.len) == 0)
-       {
-               add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 128);
-       }
-       else if (strncmp(alg.ptr, "blowfish192", alg.len) == 0)
-       {
-               add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 192);
-       }
-       else if (strncmp(alg.ptr, "blowfish256", alg.len) == 0)
-       {
-               add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_BLOWFISH, 256);
-       }
-       else if (strncmp(alg.ptr, "sha", alg.len) == 0 ||
-                        strncmp(alg.ptr, "sha1", alg.len) == 0)
-       {
-               /* sha means we use SHA for both, PRF and AUTH */
-               add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0);
-               if (this->protocol == PROTO_IKE)
-               {
-                       add_algorithm(this, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA1, 0);
-               }
-       }  
-       else if (strncmp(alg.ptr, "sha256", alg.len) == 0 ||
-                        strncmp(alg.ptr, "sha2_256", alg.len) == 0)
+       if (this->protocol == PROTO_IKE && token->type == INTEGRITY_ALGORITHM)
        {
-               add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_256_128, 0);
-               if (this->protocol == PROTO_IKE)
-               {
-                       add_algorithm(this, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA2_256, 0);
-               }
-       }
-       else if (strncmp(alg.ptr, "sha384", alg.len) == 0 ||
-                        strncmp(alg.ptr, "sha2_384", alg.len) == 0)
-       {
-               add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_384_192, 0);
-               if (this->protocol == PROTO_IKE)
-               {
-                       add_algorithm(this, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA2_384, 0);
-               }
-       }
-       else if (strncmp(alg.ptr, "sha512", alg.len) == 0 ||
-                        strncmp(alg.ptr, "sha2_512", alg.len) == 0)
-       {
-               add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA2_512_256, 0);
-               if (this->protocol == PROTO_IKE)
-               {
-                       add_algorithm(this, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_SHA2_512, 0);
-               }
-       }
-       else if (strncmp(alg.ptr, "md5", alg.len) == 0)
-       {
-               add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0);
-               if (this->protocol == PROTO_IKE)
+               pseudo_random_function_t prf;
+
+               switch (token->algorithm)
                {
-                       add_algorithm(this, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_MD5, 0);
+                       case AUTH_HMAC_SHA1_96:
+                               prf = PRF_HMAC_SHA1;
+                               break;
+                       case AUTH_HMAC_SHA2_256_128:
+                               prf = PRF_HMAC_SHA2_256;
+                               break;
+                       case AUTH_HMAC_SHA2_384_192:
+                               prf = PRF_HMAC_SHA2_384;
+                               break;
+                       case AUTH_HMAC_SHA2_512_256:
+                               prf = PRF_HMAC_SHA2_512;
+                               break;
+                       case AUTH_HMAC_MD5_96:
+                               prf = PRF_HMAC_MD5;
+                               break;
+                       case AUTH_AES_XCBC_96:
+                               prf = PRF_AES128_XCBC;
+                               break;
+                       default: 
+                               prf = PRF_UNDEFINED;
                }
-       }
-       else if (strncmp(alg.ptr, "aesxcbc", alg.len) == 0)
-       {
-               add_algorithm(this, INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0);
-               if (this->protocol == PROTO_IKE)
+               if (prf != PRF_UNDEFINED)
                {
-                       add_algorithm(this, PSEUDO_RANDOM_FUNCTION, PRF_AES128_XCBC, 0);
+                       add_algorithm(this, PSEUDO_RANDOM_FUNCTION, prf, 0);
                }
        }
-       else if (strncmp(alg.ptr, "modpnull", alg.len) == 0)
-       {
-               add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_NULL, 0);
-       }
-       else if (strncmp(alg.ptr, "modp768", alg.len) == 0)
-       {
-               add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_768_BIT, 0);
-       }
-       else if (strncmp(alg.ptr, "modp1024", alg.len) == 0)
-       {
-               add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
-       }
-       else if (strncmp(alg.ptr, "modp1536", alg.len) == 0)
-       {
-               add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_1536_BIT, 0);
-       }
-       else if (strncmp(alg.ptr, "modp2048", alg.len) == 0)
-       {
-               add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
-       }
-       else if (strncmp(alg.ptr, "modp3072", alg.len) == 0)
-       {
-               add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_3072_BIT, 0);
-       }
-       else if (strncmp(alg.ptr, "modp4096", alg.len) == 0)
-       {
-               add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_4096_BIT, 0);
-       }
-       else if (strncmp(alg.ptr, "modp6144", alg.len) == 0)
-       {
-               add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_6144_BIT, 0);
-       }
-       else if (strncmp(alg.ptr, "modp8192", alg.len) == 0)
-       {
-               add_algorithm(this, DIFFIE_HELLMAN_GROUP, MODP_8192_BIT, 0);
-       }
-       else if (strncmp(alg.ptr, "ecp192", alg.len) == 0)
-       {
-               add_algorithm(this, DIFFIE_HELLMAN_GROUP, ECP_192_BIT, 0);
-       }
-       else if (strncmp(alg.ptr, "ecp224", alg.len) == 0)
-       {
-               add_algorithm(this, DIFFIE_HELLMAN_GROUP, ECP_224_BIT, 0);
-       }
-       else if (strncmp(alg.ptr, "ecp256", alg.len) == 0)
-       {
-               add_algorithm(this, DIFFIE_HELLMAN_GROUP, ECP_256_BIT, 0);
-       }
-       else if (strncmp(alg.ptr, "ecp384", alg.len) == 0)
-       {
-               add_algorithm(this, DIFFIE_HELLMAN_GROUP, ECP_384_BIT, 0);
-       }
-       else if (strncmp(alg.ptr, "ecp521", alg.len) == 0)
-       {
-               add_algorithm(this, DIFFIE_HELLMAN_GROUP, ECP_521_BIT, 0);
-       }
-       else
-       {
-               return FAILED;
-       }
        return SUCCESS;
 }
 
diff --git a/src/charon/config/proposal_keywords.h b/src/charon/config/proposal_keywords.h
new file mode 100644 (file)
index 0000000..ae10d34
--- /dev/null
@@ -0,0 +1,26 @@
+/* proposal keywords
+ * Copyright (C) 2009 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil, Switzerland
+ *
+ * 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.
+ *
+ * RCSID $Id:$
+ */
+
+#ifndef _PROPOSAL_KEYWORDS_H_
+#define _PROPOSAL_KEYWORDS_H_
+
+typedef struct proposal_token proposal_token_t;
+
+extern const proposal_token_t* in_word_set(register const char *str, register unsigned int len);
+
+#endif /* _PROPOSAL_KEYWORDS_H_ */
+
diff --git a/src/charon/config/proposal_keywords.txt b/src/charon/config/proposal_keywords.txt
new file mode 100644 (file)
index 0000000..e195b1f
--- /dev/null
@@ -0,0 +1,101 @@
+%{
+/* proposal keywords
+ * Copyright (C) 2009 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil, Switzerland
+ *
+ * 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.
+ *
+ * RCSID $Id:$
+ */
+
+#include <string.h>
+
+#include "proposal.h"
+
+#include <crypto/crypters/crypter.h>
+#include <crypto/signers/signer.h>
+
+%}
+struct proposal_token {
+    char             *name;
+    transform_type_t  type;
+       u_int16_t         algorithm;
+    u_int16_t         keysize;  
+};
+%%
+null,             ENCRYPTION_ALGORITHM, ENCR_NULL,                0
+aes128,           ENCRYPTION_ALGORITHM, ENCR_AES_CBC,           128
+aes192,           ENCRYPTION_ALGORITHM, ENCR_AES_CBC,           192
+aes256,           ENCRYPTION_ALGORITHM, ENCR_AES_CBC,           256
+aes128ccm8,       ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8,      128
+aes128ccm64,      ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8,      128
+aes128ccm12,      ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12,     128
+aes128ccm96,      ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12,     128
+aes128ccm16,      ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16,     128
+aes128ccm128,     ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16,     128
+aes192ccm8,       ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8,      192
+aes192ccm64,      ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8,      192
+aes192ccm12,      ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12,     192
+aes192ccm96,      ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12,     192
+aes192ccm16,      ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16,     192
+aes192ccm128,     ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16,     192
+aes256ccm8,       ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8,      256
+aes256ccm64,      ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV8,      256
+aes256ccm12,      ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12,     256
+aes256ccm96,      ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV12,     256
+aes256ccm16,      ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16,     256
+aes256ccm128,     ENCRYPTION_ALGORITHM, ENCR_AES_CCM_ICV16,     256
+aes128gcm8,       ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8,      128
+aes128gcm64,      ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8,      128
+aes128gcm12,      ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12,     128
+aes128gcm96,      ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12,     128
+aes128gcm16,      ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16,     128
+aes128gcm128,     ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16,     128
+aes192gcm8,       ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8,      192
+aes192gcm64,      ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8,      192
+aes192gcm12,      ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12,     192
+aes192gcm96,      ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12,     192
+aes192gcm16,      ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16,     192
+aes192gcm128,     ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16,     192
+aes256gcm8,       ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8,      256
+aes256gcm64,      ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV8,      256
+aes256gcm12,      ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12,     256
+aes256gcm96,      ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV12,     256
+aes256gcm16,      ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16,     256
+aes256gcm128,     ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16,     256
+3des,             ENCRYPTION_ALGORITHM, ENCR_3DES,                0
+blowfish128,      ENCRYPTION_ALGORITHM, ENCR_BLOWFISH,          128
+blowfish192,      ENCRYPTION_ALGORITHM, ENCR_BLOWFISH,          192
+blowfish256,      ENCRYPTION_ALGORITHM, ENCR_BLOWFISH,          256
+sha,              INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA1_96,        0
+sha1,             INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA1_96,        0
+sha256,           INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA2_256_128,   0
+sha2_256,         INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA2_256_128,   0
+sha384,           INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA2_384_192,   0
+sha2_384,         INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA2_384_192,   0
+sha512,           INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA2_512_256,   0
+sha2_512,         INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA2_512_256,   0
+md5,              INTEGRITY_ALGORITHM,  AUTH_HMAC_MD5_96,         0
+aesxcbc,          INTEGRITY_ALGORITHM,  AUTH_AES_XCBC_96,         0
+modpnull,         DIFFIE_HELLMAN_GROUP, MODP_NULL,                0
+modp768,          DIFFIE_HELLMAN_GROUP, MODP_768_BIT,             0
+modp1024,         DIFFIE_HELLMAN_GROUP, MODP_1024_BIT,            0
+modp1536,         DIFFIE_HELLMAN_GROUP, MODP_1536_BIT,            0
+modp2048,         DIFFIE_HELLMAN_GROUP, MODP_2048_BIT,            0
+modp3072,         DIFFIE_HELLMAN_GROUP, MODP_3072_BIT,            0
+modp4096,         DIFFIE_HELLMAN_GROUP, MODP_4096_BIT,            0
+modp6144,         DIFFIE_HELLMAN_GROUP, MODP_6144_BIT,            0
+modp8192,         DIFFIE_HELLMAN_GROUP, MODP_8192_BIT,            0
+ecp192,           DIFFIE_HELLMAN_GROUP, ECP_192_BIT,              0
+ecp224,           DIFFIE_HELLMAN_GROUP, ECP_224_BIT,              0
+ecp256,           DIFFIE_HELLMAN_GROUP, ECP_256_BIT,              0
+ecp384,           DIFFIE_HELLMAN_GROUP, ECP_384_BIT,              0
+ecp521,           DIFFIE_HELLMAN_GROUP, ECP_521_BIT,              0
diff --git a/src/charon/credentials/auth_info.c b/src/charon/credentials/auth_info.c
deleted file mode 100644 (file)
index 62d5ea9..0000000
+++ /dev/null
@@ -1,607 +0,0 @@
-/*
- * Copyright (C) 2008 Tobias Brunner
- * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- *
- * $Id$
- */
-
-
-#include "auth_info.h"
-
-#include <daemon.h>
-#include <utils/linked_list.h>
-#include <utils/identification.h>
-#include <credentials/certificates/certificate.h>
-
-ENUM(auth_item_names, AUTHN_CA_CERT, AUTHZ_AC_GROUP,
-       "AUTHN_AUTH_CLASS",
-       "AUTHN_EAP_TYPE",
-       "AUTHN_EAP_VENDOR",
-       "AUTHN_EAP_IDENTITY",
-       "AUTHN_CA_CERT",
-       "AUTHN_CA_CERT_KEYID",
-       "AUTHN_CA_CERT_NAME",
-       "AUTHN_IM_CERT",
-       "AUTHN_SUBJECT_CERT",
-       "AUTHN_IM_HASH_URL",
-       "AUTHN_SUBJECT_HASH_URL",
-       "AUTHZ_PUBKEY",
-       "AUTHZ_PSK",
-       "AUTHZ_EAP",
-       "AUTHZ_CA_CERT",
-       "AUTHZ_CA_CERT_NAME",
-       "AUTHZ_IM_CERT",
-       "AUTHZ_SUBJECT_CERT",
-       "AUTHZ_CRL_VALIDATION",
-       "AUTHZ_OCSP_VALIDATION",
-       "AUTHZ_AC_GROUP",
-);
-
-typedef struct private_auth_info_t private_auth_info_t;
-
-/**
- * private data of item_set
- */
-struct private_auth_info_t {
-
-       /**
-        * public functions
-        */
-       auth_info_t public;
-       
-       /**
-        * list of item_t's
-        */
-       linked_list_t *items;
-};
-
-typedef struct item_t item_t;
-
-struct item_t {
-       /** type of this item */
-       auth_item_t type;
-       /** associated privlege value, if any */
-       void *value;
-};
-
-/**
- * enumerator for auth_info_wrapper_t.create_cert_enumerator()
- */
-typedef struct {
-       /** implements enumerator_t */
-       enumerator_t public;
-       /** inner enumerator from linked_list_t */
-       enumerator_t *inner;
-       /** the current item */
-       item_t *item;
-} item_enumerator_t;
-
-/**
- * enumerate function for item_enumerator_t
- */
-static bool enumerate(item_enumerator_t *this, auth_item_t *type, void **value)
-{
-       if (this->inner->enumerate(this->inner, &this->item))
-       {
-               *type = this->item->type;
-               *value = this->item->value;
-               return TRUE;
-       }
-       return FALSE;
-}
-
-/**
- * destroy function for item_enumerator_t
- */
-static void item_enumerator_destroy(item_enumerator_t *this)
-{
-       this->inner->destroy(this->inner);
-       free(this);
-}
-
-/**
- * Implementation of auth_info_t.create_item_enumerator.
- */
-static enumerator_t* create_item_enumerator(private_auth_info_t *this)
-{
-       item_enumerator_t *enumerator;
-       
-       enumerator = malloc_thing(item_enumerator_t);
-       enumerator->item = NULL;
-       enumerator->inner = this->items->create_enumerator(this->items);
-       enumerator->public.enumerate = (void*)enumerate;
-       enumerator->public.destroy = (void*)item_enumerator_destroy;
-       return &enumerator->public;
-}
-
-static void destroy_item_value(item_t *item);
-
-/**
- * Implementation of auth_info_t.replace_item.
- */
-static void replace_item(item_enumerator_t *enumerator, auth_item_t type, void *value)
-{
-       destroy_item_value(enumerator->item);
-       enumerator->item->type = type;
-       enumerator->item->value = value;
-}
-
-/**
- * Implementation of auth_info_t.get_item.
- */
-static bool get_item(private_auth_info_t *this, auth_item_t type, void** value)
-{
-       enumerator_t *enumerator;
-       void *current_value;
-       auth_item_t current_type;
-       bool found = FALSE;
-       
-       enumerator = create_item_enumerator(this);
-       while (enumerator->enumerate(enumerator, &current_type, &current_value))
-       {
-               if (type == current_type)
-               {
-                       *value = current_value;
-                       found = TRUE;
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
-       return found;
-}
-
-/**
- * Implementation of auth_info_t.add_item.
- */
-static void add_item(private_auth_info_t *this, auth_item_t type, void *value)
-{
-       item_t *item = malloc_thing(item_t);
-       
-       item->type = type;
-       switch (type)
-       {               
-               case AUTHZ_PUBKEY:
-               {
-                       public_key_t *key = (public_key_t*)value;
-
-                       item->value = key->get_ref(key);
-                       break;
-               }
-               case AUTHZ_PSK:
-               {
-                       shared_key_t *key = (shared_key_t*)value;
-
-                       item->value = key->get_ref(key);
-                       break;
-               }
-               case AUTHN_IM_HASH_URL:
-               case AUTHN_SUBJECT_HASH_URL:
-               {
-                       item->value = strdup(value);
-                       break;
-               }
-               case AUTHN_CA_CERT:
-               case AUTHN_IM_CERT:
-               case AUTHN_SUBJECT_CERT:
-               case AUTHZ_CA_CERT:
-               case AUTHZ_IM_CERT:
-               case AUTHZ_SUBJECT_CERT:
-               {
-                       certificate_t *cert = (certificate_t*)value;
-
-                       item->value = cert->get_ref(cert);
-                       break;
-               }
-               case AUTHZ_CRL_VALIDATION:
-               case AUTHZ_OCSP_VALIDATION:
-               {
-                       cert_validation_t *validation = malloc_thing(cert_validation_t);
-
-                       *validation = *(cert_validation_t*)value;
-                       item->value = validation;
-                       break;
-               }
-               case AUTHN_AUTH_CLASS:
-               case AUTHN_EAP_TYPE:
-               case AUTHN_EAP_VENDOR:
-               case AUTHZ_EAP:
-               {
-                       u_int *intval = malloc_thing(u_int);
-
-                       *intval = *(u_int*)value;
-                       item->value = intval;
-                       break;
-               }
-               case AUTHN_EAP_IDENTITY:
-               case AUTHN_CA_CERT_KEYID:
-               case AUTHN_CA_CERT_NAME:
-               case AUTHZ_CA_CERT_NAME:
-               case AUTHZ_AC_GROUP:
-               {
-                       identification_t *id = (identification_t*)value;
-
-                       item->value = id->clone(id);
-                       break;
-               }
-       }
-       this->items->insert_last(this->items, item);
-}
-
-
-/**
- * Implementation of auth_info_t.complies.
- */
-static bool complies(private_auth_info_t *this, auth_info_t *constraints)
-{
-       enumerator_t *enumerator;
-       bool success = TRUE;
-       auth_item_t t1, t2;
-       void *value;
-       
-       enumerator = constraints->create_item_enumerator(constraints);
-       while (enumerator->enumerate(enumerator, &t1, &value))
-       {
-               switch (t1)
-               {
-                       case AUTHN_AUTH_CLASS:
-                       case AUTHN_EAP_TYPE:
-                       case AUTHN_EAP_VENDOR:
-                       case AUTHN_EAP_IDENTITY:
-                       case AUTHN_CA_CERT_KEYID:
-                       case AUTHN_CA_CERT:
-                       case AUTHN_CA_CERT_NAME:
-                       case AUTHN_IM_CERT:
-                       case AUTHN_SUBJECT_CERT:
-                       case AUTHN_IM_HASH_URL:
-                       case AUTHN_SUBJECT_HASH_URL:
-                       {       /* skip non-authorization tokens */
-                               continue;
-                       }
-                       case AUTHZ_CRL_VALIDATION:
-                       case AUTHZ_OCSP_VALIDATION:
-                       {
-                               cert_validation_t *valid;
-                       
-                               /* OCSP validation is also sufficient for CRL constraint, but
-                                * not vice-versa */
-                               if (!get_item(this, t1, (void**)&valid) &&
-                                       t1 == AUTHZ_CRL_VALIDATION &&
-                                       !get_item(this, AUTHZ_OCSP_VALIDATION, (void**)&valid))
-                               {
-                                       DBG1(DBG_CFG, "constraint check failed: %N requires at "
-                                                "least %N, but no check done", auth_item_names, t1,
-                                                cert_validation_names, *(cert_validation_t*)value);
-                                       success = FALSE;
-                                       break;
-                               }
-                               switch (*(cert_validation_t*)value)
-                               {
-                                       case VALIDATION_SKIPPED:
-                                               if (*valid == VALIDATION_SKIPPED)
-                                               {
-                                                       break;
-                                               }       /* FALL */
-                                       case VALIDATION_GOOD:
-                                               if (*valid == VALIDATION_GOOD)
-                                               {
-                                                       break;
-                                               }       /* FALL */
-                                       default:
-                                               DBG1(DBG_CFG, "constraint check failed: %N is %N, but "
-                                                        "requires at least %N", auth_item_names, t1,
-                                                        cert_validation_names, *valid,
-                                                        cert_validation_names, *(cert_validation_t*)value);
-                                               success = FALSE;
-                                               break;
-                               }
-                               break;
-                       }
-                       case AUTHZ_CA_CERT:
-                       {
-                               enumerator_t *enumerator;
-                               certificate_t *c1, *c2;
-                               
-                               c1 = (certificate_t*)value;
-                               
-                               success = FALSE;
-                               enumerator = create_item_enumerator(this);
-                               while (enumerator->enumerate(enumerator, &t2, &c2))
-                               {
-                                       if ((t2 == AUTHZ_CA_CERT || t2 == AUTHZ_IM_CERT) &&
-                                               c1->equals(c1, c2))
-                                       {
-                                               success = TRUE;
-                                       }
-                               }
-                               enumerator->destroy(enumerator);
-                               if (!success)
-                               {
-                                       DBG1(DBG_CFG, "constraint check failed: peer not "
-                                                "authenticated by CA '%D'.", c1->get_subject(c1));
-                               }
-                               break;
-                       }
-                       case AUTHZ_CA_CERT_NAME:
-                       {
-                               enumerator_t *enumerator;
-                               certificate_t *cert;
-                               identification_t *id;
-                               
-                               id = (identification_t*)value;
-                               success = FALSE;
-                               enumerator = create_item_enumerator(this);
-                               while (enumerator->enumerate(enumerator, &t2, &cert))
-                               {
-                                       if ((t2 == AUTHZ_CA_CERT || t2 == AUTHZ_IM_CERT) &&
-                                               cert->has_subject(cert, id))
-                                       {
-                                               success = TRUE;
-                                       }
-                               }
-                               enumerator->destroy(enumerator);
-                               if (!success)
-                               {
-                                       DBG1(DBG_CFG, "constraint check failed: peer not "
-                                                "authenticated by CA '%D'.", id);
-                               }
-                               break;
-                       }
-                       case AUTHZ_PUBKEY:
-                       case AUTHZ_PSK:
-                       case AUTHZ_IM_CERT:
-                       case AUTHZ_SUBJECT_CERT:
-                       case AUTHZ_EAP:
-                       case AUTHZ_AC_GROUP:
-                       {
-                               DBG1(DBG_CFG, "constraint check %N not implemented!",
-                                        auth_item_names, t1);
-                               success = FALSE;
-                               break;
-                       }
-               }
-               if (!success)
-               {
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
-       return success;
-}
-
-/**
- * Implementation of auth_info_t.merge.
- */
-static void merge(private_auth_info_t *this, private_auth_info_t *other)
-{
-       item_t *item;
-       
-       while (other->items->remove_first(other->items, (void**)&item) == SUCCESS)
-       {
-               this->items->insert_last(this->items, item);
-       }
-}
-
-/**
- * Implementation of auth_info_t.equals.
- */
-static bool equals(private_auth_info_t *this, private_auth_info_t *other)
-{
-       enumerator_t *e1, *e2;
-       item_t *i1, *i2;
-       bool equal = TRUE, found;
-       
-       e1 = this->items->create_enumerator(this->items);
-       while (e1->enumerate(e1, &i1))
-       {
-               found = FALSE;
-               e2 = other->items->create_enumerator(other->items);
-               while (e2->enumerate(e2, &i2))
-               {
-                       if (i1->type == i2->type)
-                       {
-                               switch (i1->type)
-                               {
-                                       case AUTHZ_CRL_VALIDATION:
-                                       case AUTHZ_OCSP_VALIDATION:
-                                       {
-                                               cert_validation_t c1, c2;
-                                               
-                                               c1 = *(cert_validation_t*)i1->value;
-                                               c2 = *(cert_validation_t*)i2->value;
-                                       
-                                               if (c1 == c2)
-                                               {
-                                                       found = TRUE;
-                                                       break;
-                                               }
-                                               continue;
-                                       }
-                                       case AUTHN_IM_HASH_URL:
-                                       case AUTHN_SUBJECT_HASH_URL:
-                                       {
-                                               if (streq(i1->value, i2->value))
-                                               {
-                                                       found = TRUE;
-                                                       break;
-                                               }
-                                               continue;
-                                       }
-                                       case AUTHN_CA_CERT:
-                                       case AUTHN_IM_CERT:
-                                       case AUTHN_SUBJECT_CERT:
-                                       case AUTHZ_CA_CERT:
-                                       case AUTHZ_IM_CERT:
-                                       case AUTHZ_SUBJECT_CERT:
-                                       {
-                                               certificate_t *c1, *c2;
-                                               
-                                               c1 = (certificate_t*)i1->value;
-                                               c2 = (certificate_t*)i2->value;
-                                       
-                                               if (c1->equals(c1, c2))
-                                               {
-                                                       found = TRUE;
-                                                       break;
-                                               }
-                                               continue;
-                                       }
-                                       case AUTHN_EAP_IDENTITY:
-                                       case AUTHN_CA_CERT_KEYID:
-                                       case AUTHN_CA_CERT_NAME:
-                                       case AUTHZ_CA_CERT_NAME:
-                                       {
-                                               identification_t *c1, *c2;
-                                               
-                                               c1 = (identification_t*)i1->value;
-                                               c2 = (identification_t*)i2->value;
-                                       
-                                               if (c1->equals(c1, c2))
-                                               {
-                                                       found = TRUE;
-                                                       break;
-                                               }
-                                               continue;
-                                       }
-                                       case AUTHN_AUTH_CLASS:
-                                       case AUTHN_EAP_TYPE:
-                                       case AUTHN_EAP_VENDOR:
-                                       {
-                                               if (*(u_int*)i1->value == *(u_int*)i2->value)
-                                               {
-                                                       found = TRUE;
-                                                       break;
-                                               }
-                                       }
-                                       case AUTHZ_PUBKEY:
-                                       case AUTHZ_PSK:
-                                       case AUTHZ_EAP:
-                                       case AUTHZ_AC_GROUP:
-                                               /* TODO: implement value comparison */
-                                               break;
-                               }
-                               break;
-                       }
-               }
-               e2->destroy(e2);
-               if (!found)
-               {
-                       equal = FALSE;
-                       break;
-               }
-       }
-       e1->destroy(e1);
-       return equal;
-}
-
-/**
- * Destroy the value associated with an item
- */
-static void destroy_item_value(item_t *item)
-{
-       switch (item->type)
-       {
-               case AUTHZ_PUBKEY:
-               {
-                       public_key_t *key = (public_key_t*)item->value;
-                       key->destroy(key);
-                       break;
-               }
-               case AUTHZ_PSK:
-               {
-                       shared_key_t *key = (shared_key_t*)item->value;
-                       key->destroy(key);
-                       break;
-               }
-               case AUTHN_CA_CERT:
-               case AUTHN_IM_CERT:
-               case AUTHN_SUBJECT_CERT:
-               case AUTHZ_CA_CERT:
-               case AUTHZ_IM_CERT:
-               case AUTHZ_SUBJECT_CERT:
-               {
-                       certificate_t *cert = (certificate_t*)item->value;
-                       cert->destroy(cert);
-                       break;
-               }
-               case AUTHN_AUTH_CLASS:
-               case AUTHN_EAP_TYPE:
-               case AUTHN_EAP_VENDOR:
-               case AUTHN_IM_HASH_URL:
-               case AUTHN_SUBJECT_HASH_URL:
-               case AUTHZ_CRL_VALIDATION:
-               case AUTHZ_OCSP_VALIDATION:
-               case AUTHZ_EAP:
-               {
-                       free(item->value);
-                       break;
-               }
-               case AUTHN_EAP_IDENTITY:
-               case AUTHN_CA_CERT_KEYID:
-               case AUTHN_CA_CERT_NAME:
-               case AUTHZ_CA_CERT_NAME:
-               case AUTHZ_AC_GROUP:
-               {
-                       identification_t *id = (identification_t*)item->value;
-                       id->destroy(id);
-                       break;
-               }
-       }
-}
-
-/**
- * Implementation of auth_info_t.purge
- */
-static void purge(private_auth_info_t *this)
-{
-       item_t *item;
-       
-       while (this->items->remove_last(this->items, (void**)&item) == SUCCESS)
-       {
-               destroy_item_value(item);
-               free(item);
-       }
-}
-
-/**
- * Implementation of auth_info_t.destroy
- */
-static void destroy(private_auth_info_t *this)
-{
-       purge(this);
-       this->items->destroy(this->items);
-       free(this);
-}
-
-/*
- * see header file
- */
-auth_info_t *auth_info_create()
-{
-       private_auth_info_t *this = malloc_thing(private_auth_info_t);
-       
-       this->public.add_item = (void(*)(auth_info_t*, auth_item_t type, void *value))add_item;
-       this->public.get_item = (bool(*)(auth_info_t*, auth_item_t type, void **value))get_item;
-       this->public.replace_item = (void(*)(enumerator_t*,auth_item_t,void*))replace_item;
-       this->public.create_item_enumerator = (enumerator_t*(*)(auth_info_t*))create_item_enumerator;
-       this->public.complies = (bool(*)(auth_info_t*, auth_info_t *))complies;
-       this->public.merge = (void(*)(auth_info_t*, auth_info_t *other))merge;
-       this->public.purge = (void(*)(auth_info_t*))purge;
-       this->public.equals = (bool(*)(auth_info_t*, auth_info_t *other))equals;
-       this->public.destroy = (void(*)(auth_info_t*))destroy;
-       
-       this->items = linked_list_create();
-       
-       return &this->public;
-}
-
diff --git a/src/charon/credentials/auth_info.h b/src/charon/credentials/auth_info.h
deleted file mode 100644 (file)
index f480a6e..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (C) 2008 Tobias Brunner
- * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-/**
- * @defgroup auth_info auth_info
- * @{ @ingroup ccredentials
- */
-
-#ifndef AUTH_INFO_H_
-#define AUTH_INFO_H_
-
-#include <utils/enumerator.h>
-
-typedef struct auth_info_t auth_info_t;
-typedef enum auth_item_t auth_item_t;
-
-/**
- * Authentication/Authorization process helper item.
- *
- * For the authentication process, further information may be needed. These
- * items are defined as auth_item_t and have a AUTHN prefix. 
- * The authentication process returns important data for the authorization 
- * process, these items are defined with a AUTHZ prefix.
- * Authentication uses AUTHN items and creates AUTHZ items during authentication,
- * authorization reads AUTHZ values to give out privileges.
- *
- *                +---+             +---------------------+
- *                | A |             | A                   |
- *                | u |             | u    +-----------+  |
- *                | t |             | t    |  Required |  |
- *                | h |             | h    | auth_info |  |
- *                | e |             | o    +-----------+  |
- *                | n |             | r           |       |
- * +-----------+  | t |             | i           |       |
- * | Provided  |  | i |             | z           V       |
- * | auth_info |--| c |-------------| a  ----> match? ----|------->
- * +-----------+  | a |             | t                   |
- *                | t |             | i                   |
- *                | i |             | o                   |
- *                | o |             | n                   |
- *                | n |             |                     |
- *                +---+             +---------------------+
- */
-enum auth_item_t {
-
-       /*
-        * items provided to authentication process
-        */
-       
-       /** authentication class to use, value is auth_class_t* */
-       AUTHN_AUTH_CLASS,
-       /** EAP method to request from peer, value is eap_type_t* */
-       AUTHN_EAP_TYPE,
-       /** EAP vendor to used in conjunction with EAP method, value is u_int32_t* */
-       AUTHN_EAP_VENDOR,
-       /** EAP identity to use within EAP-Identity exchange */
-       AUTHN_EAP_IDENTITY,
-       /** CA certificate to use for authentication, value is certificate_t* */
-       AUTHN_CA_CERT,
-       /** Keyid of a CA certificate to use, value is identification_t* */
-       AUTHN_CA_CERT_KEYID,
-       /** subject DN of a CA certificate to use, value is identification_t* */
-       AUTHN_CA_CERT_NAME,
-       /** intermediate certificate, value is certificate_t* */
-       AUTHN_IM_CERT,
-       /** certificate for trustchain verification, value is certificate_t* */
-       AUTHN_SUBJECT_CERT,
-       /** intermediate certificate supplied as hash and url */
-       AUTHN_IM_HASH_URL,
-       /** end-entity certificate supplied as hash and url */
-       AUTHN_SUBJECT_HASH_URL,
-       
-       /*
-        * item provided to authorization process
-        */
-       
-       /** subject has been authenticated by public key, value is public_key_t* */
-       AUTHZ_PUBKEY,
-       /** subject has ben authenticated using preshared secrets, value is shared_key_t* */ 
-       AUTHZ_PSK,
-       /** subject has been authenticated using EAP, value is eap_type_t* */
-       AUTHZ_EAP,
-       /** certificate authority, value is certificate_t* */
-       AUTHZ_CA_CERT,
-       /** subject DN of a certificate authority, value is identification_t* */
-       AUTHZ_CA_CERT_NAME,
-       /** intermediate certificate in trustchain, value is certificate_t* */
-       AUTHZ_IM_CERT,
-       /** subject certificate, value is certificate_t* */
-       AUTHZ_SUBJECT_CERT,
-       /** result of a CRL validation, value is cert_validation_t */
-       AUTHZ_CRL_VALIDATION,
-       /** result of a OCSP validation, value is cert_validation_t */
-       AUTHZ_OCSP_VALIDATION,
-       /** subject is in attribute certificate group, value is identification_t* */
-       AUTHZ_AC_GROUP,
-};
-
-
-/**
- * enum name for auth_item_t.
- */
-extern enum_name_t *auth_item_names;
-
-/**
- * The auth_info class contains auth_item_t's used for AA.
- *
- * A auth_info allows the separation of authentication and authorization. 
- */
-struct auth_info_t {
-
-       /**
-        * Add an item to the set.
-        *
-        * @param type          auth_info type
-        * @param value         associated value to auth_info type, if any
-        */
-       void (*add_item)(auth_info_t *this, auth_item_t type, void *value);
-       
-       /**
-        * Get an item.
-        *
-        * @param type          auth_info type to get
-        * @param value         pointer to a pointer receiving item
-        * @return                      bool if item has been found
-        */
-       bool (*get_item)(auth_info_t *this, auth_item_t type, void **value);
-       
-       /**
-        * Replace an item.
-        * 
-        * @param type          new auth_info type
-        * @param value         pointer to the new value
-        */
-       void (*replace_item)(enumerator_t *this, auth_item_t type, void *value);
-       
-       /**
-        * Create an enumerator over all items.
-        *
-        * @return                      enumerator over (auth_item_t type, void *value)
-        */
-       enumerator_t* (*create_item_enumerator)(auth_info_t *this);
-       
-       /**
-        * Check if this fulfills a set of required constraints.
-        *
-        * @param constraints   required authorization infos
-        * @return                              TRUE if this complies with constraints
-        */
-       bool (*complies)(auth_info_t *this, auth_info_t *constraints);
-       
-       /**
-        * Merge items from other into this.
-        *
-        * Items do not get cloned, but moved from other to this.
-        *
-        * @param other         items to read for merge
-        */
-       void (*merge)(auth_info_t *this, auth_info_t *other);
-       
-       /**
-        * Purge all items in auth_info.
-        */
-       void (*purge)(auth_info_t *this);
-       
-       /**
-        * Check two auth_infos for equality.
-        *
-        * @param other         other item to compaire against this
-        * @return                      TRUE if auth infos identical
-        */
-       bool (*equals)(auth_info_t *this, auth_info_t *other);
-       
-       /**
-     * Destroy a auth_info instance with all associated values.
-     */
-    void (*destroy)(auth_info_t *this);
-};
-
-/**
- * Create a auth_info instance.
- */
-auth_info_t *auth_info_create();
-
-#endif /** AUTH_INFO_H_ @}*/
index 2721edc4ab13adbb5df7e4a7d744ae37389abbed..3cd4e35ed1a3d5a4f9fa9823843fc01b34b4fe47 100644 (file)
@@ -23,7 +23,7 @@
 #include <utils/mutex.h>
 #include <utils/linked_list.h>
 #include <credentials/sets/cert_cache.h>
-#include <credentials/sets/auth_info_wrapper.h>
+#include <credentials/sets/auth_cfg_wrapper.h>
 #include <credentials/sets/ocsp_response_wrapper.h>
 #include <credentials/certificates/x509.h>
 #include <credentials/certificates/crl.h>
@@ -625,7 +625,7 @@ static certificate_t *get_better_ocsp(private_credential_manager_t *this,
  */
 static cert_validation_t check_ocsp(private_credential_manager_t *this,
                                                                    x509_t *subject, x509_t *issuer, 
-                                                                   auth_info_t *auth)
+                                                                   auth_cfg_t *auth)
 {
        enumerator_t *enumerator;
        cert_validation_t valid = VALIDATION_SKIPPED;
@@ -706,7 +706,11 @@ static cert_validation_t check_ocsp(private_credential_manager_t *this,
        }
        if (auth)
        {
-               auth->add_item(auth, AUTHZ_OCSP_VALIDATION, &valid);
+               auth->add(auth, AUTH_RULE_OCSP_VALIDATION, valid);
+               if (valid == VALIDATION_GOOD)
+               {       /* successful OCSP check fulfills also CRL constraint */
+                       auth->add(auth, AUTH_RULE_CRL_VALIDATION, VALIDATION_GOOD);
+               }
        }
        DESTROY_IF(best);
        return valid;
@@ -728,6 +732,7 @@ static certificate_t* fetch_crl(private_credential_manager_t *this, char *url)
        }
        crl = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL,
                                                         BUILD_BLOB_ASN1_DER, chunk, BUILD_END);
+       chunk_free(&chunk);
        if (!crl)
        {
                DBG1(DBG_CFG, "crl fetched successfully but parsing failed");
@@ -833,7 +838,7 @@ static certificate_t *get_better_crl(private_credential_manager_t *this,
  */
 static cert_validation_t check_crl(private_credential_manager_t *this,
                                                                   x509_t *subject, x509_t *issuer, 
-                                                                  auth_info_t *auth)
+                                                                  auth_cfg_t *auth)
 {
        cert_validation_t valid = VALIDATION_SKIPPED;
        identification_t *keyid = NULL;
@@ -841,7 +846,7 @@ static cert_validation_t check_crl(private_credential_manager_t *this,
        certificate_t *current;
        public_key_t *public;
        enumerator_t *enumerator;
-       char *uri;
+       char *uri = NULL;
        
        /* derive the authorityKeyIdentifier from the issuer's public key */
        current = &issuer->interface;
@@ -920,7 +925,16 @@ static cert_validation_t check_crl(private_credential_manager_t *this,
        }
        if (auth)
        {
-               auth->add_item(auth, AUTHZ_CRL_VALIDATION, &valid);
+               if (valid == VALIDATION_SKIPPED)
+               {       /* if we skipped CRL validation, we use the result of OCSP for
+                        * constraint checking */
+                       auth->add(auth, AUTH_RULE_CRL_VALIDATION,
+                                         auth->get(auth, AUTH_RULE_OCSP_VALIDATION));
+               }
+               else
+               {
+                       auth->add(auth, AUTH_RULE_CRL_VALIDATION, valid);
+               }
        }
        DESTROY_IF(best);
        return valid;
@@ -931,7 +945,7 @@ static cert_validation_t check_crl(private_credential_manager_t *this,
  */
 static bool check_certificate(private_credential_manager_t *this,
                                                          certificate_t *subject, certificate_t *issuer,
-                                                         bool crl, bool ocsp, auth_info_t *auth)
+                                                         bool crl, bool ocsp, auth_cfg_t *auth)
 {
        time_t not_before, not_after;
        
@@ -963,7 +977,7 @@ static bool check_certificate(private_credential_manager_t *this,
                                        DBG1(DBG_CFG, "certificate status is good");
                                        return TRUE;
                                case VALIDATION_REVOKED:
-                                       /* has already been logged */                   
+                                       /* has already been logged */
                                        return FALSE;
                                case VALIDATION_SKIPPED:
                                        DBG2(DBG_CFG, "ocsp check skipped, no ocsp found");
@@ -983,8 +997,8 @@ static bool check_certificate(private_credential_manager_t *this,
                                case VALIDATION_GOOD:
                                        DBG1(DBG_CFG, "certificate status is good");
                                        return TRUE;
-                               case VALIDATION_REVOKED:                
-                                       /* has already been logged */                   
+                               case VALIDATION_REVOKED:
+                                       /* has already been logged */
                                        return FALSE;
                                case VALIDATION_FAILED:
                                case VALIDATION_SKIPPED:
@@ -1050,14 +1064,14 @@ static certificate_t *get_issuer_cert(private_credential_manager_t *this,
  * try to verify the trust chain of subject, return TRUE if trusted
  */
 static bool verify_trust_chain(private_credential_manager_t *this,
-                                                          certificate_t *subject, auth_info_t *result,
+                                                          certificate_t *subject, auth_cfg_t *result,
                                                           bool trusted, bool crl, bool ocsp)
 {
        certificate_t *current, *issuer;
-       auth_info_t *auth;
+       auth_cfg_t *auth;
        u_int level = 0;
        
-       auth = auth_info_create();
+       auth = auth_cfg_create();
        current = subject->get_ref(subject);
        while (level++ < MAX_CA_LEVELS)
        {
@@ -1067,14 +1081,14 @@ static bool verify_trust_chain(private_credential_manager_t *this,
                        /* accept only self-signed CAs as trust anchor */
                        if (this->cache->issued_by(this->cache, issuer, issuer))
                        {
-                               auth->add_item(auth, AUTHZ_CA_CERT, issuer);
+                               auth->add(auth, AUTH_RULE_CA_CERT, issuer->get_ref(issuer));
                                DBG1(DBG_CFG, "  using trusted ca certificate \"%D\"",
                                         issuer->get_subject(issuer));
                                trusted = TRUE;
                        }
                        else
                        {
-                               auth->add_item(auth, AUTHZ_IM_CERT, issuer);
+                               auth->add(auth, AUTH_RULE_IM_CERT, issuer->get_ref(issuer));
                                DBG1(DBG_CFG, "  using trusted intermediate ca certificate "
                                         "\"%D\"", issuer->get_subject(issuer));
                        }
@@ -1091,7 +1105,7 @@ static bool verify_trust_chain(private_credential_manager_t *this,
                                        issuer->destroy(issuer);
                                        break;
                                }
-                               auth->add_item(auth, AUTHZ_IM_CERT, issuer);
+                               auth->add(auth, AUTH_RULE_IM_CERT, issuer->get_ref(issuer));
                                DBG1(DBG_CFG, "  using untrusted intermediate certificate "
                                         "\"%D\"", issuer->get_subject(issuer));
                        }
@@ -1123,7 +1137,7 @@ static bool verify_trust_chain(private_credential_manager_t *this,
        }
        if (trusted)
        {
-               result->merge(result, auth);
+               result->merge(result, auth, FALSE);
        }
        auth->destroy(auth);
        return trusted;
@@ -1149,20 +1163,20 @@ typedef struct {
        bool ocsp;
        /** pretrusted certificate we have served at first invocation */
        certificate_t *pretrusted;
-       /** currently enumerating auth info */
-       auth_info_t *auth;
+       /** currently enumerating auth config */
+       auth_cfg_t *auth;
 } trusted_enumerator_t;
 
 /**
  * Implements trusted_enumerator_t.enumerate
  */
 static bool trusted_enumerate(trusted_enumerator_t *this,
-                                                         certificate_t **cert, auth_info_t **auth)
+                                                         certificate_t **cert, auth_cfg_t **auth)
 {
        certificate_t *current;
        
        DESTROY_IF(this->auth);
-       this->auth = auth_info_create();
+       this->auth = auth_cfg_create();
        
        if (!this->candidates)
        {
@@ -1181,7 +1195,8 @@ static bool trusted_enumerate(trusted_enumerator_t *this,
                                verify_trust_chain(this->this, this->pretrusted, this->auth,
                                                                   TRUE, this->crl, this->ocsp))
                        {
-                               this->auth->add_item(this->auth, AUTHZ_CA_CERT, this->pretrusted);
+                               this->auth->add(this->auth, AUTH_RULE_SUBJECT_CERT,
+                                                               this->pretrusted->get_ref(this->pretrusted));
                                DBG1(DBG_CFG, "  using trusted certificate \"%D\"",
                                         this->pretrusted->get_subject(this->pretrusted));
                                *cert = this->pretrusted;
@@ -1264,15 +1279,15 @@ typedef struct {
        private_credential_manager_t *this;
        /** currently enumerating key */
        public_key_t *current;
-       /** credset wrapper around auth */
-       auth_info_wrapper_t *wrapper;
+       /** credset wrapper around auth config */
+       auth_cfg_wrapper_t *wrapper;
 } public_enumerator_t;
 
 /**
  * Implements public_enumerator_t.enumerate
  */
 static bool public_enumerate(public_enumerator_t *this,
-                                                        public_key_t **key, auth_info_t **auth)
+                                                        public_key_t **key, auth_cfg_t **auth)
 {
        certificate_t *cert;
        
@@ -1312,7 +1327,7 @@ static void public_destroy(public_enumerator_t *this)
  * Implementation of credential_manager_t.create_public_enumerator.
  */
 static enumerator_t* create_public_enumerator(private_credential_manager_t *this,
-                                               key_type_t type, identification_t *id, auth_info_t *auth)
+                                               key_type_t type, identification_t *id, auth_cfg_t *auth)
 {
        public_enumerator_t *enumerator = malloc_thing(public_enumerator_t);
        
@@ -1324,7 +1339,7 @@ static enumerator_t* create_public_enumerator(private_credential_manager_t *this
        enumerator->wrapper = NULL;
        if (auth)
        {
-               enumerator->wrapper = auth_info_wrapper_create(auth);
+               enumerator->wrapper = auth_cfg_wrapper_create(auth);
                add_local_set(this, &enumerator->wrapper->set);
        }
        this->lock->read_lock(this->lock);
@@ -1334,40 +1349,22 @@ static enumerator_t* create_public_enumerator(private_credential_manager_t *this
 /**
  * Check if a certificate's keyid is contained in the auth helper
  */
-static bool auth_contains_cacert(auth_info_t *auth, certificate_t *cert)
+static bool auth_contains_cacert(auth_cfg_t *auth, certificate_t *cert)
 {
        enumerator_t *enumerator;
        identification_t *value;
-       auth_item_t type;
+       auth_rule_t type;
        bool found = FALSE;
 
-       enumerator = auth->create_item_enumerator(auth);
+       enumerator = auth->create_enumerator(auth);
        while (enumerator->enumerate(enumerator, &type, &value))
        {
-               if (type == AUTHN_CA_CERT && cert->equals(cert, (certificate_t*)value))
+               if (type == AUTH_RULE_CA_CERT &&
+                       cert->equals(cert, (certificate_t*)value))
                {
                        found = TRUE;
                        break;
                }
-               if (type == AUTHN_CA_CERT_KEYID)
-               {
-                       public_key_t *public;
-                       identification_t *certid, *keyid;
-                       
-                       public = cert->get_public_key(cert);
-                       if (public)
-                       {
-                               keyid = (identification_t*)value;
-                               certid = public->get_id(public, keyid->get_type(keyid));
-                               if (certid && certid->equals(certid, keyid))
-                               {
-                                       public->destroy(public);
-                                       found = TRUE;
-                                       break;
-                               }
-                               public->destroy(public);
-                       }
-               }
        }
        enumerator->destroy(enumerator);
        return found;
@@ -1376,19 +1373,21 @@ static bool auth_contains_cacert(auth_info_t *auth, certificate_t *cert)
 /**
  * build a trustchain from subject up to a trust anchor in trusted
  */
-static auth_info_t *build_trustchain(private_credential_manager_t *this,
-                                                                        certificate_t *subject, auth_info_t *auth)
+static auth_cfg_t *build_trustchain(private_credential_manager_t *this,
+                                                                        certificate_t *subject, auth_cfg_t *auth)
 {      
        certificate_t *issuer, *current;
-       auth_info_t *trustchain;
+       auth_cfg_t *trustchain;
        u_int level = 0;
        
-       trustchain = auth_info_create();
+       trustchain = auth_cfg_create();
        
-       if (!auth->get_item(auth, AUTHN_CA_CERT, (void**)&current))
+       current = auth->get(auth, AUTH_RULE_CA_CERT);
+       if (!current)
        {
                /* no trust anchor specified, return this cert only */
-               trustchain->add_item(trustchain, AUTHZ_SUBJECT_CERT, subject);
+               trustchain->add(trustchain, AUTH_RULE_SUBJECT_CERT,
+                                               subject->get_ref(subject));
                return trustchain;
        }
        current = subject->get_ref(subject);
@@ -1396,26 +1395,23 @@ static auth_info_t *build_trustchain(private_credential_manager_t *this,
        {
                if (auth_contains_cacert(auth, current))
                {
-                       trustchain->add_item(trustchain, AUTHZ_CA_CERT, current);
-                       current->destroy(current);
+                       trustchain->add(trustchain, AUTH_RULE_CA_CERT, current);
                        return trustchain;
                }
                if (subject == current)
                {
-                       trustchain->add_item(trustchain, AUTHZ_SUBJECT_CERT, current);
+                       trustchain->add(trustchain, AUTH_RULE_SUBJECT_CERT, current);
                }
                else
                {
-                       trustchain->add_item(trustchain, AUTHZ_IM_CERT, current);
+                       trustchain->add(trustchain, AUTH_RULE_IM_CERT, current);
                }
                issuer = get_issuer_cert(this, current, FALSE);
                if (!issuer || issuer->equals(issuer, current) || level > MAX_CA_LEVELS)
                {
                        DESTROY_IF(issuer);
-                       current->destroy(current);
                        break;
                }
-               current->destroy(current);
                current = issuer;
                level++;
        }
@@ -1451,12 +1447,12 @@ static private_key_t *get_private_by_cert(private_credential_manager_t *this,
  */
 static private_key_t *get_private(private_credential_manager_t *this,
                                                                  key_type_t type, identification_t *id,
-                                                                 auth_info_t *auth)
+                                                                 auth_cfg_t *auth)
 {
        enumerator_t *enumerator;
        certificate_t *cert;
        private_key_t *private = NULL;
-       auth_info_t *trustchain;
+       auth_cfg_t *trustchain;
        
        /* check if this is a lookup by key ID, and do it if so */
        if (id)
@@ -1471,8 +1467,25 @@ static private_key_t *get_private(private_credential_manager_t *this,
                                break;
                }
        }
-       
-       /* try to build a trustchain for each certificate found */
+
+       /* if a specific certificate is preferred, check for a matching key */
+       cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
+       if (cert)
+       {
+               private = get_private_by_cert(this, cert, type);
+               if (private)
+               {
+                       trustchain = build_trustchain(this, cert, auth);
+                       if (trustchain)
+                       {
+                               auth->merge(auth, trustchain, FALSE);
+                               trustchain->destroy(trustchain);
+                       }
+                       return private;
+               }
+       }
+                       
+       /* try to build a trust chain for each certificate found */
        enumerator = create_cert_enumerator(this, CERT_ANY, type, id, FALSE);
        while (enumerator->enumerate(enumerator, &cert))
        {
@@ -1482,7 +1495,7 @@ static private_key_t *get_private(private_credential_manager_t *this,
                        trustchain = build_trustchain(this, cert, auth);
                        if (trustchain)
                        {
-                               auth->merge(auth, trustchain);
+                               auth->merge(auth, trustchain, FALSE);
                                trustchain->destroy(trustchain);
                                break;
                        }
@@ -1491,6 +1504,7 @@ static private_key_t *get_private(private_credential_manager_t *this,
                }
        }
        enumerator->destroy(enumerator);
+
        /* if no valid trustchain was found, fall back to the first usable cert */
        if (!private)
        {
@@ -1500,7 +1514,7 @@ static private_key_t *get_private(private_credential_manager_t *this,
                        private = get_private_by_cert(this, cert, type);
                        if (private)
                        {
-                               auth->add_item(auth, AUTHZ_SUBJECT_CERT, cert);
+                               auth->add(auth, AUTH_RULE_SUBJECT_CERT, cert->get_ref(cert));
                                break;
                        }
                }
@@ -1566,8 +1580,8 @@ credential_manager_t *credential_manager_create()
        this->public.create_cdp_enumerator = (enumerator_t *(*)(credential_manager_t*, certificate_type_t type, identification_t *id))create_cdp_enumerator;
        this->public.get_cert = (certificate_t *(*)(credential_manager_t *this,certificate_type_t cert, key_type_t key,identification_t *, bool))get_cert;
        this->public.get_shared = (shared_key_t *(*)(credential_manager_t *this,shared_key_type_t type,identification_t *me, identification_t *other))get_shared;
-       this->public.get_private = (private_key_t*(*)(credential_manager_t*, key_type_t type, identification_t *, auth_info_t*))get_private;
-       this->public.create_public_enumerator = (enumerator_t*(*)(credential_manager_t*, key_type_t type, identification_t *id, auth_info_t *aut))create_public_enumerator;
+       this->public.get_private = (private_key_t*(*)(credential_manager_t*, key_type_t type, identification_t *, auth_cfg_t*))get_private;
+       this->public.create_public_enumerator = (enumerator_t*(*)(credential_manager_t*, key_type_t type, identification_t *id, auth_cfg_t *aut))create_public_enumerator;
        this->public.flush_cache = (void(*)(credential_manager_t*, certificate_type_t type))flush_cache;
        this->public.cache_cert = (void(*)(credential_manager_t*, certificate_t *cert))cache_cert;
        this->public.add_set = (void(*)(credential_manager_t*, credential_set_t *set))add_set;
index 23f43cf5529d724103e00597d9e5d6c17083f796..c628e7e101d6739d1a5d9f813b8536ab7589efed 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007-2008 Martin Willi
+ * Copyright (C) 2007-2009 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
 
 #include <utils/identification.h>
 #include <utils/enumerator.h>
-#include <credentials/auth_info.h>
+#include <config/auth_cfg.h>
 #include <credentials/credential_set.h>
 #include <credentials/keys/private_key.h>
 #include <credentials/keys/shared_key.h>
@@ -122,7 +122,6 @@ struct credential_manager_t {
         * @param type          kind of requested shared key
         * @param me            own identity
         * @param other         peers identity
-        * @param auth          auth_info helper 
         * @return                      shared_key_t, NULL if none found
         */                        
        shared_key_t *(*get_shared)(credential_manager_t *this, shared_key_type_t type,
@@ -138,11 +137,11 @@ struct credential_manager_t {
         *
         * @param type          type of the key to get
         * @param id            identification the key belongs to
-        * @param auth          auth_info helper, including trusted CA certificates
+        * @param auth          auth config, including trusted CA certificates
         * @return                      private_key_t, NULL if none found
         */
        private_key_t* (*get_private)(credential_manager_t *this, key_type_t type,
-                                                                 identification_t *id, auth_info_t *auth);
+                                                                 identification_t *id, auth_cfg_t *auth);
        
        /**
         * Create an enumerator over trusted public keys.
@@ -150,9 +149,8 @@ struct credential_manager_t {
         * This method gets a an enumerator over trusted public keys to verify a
         * signature created by id. The auth parameter contains additional 
         * authentication infos, e.g. peer and intermediate certificates.
-        * The resulting enumerator enumerates over public_key_t *, auth_info_t *,
-        * where the auth info contains gained privileges for the authorization
-        * process.
+        * The resulting enumerator enumerates over public_key_t *, auth_cfg_t *,
+        * where the auth config helper contains rules for constraint checks.
         *
         * @param type          type of the key to get
         * @param id            owner of the key, signer of the signature
@@ -160,7 +158,7 @@ struct credential_manager_t {
         * @return                      enumerator
         */
        enumerator_t* (*create_public_enumerator)(credential_manager_t *this,
-                                       key_type_t type, identification_t *id, auth_info_t *auth);
+                                       key_type_t type, identification_t *id, auth_cfg_t *auth);
        
        /**
         * Cache a certificate by invoking cache_cert() on all registerd sets.
similarity index 67%
rename from src/charon/credentials/sets/auth_info_wrapper.c
rename to src/charon/credentials/sets/auth_cfg_wrapper.c
index 7ec75be1544355effcf8a3d82de37cf71f0ff4e5..2e93cc53a60bfd05b0d123f053d41189fe76c8d8 100644 (file)
@@ -1,6 +1,6 @@
 /*
+ * Copyright (C) 2008-2009 Martin Willi
  * Copyright (C) 2008 Tobias Brunner
- * Copyright (C) 2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
 
 #include <daemon.h>
 
-#include "auth_info_wrapper.h"
+#include "auth_cfg_wrapper.h"
 
-typedef struct private_auth_info_wrapper_t private_auth_info_wrapper_t;
+typedef struct private_auth_cfg_wrapper_t private_auth_cfg_wrapper_t;
 
 /**
- * private data of auth_info_wrapper
+ * private data of auth_cfg_wrapper
  */
-struct private_auth_info_wrapper_t {
+struct private_auth_cfg_wrapper_t {
 
        /**
         * public functions
         */
-       auth_info_wrapper_t public;
+       auth_cfg_wrapper_t public;
        
        /**
         * wrapped auth info
         */
-       auth_info_t *auth;
+       auth_cfg_t *auth;
 };
 
 /**
- * enumerator for auth_info_wrapper_t.create_cert_enumerator()
+ * enumerator for auth_cfg_wrapper_t.create_cert_enumerator()
  */
 typedef struct {
        /** implements enumerator_t */
        enumerator_t public;
-       /** inner enumerator from auth_info */
+       /** inner enumerator from auth_cfg */
        enumerator_t *inner;
-       /** wrapped auth info */
-       auth_info_t *auth;
+       /** wrapped auth round */
+       auth_cfg_t *auth;
        /** enumerated cert type */
        certificate_type_t cert;
        /** enumerated key type */
@@ -57,10 +57,11 @@ typedef struct {
 } wrapper_enumerator_t;
 
 /**
- * Tries to fetch a certificate that was supplied as "Hash and URL" (replaces the
- * item's type and value in place).
+ * Tries to fetch a certificate that was supplied as "Hash and URL"
+ * (replaces rule type and value in place).
  */
-static bool fetch_cert(wrapper_enumerator_t *enumerator, auth_item_t *type, void **value)
+static bool fetch_cert(wrapper_enumerator_t *enumerator,
+                                          auth_rule_t *rule, void **value)
 {
        char *url = (char*)*value;
        if (!url)
@@ -77,29 +78,38 @@ static bool fetch_cert(wrapper_enumerator_t *enumerator, auth_item_t *type, void
        {
                DBG1(DBG_CFG, "  fetching certificate failed");
                /* we set the item to NULL, so we can skip it */
-               enumerator->auth->replace_item(enumerator->inner, *type, NULL);
+               enumerator->auth->replace(enumerator->auth, enumerator->inner,
+                                                                 *rule, NULL);
                return FALSE;
        }
        
        cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
-                                         BUILD_BLOB_ASN1_DER, data, BUILD_END);
+                                                         BUILD_BLOB_ASN1_DER, data, BUILD_END);
        free(data.ptr);
        
        if (!cert)
        {
                DBG1(DBG_CFG, "  parsing fetched certificate failed");
                /* we set the item to NULL, so we can skip it */
-               enumerator->auth->replace_item(enumerator->inner, *type, NULL);
+               enumerator->auth->replace(enumerator->auth, enumerator->inner,
+                                                                 *rule, NULL);
                return FALSE;
        }
        
        DBG1(DBG_CFG, "  fetched certificate \"%D\"", cert->get_subject(cert));
        charon->credentials->cache_cert(charon->credentials, cert);
        
-       *type = (*type == AUTHN_IM_HASH_URL) ? AUTHN_IM_CERT : AUTHN_SUBJECT_CERT;
+       if (*rule == AUTH_HELPER_IM_HASH_URL)
+       {
+               *rule = AUTH_HELPER_IM_CERT;
+       }
+       else
+       {
+               *rule = AUTH_HELPER_SUBJECT_CERT;
+       }
        *value = cert;
-       enumerator->auth->replace_item(enumerator->inner, *type, cert);
-       
+       enumerator->auth->replace(enumerator->auth, enumerator->inner,
+                                                         *rule, cert->get_ref(cert));
        return TRUE;
 }
 
@@ -108,26 +118,25 @@ static bool fetch_cert(wrapper_enumerator_t *enumerator, auth_item_t *type, void
  */
 static bool enumerate(wrapper_enumerator_t *this, certificate_t **cert)
 {
-       auth_item_t type;
+       auth_rule_t rule;
        certificate_t *current;
        public_key_t *public;
 
-       while (this->inner->enumerate(this->inner, &type, &current))
+       while (this->inner->enumerate(this->inner, &rule, &current))
        {
-               if (type == AUTHN_IM_HASH_URL ||
-                       type == AUTHN_SUBJECT_HASH_URL)
-               {
-                       if (!fetch_cert(this, &type, (void**)&current))
+               if (rule == AUTH_HELPER_IM_HASH_URL ||
+                       rule == AUTH_HELPER_SUBJECT_HASH_URL)
+               {       /* on-demand fetching of hash and url certificates */
+                       if (!fetch_cert(this, &rule, (void**)&current))
                        {
                                continue;
                        }
                }
-               else if (type != AUTHN_SUBJECT_CERT && 
-                                type != AUTHN_IM_CERT)
-               {
+               else if (rule != AUTH_HELPER_SUBJECT_CERT &&
+                                rule != AUTH_HELPER_IM_CERT)
+               {       /* handle only HELPER certificates */
                        continue;
                }
-
                if (this->cert != CERT_ANY && this->cert != current->get_type(current))
                {       /* CERT type requested, but does not match */
                        continue;
@@ -164,9 +173,9 @@ static void wrapper_enumerator_destroy(wrapper_enumerator_t *this)
 }
 
 /**
- * implementation of auth_info_wrapper_t.set.create_cert_enumerator
+ * implementation of auth_cfg_wrapper_t.set.create_cert_enumerator
  */
-static enumerator_t *create_enumerator(private_auth_info_wrapper_t *this,
+static enumerator_t *create_enumerator(private_auth_cfg_wrapper_t *this,
                                                                           certificate_type_t cert, key_type_t key, 
                                                                           identification_t *id, bool trusted)
 {
@@ -181,16 +190,16 @@ static enumerator_t *create_enumerator(private_auth_info_wrapper_t *this,
        enumerator->cert = cert;
        enumerator->key = key;
        enumerator->id = id;
-       enumerator->inner = this->auth->create_item_enumerator(this->auth);
+       enumerator->inner = this->auth->create_enumerator(this->auth);
        enumerator->public.enumerate = (void*)enumerate;
        enumerator->public.destroy = (void*)wrapper_enumerator_destroy;
        return &enumerator->public;
 }
 
 /**
- * Implementation of auth_info_wrapper_t.destroy
+ * Implementation of auth_cfg_wrapper_t.destroy
  */
-static void destroy(private_auth_info_wrapper_t *this)
+static void destroy(private_auth_cfg_wrapper_t *this)
 {
        free(this);
 }
@@ -198,16 +207,16 @@ static void destroy(private_auth_info_wrapper_t *this)
 /*
  * see header file
  */
-auth_info_wrapper_t *auth_info_wrapper_create(auth_info_t *auth)
+auth_cfg_wrapper_t *auth_cfg_wrapper_create(auth_cfg_t *auth)
 {
-       private_auth_info_wrapper_t *this = malloc_thing(private_auth_info_wrapper_t);
+       private_auth_cfg_wrapper_t *this = malloc_thing(private_auth_cfg_wrapper_t);
        
        this->public.set.create_private_enumerator = (void*)return_null;
        this->public.set.create_cert_enumerator = (void*)create_enumerator;
        this->public.set.create_shared_enumerator = (void*)return_null;
        this->public.set.create_cdp_enumerator = (void*)return_null;
        this->public.set.cache_cert = (void*)nop;
-       this->public.destroy = (void(*)(auth_info_wrapper_t*))destroy;
+       this->public.destroy = (void(*)(auth_cfg_wrapper_t*))destroy;
        
        this->auth = auth;
        
similarity index 60%
rename from src/charon/credentials/sets/auth_info_wrapper.h
rename to src/charon/credentials/sets/auth_cfg_wrapper.h
index 9186715f033eef842573364b4941f6933054b984..9baf064afbeaf6a4df73c87dbf88c754ed59cd19 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2008-2009 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  */
 
 /**
- * @defgroup auth_info_wrapper auth_info_wrapper
+ * @defgroup auth_cfg_wrapper auth_cfg_wrapper
  * @{ @ingroup sets
  */
 
-#ifndef AUTH_INFO_WRAPPER_H_
-#define AUTH_INFO_WRAPPER_H_
+#ifndef AUTH_CFG_WRAPPER_H_
+#define AUTH_CFG_WRAPPER_H_
 
+#include <config/auth_cfg.h>
 #include <credentials/credential_set.h>
-#include <credentials/auth_info.h>
 
-typedef struct auth_info_wrapper_t auth_info_wrapper_t;
+typedef struct auth_cfg_wrapper_t auth_cfg_wrapper_t;
 
 /**
- * A wrapper around auth_info_t to handle it like a credential set.
+ * A wrapper around auth_cfg_t to handle it as a credential set.
  */
-struct auth_info_wrapper_t {
+struct auth_cfg_wrapper_t {
 
        /**
         * implements credential_set_t
@@ -39,17 +39,17 @@ struct auth_info_wrapper_t {
        credential_set_t set;
                
        /**
-     * Destroy a auth_info_wrapper instance.
+     * Destroy a auth_cfg_wrapper instance.
      */
-    void (*destroy)(auth_info_wrapper_t *this);
+    void (*destroy)(auth_cfg_wrapper_t *this);
 };
 
 /**
- * Create a auth_info_wrapper instance.
+ * Create a auth_cfg_wrapper instance.
  *
  * @param auth         the wrapped auth info
  * @return                     wrapper around auth
  */
-auth_info_wrapper_t *auth_info_wrapper_create(auth_info_t *auth);
+auth_cfg_wrapper_t *auth_cfg_wrapper_create(auth_cfg_t *auth);
 
-#endif /** AUTH_INFO_WRAPPER_H_ @}*/
+#endif /** AUTH_CFG_WRAPPER_H_ @}*/
index ca7cb1e7792842c06f7b0676c504d09d865c6c1b..759f4ed558439c6e9b35a9ab87f8ff96aaf91e0f 100644 (file)
@@ -523,17 +523,16 @@ static void generate_payload (private_generator_t *this,payload_t *payload)
 {
        int i;
        this->data_struct = payload;
-       size_t rule_count;
+       size_t rule_count, offset_start;
        encoding_rule_t *rules;
        payload_type_t payload_type;
-       u_int8_t *payload_start;
        
        /* get payload type */
        payload_type = payload->get_type(payload);
        /* spi size has to get reseted */
        this->last_spi_size = 0;
        
-       payload_start = this->out_position;
+       offset_start = this->out_position - this->buffer;
        
        DBG2(DBG_ENC, "generating payload of type %N",
                 payload_type_names, payload_type);
@@ -893,7 +892,8 @@ static void generate_payload (private_generator_t *this,payload_t *payload)
        DBG2(DBG_ENC, "generating %N payload finished",
                 payload_type_names, payload_type);
        DBG3(DBG_ENC, "generated data for this payload %b",
-                payload_start, this->out_position-payload_start);
+                this->buffer + offset_start,
+                this->out_position - this->buffer - offset_start);
 }
 
 /**
index a605bd3fd9aa4107772d640d8be53b340801893b..993d48b894d94b699e0fa3e53e2edcfe4a8e0d94 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2006-2007 Tobias Brunner
+ * Copyright (C) 2005-2009 Martin Willi
  * Copyright (C) 2006 Daniel Roethlisberger
- * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
@@ -208,7 +208,7 @@ static payload_rule_t ike_auth_i_payload_rules[] = {
        {NOTIFY,                                                0,      MAX_NOTIFY_PAYLOADS,    TRUE,   FALSE},
        {EXTENSIBLE_AUTHENTICATION,             0,      1,                                              TRUE,   TRUE},
        {AUTHENTICATION,                                0,      1,                                              TRUE,   TRUE},
-       {ID_INITIATOR,                                  1,      1,                                              TRUE,   FALSE},
+       {ID_INITIATOR,                                  0,      1,                                              TRUE,   FALSE},
        {CERTIFICATE,                                   0,      4,                                              TRUE,   FALSE},
        {CERTIFICATE_REQUEST,                   0,      1,                                              TRUE,   FALSE},
        {ID_RESPONDER,                                  0,      1,                                              TRUE,   FALSE},
@@ -217,9 +217,9 @@ static payload_rule_t ike_auth_i_payload_rules[] = {
        {TRAFFIC_SELECTOR_INITIATOR,    0,      1,                                              TRUE,   FALSE},
        {TRAFFIC_SELECTOR_RESPONDER,    0,      1,                                              TRUE,   FALSE},
 #else
-       {SECURITY_ASSOCIATION,                  1,      1,                                              TRUE,   FALSE},
-       {TRAFFIC_SELECTOR_INITIATOR,    1,      1,                                              TRUE,   FALSE},
-       {TRAFFIC_SELECTOR_RESPONDER,    1,      1,                                              TRUE,   FALSE},
+       {SECURITY_ASSOCIATION,                  0,      1,                                              TRUE,   FALSE},
+       {TRAFFIC_SELECTOR_INITIATOR,    0,      1,                                              TRUE,   FALSE},
+       {TRAFFIC_SELECTOR_RESPONDER,    0,      1,                                              TRUE,   FALSE},
 #endif /* ME */
        {CONFIGURATION,                                 0,      1,                                              TRUE,   FALSE},
        {VENDOR_ID,                                             0,      10,                                             TRUE,   FALSE},
@@ -261,9 +261,9 @@ static payload_rule_t ike_auth_r_payload_rules[] = {
 /*     payload type                                    min     max                                             encr    suff */
        {NOTIFY,                                                0,      MAX_NOTIFY_PAYLOADS,    TRUE,   TRUE},
        {EXTENSIBLE_AUTHENTICATION,             0,      1,                                              TRUE,   TRUE},
+       {AUTHENTICATION,                                0,      1,                                              TRUE,   TRUE},
        {CERTIFICATE,                                   0,      4,                                              TRUE,   FALSE},
        {ID_RESPONDER,                                  0,      1,                                              TRUE,   FALSE},
-       {AUTHENTICATION,                                0,      1,                                              TRUE,   FALSE},
        {SECURITY_ASSOCIATION,                  0,      1,                                              TRUE,   FALSE},
        {TRAFFIC_SELECTOR_INITIATOR,    0,      1,                                              TRUE,   FALSE},
        {TRAFFIC_SELECTOR_RESPONDER,    0,      1,                                              TRUE,   FALSE},
@@ -846,11 +846,11 @@ static host_t * get_destination(private_message_t *this)
 }
 
 /**
- * Implementation of message_t.get_payload_iterator.
+ * Implementation of message_t.create_payload_enumerator.
  */
-static iterator_t *get_payload_iterator(private_message_t *this)
+static enumerator_t *create_payload_enumerator(private_message_t *this)
 {
-       return this->payloads->create_iterator(this->payloads, TRUE);
+       return this->payloads->create_enumerator(this->payloads);
 }
 
 /**
@@ -859,10 +859,10 @@ static iterator_t *get_payload_iterator(private_message_t *this)
 static payload_t *get_payload(private_message_t *this, payload_type_t type)
 {
        payload_t *current, *found = NULL;
-       iterator_t *iterator;
+       enumerator_t *enumerator;
        
-       iterator = this->payloads->create_iterator(this->payloads, TRUE);
-       while (iterator->iterate(iterator, (void**)&current))
+       enumerator = create_payload_enumerator(this);
+       while (enumerator->enumerate(enumerator, &current))
        {
                if (current->get_type(current) == type)
                {
@@ -870,16 +870,42 @@ static payload_t *get_payload(private_message_t *this, payload_type_t type)
                        break;
                }
        }
-       iterator->destroy(iterator);
+       enumerator->destroy(enumerator);
        return found;
 }
 
+/**
+ * Implementation of message_t.get_notify
+ */
+static notify_payload_t* get_notify(private_message_t *this, notify_type_t type)
+{
+       enumerator_t *enumerator;
+       notify_payload_t *notify = NULL;
+       payload_t *payload;
+       
+       enumerator = create_payload_enumerator(this);
+       while (enumerator->enumerate(enumerator, &payload))
+       {
+               if (payload->get_type(payload) == NOTIFY)
+               {
+                       notify = (notify_payload_t*)payload;
+                       if (notify->get_notify_type(notify) == type)
+                       {
+                               break;
+                       }
+                       notify = NULL;
+               }
+       }
+       enumerator->destroy(enumerator);
+       return notify;
+}
+
 /**
  * get a string representation of the message
  */
 static char* get_string(private_message_t *this, char *buf, int len)
 {
-       iterator_t *iterator;
+       enumerator_t *enumerator;
        payload_t *payload;
        int written;
        char *pos = buf;
@@ -898,8 +924,8 @@ static char* get_string(private_message_t *this, char *buf, int len)
        pos += written;
        len -= written;
        
-       iterator = this->payloads->create_iterator(this->payloads, TRUE);
-       while (iterator->iterate(iterator, (void**)&payload))
+       enumerator = create_payload_enumerator(this);
+       while (enumerator->enumerate(enumerator, &payload))
        {
                written = snprintf(pos, len, " %N", payload_type_short_names,
                                                   payload->get_type(payload));
@@ -922,7 +948,7 @@ static char* get_string(private_message_t *this, char *buf, int len)
                        len -= written;
                }
        }
-       iterator->destroy(iterator);
+       enumerator->destroy(enumerator);
        
        /* remove last space */
        snprintf(pos, len, " ]");
@@ -1076,7 +1102,7 @@ static status_t generate(private_message_t *this, crypter_t *crypter,
        generator_t *generator;
        ike_header_t *ike_header;
        payload_t *payload, *next_payload;
-       iterator_t *iterator;
+       enumerator_t *enumerator;
        status_t status;
        chunk_t packet_data;
        char str[256];
@@ -1131,21 +1157,20 @@ static status_t generate(private_message_t *this, crypter_t *crypter,
        ike_header->set_initiator_flag(ike_header, this->ike_sa_id->is_initiator(this->ike_sa_id));
        ike_header->set_initiator_spi(ike_header, this->ike_sa_id->get_initiator_spi(this->ike_sa_id));
        ike_header->set_responder_spi(ike_header, this->ike_sa_id->get_responder_spi(this->ike_sa_id));
-
+       
        generator = generator_create();
        
        payload = (payload_t*)ike_header;
-
        
        /* generate every payload expect last one, this is done later*/
-       iterator = this->payloads->create_iterator(this->payloads, TRUE);
-       while(iterator->iterate(iterator, (void**)&next_payload))
+       enumerator = create_payload_enumerator(this);
+       while (enumerator->enumerate(enumerator, &next_payload))
        {
                payload->set_next_type(payload, next_payload->get_type(next_payload));
                generator->generate_payload(generator, payload);
                payload = next_payload;
        }
-       iterator->destroy(iterator);
+       enumerator->destroy(enumerator);
        
        /* last payload has no next payload*/
        payload->set_next_type(payload, NO_PAYLOAD);
@@ -1411,72 +1436,78 @@ static status_t decrypt_payloads(private_message_t *this,crypter_t *crypter, sig
 static status_t verify(private_message_t *this)
 {
        int i;
-       iterator_t *iterator;
+       enumerator_t *enumerator;
        payload_t *current_payload;
        size_t total_found_payloads = 0;
        
        DBG2(DBG_ENC, "verifying message structure");
        
-       iterator = this->payloads->create_iterator(this->payloads,TRUE);
        /* check for payloads with wrong count*/
-       for (i = 0; i < this->message_rule->payload_rule_count;i++)
+       for (i = 0; i < this->message_rule->payload_rule_count; i++)
        {
                size_t found_payloads = 0;
-       
-               /* check all payloads for specific rule */
-               iterator->reset(iterator);
+               payload_rule_t *rule;
                
-               while(iterator->iterate(iterator,(void **)&current_payload))
+               rule = &this->message_rule->payload_rules[i];
+               enumerator = create_payload_enumerator(this);
+               
+               /* check all payloads for specific rule */
+               while (enumerator->enumerate(enumerator, &current_payload))
                {
                        payload_type_t current_payload_type;
+                       unknown_payload_t *unknown_payload;
                        
                        current_payload_type = current_payload->get_type(current_payload);
                        if (current_payload_type == UNKNOWN_PAYLOAD)
                        {
                                /* unknown payloads are ignored, IF they are not critical */
-                               unknown_payload_t *unknown_payload = (unknown_payload_t*)current_payload;
+                               unknown_payload = (unknown_payload_t*)current_payload;
                                if (unknown_payload->is_critical(unknown_payload))
                                {
                                        DBG1(DBG_ENC, "%N is not supported, but its critical!",
                                                 payload_type_names, current_payload_type);
-                                       iterator->destroy(iterator);
+                                       enumerator->destroy(enumerator);
                                        return NOT_SUPPORTED;   
                                }
                        }
-                       else if (current_payload_type == this->message_rule->payload_rules[i].payload_type)
+                       else if (current_payload_type == rule->payload_type)
                        {
                                found_payloads++;
                                total_found_payloads++;
-                               DBG2(DBG_ENC, "found payload of type %N",
-                                        payload_type_names, this->message_rule->payload_rules[i].payload_type);
+                               DBG2(DBG_ENC, "found payload of type %N", payload_type_names,
+                                        rule->payload_type);
                                
-                               /* as soon as ohe payload occures more then specified, the verification fails */
-                               if (found_payloads > this->message_rule->payload_rules[i].max_occurence)
+                               /* as soon as ohe payload occures more then specified, 
+                                * the verification fails */
+                               if (found_payloads >
+                                       rule->max_occurence)
                                {
-                                       DBG1(DBG_ENC, "payload of type %N more than %d times (%d) occured in current message",
-                                                payload_type_names, current_payload_type,
-                                                this->message_rule->payload_rules[i].max_occurence, found_payloads);
-                                       iterator->destroy(iterator);
+                                       DBG1(DBG_ENC, "payload of type %N more than %d times (%d) "
+                                                "occured in current message", payload_type_names,
+                                                current_payload_type, rule->max_occurence,
+                                                found_payloads);
+                                       enumerator->destroy(enumerator);
                                        return VERIFY_ERROR;
                                }
                        }
                }
                
-               if (found_payloads < this->message_rule->payload_rules[i].min_occurence)
+               if (found_payloads < rule->min_occurence)
                {
                        DBG1(DBG_ENC, "payload of type %N not occured %d times (%d)",
-                                payload_type_names, this->message_rule->payload_rules[i].payload_type,
-                                this->message_rule->payload_rules[i].min_occurence, found_payloads);
-                       iterator->destroy(iterator);
+                                payload_type_names, rule->payload_type, rule->min_occurence,
+                                found_payloads);
+                       enumerator->destroy(enumerator);
                        return VERIFY_ERROR;
                }
-               if ((this->message_rule->payload_rules[i].sufficient) && (this->payloads->get_count(this->payloads) == total_found_payloads))
+               if (rule->sufficient &&
+                       this->payloads->get_count(this->payloads) == total_found_payloads)
                {
-                       iterator->destroy(iterator);
+                       enumerator->destroy(enumerator);
                        return SUCCESS; 
                }
+               enumerator->destroy(enumerator);
        }
-       iterator->destroy(iterator);
        return SUCCESS;
 }
 
@@ -1604,8 +1635,9 @@ message_t *message_create_from_packet(packet_t *packet)
        this->public.get_source = (host_t * (*) (message_t*)) get_source;
        this->public.set_destination = (void (*) (message_t*,host_t*)) set_destination;
        this->public.get_destination = (host_t * (*) (message_t*)) get_destination;
-       this->public.get_payload_iterator = (iterator_t * (*) (message_t *)) get_payload_iterator;
+       this->public.create_payload_enumerator = (enumerator_t * (*) (message_t *)) create_payload_enumerator;
        this->public.get_payload = (payload_t * (*) (message_t *, payload_type_t)) get_payload;
+       this->public.get_notify = (notify_payload_t*(*)(message_t*, notify_type_t type))get_notify;
        this->public.parse_header = (status_t (*) (message_t *)) parse_header;
        this->public.parse_body = (status_t (*) (message_t *,crypter_t*,signer_t*)) parse_body;
        this->public.get_packet = (packet_t * (*) (message_t*)) get_packet;
index fcd206cb537ba20e989b06b5b8270ccdad2e9fd7..095371747683a6107ed1942ad7ab5aad49240f10 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2006-2007 Tobias Brunner
+ * Copyright (C) 2005-2009 Martin Willi
  * Copyright (C) 2006 Daniel Roethlisberger
- * Copyright (C) 2005-2006 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
@@ -286,14 +286,11 @@ struct message_t {
        void (*set_destination) (message_t *this, host_t *host);
        
        /**
-        * Returns an iterator on all stored payloads.
-        * 
-        * @warning Don't insert payloads over this iterator. 
-        *                      Use add_payload() instead.
+        * Create an enumerator over all payloads.
         *
-        * @return                      iterator_t object which has to get destroyd by the caller
+        * @return                      enumerator over payload_t
         */     
-       iterator_t * (*get_payload_iterator) (message_t *this);
+       enumerator_t * (*create_payload_enumerator) (message_t *this);
        
        /**
         * Find a payload of a specific type.
@@ -305,6 +302,14 @@ struct message_t {
         */     
        payload_t* (*get_payload) (message_t *this, payload_type_t type);
        
+       /**
+        * Get the first notify payload of a specific type.
+        *
+        * @param type          type of notification payload
+        * @return                      notify payload, NULL if no such notify found
+        */
+       notify_payload_t* (*get_notify)(message_t *this, notify_type_t type);
+       
        /**
         * Returns a clone of the internal stored packet_t object.
         *
index 2f276eb0b55b3bc8a9b9b1da333d9056fe40095b..9bbff817ab3149dcf39401a3e2095037f02cf761 100644 (file)
@@ -17,6 +17,9 @@
 
 #include "eap_mschapv2.h"
 
+#include <ctype.h>
+#include <unistd.h>
+
 #include <daemon.h>
 #include <library.h>
 #include <utils/enumerator.h>
@@ -141,7 +144,7 @@ ENUM_END(mschapv2_error_names, ERROR_CHANGING_PASSWORD);
 /* Name we send as authenticator */
 #define MSCHAPV2_HOST_NAME "strongSwan"
 /* Message sent on success */
-#define SUCCESS_MESSAGE " M=Welcome to strongSwan"
+#define SUCCESS_MESSAGE " M=Welcome2strongSwan"
 /* Message sent on failure */
 #define FAILURE_MESSAGE "E=691 R=1 C="
 /* Length of the complete failure message */
@@ -366,7 +369,6 @@ static status_t AuthenticatorResponse(chunk_t password_hash_hash,
        static const chunk_t magic1 = chunk_from_buf(magic1_data);
        static const chunk_t magic2 = chunk_from_buf(magic2_data);
        
-       status_t status = FAILED;
        chunk_t digest = chunk_empty, concat;
        hasher_t *hasher;
        
@@ -526,6 +528,24 @@ static chunk_t ascii_to_unicode(chunk_t ascii)
        return unicode;
 }
 
+/**
+ * sanitize a string for printing
+ */
+static char* sanitize(char *str)
+{
+       char *pos = str;
+       
+       while (pos && *pos)
+       {
+               if (!isprint(*pos))
+               {
+                       *pos = '?';
+               }
+               pos++;
+       }
+       return str;
+}
+
 /**
  * Returns a chunk of just the username part of the given user identity.
  * Note: the chunk points to internal data of the identification.
@@ -535,7 +555,7 @@ static chunk_t extract_username(identification_t* identification)
        char *has_domain;
        chunk_t id;
        id = identification->get_encoding(identification);
-       has_domain = (char*)memrchr(id.ptr, '\\', id.len);
+       has_domain = (char*)memchr(id.ptr, '\\', id.len);
        if (has_domain)
        {
                int len;
@@ -625,7 +645,8 @@ static status_t process_peer_challenge(private_eap_mschapv2_t *this,
                        
        if (cha->value_size != CHALLENGE_LEN)
        {
-               DBG1(DBG_IKE, "received invalid EAP-MS-CHAPv2 message: invalid challenge size");
+               DBG1(DBG_IKE, "received invalid EAP-MS-CHAPv2 message: "
+                        "invalid challenge size");
                return FAILED;
        }
                        
@@ -643,11 +664,11 @@ static status_t process_peer_challenge(private_eap_mschapv2_t *this,
        rng->destroy(rng);
                        
        shared = charon->credentials->get_shared(charon->credentials,
-                                                                                        SHARED_EAP, this->peer, this->server);
+                                                                               SHARED_EAP, this->peer, this->server);
        if (shared == NULL)
        {
                DBG1(DBG_IKE, "no EAP key found for hosts '%D' - '%D'",
-                               this->server, this->peer);
+                        this->server, this->peer);
                return NOT_FOUND;
        }
        
@@ -725,7 +746,8 @@ static status_t process_peer_success(private_eap_mschapv2_t *this,
                        token += 2;
                        if (strlen(token) != AUTH_RESPONSE_LEN - 2)
                        {
-                               DBG1(DBG_IKE, "received invalid EAP-MS-CHAPv2 message: invalid auth string");
+                               DBG1(DBG_IKE, "received invalid EAP-MS-CHAPv2 message: "
+                                        "invalid auth string");
                                goto error;
                        }
                        hex = chunk_create(token, AUTH_RESPONSE_LEN - 2);
@@ -741,7 +763,8 @@ static status_t process_peer_success(private_eap_mschapv2_t *this,
                        
        if (auth_string.ptr == NULL)    
        {
-               DBG1(DBG_IKE, "received invalid EAP-MS-CHAPv2 message: auth string missing");
+               DBG1(DBG_IKE, "received invalid EAP-MS-CHAPv2 message: "
+                        "auth string missing");
                goto error;
        }
        
@@ -751,7 +774,7 @@ static status_t process_peer_success(private_eap_mschapv2_t *this,
                goto error;
        }
        
-       DBG1(DBG_IKE, "EAP-MS-CHAPv2 succeeded: '%s'", msg);
+       DBG1(DBG_IKE, "EAP-MS-CHAPv2 succeeded: '%s'", sanitize(msg));
        
        eap = alloca(len);
        eap->code = EAP_RESPONSE;
@@ -780,7 +803,6 @@ static status_t process_peer_failure(private_eap_mschapv2_t *this,
        char *message, *token, *msg = NULL;
        int message_len, error, retryable;
        chunk_t challenge = chunk_empty;
-       u_int16_t len = SHORT_HEADER_LEN;
        
        data = in->get_data(in);
        eap = (eap_mschapv2_header_t*)data.ptr;
@@ -816,7 +838,8 @@ static status_t process_peer_failure(private_eap_mschapv2_t *this,
                        token += 2;
                        if (strlen(token) != 2 * CHALLENGE_LEN)
                        {
-                               DBG1(DBG_IKE, "received invalid EAP-MS-CHAPv2 message: invalid challenge");
+                               DBG1(DBG_IKE, "received invalid EAP-MS-CHAPv2 message:"
+                                        "invalid challenge");
                                goto error;
                        }
                        hex = chunk_create(token, 2 * CHALLENGE_LEN);
@@ -836,7 +859,8 @@ static status_t process_peer_failure(private_eap_mschapv2_t *this,
        }
        enumerator->destroy(enumerator);
                        
-       DBG1(DBG_IKE, "EAP-MS-CHAPv2 failed with error %N: '%s'", mschapv2_error_names, error, msg);
+       DBG1(DBG_IKE, "EAP-MS-CHAPv2 failed with error %N: '%s'",
+                mschapv2_error_names, error, sanitize(msg));
                        
        /**
         * at this point, if the error is retryable, we MAY retry the authentication
@@ -898,8 +922,8 @@ static status_t process_peer(private_eap_mschapv2_t *this, eap_payload_t *in,
                }
                default:
                {
-                       DBG1(DBG_IKE, "EAP-MS-CHAPv2 received packet with unsupported OpCode (%N)!",
-                                       mschapv2_opcode_names, eap->opcode);
+                       DBG1(DBG_IKE, "EAP-MS-CHAPv2 received packet with unsupported "
+                                "OpCode (%N)!", mschapv2_opcode_names, eap->opcode);
                        break;
                }
        }
@@ -925,7 +949,8 @@ static status_t process_server_retry(private_eap_mschapv2_t *this,
                 * so, to clean up our state we just fail with an EAP-Failure.
                 * this gives an unknown error on the windows side, but is also fine
                 * with the standard. */
-               DBG1(DBG_IKE, "EAP-MS-CHAPv2 verification failed: maximum number of retries reached");
+               DBG1(DBG_IKE, "EAP-MS-CHAPv2 verification failed: "
+                        "maximum number of retries reached");
                return FAILED;
        }
        
@@ -977,6 +1002,7 @@ static status_t process_server_response(private_eap_mschapv2_t *this,
        identification_t *userid;
        shared_key_t *shared;
        int name_len;
+       char buf[256];
        
        data = in->get_data(in);
        eap = (eap_mschapv2_header_t*)data.ptr;
@@ -991,10 +1017,10 @@ static status_t process_server_response(private_eap_mschapv2_t *this,
        peer_challenge = chunk_create(res->response.peer_challenge, CHALLENGE_LEN);
        
        name_len = min(data.len - RESPONSE_PAYLOAD_LEN, 255);
-       userid = identification_create_from_encoding(ID_EAP,
-                                                                                                chunk_create(res->name, name_len));
+       snprintf(buf, sizeof(buf), "%.*s", name_len, res->name);
+       userid = identification_create_from_string(buf);
+       DBG2(DBG_IKE, "EAP-MS-CHAPv2 username: '%D'", userid);
        username = extract_username(userid);
-       DBG2(DBG_IKE, "EAP-MS-CHAPv2 username: '%.*s'", name_len, res->name);
        
        shared = charon->credentials->get_shared(charon->credentials,
                                                                                         SHARED_EAP, this->server, userid);
@@ -1015,7 +1041,8 @@ static status_t process_server_response(private_eap_mschapv2_t *this,
        password = ascii_to_unicode(shared->get_key(shared));
        shared->destroy(shared);
        
-       if (GenerateStuff(this, this->challenge, peer_challenge, username, password) != SUCCESS)
+       if (GenerateStuff(this, this->challenge, peer_challenge,
+                                         username, password) != SUCCESS)
        {
                DBG1(DBG_IKE, "EAP-MS-CHAPv2 verification failed");     
                userid->destroy(userid);
@@ -1063,7 +1090,8 @@ static status_t process_server(private_eap_mschapv2_t *this, eap_payload_t *in,
        
        if (this->identifier != in->get_identifier(in))
        {
-               DBG1(DBG_IKE, "received invalid EAP-MS-CHAPv2 message: unexpected identifier");
+               DBG1(DBG_IKE, "received invalid EAP-MS-CHAPv2 message: "
+                        "unexpected identifier");
                return FAILED;
        }
        
@@ -1092,8 +1120,8 @@ static status_t process_server(private_eap_mschapv2_t *this, eap_payload_t *in,
                }
                default:
                {
-                       DBG1(DBG_IKE, "EAP-MS-CHAPv2 received packet with unsupported OpCode (%N)!",
-                                       mschapv2_opcode_names, eap->opcode);
+                       DBG1(DBG_IKE, "EAP-MS-CHAPv2 received packet with unsupported "
+                                "OpCode (%N)!", mschapv2_opcode_names, eap->opcode);
                        break;
                }
        }
index 7969007d02b0b2ec3f534e75eacb919a5e0cc55c..cd71adf5befe452a10b363563764ffe8d5b328e7 100644 (file)
@@ -52,13 +52,13 @@ static bool get_triplet(private_eap_sim_file_card_t *this,
        identification_t *id;
        char *c_rand, *c_sres, *c_kc;
        
-       
-       DBG1(DBG_CFG, "looking for rand: %b", rand, RAND_LEN);
+       DBG2(DBG_CFG, "looking for rand: %b", rand, RAND_LEN);
        
        enumerator = this->triplets->create_enumerator(this->triplets);
        while (enumerator->enumerate(enumerator, &id, &c_rand, &c_sres, &c_kc))
        {
-               DBG1(DBG_CFG, "found triplet: %b %b %b", c_rand, RAND_LEN, c_sres, SRES_LEN, c_kc, KC_LEN);
+               DBG2(DBG_CFG, "found triplet: rand %b\nsres %b\n kc %b",
+                        c_rand, RAND_LEN, c_sres, SRES_LEN, c_kc, KC_LEN);
                if (memeq(c_rand, rand, RAND_LEN))
                {
                        memcpy(sres, c_sres, SRES_LEN);
index 409e9cbd512d7109cede6c792dda5b4175981bff..9d30f891c773ea6e84f70f0078f05589267a1d68 100644 (file)
@@ -196,8 +196,7 @@ static void read_triplets(private_eap_sim_file_triplets_t *this, char *path)
                        switch (i++)
                        {
                                case 0: /* IMSI */
-                                       triplet->imsi = identification_create_from_encoding(ID_EAP,
-                                                                                       chunk_create(token, strlen(token)));
+                                       triplet->imsi = identification_create_from_string(token);
                                        continue;
                                case 1: /* rand */
                                        parse_token(triplet->rand, token, RAND_LEN);
@@ -221,7 +220,7 @@ static void read_triplets(private_eap_sim_file_triplets_t *this, char *path)
                        continue;
                }\r
                \r
-               DBG1(DBG_CFG, "triplet: imsi %D\nrand %b\nsres %b\nkc %b",\r
+               DBG2(DBG_CFG, "triplet: imsi %D\nrand %b\nsres %b\nkc %b",\r
                         triplet->imsi, triplet->rand, RAND_LEN,\r
                         triplet->sres, SRES_LEN, triplet->kc, KC_LEN);
                         
index f3cd33b6109f8f44380b40fe1b492a500e22a63a..25055daefe9d99a3715d74aa31d474fc63ed5fee 100644 (file)
@@ -57,9 +57,14 @@ struct private_load_tester_config_t {
        proposal_t *proposal;
        
        /**
-        * Authentication method to use
+        * Authentication method(s) to use/expect from initiator
         */
-       auth_class_t class;
+       char *initiator_auth;
+       
+       /**
+        * Authentication method(s) use/expected from responder
+        */
+       char *responder_auth;
        
        /**
         * incremental numbering of generated configs
@@ -67,6 +72,97 @@ struct private_load_tester_config_t {
        u_int num;
 };
 
+/**
+ * Generate auth config from string
+ */
+static void generate_auth_cfg(private_load_tester_config_t *this, char *str,
+                                                         peer_cfg_t *peer_cfg, bool local, int num)
+{
+       enumerator_t *enumerator;
+       auth_cfg_t *auth;
+       identification_t *id;
+       auth_class_t class;
+       eap_type_t type;
+       char buf[128];
+       int rnd = 0;
+       
+       enumerator = enumerator_create_token(str, "|", " ");
+       while (enumerator->enumerate(enumerator, &str))
+       {
+               auth = auth_cfg_create();
+               rnd++;
+               
+               if (streq(str, "psk"))
+               {       /* PSK authentication, use FQDNs */
+                       class = AUTH_CLASS_PSK;
+                       if ((local && !num) || (!local && num))
+                       {
+                               id = identification_create_from_string("srv.strongswan.org");
+                       }
+                       else if (local)
+                       {
+                               snprintf(buf, sizeof(buf), "c%d-r%d.strongswan.org", num, rnd);
+                               id = identification_create_from_string(buf);
+                       }
+                       else
+                       {
+                               id = identification_create_from_string("*.strongswan.org");
+                       }
+               }
+               else if (strneq(str, "eap", strlen("eap")))
+               {       /* EAP authentication, use a NAI */
+                       class = AUTH_CLASS_EAP;
+                       if (*(str + strlen("eap")) == '-')
+                       {
+                               type = eap_type_from_string(str + strlen("eap-"));
+                               if (type)
+                               {
+                                       auth->add(auth, AUTH_RULE_EAP_TYPE, type);
+                               }
+                       }
+                       if (local && num)
+                       {
+                               snprintf(buf, sizeof(buf), "1%.10d%.4d@strongswan.org", num, rnd);
+                               id = identification_create_from_string(buf);
+                       }
+                       else
+                       {
+                               id = identification_create_from_encoding(ID_ANY, chunk_empty);
+                       }
+               }
+               else
+               {
+                       if (!streq(str, "pubkey"))
+                       {
+                               DBG1(DBG_CFG, "invalid authentication: '%s', fallback to pubkey",
+                                        str);
+                       }
+                       /* certificate authentication, use distinguished names */
+                       class = AUTH_CLASS_PUBKEY;
+                       if ((local && !num) || (!local && num))
+                       {
+                               id = identification_create_from_string(
+                                                       "CN=srv, OU=load-test, O=strongSwan");
+                       }
+                       else if (local)
+                       {
+                               snprintf(buf, sizeof(buf),
+                                                "CN=c%d-r%d, OU=load-test, O=strongSwan", num, rnd);
+                               id = identification_create_from_string(buf);
+                       }
+                       else
+                       {
+                               id = identification_create_from_string(
+                                                               "CN=*, OU=load-test, O=strongSwan");
+                       }
+               }
+               auth->add(auth, AUTH_RULE_AUTH_CLASS, class);
+               auth->add(auth, AUTH_RULE_IDENTITY, id);
+               peer_cfg->add_auth_cfg(peer_cfg, auth, local);
+       }
+       enumerator->destroy(enumerator);
+}
+
 /**
  * Generate a new initiator config, num = 0 for responder config
  */
@@ -76,36 +172,26 @@ static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num)
        child_cfg_t *child_cfg;
        peer_cfg_t *peer_cfg;
        traffic_selector_t *ts;
-       auth_info_t *auth;
-       identification_t *local, *remote;
        proposal_t *proposal;
-       char buf[128];
-       
-       if (num)
-       {       /* initiator */
-               snprintf(buf, sizeof(buf), "CN=cli-%d, OU=load-test, O=strongSwan", num);
-               local = identification_create_from_string(buf);
-               snprintf(buf, sizeof(buf), "CN=srv, OU=load-test, O=strongSwan", num);
-               remote = identification_create_from_string(buf);
-       }
-       else
-       {       /* responder */
-               local = identification_create_from_string(
-                                                                               "CN=srv, OU=load-test, O=strongSwan");
-               remote = identification_create_from_string(
-                                                                               "CN=*, OU=load-test, O=strongSwan");
-       }
        
        ike_cfg = ike_cfg_create(FALSE, FALSE, "0.0.0.0", this->remote);
        ike_cfg->add_proposal(ike_cfg, this->proposal->clone(this->proposal));
-       peer_cfg = peer_cfg_create("load-test", 2, ike_cfg, local, remote,
+       peer_cfg = peer_cfg_create("load-test", 2, ike_cfg,
                        CERT_SEND_IF_ASKED, UNIQUE_NO, 1, 0, 0, /* keytries, rekey, reauth */
                        0, 0, FALSE, 0, /* jitter, overtime, mobike, dpddelay */
                        this->vip ? this->vip->clone(this->vip) : NULL,
                        this->pool, FALSE, NULL, NULL);
-       auth = peer_cfg->get_auth(peer_cfg);
-       auth->add_item(auth, AUTHN_AUTH_CLASS, &this->class);
-       child_cfg = child_cfg_create("load-test", 600, 400, 100, NULL, TRUE,
+       if (num)
+       {       /* initiator */
+               generate_auth_cfg(this, this->initiator_auth, peer_cfg, TRUE, num);
+               generate_auth_cfg(this, this->responder_auth, peer_cfg, FALSE, num);
+       }
+       else
+       {       /* responder */
+               generate_auth_cfg(this, this->responder_auth, peer_cfg, TRUE, num);
+               generate_auth_cfg(this, this->initiator_auth, peer_cfg, FALSE, num);
+       }
+       child_cfg = child_cfg_create("load-test", 1200, 600, 0, NULL, TRUE,
                                                                 MODE_TUNNEL, ACTION_NONE, ACTION_NONE, FALSE);
        proposal = proposal_create_from_string(PROTO_ESP, "aes128-sha1");
        child_cfg->add_proposal(child_cfg, proposal);
@@ -169,7 +255,6 @@ static void destroy(private_load_tester_config_t *this)
 load_tester_config_t *load_tester_config_create()
 {
        private_load_tester_config_t *this = malloc_thing(private_load_tester_config_t);
-       char *authstr;
        
        this->public.backend.create_peer_cfg_enumerator = (enumerator_t*(*)(backend_t*, identification_t *me, identification_t *other))create_peer_cfg_enumerator;
        this->public.backend.create_ike_cfg_enumerator = (enumerator_t*(*)(backend_t*, host_t *me, host_t *other))create_ike_cfg_enumerator;
@@ -195,16 +280,10 @@ load_tester_config_t *load_tester_config_create()
                this->proposal = proposal_create_from_string(PROTO_IKE,
                                                                                                         "aes128-sha1-modp768");
        }
-       authstr = lib->settings->get_str(lib->settings,
-                                                               "charon.plugins.load_tester.auth", "pubkey");
-       if (streq(authstr, "psk"))
-       {
-               this->class = AUTH_CLASS_PSK;
-       }
-       else
-       {
-               this->class = AUTH_CLASS_PUBKEY;
-       }
+       this->initiator_auth = lib->settings->get_str(lib->settings,
+                               "charon.plugins.load_tester.initiator_auth", "pubkey");
+       this->responder_auth = lib->settings->get_str(lib->settings,
+                               "charon.plugins.load_tester.responder_auth", "pubkey");
        
        this->num = 1;
        this->peer_cfg = generate_config(this, 0);
index e7cd640a728999d47aab5316438cb7e0c281f90b..de9eb3b1b40a22a5feff9ad6522e0a3b36ec9906 100644 (file)
@@ -259,9 +259,7 @@ static void set_username_password(private_nm_creds_t *this, identification_t *id
 {
        this->lock->write_lock(this->lock);
        DESTROY_IF(this->user);
-       /* for EAP authentication, we use always use ID_EAP type */
-       this->user = identification_create_from_encoding(ID_EAP,
-                                                                                                        id->get_encoding(id));
+       this->user = id->clone(id);
        free(this->pass);
        this->pass = password ? strdup(password) : NULL;
        this->lock->unlock(this->lock);
index 72744b7846dbf68acdae6a35827b482d2b7a76f1..abe55eb7de6fc3daac8297c2304b69fbcd5b0ffe 100644 (file)
@@ -151,7 +151,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
        child_cfg_t *child_cfg;
        traffic_selector_t *ts;
        ike_sa_t *ike_sa;
-       auth_info_t *auth;
+       auth_cfg_t *auth;
        auth_class_t auth_class = AUTH_CLASS_EAP;
        certificate_t *cert = NULL;
        bool agent = FALSE;
@@ -223,8 +223,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
                str = nm_setting_vpn_get_data_item(settings, "user");
                if (str)
                {
-                       user = identification_create_from_encoding(ID_KEY_ID,
-                                                                                       chunk_create(str, strlen(str)));
+                       user = identification_create_from_string(str);
                        str = nm_setting_vpn_get_secret(settings, "password");
                        creds->set_username_password(creds, user, (char*)str);
                }
@@ -322,15 +321,21 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
        ike_cfg = ike_cfg_create(TRUE, encap, "0.0.0.0", (char*)address);
        ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
        peer_cfg = peer_cfg_create(CONFIG_NAME, 2, ike_cfg,
-                                       user, gateway->clone(gateway),
                                        CERT_SEND_IF_ASKED, UNIQUE_REPLACE, 1, /* keyingtries */
                                        36000, 0, /* rekey 10h, reauth none */
                                        600, 600, /* jitter, over 10min */
                                        TRUE, 0, /* mobike, DPD */
                                        virtual ? host_create_from_string("0.0.0.0", 0) : NULL,
                                        NULL, FALSE, NULL, NULL); /* pool, mediation */
-       auth = peer_cfg->get_auth(peer_cfg);
-       auth->add_item(auth, AUTHN_AUTH_CLASS, &auth_class);
+       auth = auth_cfg_create();
+       auth->add(auth, AUTH_RULE_AUTH_CLASS, auth_class);
+       auth->add(auth, AUTH_RULE_IDENTITY, user);
+       peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
+       auth = auth_cfg_create();
+       auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
+       auth->add(auth, AUTH_RULE_IDENTITY, gateway->clone(gateway));
+       peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
+       
        child_cfg = child_cfg_create(CONFIG_NAME,
                                                                 10800, 10200, /* lifetime 3h, rekey 2h50min */
                                                                 300, /* jitter 5min */
index 1283873a4b5c95a48cf10c594d1ba07cb55eccaa..33a2bb4910a5ae957619e83400ce236fc721aed6 100644 (file)
@@ -294,8 +294,9 @@ static void request_query_config(xmlTextReaderPtr reader, xmlTextWriterPtr write
        /* <configlist> */
        xmlTextWriterStartElement(writer, "configlist");
        
-       enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends);
-       while (enumerator->enumerate(enumerator, (void**)&peer_cfg))
+       enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
+                                                                                                               NULL, NULL, NULL, NULL);
+       while (enumerator->enumerate(enumerator, &peer_cfg))
        {
                enumerator_t *children;
                child_cfg_t *child_cfg;
@@ -310,8 +311,8 @@ static void request_query_config(xmlTextReaderPtr reader, xmlTextWriterPtr write
                /* <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));
+               
+               /* TODO: write auth_cfgs */
                
                /* <ikeconfig> */
                ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
index 9761e88e92c0cdb07784e6a53885487152e11353..a1c67c69192cd73094b3a6d7c8985ef0cfb626e0 100644 (file)
@@ -401,11 +401,6 @@ static enumerator_t *create_lease_query(char *filter)
                                {
                                        id = identification_create_from_string(value);
                                }
-                               if (!id)
-                               {
-                                       fprintf(stderr, "invalid 'id' in filter string.\n");
-                                       exit(-1);
-                               }
                                break;
                        case FIL_ADDR:
                                if (value)
index 826aa831845dbea53ae671ac6fa67a047600a926..484085d11dc71ee91c4d48f25ec8f1ec8ed030c0 100644 (file)
@@ -179,7 +179,7 @@ static host_t *get_address(private_sql_attribute_t *this, char *name,
  */
 static host_t* acquire_address(private_sql_attribute_t *this,
                                                           char *name, identification_t *id,
-                                                          auth_info_t *auth, host_t *requested)
+                                                          host_t *requested)
 {
        enumerator_t *enumerator;
        u_int pool, timeout, identity;
@@ -263,7 +263,7 @@ sql_attribute_t *sql_attribute_create(database_t *db)
        private_sql_attribute_t *this = malloc_thing(private_sql_attribute_t);
        time_t now = time(NULL);
        
-       this->public.provider.acquire_address = (host_t*(*)(attribute_provider_t *this, char*, identification_t *,auth_info_t *, host_t *))acquire_address;
+       this->public.provider.acquire_address = (host_t*(*)(attribute_provider_t *this, char*, identification_t *, host_t *))acquire_address;
        this->public.provider.release_address = (bool(*)(attribute_provider_t *this, char*,host_t *, identification_t*))release_address;
        this->public.destroy = (void(*)(sql_attribute_t*))destroy;
        
index 8efa1cb2e054885910ac8da4054fc4d7a4f6d45b..802bbe7772cea8104ac823f2cbb934f2c948ee81 100644 (file)
@@ -267,7 +267,7 @@ static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
                peer_cfg_t *peer_cfg, *mediated_cfg;
                ike_cfg_t *ike;
                host_t *vip = NULL;
-               auth_info_t *auth;
+               auth_cfg_t *auth;
                
                local_id = identification_create_from_encoding(l_type, l_data);
                remote_id = identification_create_from_encoding(r_type, r_data);
@@ -291,20 +291,26 @@ static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
                if (ike)
                {
                        peer_cfg = peer_cfg_create(
-                                       name, 2, ike, local_id, remote_id, cert_policy, uniqueid,
+                                       name, 2, ike, cert_policy, uniqueid,
                                        keyingtries, rekeytime, reauthtime, jitter, overtime,
                                        mobike, dpd_delay, vip, pool,
                                        mediation, mediated_cfg, peer_id);
-                       auth = peer_cfg->get_auth(peer_cfg);
-                       auth->add_item(auth, AUTHN_AUTH_CLASS, &auth_method);
+                       auth = auth_cfg_create();
+                       auth->add(auth, AUTH_RULE_AUTH_CLASS, auth_method);
+                       auth->add(auth, AUTH_RULE_IDENTITY, local_id->clone(local_id));
+                       peer_cfg->add_auth_cfg(peer_cfg, auth, TRUE);
+                       auth = auth_cfg_create();
+                       auth->add(auth, AUTH_RULE_IDENTITY, remote_id->clone(remote_id));
                        if (eap_type)
                        {
-                               auth->add_item(auth, AUTHN_EAP_TYPE, &eap_type);
+                               auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
+                               auth->add(auth, AUTH_RULE_EAP_TYPE, eap_type);
                                if (eap_vendor)
                                {
-                                       auth->add_item(auth, AUTHN_EAP_VENDOR, &eap_vendor);
+                                       auth->add(auth, AUTH_RULE_EAP_VENDOR, eap_vendor);
                                }
                        }
+                       peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
                        add_child_cfgs(this, peer_cfg, id);
                        return peer_cfg;
                }
index f850b5320acb78aa5b8b08448d8d64b3ae366bd8..0ebc367faf4484002e2b90d6ed7fa93ef150922a 100644 (file)
@@ -191,7 +191,7 @@ int host2offset(pool_t *pool, host_t *addr)
  */
 static host_t* acquire_address(private_stroke_attribute_t *this,
                                                           char *name, identification_t *id,
-                                                          auth_info_t *auth, host_t *requested)
+                                                          host_t *requested)
 {
        pool_t *pool;
        uintptr_t offset = 0;
@@ -530,7 +530,7 @@ stroke_attribute_t *stroke_attribute_create()
 {
        private_stroke_attribute_t *this = malloc_thing(private_stroke_attribute_t);
        
-       this->public.provider.acquire_address = (host_t*(*)(attribute_provider_t *this, char*, identification_t *,auth_info_t *, host_t *))acquire_address;
+       this->public.provider.acquire_address = (host_t*(*)(attribute_provider_t *this, char*, identification_t *,host_t *))acquire_address;
        this->public.provider.release_address = (bool(*)(attribute_provider_t *this, char*,host_t *, identification_t*))release_address;
        this->public.add_pool = (void(*)(stroke_attribute_t*, stroke_msg_t *msg))add_pool;
        this->public.del_pool = (void(*)(stroke_attribute_t*, stroke_msg_t *msg))del_pool;
index 59c58ca0d58798ce5581499796b833bfe5c28c31..4a0b1ff428fa37f95be55e85088d7a2307ddd4fd 100644 (file)
@@ -54,49 +54,6 @@ struct private_stroke_config_t {
        stroke_cred_t *cred;
 };
 
-/**
- * data to pass peer_filter
- */
-typedef struct {
-       private_stroke_config_t *this;
-       identification_t *me;
-       identification_t *other;
-} peer_data_t;
-
-/**
- * destroy id enumerator data and unlock list
- */
-static void peer_data_destroy(peer_data_t *data)
-{
-       data->this->mutex->unlock(data->this->mutex);
-       free(data);
-}
-
-/**
- * filter function for peer configs
- */
-static bool peer_filter(peer_data_t *data, peer_cfg_t **in, peer_cfg_t **out)
-{
-       bool match_me = FALSE, match_other = FALSE;
-       identification_t *me, *other;
-       
-       me = (*in)->get_my_id(*in);
-       other = (*in)->get_other_id(*in);
-       
-       /* own ID may have wildcards in data (no IDr payload) or in config */
-       match_me = (!data->me || data->me->matches(data->me, me) ||
-                               me->matches(me, data->me));
-       /* others ID has wildcards in config only */
-       match_other = (!data->other || data->other->matches(data->other, other));
-       
-       if (match_me && match_other)
-       {
-               *out = *in;
-               return TRUE;
-       }
-       return FALSE;
-}
-
 /**
  * Implementation of backend_t.create_peer_cfg_enumerator.
  */
@@ -104,41 +61,15 @@ static enumerator_t* create_peer_cfg_enumerator(private_stroke_config_t *this,
                                                                                                identification_t *me,
                                                                                                identification_t *other)
 {
-       peer_data_t *data;
-       
-       data = malloc_thing(peer_data_t);
-       data->this = this;
-       data->me = me;
-       data->other = other;
-       
        this->mutex->lock(this->mutex);
-       return enumerator_create_filter(this->list->create_enumerator(this->list),
-                                                                       (void*)peer_filter, data,
-                                                                       (void*)peer_data_destroy);
-}
-
-/**
- * data to pass ike_filter
- */
-typedef struct {
-       private_stroke_config_t *this;
-       host_t *me;
-       host_t *other;
-} ike_data_t;
-
-/**
- * destroy id enumerator data and unlock list
- */
-static void ike_data_destroy(ike_data_t *data)
-{
-       data->this->mutex->unlock(data->this->mutex);
-       free(data);
+       return enumerator_create_cleaner(this->list->create_enumerator(this->list),
+                                                                        (void*)this->mutex->unlock, this->mutex);
 }
 
 /**
  * filter function for ike configs
  */
-static bool ike_filter(ike_data_t *data, peer_cfg_t **in, ike_cfg_t **out)
+static bool ike_filter(void *data, peer_cfg_t **in, ike_cfg_t **out)
 {
        *out = (*in)->get_ike_cfg(*in);
        return TRUE;
@@ -150,17 +81,10 @@ static bool ike_filter(ike_data_t *data, peer_cfg_t **in, ike_cfg_t **out)
 static enumerator_t* create_ike_cfg_enumerator(private_stroke_config_t *this,
                                                                                           host_t *me, host_t *other)
 {
-       ike_data_t *data;
-       
-       data = malloc_thing(ike_data_t);
-       data->this = this;
-       data->me = me;
-       data->other = other;
-       
        this->mutex->lock(this->mutex);
        return enumerator_create_filter(this->list->create_enumerator(this->list),
-                                                                       (void*)ike_filter, data,
-                                                                       (void*)ike_data_destroy);
+                                                                       (void*)ike_filter, this->mutex,
+                                                                       (void*)this->mutex->unlock);
 }
 
 /**
@@ -171,56 +95,40 @@ static peer_cfg_t *get_peer_cfg_by_name(private_stroke_config_t *this, char *nam
        enumerator_t *e1, *e2;
        peer_cfg_t *current, *found = NULL;
        child_cfg_t *child;
-
+       
        this->mutex->lock(this->mutex);
        e1 = this->list->create_enumerator(this->list);
        while (e1->enumerate(e1, &current))
        {
-        /* compare peer_cfgs name first */
-        if (streq(current->get_name(current), name))
-        {
-            found = current;
-            found->get_ref(found);
-            break;
-        }
-        /* compare all child_cfg names otherwise */
-        e2 = current->create_child_cfg_enumerator(current);
-        while (e2->enumerate(e2, &child))
-        {
-            if (streq(child->get_name(child), name))
-            {
-                found = current;
-                found->get_ref(found);
-                break;
-            }
-        }
-        e2->destroy(e2);
-        if (found)
-        {
-            break;
-        }
+               /* compare peer_cfgs name first */
+               if (streq(current->get_name(current), name))
+               {
+                       found = current;
+                       found->get_ref(found);
+                       break;
+               }
+               /* compare all child_cfg names otherwise */
+               e2 = current->create_child_cfg_enumerator(current);
+               while (e2->enumerate(e2, &child))
+               {
+                       if (streq(child->get_name(child), name))
+                       {
+                               found = current;
+                               found->get_ref(found);
+                               break;
+                       }
+               }
+               e2->destroy(e2);
+               if (found)
+               {
+                       break;
+               }
        }
        e1->destroy(e1);
        this->mutex->unlock(this->mutex);
        return found;
 }
 
-/**
- * check if a certificate has an ID
- */
-static identification_t *update_peerid(certificate_t *cert, identification_t *id)
-{
-       if (id->get_type(id) == ID_ANY || !cert->has_subject(cert, id))
-       {
-               DBG1(DBG_CFG, "  peerid %D not confirmed by certificate, "
-                        "defaulting to subject DN", id);
-               id->destroy(id);
-               id = cert->get_subject(cert);
-               return id->clone(id);
-       }
-       return id;
-}
-
 /**
  * parse a proposal string, either into ike_cfg or child_cfg
  */
@@ -332,45 +240,303 @@ static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg
        add_proposals(this, msg->add_conn.algorithms.ike, ike_cfg, NULL);
        return ike_cfg;                                  
 }
+
 /**
- * build a peer_cfg from a stroke msg
+ * Add CRL constraint to config
  */
-static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
-                                                                 stroke_msg_t *msg, ike_cfg_t *ike_cfg,
-                                                                 identification_t **my_issuer,
-                                                                 identification_t **other_issuer)
+static void build_crl_policy(auth_cfg_t *cfg, bool local, int policy)
 {
-       identification_t *me, *other, *peer_id = NULL;
-       peer_cfg_t *mediated_by = NULL;
-       host_t *vip = NULL;
-       certificate_t *cert;
-       unique_policy_t unique;
-       u_int32_t rekey = 0, reauth = 0, over, jitter;
+       /* CRL/OCSP policy, for remote config only */
+       if (!local)
+       {
+               switch (policy)
+               {
+                       case CRL_STRICT_YES:
+                               /* if yes, we require a GOOD validation */
+                               cfg->add(cfg, AUTH_RULE_CRL_VALIDATION, VALIDATION_GOOD);
+                               break;
+                       case CRL_STRICT_IFURI:
+                               /* for ifuri, a SKIPPED validation is sufficient */
+                               cfg->add(cfg, AUTH_RULE_CRL_VALIDATION, VALIDATION_SKIPPED);
+                               break;
+                       default:
+                               break;
+               }
+       }
+}
+
+/**
+ * build authentication config
+ */
+static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
+                                                                 stroke_msg_t *msg, bool local, bool primary)
+{
+       identification_t *identity;
+       certificate_t *certificate;
+       char *auth, *id, *cert, *ca;
+       stroke_end_t *end, *other_end;
+       auth_cfg_t *cfg;
+       char eap_buf[32];
        
-       me = identification_create_from_string(msg->add_conn.me.id ?
-                                               msg->add_conn.me.id : msg->add_conn.me.address);
-       if (!me)
+       /* select strings */
+       if (local)
        {
-               DBG1(DBG_CFG, "invalid ID: %s\n", msg->add_conn.me.id);
-               return NULL;
+               end = &msg->add_conn.me;
+               other_end = &msg->add_conn.other;
        }
-       other = identification_create_from_string(msg->add_conn.other.id ?
-                                               msg->add_conn.other.id : msg->add_conn.other.address);
-       if (!other)
+       else
        {
-               DBG1(DBG_CFG, "invalid ID: %s\n", msg->add_conn.other.id);
-               me->destroy(me);
-               return NULL;
+               end = &msg->add_conn.other;
+               other_end = &msg->add_conn.me;
+       }
+       if (primary)
+       {
+               auth = end->auth;
+               id = end->id;
+               if (!id)
+               {       /* leftid/rightid fallback to address */
+                       id = end->address;
+               }
+               cert = end->cert;
+               ca = end->ca;
+               if (ca && streq(ca, "%same"))
+               {
+                       ca = other_end->ca;
+               }
+       }
+       else
+       {
+               auth = end->auth2;
+               id = end->id2;
+               if (local && !id)
+               {       /* leftid2 falls back to leftid */
+                       id = end->id;
+               }
+               cert = end->cert2;
+               ca = end->ca2;
+               if (ca && streq(ca, "%same"))
+               {
+                       ca = other_end->ca2;
+               }
        }
        
+       if (!auth)
+       {
+               if (primary)
+               {
+                       if (local)
+                       {       /* "leftauth" not defined, fall back to deprecated "authby" */
+                               switch (msg->add_conn.auth_method)
+                               {
+                                       default:
+                                       case AUTH_CLASS_PUBKEY:
+                                               auth = "pubkey";
+                                               break;
+                                       case AUTH_CLASS_PSK:
+                                               auth = "psk";
+                                               break;
+                                       case AUTH_CLASS_EAP:
+                                               auth = "eap";
+                                               break;
+                               }
+                       }
+                       else
+                       {       /* "rightauth" not defined, fall back to deprecated "eap" */
+                               if (msg->add_conn.eap_type)
+                               {
+                                       if (msg->add_conn.eap_vendor)
+                                       {
+                                               snprintf(eap_buf, sizeof(eap_buf), "eap-%d-%d",
+                                                                msg->add_conn.eap_type,
+                                                                msg->add_conn.eap_vendor);
+                                       }
+                                       else
+                                       {
+                                               snprintf(eap_buf, sizeof(eap_buf), "eap-%d",
+                                                                msg->add_conn.eap_type);
+                                       }
+                                       auth = eap_buf;
+                               }
+                               else
+                               {       /* not EAP => no constraints for this peer */
+                                       auth = "any";
+                               }
+                       }
+               }
+               else
+               {       /* no second authentication round, fine */
+                       return NULL;
+               }
+       }
+       
+       cfg = auth_cfg_create();
+       
+       /* add identity and peer certifcate */
+       identity = identification_create_from_string(id);
+       if (cert)
+       {
+               certificate = this->cred->load_peer(this->cred, cert);
+               if (certificate)
+               {
+                       if (local)
+                       {
+                               this->ca->check_for_hash_and_url(this->ca, certificate);
+                       }
+                       cfg->add(cfg, AUTH_RULE_SUBJECT_CERT, certificate); 
+                       if (identity->get_type(identity) == ID_ANY ||
+                               !certificate->has_subject(certificate, identity))
+                       {
+                               DBG1(DBG_CFG, "  peerid %D not confirmed by certificate, "
+                                        "defaulting to subject DN: %D", identity,
+                                        certificate->get_subject(certificate));
+                               identity->destroy(identity);
+                               identity = certificate->get_subject(certificate);
+                               identity = identity->clone(identity);
+                       }
+               }
+       }
+       cfg->add(cfg, AUTH_RULE_IDENTITY, identity);
+       
+       /* CA constraint */
+       if (ca)
+       {
+               identity = identification_create_from_string(ca);
+               certificate = charon->credentials->get_cert(charon->credentials,
+                                                                                       CERT_X509, KEY_ANY, identity, TRUE);
+               identity->destroy(identity);
+               if (certificate)
+               {
+                       cfg->add(cfg, AUTH_RULE_CA_CERT, certificate);
+               }
+               else
+               {
+                       DBG1(DBG_CFG, "CA certificate %s not found, discarding CA "
+                                "constraint", ca);
+               }
+       }
+       
+       /* AC groups */
+       if (end->groups)
+       {
+               enumerator_t *enumerator;
+               char *group;
+               
+               enumerator = enumerator_create_token(end->groups, ",", " ");
+               while (enumerator->enumerate(enumerator, &group))
+               {
+                       identity = identification_create_from_encoding(ID_IETF_ATTR_STRING,
+                                                                                       chunk_create(group, strlen(group)));
+                       cfg->add(cfg, AUTH_RULE_AC_GROUP, identity);
+               }
+               enumerator->destroy(enumerator);
+       }
+       
+       /* authentication metod (class, actually) */
+       if (streq(auth, "pubkey") ||
+               streq(auth, "rsasig") || streq(auth, "rsa") ||
+               streq(auth, "ecdsasig") || streq(auth, "ecdsa"))
+       {
+               cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
+               build_crl_policy(cfg, local, msg->add_conn.crl_policy);
+       }
+       else if (streq(auth, "psk") || streq(auth, "secret"))
+       {
+               cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
+       }
+       else if (strneq(auth, "eap", 3))
+       {
+               enumerator_t *enumerator;
+               char *str;
+               int i = 0, type = 0, vendor;
+               
+               cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
+               
+               /* parse EAP string, format: eap[-type[-vendor]] */
+               enumerator = enumerator_create_token(auth, "-", " ");
+               while (enumerator->enumerate(enumerator, &str))
+               {
+                       switch (i)
+                       {
+                               case 1:
+                                       type = eap_type_from_string(str);
+                                       if (!type)
+                                       {
+                                               type = atoi(str);
+                                               if (!type)
+                                               {
+                                                       DBG1(DBG_CFG, "unknown EAP method: %s", str);
+                                                       break;
+                                               }
+                                       }
+                                       cfg->add(cfg, AUTH_RULE_EAP_TYPE, type);
+                                       break;
+                               case 2:
+                                       if (type)
+                                       {
+                                               vendor = atoi(str);
+                                               if (vendor)
+                                               {
+                                                       cfg->add(cfg, AUTH_RULE_EAP_VENDOR, vendor);
+                                               }
+                                               else
+                                               {
+                                                       DBG1(DBG_CFG, "unknown EAP vendor: %s", str);
+                                               }
+                                       }
+                                       break;
+                               default:
+                                       break;
+                       }
+                       i++;
+               }
+               enumerator->destroy(enumerator);
+               
+               if (msg->add_conn.eap_identity)
+               {
+                       if (streq(msg->add_conn.eap_identity, "%identity"))
+                       {
+                               identity = identification_create_from_encoding(ID_ANY,
+                                                                                                                          chunk_empty);
+                       }
+                       else
+                       {
+                               identity = identification_create_from_string(
+                                                                                                       msg->add_conn.eap_identity);
+                       }
+                       cfg->add(cfg, AUTH_RULE_EAP_IDENTITY, identity);
+               }
+       }
+       else
+       {
+               if (!streq(auth, "any"))
+               {
+                       DBG1(DBG_CFG, "authentication method %s unknown, fallback to any",
+                                auth);
+               }
+               build_crl_policy(cfg, local, msg->add_conn.crl_policy);
+       }
+       return cfg;
+}
+
+/**
+ * build a peer_cfg from a stroke msg
+ */
+static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
+                                                                 stroke_msg_t *msg, ike_cfg_t *ike_cfg)
+{
+       identification_t *peer_id = NULL;
+       peer_cfg_t *mediated_by = NULL;
+       host_t *vip = NULL;
+       unique_policy_t unique;
+       u_int32_t rekey = 0, reauth = 0, over, jitter;
+       peer_cfg_t *peer_cfg;
+       auth_cfg_t *auth_cfg;
        
 #ifdef ME
        if (msg->add_conn.ikeme.mediation && msg->add_conn.ikeme.mediated_by)
        {
                DBG1(DBG_CFG, "a mediation connection cannot be a"
                                " mediated connection at the same time, aborting");
-               me->destroy(me);
-               other->destroy(other);
                return NULL;
        }
        
@@ -388,8 +554,6 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
                {
                        DBG1(DBG_CFG, "mediation connection '%s' not found, aborting",
                                 msg->add_conn.ikeme.mediated_by);
-                       me->destroy(me);
-                       other->destroy(other);
                        return NULL;
                }
                
@@ -399,56 +563,19 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
                                 "no mediation connection, aborting", 
                                msg->add_conn.ikeme.mediated_by, msg->add_conn.name);
                        mediated_by->destroy(mediated_by);
-                       me->destroy(me);
-                       other->destroy(other);
                        return NULL;
                }
-       }
-       
-       if (msg->add_conn.ikeme.peerid)
-       {
-               peer_id = identification_create_from_string(msg->add_conn.ikeme.peerid);
-               if (!peer_id)
+               if (msg->add_conn.ikeme.peerid)
                {
-                       DBG1(DBG_CFG, "invalid peer ID: %s\n", msg->add_conn.ikeme.peerid);
-                       mediated_by->destroy(mediated_by);
-                       me->destroy(me);
-                       other->destroy(other);
-                       return NULL;
+                       peer_id = identification_create_from_string(msg->add_conn.ikeme.peerid);
                }
-       }
-       else
-       {
-               /* no peer ID supplied, assume right ID */
-               peer_id = other->clone(other);
-       }
-#endif /* ME */
-       
-       if (msg->add_conn.me.cert)
-       {
-               cert = this->cred->load_peer(this->cred, msg->add_conn.me.cert);
-               if (cert)
+               else if (msg->add_conn.other.id)
                {
-                       identification_t *issuer = cert->get_issuer(cert);
-
-                       *my_issuer = issuer->clone(issuer); 
-                       this->ca->check_for_hash_and_url(this->ca, cert);
-                       me = update_peerid(cert, me);
-                       cert->destroy(cert);
-               }
-       }
-       if (msg->add_conn.other.cert)
-       {
-               cert = this->cred->load_peer(this->cred, msg->add_conn.other.cert);
-               if (cert)
-               {
-                       identification_t *issuer = cert->get_issuer(cert);
-
-                       *other_issuer = issuer->clone(issuer); 
-                       other = update_peerid(cert, other);
-                       cert->destroy(cert);
+                       peer_id = identification_create_from_string(msg->add_conn.other.id);
                }
        }
+#endif /* ME */
+       
        jitter = msg->add_conn.rekey.margin * msg->add_conn.rekey.fuzz / 100;
        over = msg->add_conn.rekey.margin;
        if (msg->add_conn.rekey.reauth)
@@ -512,179 +639,45 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
        /* other.sourceip is managed in stroke_attributes. If it is set, we define
         * the pool name as the connection name, which the attribute provider
         * uses to serve pool addresses. */
-       return peer_cfg_create(msg->add_conn.name,
-               msg->add_conn.ikev2 ? 2 : 1, ike_cfg, me, other,
+       peer_cfg = peer_cfg_create(msg->add_conn.name,
+               msg->add_conn.ikev2 ? 2 : 1, ike_cfg,
                msg->add_conn.me.sendcert, unique, 
                msg->add_conn.rekey.tries, rekey, reauth, jitter, over,
                msg->add_conn.mobike, msg->add_conn.dpd.delay,
                vip, msg->add_conn.other.sourceip_size ?
                                                        msg->add_conn.name : msg->add_conn.other.sourceip,
                msg->add_conn.ikeme.mediation, mediated_by, peer_id);
-}
-
-/**
- * fill in auth_info from stroke message
- */
-static void build_auth_info(private_stroke_config_t *this,
-                                                       stroke_msg_t *msg, auth_info_t *auth,
-                                                       identification_t *my_ca,
-                                                       identification_t *other_ca)
-{
-       identification_t *id;
-       bool my_ca_same = FALSE;
-       bool other_ca_same = FALSE;
-       cert_validation_t valid;
-
-       switch (msg->add_conn.crl_policy)
-       {
-               case CRL_STRICT_YES:
-                       valid = VALIDATION_GOOD;
-                       auth->add_item(auth, AUTHZ_CRL_VALIDATION, &valid);
-                       break;
-               case CRL_STRICT_IFURI:
-                       valid = VALIDATION_SKIPPED;
-                       auth->add_item(auth, AUTHZ_CRL_VALIDATION, &valid);
-                       break;
-               default:
-                       break;
-       }
        
-       if (msg->add_conn.me.ca)
+       /* build leftauth= */
+       auth_cfg = build_auth_cfg(this, msg, TRUE, TRUE);
+       if (auth_cfg)
        {
-               if (my_ca)
-               {
-                       my_ca->destroy(my_ca);
-                       my_ca = NULL;
-               }
-               if (streq(msg->add_conn.me.ca, "%same"))
-               {
-                       my_ca_same = TRUE;
-               }
-               else
-               {
-                       my_ca = identification_create_from_string(msg->add_conn.me.ca);
-               }
+               peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, TRUE);
        }
-
-       if (msg->add_conn.other.ca)
-       {
-               if (other_ca)
-               {
-                       other_ca->destroy(other_ca);
-                       other_ca = NULL;
-               }
-               if (streq(msg->add_conn.other.ca, "%same"))
-               {
-                       other_ca_same = TRUE;
-               }
-               else
-               {
-                       other_ca = identification_create_from_string(msg->add_conn.other.ca);
-               }
-       }
-
-       if (other_ca_same && my_ca)
-       {
-               other_ca = my_ca->clone(my_ca);
-       }
-       else if (my_ca_same && other_ca)
-       {
-               my_ca = other_ca->clone(other_ca);
-       }
-       
-       if (other_ca)
-       {
-               DBG2(DBG_CFG, "  other ca: %D", other_ca);
-               certificate_t *cert = charon->credentials->get_cert(charon->credentials, 
-                                                                       CERT_X509, KEY_ANY, other_ca, TRUE);
-               if (cert)
-               {
-                       auth->add_item(auth, AUTHZ_CA_CERT, cert);
-                       cert->destroy(cert);
-               }
-               else
-               {
-                       auth->add_item(auth, AUTHZ_CA_CERT_NAME, other_ca);
-               }
-               other_ca->destroy(other_ca);
-       }
-
-       if (my_ca)
-       {
-               DBG2(DBG_CFG, "  my ca:    %D", my_ca);
-               certificate_t *cert = charon->credentials->get_cert(charon->credentials, 
-                                                                       CERT_X509, KEY_ANY, my_ca, TRUE);
-               if (cert)
-               {
-                       auth->add_item(auth, AUTHN_CA_CERT, cert);
-                       cert->destroy(cert);
-               }
-               else
-               {
-                       auth->add_item(auth, AUTHN_CA_CERT_NAME, my_ca);
-               }
-               my_ca->destroy(my_ca);
+       else
+       {       /* we require at least one config on our side */
+               peer_cfg->destroy(peer_cfg);
+               return NULL;
        }
-       auth->add_item(auth, AUTHN_AUTH_CLASS, &msg->add_conn.auth_method);
-       if (msg->add_conn.eap_type)
+       /* build leftauth2= */
+       auth_cfg = build_auth_cfg(this, msg, TRUE, FALSE);
+       if (auth_cfg)
        {
-               auth->add_item(auth, AUTHN_EAP_TYPE, &msg->add_conn.eap_type);
-               if (msg->add_conn.eap_vendor)
-               {
-                       auth->add_item(auth, AUTHN_EAP_VENDOR, &msg->add_conn.eap_vendor);
-               }
+               peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, TRUE);
        }
-
-       if (msg->add_conn.eap_identity)
+       /* build rightauth= */
+       auth_cfg = build_auth_cfg(this, msg, FALSE, TRUE);
+       if (auth_cfg)
        {
-               if (streq(msg->add_conn.eap_identity, "%identity"))
-               {
-                       id = identification_create_from_encoding(ID_ANY, chunk_empty);
-               }
-               else
-               {
-                       id = identification_create_from_encoding(ID_EAP, chunk_create(
-                                                                               msg->add_conn.eap_identity,
-                                                                               strlen(msg->add_conn.eap_identity)));
-               }
-               auth->add_item(auth, AUTHN_EAP_IDENTITY, id);
-               id->destroy(id);
+               peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, FALSE);
        }
-
-       if (msg->add_conn.other.groups)
+       /* build rightauth2= */
+       auth_cfg = build_auth_cfg(this, msg, FALSE, FALSE);
+       if (auth_cfg)
        {
-               chunk_t line = { msg->add_conn.other.groups,
-                                                strlen(msg->add_conn.other.groups) };
-
-               while (eat_whitespace(&line))
-               {
-                       chunk_t group;
-
-                       /* extract the next comma-separated group attribute */
-                       if (!extract_token(&group, ',', &line))
-                       {
-                               group = line;
-                               line.len = 0;
-                       }
-
-                       /* remove any trailing spaces */
-                       while (group.len > 0 && *(group.ptr + group.len - 1) == ' ')
-                       {
-                               group.len--;
-                       }
-
-                       /* add the group attribute to the list */
-                       if (group.len > 0)
-                       {
-                               identification_t *ac_group;
-
-                               ac_group = identification_create_from_encoding(
-                                                                       ID_IETF_ATTR_STRING, group);
-                               auth->add_item(auth, AUTHZ_AC_GROUP, ac_group);
-                               ac_group->destroy(ac_group);    
-                       }
-               }
+               peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, FALSE);
        }
+       return peer_cfg;
 }
 
 /**
@@ -799,7 +792,6 @@ static void add(private_stroke_config_t *this, stroke_msg_t *msg)
        ike_cfg_t *ike_cfg, *existing_ike;
        peer_cfg_t *peer_cfg, *existing;
        child_cfg_t *child_cfg;
-       identification_t *my_issuer = NULL, *other_issuer = NULL;
        enumerator_t *enumerator;
        bool use_existing = FALSE;
 
@@ -808,15 +800,13 @@ static void add(private_stroke_config_t *this, stroke_msg_t *msg)
        {
                return;
        }
-       peer_cfg = build_peer_cfg(this, msg, ike_cfg, &my_issuer, &other_issuer);
+       peer_cfg = build_peer_cfg(this, msg, ike_cfg);
        if (!peer_cfg)
        {
                ike_cfg->destroy(ike_cfg);
                return;
        }
        
-       build_auth_info(this, msg, peer_cfg->get_auth(peer_cfg),
-                                       my_issuer, other_issuer);
        enumerator = create_peer_cfg_enumerator(this, NULL, NULL);
        while (enumerator->enumerate(enumerator, &existing))
        {
@@ -850,9 +840,7 @@ static void add(private_stroke_config_t *this, stroke_msg_t *msg)
        else
        {
                /* add config to backend */
-               DBG1(DBG_CFG, "added configuration '%s': %s[%D]...%s[%D]", msg->add_conn.name,
-                        ike_cfg->get_my_addr(ike_cfg), peer_cfg->get_my_id(peer_cfg),
-                        ike_cfg->get_other_addr(ike_cfg), peer_cfg->get_other_id(peer_cfg));
+               DBG1(DBG_CFG, "added configuration '%s'", msg->add_conn.name);
                this->mutex->lock(this->mutex);
                this->list->insert_last(this->list, peer_cfg);
                this->mutex->unlock(this->mutex);
index 434aec22b1cf0db9730dc56703bd3801a6bc6318..7fb33da9e1a8b0991477b5a3b77f6da218ba2397 100644 (file)
@@ -905,26 +905,13 @@ static void load_secrets(private_stroke_cred_t *this)
                                        continue;
                                }
                                
-                               if (type == SHARED_EAP)
+                               /* NULL terminate the ID string */
+                               *(id.ptr + id.len) = '\0';
+                               peer_id = identification_create_from_string(id.ptr);
+                               if (peer_id->get_type(peer_id) == ID_ANY)
                                {
-                                       /* we use a special EAP identity type for EAP secrets */
-                                       peer_id = identification_create_from_encoding(ID_EAP, id);
-                               }
-                               else
-                               {
-                                       /* NULL terminate the ID string */
-                                       *(id.ptr + id.len) = '\0';
-                                       peer_id = identification_create_from_string(id.ptr);
-                                       if (peer_id == NULL)
-                                       {
-                                               DBG1(DBG_CFG, "line %d: malformed ID: %s", line_nr, id.ptr);
-                                               goto error;
-                                       }
-                                       if (peer_id->get_type(peer_id) == ID_ANY)
-                                       {
-                                               peer_id->destroy(peer_id);
-                                               continue;
-                                       }
+                                       peer_id->destroy(peer_id);
+                                       continue;
                                }
                                
                                shared_key->add_owner(shared_key, peer_id);
index 94b3def3a90ef707789bfa1fe01fbc74c023c49c..9c98770dd073c02e13438948c811d7a209cecadf 100644 (file)
@@ -54,23 +54,6 @@ struct private_stroke_list_t {
        stroke_attribute_t *attribute;
 };
 
-/**
- * get the authentication class of a config
- */
-auth_class_t get_auth_class(peer_cfg_t *config)
-{
-       auth_class_t *class;
-       auth_info_t *auth_info;
-       
-       auth_info = config->get_auth(config);
-       if (auth_info->get_item(auth_info, AUTHN_AUTH_CLASS, (void**)&class))
-       {
-               return *class;
-       }
-       /* fallback to pubkey authentication */
-       return AUTH_CLASS_PUBKEY;
-}
-
 /**
  * log an IKE_SA to out
  */
@@ -110,9 +93,11 @@ static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
                if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED)
                {
                        time_t rekey, reauth;
+                       peer_cfg_t *peer_cfg;
                        
                        rekey = ike_sa->get_statistic(ike_sa, STAT_REKEY);
                        reauth = ike_sa->get_statistic(ike_sa, STAT_REAUTH);
+                       peer_cfg = ike_sa->get_peer_cfg(ike_sa);
                        
                        if (rekey)
                        {
@@ -120,9 +105,24 @@ static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
                        }
                        if (reauth)
                        {
-                               fprintf(out, ", %N reauthentication in %V", auth_class_names,
-                                               get_auth_class(ike_sa->get_peer_cfg(ike_sa)),
-                                               &reauth, &now);
+                               bool first = TRUE;
+                               enumerator_t *enumerator;
+                               auth_cfg_t *auth;
+                               
+                               fprintf(out, ", ");
+                               enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, TRUE);
+                               while (enumerator->enumerate(enumerator, &auth))
+                               {
+                                       if (!first)
+                                       {
+                                               fprintf(out, "+");
+                                       }
+                                       first = FALSE;
+                                       fprintf(out, "%N", auth_class_names,
+                                                       auth->get(auth, AUTH_RULE_AUTH_CLASS));
+                               }
+                               enumerator->destroy(enumerator);
+                               fprintf(out, " reauthentication in %V", &reauth, &now);
                        }
                        if (!rekey && !reauth)
                        {
@@ -247,6 +247,107 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
                        child_sa->get_traffic_selectors(child_sa, FALSE));
 }
 
+/**
+ * Log a configs local or remote authentication config to out
+ */
+static void log_auth_cfgs(FILE *out, peer_cfg_t *peer_cfg, bool local)
+{
+       enumerator_t *enumerator, *rules;
+       auth_rule_t rule;
+       auth_cfg_t *auth;
+       auth_class_t auth_class;
+       identification_t *id;
+       certificate_t *cert;
+       cert_validation_t valid;
+       char *name;
+       
+       name = peer_cfg->get_name(peer_cfg);
+       
+       enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, local);
+       while (enumerator->enumerate(enumerator, &auth))
+       {
+               fprintf(out, "%12s:   %s [%D] uses ", name,     local ? "local: " : "remote:",
+                               auth->get(auth, AUTH_RULE_IDENTITY));
+
+               auth_class = (uintptr_t)auth->get(auth, AUTH_RULE_AUTH_CLASS);
+               if (auth_class != AUTH_CLASS_EAP)
+               {
+                       fprintf(out, "%N authentication\n", auth_class_names, auth_class);
+               }
+               else
+               {
+                       if ((uintptr_t)auth->get(auth, AUTH_RULE_EAP_TYPE) == EAP_NAK)
+                       {
+                               fprintf(out, "EAP authentication");
+                       }
+                       else
+                       {
+                               if ((uintptr_t)auth->get(auth, AUTH_RULE_EAP_VENDOR))
+                               {
+                                       fprintf(out, "EAP_%d-%d authentication",
+                                               (uintptr_t)auth->get(auth, AUTH_RULE_EAP_TYPE),
+                                               (uintptr_t)auth->get(auth, AUTH_RULE_EAP_VENDOR));
+                               }
+                               else
+                               {
+                                       fprintf(out, "%N authentication", eap_type_names,
+                                               (uintptr_t)auth->get(auth, AUTH_RULE_EAP_TYPE));
+                               }
+                       }
+                       id = auth->get(auth, AUTH_RULE_EAP_IDENTITY);
+                       if (id)
+                       {
+                               fprintf(out, " with EAP identity '%D'", id);
+                       }
+                       fprintf(out, "\n");
+               }
+
+               cert = auth->get(auth, AUTH_RULE_CA_CERT);
+               if (cert)
+               {
+                       fprintf(out, "%12s:    ca:    \"%D\"\n", name, cert->get_subject(cert));
+               }
+
+               cert = auth->get(auth, AUTH_RULE_IM_CERT);
+               if (cert)
+               {
+                       fprintf(out, "%12s:    im-ca: \"%D\"\n", name, cert->get_subject(cert));
+               }
+
+               cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
+               if (cert)
+               {
+                       fprintf(out, "%12s:    cert:  \"%D\"\n", name,
+                                       cert->get_subject(cert));
+               }
+
+               valid = (uintptr_t)auth->get(auth, AUTH_RULE_OCSP_VALIDATION);
+               if (valid != VALIDATION_FAILED)
+               {
+                       fprintf(out, "%12s:    ocsp:  status must be GOOD%s\n", name,
+                                       (valid == VALIDATION_SKIPPED) ? " or SKIPPED" : "");
+               }
+               
+               valid = (uintptr_t)auth->get(auth, AUTH_RULE_CRL_VALIDATION);
+               if (valid != VALIDATION_FAILED)
+               {
+                       fprintf(out, "%12s:    crl:   status must be GOOD%s\n", name,
+                                       (valid == VALIDATION_SKIPPED) ? " or SKIPPED" : "");
+               }
+
+               rules = auth->create_enumerator(auth);
+               while (rules->enumerate(rules, &rule, &id))
+               {
+                       if (rule == AUTH_RULE_AC_GROUP)
+                       {
+                               fprintf(out, "%12s:    group: %D\n", name, id);
+                       }
+               }
+               rules->destroy(rules);
+       }
+       enumerator->destroy(enumerator);
+}
+
 /**
  * Implementation of stroke_list_t.status.
  */
@@ -313,138 +414,42 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo
                enumerator->destroy(enumerator);
        
                fprintf(out, "Connections:\n");
-               enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends);
-               while (enumerator->enumerate(enumerator, (void**)&peer_cfg))
+               enumerator = charon->backends->create_peer_cfg_enumerator(
+                                                                       charon->backends, NULL, NULL, NULL, NULL);
+               while (enumerator->enumerate(enumerator, &peer_cfg))
                {
-                       void *ptr;
-                       certificate_t *cert;
-                       auth_item_t item;
-                       auth_info_t *auth;
-                       enumerator_t *auth_enumerator;
-                       identification_t *my_ca = NULL, *other_ca = NULL;
-                       identification_t *eap_identity = NULL;
-                       u_int32_t *eap_type = NULL;
-                       bool ac_groups = FALSE;
-
                        if (peer_cfg->get_ike_version(peer_cfg) != 2 ||
                                (name && !streq(name, peer_cfg->get_name(peer_cfg))))
                        {
                                continue;
                        }
                        
-                       /* determine any required CAs, EAP type, EAP identity,
-                        * and the presence of AC groups
-                        */
-                       auth = peer_cfg->get_auth(peer_cfg);
-                       auth_enumerator = auth->create_item_enumerator(auth);
-                       while (auth_enumerator->enumerate(auth_enumerator, &item, &ptr))
-                       {
-                               switch (item)
-                               {
-                                       case AUTHN_EAP_TYPE:
-                                               eap_type = (u_int32_t *)ptr;
-                                               break;
-                                       case AUTHN_EAP_IDENTITY:
-                                               eap_identity = (identification_t *)ptr;
-                                               break;
-                                       case AUTHN_CA_CERT:
-                                               cert = (certificate_t *)ptr;
-                                               my_ca = cert->get_subject(cert);
-                                               break;
-                                       case AUTHN_CA_CERT_NAME:
-                                               my_ca = (identification_t *)ptr;
-                                               break;
-                                       case AUTHZ_CA_CERT:
-                                               cert = (certificate_t *)ptr;
-                                               other_ca = cert->get_subject(cert);
-                                               break;
-                                       case AUTHZ_CA_CERT_NAME:
-                                               other_ca = (identification_t *)ptr;
-                                               break;
-                                       case AUTHZ_AC_GROUP:
-                                               ac_groups = TRUE;
-                                               break;
-                                       default:
-                                               break;
-                               }
-                       }
-                       auth_enumerator->destroy(auth_enumerator);
-
                        ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
-                       fprintf(out, "%12s:  %s[%D]...%s[%D]\n", peer_cfg->get_name(peer_cfg),
-                                       ike_cfg->get_my_addr(ike_cfg), peer_cfg->get_my_id(peer_cfg),
-                                       ike_cfg->get_other_addr(ike_cfg), peer_cfg->get_other_id(peer_cfg));
-                       if (my_ca || other_ca)
-                       {
-                               fprintf(out, "%12s:  CAs: ", peer_cfg->get_name(peer_cfg));
-                               if (my_ca)
-                               {
-                                       fprintf(out, "\"%D\"...", my_ca);
-                               }
-                               else
-                               {
-                                       fprintf(out, "%%any...");
-                               }
-                               if (other_ca)
-                               {
-                                       fprintf(out, "\"%D\"\n", other_ca);
-                               }
-                               else
-                               {
-                                       fprintf(out, "%%any\n");
-                               }
-                       }
-
-                       if (ac_groups)
-                       {
-                               bool first = TRUE;
-
-                               fprintf(out, "%12s:  groups: ",  peer_cfg->get_name(peer_cfg));
-                               auth_enumerator = auth->create_item_enumerator(auth);
-                               while (auth_enumerator->enumerate(auth_enumerator, &item, &ptr))
-                               {
-                                       if (item == AUTHZ_AC_GROUP)
-                                       {
-                                               identification_t *group = (identification_t *)ptr;
-
-                                               fprintf(out, "%s%D", first? "":", ", group);
-                                               first = FALSE;
-                                       }
-                               }
-                               auth_enumerator->destroy(auth_enumerator);
-                               fprintf(out, "\n");
-                       }
-
-                       fprintf(out, "%12s:  %N ",  peer_cfg->get_name(peer_cfg),
-                                       auth_class_names, get_auth_class(peer_cfg));
-                       if (eap_type)
-                       {
-                               fprintf(out, "and %N ", eap_type_names, *eap_type);
-                       }
-                       fprintf(out, "authentication");
-                       if (eap_identity)
-                       {
-                               fprintf(out, ", EAP identity: '%D'", eap_identity);
-                       }
+                       fprintf(out, "%12s:  %s...%s", peer_cfg->get_name(peer_cfg),
+                               ike_cfg->get_my_addr(ike_cfg), ike_cfg->get_other_addr(ike_cfg));
+                       
                        dpd = peer_cfg->get_dpd(peer_cfg);
                        if (dpd)
                        {
                                fprintf(out, ", dpddelay=%us", dpd);
                        }
                        fprintf(out, "\n");
-
+                       
+                       log_auth_cfgs(out, peer_cfg, TRUE);
+                       log_auth_cfgs(out, peer_cfg, FALSE);
+                       
                        children = peer_cfg->create_child_cfg_enumerator(peer_cfg);
                        while (children->enumerate(children, &child_cfg))
                        {
                                linked_list_t *my_ts, *other_ts;
-
+                               
                                my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, NULL);
                                other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, NULL);
-                               fprintf(out, "%12s:    %#R=== %#R", child_cfg->get_name(child_cfg),
+                               fprintf(out, "%12s:   child:  %#R=== %#R", child_cfg->get_name(child_cfg),
                                                my_ts, other_ts);
                                my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
                                other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
-
+                               
                                if (dpd)
                                {
                                        fprintf(out, ", dpdaction=%N", action_names,
index 53edde031e78c47b1b055708d133c9a24bfc7f97..85f1e8f4ea4e52178e1345847d20cf0922773874 100644 (file)
@@ -143,18 +143,28 @@ static void pop_end(stroke_msg_t *msg, const char* label, stroke_end_t *end)
        pop_string(msg, &end->address);
        pop_string(msg, &end->subnets);
        pop_string(msg, &end->sourceip);
+       pop_string(msg, &end->auth);
+       pop_string(msg, &end->auth2);
        pop_string(msg, &end->id);
+       pop_string(msg, &end->id2);
        pop_string(msg, &end->cert);
+       pop_string(msg, &end->cert2);
        pop_string(msg, &end->ca);
+       pop_string(msg, &end->ca2);
        pop_string(msg, &end->groups);
        pop_string(msg, &end->updown);
        
        DBG2(DBG_CFG, "  %s=%s", label, end->address);
        DBG2(DBG_CFG, "  %ssubnet=%s", label, end->subnets);
        DBG2(DBG_CFG, "  %ssourceip=%s", label, end->sourceip);
+       DBG2(DBG_CFG, "  %sauth=%s", label, end->auth);
+       DBG2(DBG_CFG, "  %sauth2=%s", label, end->auth2);
        DBG2(DBG_CFG, "  %sid=%s", label, end->id);
+       DBG2(DBG_CFG, "  %sid2=%s", label, end->id2);
        DBG2(DBG_CFG, "  %scert=%s", label, end->cert);
+       DBG2(DBG_CFG, "  %scert2=%s", label, end->cert2);
        DBG2(DBG_CFG, "  %sca=%s", label, end->ca);
+       DBG2(DBG_CFG, "  %sca2=%s", label, end->ca2);
        DBG2(DBG_CFG, "  %sgroups=%s", label, end->groups);
        DBG2(DBG_CFG, "  %supdown=%s", label, end->updown);
 }
index c9d54a5325a3171b91e5aaa3891869124f7262a2..d185476fd24d170f75deb490c9cf2fbb6c188e07 100644 (file)
@@ -82,24 +82,6 @@ static proposal_t *create_proposal(char *string, protocol_id_t proto)
        return proposal;
 }
 
-/**
- * create an identity, with fallback to %any
- */
-static identification_t *create_id(char *string)
-{
-       identification_t *id = NULL;
-       
-       if (string)
-       {
-               id = identification_create_from_string(string);
-       }
-       if (!id)
-       {
-               id = identification_create_from_encoding(ID_ANY, chunk_empty);
-       }
-       return id;
-}
-
 /**
  * create an traffic selector, fallback to dynamic
  */
@@ -163,8 +145,7 @@ static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg)
        char *remote_id, *remote_addr, *remote_net;
        child_cfg_t *child_cfg;
        ike_cfg_t *ike_cfg;
-       auth_info_t *auth;
-       auth_class_t class;
+       auth_cfg_t *auth;
        
        /* defaults */
        name = "unnamed";
@@ -187,16 +168,26 @@ static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg)
                ike_cfg = ike_cfg_create(FALSE, FALSE, local_addr, remote_addr);
                ike_cfg->add_proposal(ike_cfg, create_proposal(ike_proposal, PROTO_IKE));
                this->peer_cfg = peer_cfg_create(
-                                       name, 2, ike_cfg, create_id(local_id), create_id(remote_id),
-                                       CERT_SEND_IF_ASKED, UNIQUE_NO,
+                                       name, 2, ike_cfg, CERT_SEND_IF_ASKED, UNIQUE_NO,
                                        1, create_rekey(ike_rekey), 0,  /* keytries, rekey, reauth */
                                        1800, 900,                                              /* jitter, overtime */
                                        TRUE, 60,                                               /* mobike, dpddelay */
                                        NULL, NULL,                                     /* vip, pool */
                                        FALSE, NULL, NULL);                     /* mediation, med by, peer id */
-               auth = this->peer_cfg->get_auth(this->peer_cfg);
-               class = AUTH_CLASS_PSK;
-               auth->add_item(auth, AUTHN_AUTH_CLASS, &class);
+               auth = auth_cfg_create();
+               auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
+               auth->add(auth, AUTH_RULE_IDENTITY,
+                                 identification_create_from_string(local_id));
+               this->peer_cfg->add_auth_cfg(this->peer_cfg, auth, TRUE);
+               
+               auth = auth_cfg_create();
+               auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
+               if (remote_id)
+               {
+                       auth->add(auth, AUTH_RULE_IDENTITY,
+                                         identification_create_from_string(remote_id));
+               }
+               this->peer_cfg->add_auth_cfg(this->peer_cfg, auth, FALSE);
                child_cfg = child_cfg_create(name,
                                        create_rekey(esp_rekey) + 300, create_rekey(ike_rekey), 300,
                                        NULL, TRUE,     MODE_TUNNEL, ACTION_NONE, ACTION_NONE, FALSE);
index 2ffdd2b7bcb3aa43b0dedaf954d16cd31021d0ac..7a428afb0e694972e607c2c49c9060578883e300 100644 (file)
@@ -39,15 +39,15 @@ typedef struct private_uci_control_t private_uci_control_t;
  * private data of uci_control_t
  */
 struct private_uci_control_t {
-
+       
        /**
-        * Public part
-        */
+        * Public part
+        */
        uci_control_t public;
-
+       
        /**
-        * Job 
-        */
+        * Job 
+        */
        callback_job_t *job;
 };
 
@@ -86,13 +86,14 @@ static void status(private_uci_control_t *this, char *name)
        char buf[2048];
        FILE *out = NULL;
        
-    configs = charon->backends->create_peer_cfg_enumerator(charon->backends);
-    while (configs->enumerate(configs, &peer_cfg))
-    {
-       if (name && !streq(name, peer_cfg->get_name(peer_cfg)))
-       {
-               continue;
-       }
+       configs = charon->backends->create_peer_cfg_enumerator(charon->backends,
+                                                                                                               NULL, NULL, NULL, NULL);
+       while (configs->enumerate(configs, &peer_cfg))
+       {
+               if (name && !streq(name, peer_cfg->get_name(peer_cfg)))
+               {
+                       continue;
+               }
                sas = charon->controller->create_ike_sa_enumerator(charon->controller);
                while (sas->enumerate(sas, &ike_sa))
                {
@@ -108,9 +109,9 @@ static void status(private_uci_control_t *this, char *name)
                                        continue;
                                }
                        }
-               fprintf(out, "%-8s %-20D %-16H ", ike_sa->get_name(ike_sa),
-                       ike_sa->get_other_id(ike_sa), ike_sa->get_other_host(ike_sa));
-               
+                       fprintf(out, "%-8s %-20D %-16H ", ike_sa->get_name(ike_sa),
+                               ike_sa->get_other_id(ike_sa), ike_sa->get_other_host(ike_sa));
+                       
                        children = ike_sa->create_child_sa_iterator(ike_sa);
                        while (children->iterate(children, (void**)&child_sa))
                        {
@@ -118,7 +119,7 @@ static void status(private_uci_control_t *this, char *name)
                                                child_sa->get_traffic_selectors(child_sa, FALSE));
                        }
                        children->destroy(children);
-               fprintf(out, "\n");
+                       fprintf(out, "\n");
                }
                sas->destroy(sas);
        }
@@ -142,7 +143,7 @@ static void initiate(private_uci_control_t *this, char *name)
        peer_cfg_t *peer_cfg;
        child_cfg_t *child_cfg;
        enumerator_t *enumerator;
-
+       
        peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends, name);
        if (peer_cfg)
        {
@@ -174,7 +175,7 @@ static void terminate(private_uci_control_t *this, char *name)
        enumerator_t *enumerator;
        ike_sa_t *ike_sa;
        u_int id;
-
+       
        enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
        while (enumerator->enumerate(enumerator, &ike_sa))
        {
@@ -240,7 +241,7 @@ static job_requeue_t receive(private_uci_control_t *this)
        char message[128];
        int oldstate, len;
        FILE *in;
-
+       
        memset(message, 0, sizeof(message));
        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
        in = fopen(FIFO_FILE, "r");
@@ -281,9 +282,9 @@ static void destroy(private_uci_control_t *this)
 uci_control_t *uci_control_create()
 {
        private_uci_control_t *this = malloc_thing(private_uci_control_t);
-
+       
        this->public.destroy = (void(*)(uci_control_t*))destroy;
-
+       
        unlink(FIFO_FILE);
        if (mkfifo(FIFO_FILE, S_IRUSR|S_IWUSR) != 0)
        {
index 60f6fc93482f3241e6174afd0b560f3661b44c49..2813850e83204ac4470013df4d30b136e61a6c9c 100644 (file)
@@ -81,10 +81,6 @@ static bool shared_enumerator_enumerate(shared_enumerator_t *this,
                if (me)
                {
                        local = identification_create_from_string(local_id);
-                       if (!local)
-                       {
-                               continue;
-                       }
                        *me = this->me ? this->me->matches(this->me, local)
                                                   : ID_MATCH_ANY;
                        local->destroy(local);
@@ -96,10 +92,6 @@ static bool shared_enumerator_enumerate(shared_enumerator_t *this,
                if (other)
                {
                        remote = identification_create_from_string(remote_id);
-                       if (!remote)
-                       {
-                               continue;
-                       }
                        *other = this->other ? this->other->matches(this->other, remote)
                                                                 : ID_MATCH_ANY;
                        remote->destroy(remote);
index 1719190b1258244cd0d7373dcf367305912eb9ba..37bdd10879a78cc57477ddccb8e797559c99f4c9 100644 (file)
@@ -15,7 +15,7 @@
 
 #include <daemon.h>
 #include <library.h>
-#include <credentials/auth_info.h>
+#include <config/auth_cfg.h>
 
 
 char buf[] = {0x01,0x02,0x03,0x04};
@@ -75,14 +75,14 @@ chunk_t certchunk = chunk_from_buf(certbuf);
 /*******************************************************************************
  * auth info test
  ******************************************************************************/
-bool test_auth_info()
+bool test_auth_cfg()
 {
-       auth_info_t *auth = auth_info_create(), *auth2;
+       auth_cfg_t *auth = auth_cfg_create(), *auth2;
        certificate_t *c1, *c2;
        enumerator_t *enumerator;
        int round = 0;
        void *value;
-       auth_item_t type;
+       auth_rule_t type;
        
        c1 = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
                                                        BUILD_BLOB_ASN1_DER, certchunk,
@@ -92,8 +92,9 @@ bool test_auth_info()
                return FALSE;
        }
        
-       auth->add_item(auth, AUTHN_SUBJECT_CERT, c1);
-       if (!auth->get_item(auth, AUTHN_SUBJECT_CERT, (void**)&c2))
+       auth->add(auth, AUTH_RULE_SUBJECT_CERT, c1->get_ref(c1));
+       c2 = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
+       if (!c2)
        {
                return FALSE;
        }
@@ -102,11 +103,11 @@ bool test_auth_info()
                return FALSE;
        }
        
-       enumerator = auth->create_item_enumerator(auth);
+       enumerator = auth->create_enumerator(auth);
        while (enumerator->enumerate(enumerator, &type, &value))
        {
                round++;
-               if (round == 1 && type == AUTHN_SUBJECT_CERT && value == c1)
+               if (round == 1 && type == AUTH_RULE_SUBJECT_CERT && value == c1)
                {
                        continue;
                }
@@ -114,20 +115,20 @@ bool test_auth_info()
        }
        enumerator->destroy(enumerator);
        
-       auth2 = auth_info_create();
-       auth2->add_item(auth2, AUTHN_CA_CERT, c1);
-       auth2->merge(auth2, auth);
+       auth2 = auth_cfg_create();
+       auth2->add(auth2, AUTH_RULE_CA_CERT, c1->get_ref(c1));
+       auth2->merge(auth2, auth, FALSE);
        
        round = 0;
-       enumerator = auth2->create_item_enumerator(auth2);
+       enumerator = auth2->create_enumerator(auth2);
        while (enumerator->enumerate(enumerator, &type, &value))
        {
                round++;
-               if (round == 1 && type == AUTHN_CA_CERT && value == c1)
+               if (round == 1 && type == AUTH_RULE_CA_CERT && value == c1)
                {
                        continue;
                }
-               if (round == 2 && type == AUTHN_SUBJECT_CERT && value == c1)
+               if (round == 2 && type == AUTH_RULE_SUBJECT_CERT && value == c1)
                {
                        continue;
                }
index d65eb0cc4c7e9188f410ef275d48228d8a1474db..7b4603bd7bb0dd028c74ba59990a1ff1796695ac 100644 (file)
@@ -33,8 +33,8 @@ bool test_med_db()
        chunk_t keyid = chunk_from_buf(keyid_buf);
        identification_t *id, *found;
        enumerator_t *enumerator;
-       auth_info_t *auth;
        public_key_t *public;
+       auth_cfg_t *auth;
        bool good = FALSE;
        
        id = identification_create_from_encoding(ID_KEY_ID, keyid);
index b11f71704cf2f18f7189e8bd795cec4b59326221..3c792ef04f4e97d16c754823f63b3c9835cf9d7d 100644 (file)
 
 static void* testing(void *thread)
 {
-       int i;  
-       auth_info_t *auth;
+       int i;
        host_t *addr[ALLOCS];
        identification_t *id[ALLOCS];
        
-       
-       auth = auth_info_create();
-       
        /* prepare identities */
        for (i = 0; i < ALLOCS; i++)
        {
@@ -40,17 +36,13 @@ static void* testing(void *thread)
                
                snprintf(buf, sizeof(buf), "%d-%d@strongswan.org", (int)thread, i);
                id[i] = identification_create_from_string(buf);
-               if (!id[i])
-               {
-                       return (void*)FALSE;
-               }
        }
        
        /* allocate addresses */
        for (i = 0; i < ALLOCS; i++)
        {
                addr[i] = charon->attributes->acquire_address(charon->attributes, 
-                                                                                                         "test", id[i], auth, NULL);
+                                                                                                         "test", id[i], NULL);
                if (!addr[i])
                {
                        return (void*)FALSE;
@@ -69,7 +61,6 @@ static void* testing(void *thread)
                addr[i]->destroy(addr[i]);
                id[i]->destroy(id[i]);
        }
-       auth->destroy(auth);
        return (void*)TRUE;
 }
 
index db9e76e6368f3ab02431dc0492b35eda88dd5bf0..69eac3b216c973c719f808d562fb97c1c2482075 100644 (file)
@@ -75,6 +75,8 @@ static void initiate(private_initiate_mediation_job_t *this)
 {
        ike_sa_t *mediated_sa, *mediation_sa;
        peer_cfg_t *mediated_cfg, *mediation_cfg;
+       enumerator_t *enumerator;
+       auth_cfg_t *auth_cfg;
        
        mediated_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
                                                                                                   this->mediated_sa_id);
@@ -88,8 +90,20 @@ static void initiate(private_initiate_mediation_job_t *this)
                mediation_cfg = mediated_cfg->get_mediated_by(mediated_cfg);
                mediation_cfg->get_ref(mediation_cfg);
                
+               enumerator = mediation_cfg->create_auth_cfg_enumerator(mediation_cfg,
+                                                                                                                          TRUE);
+               if (!enumerator->enumerate(enumerator, &auth_cfg) ||
+                       auth_cfg->get(auth_cfg, AUTH_RULE_IDENTITY) == NULL)
+               {
+                       mediated_cfg->destroy(mediated_cfg);
+                       mediation_cfg->destroy(mediation_cfg);
+                       enumerator->destroy(enumerator);
+                       destroy(this);
+                       return;
+               }
+               
                if (charon->connect_manager->check_and_register(charon->connect_manager,
-                               mediation_cfg->get_my_id(mediation_cfg),
+                               auth_cfg->get(auth_cfg, AUTH_RULE_IDENTITY),
                                mediated_cfg->get_peer_id(mediated_cfg),
                                this->mediated_sa_id))
                {
index cdd3245fe652f454a39087d25c7ed98c526c36a0..0c33528a06e5570e5102291ffbebbb849c63e71e 100644 (file)
@@ -1,6 +1,6 @@
 /*
+ * Copyright (C) 2006-2009 Martin Willi
  * Copyright (C) 2008 Tobias Brunner
- * Copyright (C) 2006-2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
 #include <sa/authenticators/pubkey_authenticator.h>
 #include <sa/authenticators/psk_authenticator.h>
 #include <sa/authenticators/eap_authenticator.h>
+#include <encoding/payloads/auth_payload.h>
 
 
 ENUM_BEGIN(auth_method_names, AUTH_RSA, AUTH_DSS,
@@ -35,7 +36,8 @@ ENUM_NEXT(auth_method_names, AUTH_ECDSA_256, AUTH_ECDSA_521, AUTH_DSS,
        "ECDSA-521 signature");
 ENUM_END(auth_method_names, AUTH_ECDSA_521);
 
-ENUM(auth_class_names, AUTH_CLASS_PUBKEY, AUTH_CLASS_EAP,
+ENUM(auth_class_names, AUTH_CLASS_ANY, AUTH_CLASS_EAP,
+       "any",
        "public key",
        "pre-shared key",
        "EAP",
@@ -44,17 +46,23 @@ ENUM(auth_class_names, AUTH_CLASS_PUBKEY, AUTH_CLASS_EAP,
 /**
  * Described in header.
  */
-authenticator_t *authenticator_create_from_class(ike_sa_t *ike_sa,
-                                                                                                auth_class_t class)
+authenticator_t *authenticator_create_builder(
+                                                                       ike_sa_t *ike_sa, auth_cfg_t *cfg,
+                                                                       chunk_t received_nonce, chunk_t sent_init)
 {
-       switch (class)
+       switch ((uintptr_t)cfg->get(cfg, AUTH_RULE_AUTH_CLASS))
        {
+               case AUTH_CLASS_ANY:
+                       /* defaults to PUBKEY */
                case AUTH_CLASS_PUBKEY:
-                       return (authenticator_t*)pubkey_authenticator_create(ike_sa);
+                       return (authenticator_t*)pubkey_authenticator_create_builder(ike_sa,
+                                                                                       received_nonce, sent_init);
                case AUTH_CLASS_PSK:
-                       return (authenticator_t*)psk_authenticator_create(ike_sa);
+                       return (authenticator_t*)psk_authenticator_create_builder(ike_sa,
+                                                                                       received_nonce, sent_init);
                case AUTH_CLASS_EAP:
-                       return (authenticator_t*)eap_authenticator_create(ike_sa);
+                       return (authenticator_t*)eap_authenticator_create_builder(ike_sa,
+                                                                                       received_nonce, sent_init);
                default:
                        return NULL;
        }
@@ -63,19 +71,31 @@ authenticator_t *authenticator_create_from_class(ike_sa_t *ike_sa,
 /**
  * Described in header.
  */
-authenticator_t *authenticator_create_from_method(ike_sa_t *ike_sa,
-                                                                                                 auth_method_t method)
+authenticator_t *authenticator_create_verifier(
+                                                                       ike_sa_t *ike_sa, message_t *message,
+                                                                       chunk_t sent_nonce, chunk_t received_init)
 {
-       switch (method)
+       auth_payload_t *auth_payload;
+       
+       auth_payload = (auth_payload_t*)message->get_payload(message, AUTHENTICATION);
+       if (auth_payload == NULL)
+       {
+               return (authenticator_t*)eap_authenticator_create_verifier(ike_sa,
+                                                                                                       sent_nonce, received_init);
+       }
+       switch (auth_payload->get_auth_method(auth_payload))
        {
                case AUTH_RSA:
                case AUTH_ECDSA_256:
                case AUTH_ECDSA_384:
                case AUTH_ECDSA_521:
-                       return (authenticator_t*)pubkey_authenticator_create(ike_sa);
+                       return (authenticator_t*)pubkey_authenticator_create_verifier(ike_sa,
+                                                                                                       sent_nonce, received_init);
                case AUTH_PSK:
-                       return (authenticator_t*)psk_authenticator_create(ike_sa);
+                       return (authenticator_t*)psk_authenticator_create_verifier(ike_sa,
+                                                                                                       sent_nonce, received_init);
                default:
                        return NULL;
        }
 }
+
index cd42191e6b16e73963b614fd535748db40e2ecc1..db3f110ca173172494f11efc030ec2d2cb21754e 100644 (file)
@@ -1,6 +1,6 @@
 /*
+ * Copyright (C) 2005-2009 Martin Willi
  * Copyright (C) 2008 Tobias Brunner
- * Copyright (C) 2005-2008 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
@@ -30,9 +30,8 @@ typedef enum auth_class_t auth_class_t;
 typedef struct authenticator_t authenticator_t;
 
 #include <library.h>
+#include <config/auth_cfg.h>
 #include <sa/ike_sa.h>
-#include <config/peer_cfg.h>
-#include <encoding/payloads/auth_payload.h>
 
 /**
  * Method to use for authentication, as defined in IKEv2.
@@ -84,6 +83,8 @@ extern enum_name_t *auth_method_names;
  * certificate finally dictates wich method is used.
  */
 enum auth_class_t {
+       /** any class acceptable */
+       AUTH_CLASS_ANY = 0,
        /** authentication using public keys (RSA, ECDSA) */
        AUTH_CLASS_PUBKEY = 1,
        /** authentication using a pre-shared secrets */
@@ -100,66 +101,64 @@ extern enum_name_t *auth_class_names;
 /**
  * Authenticator interface implemented by the various authenticators.
  *
- * Currently the following two AUTH methods are supported:
- *  - shared key message integrity code
- *  - RSA digital signature
- *  - EAP using the EAP framework and one of the EAP plugins
- *  - ECDSA is supported using OpenSSL
+ * An authenticator implementation handles AUTH and EAP payloads. Received
+ * messages are passed to the process() method, to send authentication data
+ * the message is passed to the build() method.
  */
 struct authenticator_t {
 
        /**
-        * Verify a received authentication payload.
+        * Process an incoming message using the authenticator.
         *
-        * @param ike_sa_init   binary representation of received ike_sa_init
-        * @param my_nonce              the sent nonce
-        * @param auth_payload  authentication payload to verify
+        * @param message               message containing authentication payloads
         * @return
-        *                                              - SUCCESS,
-        *                                              - FAILED if verification failed
-        *                                              - INVALID_ARG if auth_method does not match
-        *                                              - NOT_FOUND if credentials not found
+        *                                              - SUCCESS if authentication successful
+        *                                              - FAILED if authentication failed
+        *                                              - NEED_MORE if another exchange required
         */
-       status_t (*verify) (authenticator_t *this, chunk_t ike_sa_init,
-                                               chunk_t my_nonce, auth_payload_t *auth_payload);
-
+       status_t (*process)(authenticator_t *this, message_t *message);
+       
        /**
-        * Build an authentication payload to send to the other peer.
+        * Attach authentication data to an outgoing message.
         *
-        * @param ike_sa_init   binary representation of sent ike_sa_init
-        * @param other_nonce   the received nonce
-        * @param auth_payload  the resulting authentication payload
+        * @param message               message to add authentication data to
         * @return
-        *                                              - SUCCESS,
-        *                                              - NOT_FOUND if credentials not found
+        *                                              - SUCCESS if authentication successful
+        *                                              - FAILED if authentication failed
+        *                                              - NEED_MORE if another exchange required
         */
-       status_t (*build) (authenticator_t *this, chunk_t ike_sa_init,
-                                          chunk_t other_nonce, auth_payload_t **auth_payload);
-
+       status_t (*build)(authenticator_t *this, message_t *message);
+       
        /**
-        * Destroys a authenticator_t object.
+        * Destroy authenticator instance.
         */
        void (*destroy) (authenticator_t *this);
 };
 
 /**
- * Creates an authenticator for the specified auth class (as configured).
+ * Create an authenticator to build signatures.
  *
- * @param ike_sa               associated ike_sa
- * @param class                        class of authentication to use
- * @return                             authenticator_t object
+ * @param ike_sa                       associated ike_sa
+ * @param cfg                          authentication configuration
+ * @param received_nonce       nonce received in IKE_SA_INIT
+ * @param sent_init                    sent IKE_SA_INIT message data
+ * @return                                     authenticator, NULL if not supported
  */
-authenticator_t *authenticator_create_from_class(ike_sa_t *ike_sa,
-                                                                                                auth_class_t class);
+authenticator_t *authenticator_create_builder(
+                                                                       ike_sa_t *ike_sa, auth_cfg_t *cfg,
+                                                                       chunk_t received_nonce, chunk_t sent_init);
 
 /**
- * Creates an authenticator for method (as received in payload).
+ * Create an authenticator to verify signatures.
  * 
- * @param ike_sa               associated ike_sa
- * @param method               method as found in payload
- * @return                             authenticator_t object
+ * @param ike_sa                       associated ike_sa
+ * @param message                      message containing authentication data
+ * @param sent_nonce           nonce sent in IKE_SA_INIT
+ * @param received_init                received IKE_SA_INIT message data
+ * @return                                     authenticator, NULL if not supported
  */
-authenticator_t *authenticator_create_from_method(ike_sa_t *ike_sa,    
-                                                                                                 auth_method_t method);
+authenticator_t *authenticator_create_verifier(
+                                                                       ike_sa_t *ike_sa, message_t *message,
+                                                                       chunk_t sent_nonce, chunk_t received_init);
 
 #endif /** AUTHENTICATOR_H_ @}*/
index 578d302ea9d7be9a2f96a2c2f01c89ae5937b484..ecb46c29364289684d845d8303d460567b7cba36 100644 (file)
@@ -65,9 +65,9 @@ struct private_eap_manager_t {
        linked_list_t *methods;
        
        /**
-        * mutex to lock methods
+        * rwlock to lock methods
         */
-       mutex_t *mutex;
+       rwlock_t *lock;
 };
 
 /**
@@ -84,9 +84,9 @@ static void add_method(private_eap_manager_t *this, eap_type_t type,
        entry->role = role;
        entry->constructor = constructor;
 
-       this->mutex->lock(this->mutex);
+       this->lock->write_lock(this->lock);
        this->methods->insert_last(this->methods, entry);
-       this->mutex->unlock(this->mutex);
+       this->lock->unlock(this->lock);
 }
 
 /**
@@ -97,7 +97,7 @@ static void remove_method(private_eap_manager_t *this, eap_constructor_t constru
        enumerator_t *enumerator;
        eap_entry_t *entry;
        
-       this->mutex->lock(this->mutex);
+       this->lock->write_lock(this->lock);
        enumerator = this->methods->create_enumerator(this->methods);
        while (enumerator->enumerate(enumerator, &entry))
        {
@@ -108,7 +108,7 @@ static void remove_method(private_eap_manager_t *this, eap_constructor_t constru
                }
        }
        enumerator->destroy(enumerator);
-       this->mutex->unlock(this->mutex);
+       this->lock->unlock(this->lock);
 }
 
 /**
@@ -123,7 +123,7 @@ static eap_method_t* create_instance(private_eap_manager_t *this,
        eap_entry_t *entry;
        eap_method_t *method = NULL;
        
-       this->mutex->lock(this->mutex);
+       this->lock->read_lock(this->lock);
        enumerator = this->methods->create_enumerator(this->methods);
        while (enumerator->enumerate(enumerator, &entry))
        {
@@ -138,7 +138,7 @@ static eap_method_t* create_instance(private_eap_manager_t *this,
                }
        }
        enumerator->destroy(enumerator);
-       this->mutex->unlock(this->mutex);
+       this->lock->unlock(this->lock);
        return method;
 }
 
@@ -148,7 +148,7 @@ static eap_method_t* create_instance(private_eap_manager_t *this,
 static void destroy(private_eap_manager_t *this)
 {
        this->methods->destroy_function(this->methods, free);
-       this->mutex->destroy(this->mutex);
+       this->lock->destroy(this->lock);
        free(this);
 }
 
@@ -165,7 +165,7 @@ eap_manager_t *eap_manager_create()
        this->public.destroy = (void(*)(eap_manager_t*))destroy;
        
        this->methods = linked_list_create();
-       this->mutex = mutex_create(MUTEX_DEFAULT);
+       this->lock = rwlock_create(RWLOCK_DEFAULT);
        
        return &this->public;
 }
index d27a8ac2f4bdb7b08f2f63d13ff292404cda6a10..9aef352e24fd81e1406d7f56337b83538638fa6a 100644 (file)
@@ -36,6 +36,36 @@ ENUM_NEXT(eap_type_names, EAP_RADIUS, EAP_EXPERIMENTAL, EAP_MSCHAPV2,
        "EAP_EXPERIMENTAL");
 ENUM_END(eap_type_names, EAP_EXPERIMENTAL);
 
+/*
+ * See header
+ */
+eap_type_t eap_type_from_string(char *name)
+{
+       int i;
+       static struct {
+               char *name;
+               eap_type_t type;
+       } types[] = {
+               {"identity",    EAP_IDENTITY},
+               {"md5",                 EAP_MD5},
+               {"otp",                 EAP_OTP},
+               {"gtc",                 EAP_GTC},
+               {"sim",                 EAP_SIM},
+               {"aka",                 EAP_AKA},
+               {"mschapv2",    EAP_MSCHAPV2},
+               {"radius",              EAP_RADIUS},
+       };
+       
+       for (i = 0; i < countof(types); i++)
+       {
+               if (strcasecmp(name, types[i].name) == 0)
+               {
+                       return types[i].type;
+               }
+       }
+       return 0;
+}
+
 ENUM(eap_code_names, EAP_REQUEST, EAP_FAILURE,
        "EAP_REQUEST",
        "EAP_RESPONSE",
@@ -48,3 +78,6 @@ ENUM(eap_role_names, EAP_SERVER, EAP_PEER,
        "EAP_PEER",
 );
 
+
+
+
index 1aa6162ee5475cb2be351ce63e6e68a572eb8b91..43a336adaaf7c147782e4c39a891f81d2917a2b6 100644 (file)
@@ -68,6 +68,14 @@ enum eap_type_t {
  */
 extern enum_name_t *eap_type_names;
 
+/**
+ * Lookup the EAP method type from a string.
+ *
+ * @param name         EAP method name (such as "md5", "aka")
+ * @return                     method type, 0 if unkown
+ */
+eap_type_t eap_type_from_string(char *name);
+
 /**
  * EAP code, type of an EAP message
  */
@@ -83,7 +91,6 @@ enum eap_code_t {
  */
 extern enum_name_t *eap_code_names;
 
-
 /**
  * Interface of an EAP method for server and client side.
  *
index 69a2e4df979249261eb7b73dee0997d6a155ebd9..3c6d66dfefbb27cd97e290100b305495ed74fdc0 100644 (file)
@@ -39,7 +39,7 @@ struct sim_card_t {
         * The returned identity owned by the sim_card and not destroyed outside.
         * The SIM card may return ID_ANY if it does not support/use an IMSI.
         *
-        * @return              identity of type ID_EAP/ID_ANY
+        * @return              identity
         */
        identification_t* (*get_imsi)(sim_card_t *this);
        
@@ -63,7 +63,7 @@ struct sim_provider_t {
        /**
         * Get a single triplet to authenticate a EAP client.
         *
-        * @param imsi  client identity of type ID_EAP
+        * @param imsi  client identity
         * @param rand  RAND output buffer, fixed size 16 bytes
         * @param sres  SRES output buffer, fixed size 4 byte
         * @param kc    KC output buffer, fixed size 8 bytes
index 9d7113fd27a3697e7e7859a15402a39d43d75347..876cb7b74070c52553306b23a3fc02287332a439 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2008 Martin Willi
+ * Copyright (C) 2006-2009 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * $Id$
  */
 
-#include <string.h>
-
 #include "eap_authenticator.h"
 
 #include <daemon.h>
-#include <config/peer_cfg.h>
 #include <sa/authenticators/eap/eap_method.h>
+#include <encoding/payloads/auth_payload.h>
+#include <encoding/payloads/eap_payload.h>
 
 typedef struct private_eap_authenticator_t private_eap_authenticator_t;
 
@@ -41,9 +40,14 @@ struct private_eap_authenticator_t {
        ike_sa_t *ike_sa;
        
        /**
-        * Role of this authenticator, PEER or SERVER
+        * nonce to include in AUTH calculation
         */
-       eap_role_t role;
+       chunk_t nonce;
+       
+       /**
+        * IKE_SA_INIT message data to include in AUTH calculation
+        */
+       chunk_t ike_sa_init;
        
        /**
         * Current EAP method processing
@@ -56,442 +60,509 @@ struct private_eap_authenticator_t {
        chunk_t msk;
        
        /**
-        * should we do a EAP-Identity exchange as server?
+        * EAP authentication method completed successfully
         */
-       bool do_eap_identity;
+       bool eap_complete;
        
        /**
-        * saved EAP type if we do eap_identity
+        * authentication payload verified successfully
         */
-       eap_type_t type;
+       bool auth_complete;
        
        /**
-        * saved vendor id if we do eap_identity
+        * generated EAP payload
         */
-       u_int32_t vendor;
+       eap_payload_t *eap_payload;
+       
+       /**
+        * EAP identity of peer
+        */
+       identification_t *eap_identity;
 };
+
 /**
- * Implementation of authenticator_t.verify.
+ * load an EAP method
  */
-static status_t verify(private_eap_authenticator_t *this, chunk_t ike_sa_init,
-                                          chunk_t my_nonce, auth_payload_t *auth_payload)
+static eap_method_t *load_method(private_eap_authenticator_t *this,
+                                                       eap_type_t type, u_int32_t vendor, eap_role_t role)
 {
-       chunk_t auth_data, recv_auth_data;
-       identification_t *other_id;
-       keymat_t *keymat;
-       
-       other_id = this->ike_sa->get_other_id(this->ike_sa);
-       keymat = this->ike_sa->get_keymat(this->ike_sa);
-       
-       auth_data = keymat->get_psk_sig(keymat, TRUE, ike_sa_init, my_nonce,
-                                                                       this->msk, other_id);
+       identification_t *server, *peer;
        
-       recv_auth_data = auth_payload->get_data(auth_payload);
-       if (!auth_data.len || !chunk_equals(auth_data, recv_auth_data))
+       if (role == EAP_SERVER)
        {
-               DBG1(DBG_IKE, "verification of AUTH payload created from EAP MSK failed");
-               chunk_free(&auth_data);
-               return FAILED;
+               server = this->ike_sa->get_my_id(this->ike_sa);
+               peer = this->ike_sa->get_other_id(this->ike_sa);
        }
-       chunk_free(&auth_data);
-       
-       DBG1(DBG_IKE, "authentication of '%D' with %N successful",
-                other_id, auth_class_names, AUTH_CLASS_EAP);
-       return SUCCESS;
-}
-
-/**
- * Implementation of authenticator_t.build.
- */
-static status_t build(private_eap_authenticator_t *this, chunk_t ike_sa_init,
-                                         chunk_t other_nonce, auth_payload_t **auth_payload)
-{
-       identification_t *my_id;
-       chunk_t auth_data;
-       keymat_t *keymat;
-       
-       my_id = this->ike_sa->get_my_id(this->ike_sa);
-       keymat = this->ike_sa->get_keymat(this->ike_sa);
-       
-       DBG1(DBG_IKE, "authentication of '%D' (myself) with %N",
-                my_id, auth_class_names, AUTH_CLASS_EAP);
-       
-       auth_data = keymat->get_psk_sig(keymat, FALSE, ike_sa_init, other_nonce,
-                                                                       this->msk, my_id);
-       
-       *auth_payload = auth_payload_create();
-       (*auth_payload)->set_auth_method(*auth_payload, AUTH_PSK);
-       (*auth_payload)->set_data(*auth_payload, auth_data);
-       chunk_free(&auth_data);
-       
-       return SUCCESS;
+       else
+       {
+               server = this->ike_sa->get_other_id(this->ike_sa);
+               peer = this->ike_sa->get_my_id(this->ike_sa);
+       }
+       if (this->eap_identity)
+       {
+               peer = this->eap_identity;
+       }
+       return charon->eap->create_instance(charon->eap, type, vendor,
+                                                                               role, server, peer);
 }
 
 /**
- * get the peers identity to use in the EAP method
+ * Initiate EAP conversation as server
  */
-static identification_t *get_peer_id(private_eap_authenticator_t *this)
+static eap_payload_t* server_initiate_eap(private_eap_authenticator_t *this,
+                                                                                 bool do_identity)
 {
+       auth_cfg_t *auth;
+       eap_type_t type;
        identification_t *id;
-       peer_cfg_t *config;
-       auth_info_t *auth;
+       u_int32_t vendor;
+       eap_payload_t *out;
        
-       id = this->ike_sa->get_eap_identity(this->ike_sa);
-       if (!id)
+       auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
+       
+       /* initiate EAP-Identity exchange if required */
+       if (!this->eap_identity && do_identity)
        {
-               config = this->ike_sa->get_peer_cfg(this->ike_sa);
-               auth = config->get_auth(config);
-               if (!auth->get_item(auth, AUTHN_EAP_IDENTITY, (void**)&id) ||
-                       id->get_type(id) == ID_ANY)
+               id = auth->get(auth, AUTH_RULE_EAP_IDENTITY);
+               if (id)
                {
-                       if (this->role == EAP_PEER)
-                       {
-                               id = this->ike_sa->get_my_id(this->ike_sa);
-                       }
-                       else
+                       this->method = load_method(this, EAP_IDENTITY, 0, EAP_SERVER);
+                       if (this->method)
                        {
-                               id = this->ike_sa->get_other_id(this->ike_sa);
+                               if (this->method->initiate(this->method, &out) == NEED_MORE)
+                               {
+                                       DBG1(DBG_IKE, "initiating EAP-Identity request");
+                                       return out;
+                               }
+                               this->method->destroy(this->method);
                        }
+                       DBG1(DBG_IKE, "EAP-Identity request configured, but not supported");
                }
        }
-       if (id->get_type(id) == ID_EAP)
+       /* invoke real EAP method */
+       type = (uintptr_t)auth->get(auth, AUTH_RULE_EAP_TYPE);
+       vendor = (uintptr_t)auth->get(auth, AUTH_RULE_EAP_VENDOR);
+       this->method = load_method(this, type, vendor, EAP_SERVER);
+       if (this->method &&
+               this->method->initiate(this->method, &out) == NEED_MORE)
        {
-               return id->clone(id);
+               if (vendor)
+               {
+                       DBG1(DBG_IKE, "initiating EAP vendor type %d-%d", type, vendor);
+                       
+               }
+               else
+               {
+                       DBG1(DBG_IKE, "initiating %N", eap_type_names, type);
+               }
+               return out;
        }
-       return identification_create_from_encoding(ID_EAP, id->get_encoding(id));
-}
-
-/**
- * get the servers identity to use in the EAP method
- */
-static identification_t *get_server_id(private_eap_authenticator_t *this)
-{
-       identification_t *id;
-       
-       if (this->role == EAP_SERVER)
+       if (vendor)
        {
-               id = this->ike_sa->get_my_id(this->ike_sa);
+               DBG1(DBG_IKE, "initiating EAP vendor type %d-%d failed", type, vendor);
        }
        else
        {
-               id = this->ike_sa->get_other_id(this->ike_sa);
-       }
-       if (id->get_type(id) == ID_EAP)
-       {
-               return id->clone(id);
+               DBG1(DBG_IKE, "initiating %N failed", eap_type_names, type);
        }
-       return identification_create_from_encoding(ID_EAP, id->get_encoding(id));
+       return eap_payload_create_code(EAP_FAILURE, 0);
 }
 
 /**
- * load an EAP method using the correct identities
+ * Handle EAP exchange as server
  */
-static eap_method_t *load_method(private_eap_authenticator_t *this,
-                                                       eap_type_t type, u_int32_t vendor, eap_role_t role)
+static eap_payload_t* server_process_eap(private_eap_authenticator_t *this,
+                                                                                eap_payload_t *in)
 {
-       identification_t *server, *peer;
-       eap_method_t *method;
+       eap_type_t type, received_type;
+       u_int32_t vendor, received_vendor;
+       eap_payload_t *out;
+       auth_cfg_t *cfg;
        
-       server = get_server_id(this);
-       peer = get_peer_id(this);
-       method = charon->eap->create_instance(charon->eap, type, vendor, role,
-                                                                                 server, peer);                 
-       server->destroy(server);
-       peer->destroy(peer);
-       return method;
-}
-
-/**
- * Implementation of eap_authenticator_t.initiate
- */
-static status_t initiate(private_eap_authenticator_t *this, eap_type_t type,
-                                                u_int32_t vendor, eap_payload_t **out)
-{
-       /* if initiate() is called, role is always server */
-       this->role = EAP_SERVER;
-       
-       if (this->do_eap_identity)
-       {       /* do an EAP-Identity request first */
-               this->type = type;
-               this->vendor = vendor;
-               vendor = 0;
-               type = EAP_IDENTITY;
-       }
-       
-       if (type == 0)
+       if (in->get_code(in) != EAP_RESPONSE)
        {
-               DBG1(DBG_IKE,
-                        "client requested EAP authentication, but configuration forbids it");
-               *out = eap_payload_create_code(EAP_FAILURE, 0);
-               return FAILED;
+               DBG1(DBG_IKE, "received %N, sending %N",
+                        eap_code_names, in->get_code(in), eap_code_names, EAP_FAILURE);
+               return eap_payload_create_code(EAP_FAILURE, in->get_identifier(in));
        }
        
-       if (vendor)
-       {
-               DBG1(DBG_IKE, "requesting vendor specific EAP method %d-%d",
-                        type, vendor);
-       }
-       else
-       {
-               DBG1(DBG_IKE, "requesting EAP method %N", eap_type_names, type);
-       }
-       this->method = load_method(this, type, vendor, this->role);
-       if (this->method == NULL)
+       type = this->method->get_type(this->method, &vendor);
+       received_type = in->get_type(in, &received_vendor);
+       if (type != received_type || vendor != received_vendor)
        {
-               if (vendor == 0 && type == EAP_IDENTITY)
+               if (received_vendor == 0 && received_type == EAP_NAK)
                {
-                       DBG1(DBG_IKE, "skipping %N, no implementation found",
-                                eap_type_names, type);
-                       this->do_eap_identity = FALSE;
-                       return initiate(this, this->type, this->vendor, out);
+                       DBG1(DBG_IKE, "received %N, sending %N",
+                                eap_type_names, EAP_NAK, 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, 0);
-               return FAILED;
+               else
+               {
+                       DBG1(DBG_IKE, "received invalid EAP response, sending %N",
+                                eap_code_names, EAP_FAILURE);
+               }
+               return eap_payload_create_code(EAP_FAILURE, in->get_identifier(in));
        }
-       if (this->method->initiate(this->method, out) != NEED_MORE)
+       
+       switch (this->method->process(this->method, in, &out))
        {
-               DBG1(DBG_IKE, "failed to initiate EAP exchange, sending %N",
-                        eap_code_names, EAP_FAILURE);
-               *out = eap_payload_create_code(EAP_FAILURE, 0);
-               return FAILED;  
+               case NEED_MORE:
+                       return out;
+               case SUCCESS:
+                       if (type == EAP_IDENTITY)
+                       {
+                               chunk_t data;
+                               char buf[256];
+                               
+                               if (this->method->get_msk(this->method, &data) == SUCCESS)
+                               {
+                                       snprintf(buf, sizeof(buf), "%.*s", data.len, data.ptr);
+                                       this->eap_identity = identification_create_from_string(buf);
+                                       DBG1(DBG_IKE, "received EAP identity '%D'",
+                                                this->eap_identity);
+                               }
+                               /* restart EAP exchange, but with real method */
+                               this->method->destroy(this->method);
+                               return server_initiate_eap(this, FALSE);
+                       }
+                       if (this->method->get_msk(this->method, &this->msk) == SUCCESS)
+                       {
+                               this->msk = chunk_clone(this->msk);
+                       }
+                       if (vendor)
+                       {
+                               DBG1(DBG_IKE, "EAP vendor specific method %d-%d succeeded, "
+                                        "%sMSK established", type, vendor,
+                                        this->msk.ptr ? "" : "no ");
+                       }
+                       else
+                       {
+                               DBG1(DBG_IKE, "EAP method %N succeeded, %sMSK established",
+                                        eap_type_names, type, this->msk.ptr ? "" : "no ");
+                       }
+                       this->ike_sa->set_condition(this->ike_sa, COND_EAP_AUTHENTICATED,
+                                                                               TRUE);
+                       cfg = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
+                       cfg->add(cfg, AUTH_RULE_EAP_TYPE, type);
+                       if (vendor)
+                       {
+                               cfg->add(cfg, AUTH_RULE_EAP_VENDOR, vendor);
+                       }
+                       this->eap_complete = TRUE;
+                       return eap_payload_create_code(EAP_SUCCESS, in->get_identifier(in));
+               case FAILED:
+               default:
+                       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));
+                       }
+                       return eap_payload_create_code(EAP_FAILURE, in->get_identifier(in));
        }
-       return NEED_MORE;
 }
 
 /**
  * Processing method for a peer
  */
-static status_t process_peer(private_eap_authenticator_t *this,
-                                                        eap_payload_t *in, eap_payload_t **out)
+static eap_payload_t* client_process_eap(private_eap_authenticator_t *this,
+                                                                                eap_payload_t *in)
 {
        eap_type_t type;
        u_int32_t vendor;
+       auth_cfg_t *auth;
+       eap_payload_t *out;
+       identification_t *id;
        
        type = in->get_type(in, &vendor);
        
        if (!vendor && type == EAP_IDENTITY)
        {
-               eap_method_t *method;
+               DESTROY_IF(this->eap_identity);
+               auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
+               id = auth->get(auth, AUTH_RULE_EAP_IDENTITY);
+               if (!id || id->get_type(id) == ID_ANY)
+               {
+                       id = this->ike_sa->get_my_id(this->ike_sa);
+               }
+               DBG1(DBG_IKE, "server requested %N, sending '%D'",
+                        eap_type_names, type, id);
+               this->eap_identity = id->clone(id);
                
-               method = load_method(this, type, 0, EAP_PEER);
-               if (method == NULL || method->process(method, in, out) != SUCCESS)
+               this->method = load_method(this, type, vendor, EAP_PEER);
+               if (this->method)
                {
-                       DBG1(DBG_IKE, "EAP server requested %N, but unable to process",
-                                eap_type_names, type);
-                       DESTROY_IF(method);
-                       return FAILED;
+                       if (this->method->process(this->method, in, &out) == SUCCESS)
+                       {
+                               this->method->destroy(this->method);
+                               this->method = NULL;
+                               return out;
+                       }
+                       this->method->destroy(this->method);
+                       this->method = NULL;
                }
-               DBG1(DBG_IKE, "EAP server requested %N", eap_type_names, type);  
-               method->destroy(method);
-               return NEED_MORE;
+               DBG1(DBG_IKE, "%N not supported, sending EAP_NAK",
+                        eap_type_names, type);
+               return eap_payload_create_nak(in->get_identifier(in));
        }
-       
-       /* create an eap_method for the first call */
        if (this->method == NULL)
        {
                if (vendor)
                {
-                       DBG1(DBG_IKE, "EAP server requested vendor specific EAP method %d-%d",
+                       DBG1(DBG_IKE, "server requested vendor specific EAP method %d-%d",
                                 type, vendor);
                }
                else
                {
-                       DBG1(DBG_IKE, "EAP server requested %N authentication",
+                       DBG1(DBG_IKE, "server requested %N authentication",
                                 eap_type_names, type);
                }
                this->method = load_method(this, type, vendor, EAP_PEER);
-               if (this->method == NULL)
+               if (!this->method)
                {
-                       DBG1(DBG_IKE, "EAP server requested unsupported "
-                                "EAP method, sending EAP_NAK");
-                       *out = eap_payload_create_nak(in->get_identifier(in));
-                       return NEED_MORE;
+                       DBG1(DBG_IKE, "EAP method not supported, sending EAP_NAK");
+                       return eap_payload_create_nak(in->get_identifier(in));
                }
        }
        
        type = this->method->get_type(this->method, &vendor);
        
-       switch (this->method->process(this->method, in, out))
+       if (this->method->process(this->method, in, &out) == NEED_MORE)
+       {       /* client methods should never return SUCCESS */
+               return out;
+       }
+       
+       if (vendor)
        {
-               case NEED_MORE:
-                       return NEED_MORE;
-               case SUCCESS:
-                       if (vendor)
-                       {
-                               DBG1(DBG_IKE, "EAP vendor specific method %d-%d succeded",
-                                        type, vendor);
-                       }
-                       else
-                       {
-                               DBG1(DBG_IKE, "EAP method %N succeeded", eap_type_names, type);
-                       }
-                       return SUCCESS;
-               case FAILED:
-               default:
-                       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;
+               DBG1(DBG_IKE, "vendor specific EAP method %d-%d failed", type, vendor);
+       }
+       else
+       {
+               DBG1(DBG_IKE, "%N method failed", eap_type_names, type);
        }
+       return NULL;
 }
 
 /**
- * handle an EAP-Identity response on the server
+ * Verify AUTH payload
  */
-static status_t process_eap_identity(private_eap_authenticator_t *this,
-                                                                        eap_payload_t **out)
+static bool verify_auth(private_eap_authenticator_t *this, message_t *message)
 {
-       chunk_t data;
-       identification_t *id;
-
-       if (this->method->get_msk(this->method, &data) == SUCCESS)
+       auth_payload_t *auth_payload;
+       chunk_t auth_data, recv_auth_data;
+       identification_t *other_id;
+       auth_cfg_t *auth;
+       keymat_t *keymat;
+       
+       auth_payload = (auth_payload_t*)message->get_payload(message,
+                                                                                                                AUTHENTICATION);
+       if (!auth_payload)
        {
-               id = identification_create_from_encoding(ID_EAP, data);
-               DBG1(DBG_IKE, "using EAP identity '%D'", id);
-               this->ike_sa->set_eap_identity(this->ike_sa, id);
+               DBG1(DBG_IKE, "AUTH payload missing");
+               return FALSE;
        }
-       /* restart EAP exchange, but with real method */
-       this->method->destroy(this->method);
-       this->method = NULL;
-       this->do_eap_identity = FALSE;
-       return initiate(this, this->type, this->vendor, out);
+       other_id = this->ike_sa->get_other_id(this->ike_sa);
+       keymat = this->ike_sa->get_keymat(this->ike_sa);
+       auth_data = keymat->get_psk_sig(keymat, TRUE, this->ike_sa_init,
+                                                                       this->nonce, this->msk, other_id);
+       recv_auth_data = auth_payload->get_data(auth_payload);
+       if (!auth_data.len || !chunk_equals(auth_data, recv_auth_data))
+       {
+               DBG1(DBG_IKE, "verification of AUTH payload with%s EAP MSK failed",
+                        this->msk.ptr ? "" : "out");
+               chunk_free(&auth_data);
+               return FALSE;
+       }
+       chunk_free(&auth_data);
+       
+       DBG1(DBG_IKE, "authentication of '%D' with %N successful",
+                other_id, auth_class_names, AUTH_CLASS_EAP);
+       this->auth_complete = TRUE;
+       auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
+       auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_EAP);
+       return TRUE;
+}
+
+/**
+ * Build AUTH payload
+ */
+static void build_auth(private_eap_authenticator_t *this, message_t *message)
+{
+       auth_payload_t *auth_payload;
+       identification_t *my_id;
+       chunk_t auth_data;
+       keymat_t *keymat;
+       
+       my_id = this->ike_sa->get_my_id(this->ike_sa);
+       keymat = this->ike_sa->get_keymat(this->ike_sa);
+       
+       DBG1(DBG_IKE, "authentication of '%D' (myself) with %N",
+                my_id, auth_class_names, AUTH_CLASS_EAP);
+       
+       auth_data = keymat->get_psk_sig(keymat, FALSE, this->ike_sa_init,
+                                                                       this->nonce, this->msk, my_id);
+       auth_payload = auth_payload_create();
+       auth_payload->set_auth_method(auth_payload, AUTH_PSK);
+       auth_payload->set_data(auth_payload, auth_data);
+       message->add_payload(message, (payload_t*)auth_payload);
+       chunk_free(&auth_data);
 }
 
 /**
- * Processing method for a server
+ * Implementation of authenticator_t.process for a server
  */
 static status_t process_server(private_eap_authenticator_t *this,
-                                                          eap_payload_t *in, eap_payload_t **out)
+                                                          message_t *message)
 {
-       eap_type_t type;
-       u_int32_t vendor;
+       eap_payload_t *eap_payload;
        
-       type = this->method->get_type(this->method, &vendor);
+       if (this->eap_complete)
+       {
+               if (!verify_auth(this, message))
+               {
+                       return FAILED;
+               }
+               return NEED_MORE;
+       }
        
-       switch (this->method->process(this->method, in, out))
+       if (!this->method)
        {
-               case NEED_MORE:
-                       return NEED_MORE;
-               case SUCCESS:
-                       if (this->do_eap_identity)
-                       {
-                               return process_eap_identity(this, out);
-                       }
-                       if (this->method->get_msk(this->method, &this->msk) == SUCCESS)
-                       {
-                               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, %sMSK established",
-                                        eap_type_names, type, this->msk.ptr ? "" : "no ");
-                       }
-                       *out = eap_payload_create_code(EAP_SUCCESS, in->get_identifier(in));
-                       return SUCCESS;
-               case FAILED:
-               default:
-                       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, in->get_identifier(in));
+               this->eap_payload = server_initiate_eap(this, TRUE);
+       }
+       else
+       {
+               eap_payload = (eap_payload_t*)message->get_payload(message,
+                                                                                                       EXTENSIBLE_AUTHENTICATION);
+               if (!eap_payload)
+               {
                        return FAILED;
+               }
+               this->eap_payload = server_process_eap(this, eap_payload);
        }
+       return NEED_MORE;
 }
 
 /**
- * Implementation of eap_authenticator_t.process
+ * Implementation of authenticator_t.build for a server
  */
-static status_t process(private_eap_authenticator_t *this, eap_payload_t *in,
-                                               eap_payload_t **out)
+static status_t build_server(private_eap_authenticator_t *this,
+                                                        message_t *message)
 {
-       eap_code_t code = in->get_code(in);
+       if (this->eap_payload)
+       {
+               eap_code_t code;
+               
+               code = this->eap_payload->get_code(this->eap_payload);
+               message->add_payload(message, (payload_t*)this->eap_payload);
+               this->eap_payload = NULL;
+               if (code == EAP_FAILURE)
+               {
+                       return FAILED;
+               }
+               return NEED_MORE;
+       }
+       if (this->eap_complete && this->auth_complete)
+       {
+               build_auth(this, message);
+               return SUCCESS;
+       }
+       return FAILED;
+}
+
+/**
+ * Implementation of authenticator_t.process for a client
+ */
+static status_t process_client(private_eap_authenticator_t *this,
+                                                          message_t *message)
+{
+       eap_payload_t *eap_payload;
        
-       switch (this->role)
+       if (this->eap_complete)
        {
-               case EAP_SERVER:
+               if (!verify_auth(this, message))
                {
-                       switch (code)
-                       {
-                               case EAP_RESPONSE:
-                               {
-                                       return process_server(this, in, out);
-                               }
-                               default:
-                               {
-                                       DBG1(DBG_IKE, "received %N, sending %N",
-                                                eap_code_names, code, eap_code_names, EAP_FAILURE);
-                                       *out = eap_payload_create_code(EAP_FAILURE,
-                                                                                                  in->get_identifier(in));
-                                       return FAILED;
-                               }
-                       }
+                       return FAILED;
                }
-               case EAP_PEER:
+               return SUCCESS;
+       }
+       
+       eap_payload = (eap_payload_t*)message->get_payload(message,
+                                                                                                       EXTENSIBLE_AUTHENTICATION);
+       if (eap_payload)
+       {
+               switch (eap_payload->get_code(eap_payload))
                {
-                       switch (code)
+                       case EAP_REQUEST:
+                       {
+                               this->eap_payload = client_process_eap(this, eap_payload);
+                               return NEED_MORE;
+                       }
+                       case EAP_SUCCESS:
                        {
-                               case EAP_REQUEST:
+                               eap_type_t type;
+                               u_int32_t vendor;
+                               auth_cfg_t *cfg;
+                               
+                               if (this->method->get_msk(this->method, &this->msk) == SUCCESS)
                                {
-                                       return process_peer(this, in, out);
+                                       this->msk = chunk_clone(this->msk);
                                }
-                               case EAP_SUCCESS:
+                               type = this->method->get_type(this->method, &vendor);
+                               if (vendor)
                                {
-                                       if (this->method->get_msk(this->method, &this->msk) == SUCCESS)
-                                       {
-                                               this->msk = chunk_clone(this->msk);
-                                       }
-                                       return SUCCESS;
+                                       DBG1(DBG_IKE, "EAP vendor specific method %d-%d succeeded, "
+                                                "%sMSK established", type, vendor,
+                                                this->msk.ptr ? "" : "no ");
                                }
-                               case EAP_FAILURE:
-                               default:
+                               else
                                {
-                                       DBG1(DBG_IKE, "received %N, EAP authentication failed",
-                                                eap_code_names, code);
-                                       return FAILED;
+                                       DBG1(DBG_IKE, "EAP method %N succeeded, %sMSK established",
+                                                eap_type_names, type, this->msk.ptr ? "" : "no ");
                                }
+                               cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
+                               cfg->add(cfg, AUTH_RULE_EAP_TYPE, type);
+                               if (vendor)
+                               {
+                                       cfg->add(cfg, AUTH_RULE_EAP_VENDOR, vendor);
+                               }
+                               this->eap_complete = TRUE;
+                               return NEED_MORE;
+                       }
+                       case EAP_FAILURE:
+                       default:
+                       {
+                               DBG1(DBG_IKE, "received %N, EAP authentication failed",
+                                        eap_code_names, eap_payload->get_code(eap_payload));
+                               return FAILED;
                        }
-               }
-               default:
-               {
-                       return FAILED;
                }
        }
+       return FAILED;
 }
 
 /**
- * Implementation of authenticator_t.is_mutual.
+ * Implementation of authenticator_t.build for a client
  */
-static bool is_mutual(private_eap_authenticator_t *this)
+static status_t build_client(private_eap_authenticator_t *this,        
+                                                        message_t *message)
 {
-       if (this->method)
+       if (this->eap_payload)
        {
-               return this->method->is_mutual(this->method);
+               message->add_payload(message, (payload_t*)this->eap_payload);
+               this->eap_payload = NULL;
+               return NEED_MORE;
        }
-       return FALSE;
+       if (this->eap_complete)
+       {
+               build_auth(this, message);
+               return NEED_MORE;
+       }
+       return NEED_MORE;
 }
 
 /**
@@ -500,6 +571,8 @@ static bool is_mutual(private_eap_authenticator_t *this)
 static void destroy(private_eap_authenticator_t *this)
 {
        DESTROY_IF(this->method);
+       DESTROY_IF(this->eap_payload);
+       DESTROY_IF(this->eap_identity);
        chunk_free(&this->msk);
        free(this);
 }
@@ -507,46 +580,50 @@ static void destroy(private_eap_authenticator_t *this)
 /*
  * Described in header.
  */
-eap_authenticator_t *eap_authenticator_create(ike_sa_t *ike_sa)
+eap_authenticator_t *eap_authenticator_create_builder(ike_sa_t *ike_sa,
+                                                                       chunk_t received_nonce, chunk_t sent_init)
 {
-       peer_cfg_t *config;
-       auth_info_t *auth;
-       identification_t *id;
        private_eap_authenticator_t *this = malloc_thing(private_eap_authenticator_t);
        
-       /* public functions */
-       this->public.authenticator_interface.verify = (status_t(*)(authenticator_t*,chunk_t,chunk_t,auth_payload_t*))verify;
-       this->public.authenticator_interface.build = (status_t(*)(authenticator_t*,chunk_t,chunk_t,auth_payload_t**))build;
-       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,u_int32_t,eap_payload_t**))initiate;
-       this->public.process = (status_t(*)(eap_authenticator_t*,eap_payload_t*,eap_payload_t**))process;
+       this->public.authenticator.build = (status_t(*)(authenticator_t*, message_t *message))build_client;
+       this->public.authenticator.process = (status_t(*)(authenticator_t*, message_t *message))process_client;
+       this->public.authenticator.destroy = (void(*)(authenticator_t*))destroy;
        
-       /* private data */
        this->ike_sa = ike_sa;
-       this->role = EAP_PEER;
+       this->ike_sa_init = sent_init;
+       this->nonce = received_nonce;
+       this->msk = chunk_empty;
        this->method = NULL;
+       this->eap_payload = NULL;
+       this->eap_complete = FALSE;
+       this->auth_complete = FALSE;
+       this->eap_identity = NULL;
+       
+       return &this->public;
+}
+
+/*
+ * Described in header.
+ */
+eap_authenticator_t *eap_authenticator_create_verifier(ike_sa_t *ike_sa,
+                                                                       chunk_t sent_nonce, chunk_t received_init)
+{
+       private_eap_authenticator_t *this = malloc_thing(private_eap_authenticator_t);
+       
+       this->public.authenticator.build = (status_t(*)(authenticator_t*, message_t *messageh))build_server;
+       this->public.authenticator.process = (status_t(*)(authenticator_t*, message_t *message))process_server;
+       this->public.authenticator.destroy = (void(*)(authenticator_t*))destroy;
+       
+       this->ike_sa = ike_sa;
+       this->ike_sa_init = received_init;
+       this->nonce = sent_nonce;
        this->msk = chunk_empty;
-       this->do_eap_identity = FALSE;
-       this->type = 0;
-       this->vendor = 0;
+       this->method = NULL;
+       this->eap_payload = NULL;
+       this->eap_complete = FALSE;
+       this->auth_complete = FALSE;
+       this->eap_identity = NULL;
        
-       config = ike_sa->get_peer_cfg(ike_sa);
-       if (config)
-       {
-               auth = config->get_auth(config);
-               if (auth->get_item(auth, AUTHN_EAP_IDENTITY, (void**)&id))
-               {
-                       if (id->get_type(id) == ID_ANY)
-                       {       /* %any as configured EAP identity runs EAP-Identity first */
-                               this->do_eap_identity = TRUE;
-                       }
-                       else
-                       {
-                               ike_sa->set_eap_identity(ike_sa, id->clone(id));
-                       }
-               }
-       }
        return &this->public;
 }
+
index 0aaa07f351231e4e55e32420a053c805e85d266e..ac01647b1f5b4f62bc3331e5d3de38a2950273dc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2006-2009 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
 typedef struct eap_authenticator_t eap_authenticator_t;
 
 #include <sa/authenticators/authenticator.h>
-#include <encoding/payloads/eap_payload.h>
 
 /**
- * Implementation of the authenticator_t interface using AUTH_CLASS_EAP.
+ * Implementation of authenticator_t using EAP authentication.
  *
  * Authentication using EAP involves the most complex authenticator. It stays
  * alive over multiple ike_auth transactions and handles multiple EAP
  * messages.
- * EAP authentication must be clearly distinguished between using
- * mutual EAP methods and using methods not providing server authentication.
- * If no mutual authentication is used, the server must prove it's identity
- * by traditional AUTH methods (RSA, psk). Only when the EAP method is mutual,
- * the client should accept an EAP-only authentication.
- * RFC4306 does always use traditional authentiction, EAP only authentication
- * is described in the internet draft draft-eronen-ipsec-ikev2-eap-auth-05.txt.
  *
  * @verbatim
                           ike_sa_init
@@ -49,12 +41,12 @@ typedef struct eap_authenticator_t eap_authenticator_t;
                  followed by multiple ike_auth:
 
      +--------+                                +--------+
-     |  EAP   |    ID, SA, TS, N(EAP_ONLY)     |  EAP   |
+     |  EAP   |       IDi, [IDr,] SA, TS       |  EAP   |
      | client |  --------------------------->  | server |
-     |        |          ID, [AUTH,] EAP       |        |  AUTH payload is
-     |        |  <---------------------------  |        |  only included if
-     |        |              EAP               |        |  authentication
-     |        |  --------------------------->  |        |  is not mutual.
+     |        |          ID, AUTH, EAP         |        |
+     |        |  <---------------------------  |        |
+     |        |              EAP               |        |
+     |        |  --------------------------->  |        |
      |        |              EAP               |        |
      |        |  <---------------------------  |        |
      |        |              EAP               |        |
@@ -74,74 +66,29 @@ struct eap_authenticator_t {
        /**
         * Implemented authenticator_t interface.
         */
-       authenticator_t authenticator_interface;
-       
-       /**
-        * Check if the EAP method was/is mutual and secure.
-        *
-        * RFC4306 proposes to authenticate the EAP responder (server) by standard
-        * IKEv2 methods (RSA, psk). Not all, but some EAP methods
-        * provide mutual authentication, which would result in a redundant
-        * authentication. If the client supports EAP_ONLY_AUTHENTICATION, and
-        * the the server provides mutual authentication, authentication using
-        * RSA/PSK may be omitted. If the server did not include a traditional
-        * AUTH payload, the client must verify that the server initiated mutual
-        * EAP authentication before it can trust the server.
-        *
-        * @return              TRUE, if no AUTH payload required, FALSE otherwise
-        */
-       bool (*is_mutual) (eap_authenticator_t* this);
-       
-       /**
-        * Initiate the EAP exchange.
-        *
-        * The server initiates EAP exchanges, so the client never calls
-        * this method. If initiate() returns NEED_MORE, the EAP authentication
-        * process started. In any case, a payload is created in "out".
-        *
-        * @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,
-                                                 u_int32_t vendor, eap_payload_t **out);
-       
-       /**
-        * Process an EAP message.
-        *
-        * After receiving an EAP message "in", the peer/server processes
-        * the payload and creates a reply/subsequent request.
-        * The server side always returns NEED_MORE if another EAP message
-        * is expected from the client, SUCCESS if EAP exchange completed and
-        * "out" is EAP_SUCCES, or FAILED if the EAP exchange failed with
-        * a EAP_FAILURE payload in "out". Anyway, a payload in "out" is always
-        * created.
-        * The peer (client) side only creates a "out" payload if result is
-        * NEED_MORE, a SUCCESS/FAILED is returned whenever a
-        * EAP_SUCCESS/EAP_FAILURE message is received in "in".
-        * If a SUCCESS is returned (on any side), the EAP authentication was
-        * successful and the AUTH payload can be exchanged.
-        *
-        * @param in    received EAP message
-        * @param out   created EAP message to send
-        * @return
-        *                              - FAILED, if authentication/EAP exchange failed
-        *                              - SUCCESS, if authentication completed
-        *                              - NEED_MORE, if more EAP exchanges reqired
-        */
-       status_t (*process) (eap_authenticator_t* this,
-                                                eap_payload_t *in, eap_payload_t **out);
+       authenticator_t authenticator;
 };
 
 /**
- * Creates an authenticator for AUTH_CLASS_EAP.
+ * Create an authenticator to authenticate against an EAP server.
  *
- * @param ike_sa               associated ike_sa
- * @return                             eap_authenticator_t object
+ * @param ike_sa                       associated ike_sa
+ * @param received_nonce       nonce received in IKE_SA_INIT
+ * @param sent_init                    sent IKE_SA_INIT message data
+ * @return                                     EAP authenticator
+ */
+eap_authenticator_t *eap_authenticator_create_builder(ike_sa_t *ike_sa,
+                                                                       chunk_t received_nonce, chunk_t sent_init);
+
+/**
+ * Create an authenticator to authenticate EAP clients.
+ * 
+ * @param ike_sa                       associated ike_sa
+ * @param sent_nonce           nonce sent in IKE_SA_INIT
+ * @param received_init                received IKE_SA_INIT message data
+ * @return                                     EAP authenticator
  */
-eap_authenticator_t *eap_authenticator_create(ike_sa_t *ike_sa);
+eap_authenticator_t *eap_authenticator_create_verifier(ike_sa_t *ike_sa,
+                                                                       chunk_t sent_nonce, chunk_t received_init);
 
 #endif /** EAP_AUTHENTICATOR_H_ @}*/
index a3c84c491a6d8062106405069054764ca67dafd4..45baa8e9c14b6dee082dc92ab66657e8e7473629 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005-2009 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
  * $Id$
  */
 
-#include <string.h>
-
 #include "psk_authenticator.h"
 
 #include <daemon.h>
-#include <credentials/auth_info.h>
-
+#include <encoding/payloads/auth_payload.h>
 
 typedef struct private_psk_authenticator_t private_psk_authenticator_t;
 
@@ -40,22 +37,74 @@ struct private_psk_authenticator_t {
         * Assigned IKE_SA
         */
        ike_sa_t *ike_sa;
+       
+       /**
+        * nonce to include in AUTH calculation
+        */
+       chunk_t nonce;
+       
+       /**
+        * IKE_SA_INIT message data to include in AUTH calculation
+        */
+       chunk_t ike_sa_init;
 };
 
+/*
+ * Implementation of authenticator_t.build for builder
+ */
+static status_t build(private_psk_authenticator_t *this, message_t *message)
+{
+       identification_t *my_id, *other_id;
+       auth_payload_t *auth_payload;
+       shared_key_t *key;
+       chunk_t auth_data;
+       keymat_t *keymat;
+       
+       keymat = this->ike_sa->get_keymat(this->ike_sa);
+       my_id = this->ike_sa->get_my_id(this->ike_sa);
+       other_id = this->ike_sa->get_other_id(this->ike_sa);
+       DBG1(DBG_IKE, "authentication of '%D' (myself) with %N",
+                my_id, auth_method_names, AUTH_PSK);
+       key = charon->credentials->get_shared(charon->credentials, SHARED_IKE,
+                                                                                 my_id, other_id);
+       if (key == NULL)
+       {
+               DBG1(DBG_IKE, "no shared key found for '%D' - '%D'", my_id, other_id);
+               return NOT_FOUND;
+       }
+       auth_data = keymat->get_psk_sig(keymat, FALSE, this->ike_sa_init,
+                                                                       this->nonce, key->get_key(key), my_id);
+       key->destroy(key);
+       DBG2(DBG_IKE, "successfully created shared key MAC");
+       auth_payload = auth_payload_create();
+       auth_payload->set_auth_method(auth_payload, AUTH_PSK);
+       auth_payload->set_data(auth_payload, auth_data);
+       chunk_free(&auth_data);
+       message->add_payload(message, (payload_t*)auth_payload);
+       
+       return SUCCESS;
+}
+
 /**
- * Implementation of authenticator_t.verify.
+ * Implementation of authenticator_t.process for verifier
  */
-static status_t verify(private_psk_authenticator_t *this, chunk_t ike_sa_init,
-                                          chunk_t my_nonce, auth_payload_t *auth_payload)
+static status_t process(private_psk_authenticator_t *this, message_t *message)
 {
        chunk_t auth_data, recv_auth_data;
        identification_t *my_id, *other_id;
+       auth_payload_t *auth_payload;
+       auth_cfg_t *auth;
        shared_key_t *key;
        enumerator_t *enumerator;
        bool authenticated = FALSE;
        int keys_found = 0;
        keymat_t *keymat;
        
+       auth_payload = (auth_payload_t*)message->get_payload(message, AUTHENTICATION);
+       if (!auth_payload)
+       {
+               return FAILED;
+       }
        keymat = this->ike_sa->get_keymat(this->ike_sa);
        recv_auth_data = auth_payload->get_data(auth_payload);
        my_id = this->ike_sa->get_my_id(this->ike_sa);
@@ -66,8 +115,8 @@ static status_t verify(private_psk_authenticator_t *this, chunk_t ike_sa_init,
        {
                keys_found++;
                
-               auth_data = keymat->get_psk_sig(keymat, TRUE, ike_sa_init, my_nonce,
-                                                                               key->get_key(key), other_id);
+               auth_data = keymat->get_psk_sig(keymat, TRUE, this->ike_sa_init,
+                                                                       this->nonce, key->get_key(key), other_id);
                if (auth_data.len && chunk_equals(auth_data, recv_auth_data))
                {
                        DBG1(DBG_IKE, "authentication of '%D' with %N successful",
@@ -89,42 +138,19 @@ static status_t verify(private_psk_authenticator_t *this, chunk_t ike_sa_init,
                         keys_found, keys_found == 1 ? "" : "s", my_id, other_id);
                return FAILED;
        }
+       
+       auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
+       auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
        return SUCCESS;
 }
 
 /**
- * Implementation of authenticator_t.build.
+ * Implementation of authenticator_t.process for builder
+ * Implementation of authenticator_t.build for verifier
  */
-static status_t build(private_psk_authenticator_t *this, chunk_t ike_sa_init,
-                                         chunk_t other_nonce, auth_payload_t **auth_payload)
+static status_t return_failed()
 {
-       identification_t *my_id, *other_id;
-       shared_key_t *key;
-       chunk_t auth_data;
-       keymat_t *keymat;
-       
-       keymat = this->ike_sa->get_keymat(this->ike_sa);
-       my_id = this->ike_sa->get_my_id(this->ike_sa);
-       other_id = this->ike_sa->get_other_id(this->ike_sa);
-       DBG1(DBG_IKE, "authentication of '%D' (myself) with %N",
-                my_id, auth_method_names, AUTH_PSK);
-       key = charon->credentials->get_shared(charon->credentials, SHARED_IKE,
-                                                                                 my_id, other_id);
-       if (key == NULL)
-       {
-               DBG1(DBG_IKE, "no shared key found for '%D' - '%D'", my_id, other_id);
-               return NOT_FOUND;
-       }
-       auth_data = keymat->get_psk_sig(keymat, FALSE, ike_sa_init, other_nonce,
-                                                                       key->get_key(key), my_id);
-       key->destroy(key);
-       DBG2(DBG_IKE, "successfully created shared key MAC");
-       *auth_payload = auth_payload_create();
-       (*auth_payload)->set_auth_method(*auth_payload, AUTH_PSK);
-       (*auth_payload)->set_data(*auth_payload, auth_data);
-       
-       chunk_free(&auth_data);
-       return SUCCESS;
+       return FAILED;
 }
 
 /**
@@ -138,17 +164,38 @@ static void destroy(private_psk_authenticator_t *this)
 /*
  * Described in header.
  */
-psk_authenticator_t *psk_authenticator_create(ike_sa_t *ike_sa)
+psk_authenticator_t *psk_authenticator_create_builder(ike_sa_t *ike_sa,
+                                                                       chunk_t received_nonce, chunk_t sent_init)
+{
+       private_psk_authenticator_t *this = malloc_thing(private_psk_authenticator_t);
+       
+       this->public.authenticator.build = (status_t(*)(authenticator_t*, message_t *message))build;
+       this->public.authenticator.process = (status_t(*)(authenticator_t*, message_t *message))return_failed;
+       this->public.authenticator.destroy = (void(*)(authenticator_t*))destroy;
+       
+       this->ike_sa = ike_sa;
+       this->ike_sa_init = sent_init;
+       this->nonce = received_nonce;
+       
+       return &this->public;
+}
+
+/*
+ * Described in header.
+ */
+psk_authenticator_t *psk_authenticator_create_verifier(ike_sa_t *ike_sa,
+                                                                       chunk_t sent_nonce, chunk_t received_init)
 {
        private_psk_authenticator_t *this = malloc_thing(private_psk_authenticator_t);
        
-       /* public functions */
-       this->public.authenticator_interface.verify = (status_t(*)(authenticator_t*,chunk_t,chunk_t,auth_payload_t*))verify;
-       this->public.authenticator_interface.build = (status_t(*)(authenticator_t*,chunk_t,chunk_t,auth_payload_t**))build;
-       this->public.authenticator_interface.destroy = (void(*)(authenticator_t*))destroy;
+       this->public.authenticator.build = (status_t(*)(authenticator_t*, message_t *messageh))return_failed;
+       this->public.authenticator.process = (status_t(*)(authenticator_t*, message_t *message))process;
+       this->public.authenticator.destroy = (void(*)(authenticator_t*))destroy;
        
-       /* private data */
        this->ike_sa = ike_sa;
+       this->ike_sa_init = received_init;
+       this->nonce = sent_nonce;
        
        return &this->public;
 }
+
index 9849acdbc4e7a02cc8692a656a8b3d413a8f57f6..c307aee5267b1dc6811031f0f2720ef25bfac39b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2006-2009 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -28,22 +28,36 @@ typedef struct psk_authenticator_t psk_authenticator_t;
 #include <sa/authenticators/authenticator.h>
 
 /**
- * Implementation of the authenticator_t interface using AUTH_PSK.
+ * Implementation of authenticator_t using pre-shared keys.
  */
 struct psk_authenticator_t {
 
        /**
         * Implemented authenticator_t interface.
         */
-       authenticator_t authenticator_interface;
+       authenticator_t authenticator;
 };
 
 /**
- * Creates an authenticator for AUTH_PSK.
+ * Create an authenticator to build PSK signatures.
  *
- * @param ike_sa               associated ike_sa
- * @return                             psk_authenticator_t object
+ * @param ike_sa                       associated ike_sa
+ * @param received_nonce       nonce received in IKE_SA_INIT
+ * @param sent_init                    sent IKE_SA_INIT message data
+ * @return                                     PSK authenticator
  */
-psk_authenticator_t *psk_authenticator_create(ike_sa_t *ike_sa);
+psk_authenticator_t *psk_authenticator_create_builder(ike_sa_t *ike_sa,
+                                                                       chunk_t received_nonce, chunk_t sent_init);
+
+/**
+ * Create an authenticator to verify PSK signatures.
+ * 
+ * @param ike_sa                       associated ike_sa
+ * @param sent_nonce           nonce sent in IKE_SA_INIT
+ * @param received_init                received IKE_SA_INIT message data
+ * @return                                     PSK authenticator
+ */
+psk_authenticator_t *psk_authenticator_create_verifier(ike_sa_t *ike_sa,
+                                                                       chunk_t sent_nonce, chunk_t received_init);
 
 #endif /** PSK_AUTHENTICATOR_H_ @}*/
index 49a4283d21aaca20aa50682c4375bde027af9e36..482d6b91d0e7d7e346f0807bc434621bda9a5380 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Tobias Brunner
- * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005-2009 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
  * $Id$
  */
 
-#include <string.h>
-
 #include "pubkey_authenticator.h"
 
 #include <daemon.h>
-#include <credentials/auth_info.h>
-
+#include <encoding/payloads/auth_payload.h>
 
 typedef struct private_pubkey_authenticator_t private_pubkey_authenticator_t;
 
@@ -41,90 +38,35 @@ struct private_pubkey_authenticator_t {
         * Assigned IKE_SA
         */
        ike_sa_t *ike_sa;
-};
-
-/**
- * Implementation of authenticator_t.verify.
- */
-static status_t verify(private_pubkey_authenticator_t *this, chunk_t ike_sa_init,
-                                          chunk_t my_nonce, auth_payload_t *auth_payload)
-{
-       public_key_t *public;
-       auth_method_t auth_method;
-       chunk_t auth_data, octets;
-       identification_t *id;
-       auth_info_t *auth, *current_auth;
-       enumerator_t *enumerator;
-       key_type_t key_type = KEY_ECDSA;
-       signature_scheme_t scheme;
-       status_t status = FAILED;
-       keymat_t *keymat;
        
-       id = this->ike_sa->get_other_id(this->ike_sa);
-       auth_method = auth_payload->get_auth_method(auth_payload);
-       switch (auth_method)
-       {
-               case AUTH_RSA:
-                       /* We are currently fixed to SHA1 hashes.
-                        * TODO: allow other hash algorithms and note it in "auth" */
-                       key_type = KEY_RSA;
-                       scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
-                       break;
-               case AUTH_ECDSA_256:
-                       scheme = SIGN_ECDSA_256;
-                       break;
-               case AUTH_ECDSA_384:
-                       scheme = SIGN_ECDSA_384;
-                       break;
-               case AUTH_ECDSA_521:
-                       scheme = SIGN_ECDSA_521;
-                       break;
-               default:
-                       return INVALID_ARG;
-       }
-       auth_data = auth_payload->get_data(auth_payload);
-       keymat = this->ike_sa->get_keymat(this->ike_sa);
-       octets = keymat->get_auth_octets(keymat, TRUE, ike_sa_init, my_nonce, id);
-       auth = this->ike_sa->get_other_auth(this->ike_sa);
-       enumerator = charon->credentials->create_public_enumerator(
-                                                                               charon->credentials, key_type, id, auth);
-       while (enumerator->enumerate(enumerator, &public, &current_auth))
-       {
-               if (public->verify(public, scheme, octets, auth_data))
-               {
-                       DBG1(DBG_IKE, "authentication of '%D' with %N successful",
-                                                  id, auth_method_names, auth_method);
-                       status = SUCCESS;
-                       auth->merge(auth, current_auth);
-                       break;
-               }
-               else
-               {
-                       DBG1(DBG_IKE, "signature validation failed, looking for another key");
-               }
-       }
-       enumerator->destroy(enumerator);
-       chunk_free(&octets);
-       return status;
-}
+       /**
+        * nonce to include in AUTH calculation
+        */
+       chunk_t nonce;
+       
+       /**
+        * IKE_SA_INIT message data to include in AUTH calculation
+        */
+       chunk_t ike_sa_init;
+};
 
 /**
- * Implementation of authenticator_t.build.
+ * Implementation of authenticator_t.build for builder
  */
-static status_t build(private_pubkey_authenticator_t *this, chunk_t ike_sa_init,
-                                         chunk_t other_nonce, auth_payload_t **auth_payload)
+static status_t build(private_pubkey_authenticator_t *this, message_t *message)
 {
        chunk_t octets, auth_data;
        status_t status = FAILED;
        private_key_t *private;
        identification_t *id;
-       auth_info_t *auth;
+       auth_cfg_t *auth;
+       auth_payload_t *auth_payload;
        auth_method_t auth_method;
        signature_scheme_t scheme;
        keymat_t *keymat;
 
        id = this->ike_sa->get_my_id(this->ike_sa);
-       auth = this->ike_sa->get_my_auth(this->ike_sa);
+       auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
        private = charon->credentials->get_private(charon->credentials, KEY_ANY,
                                                                                           id, auth);
        if (private == NULL)
@@ -169,15 +111,15 @@ static status_t build(private_pubkey_authenticator_t *this, chunk_t ike_sa_init,
                        return status;
        }
        keymat = this->ike_sa->get_keymat(this->ike_sa);
-       octets = keymat->get_auth_octets(keymat, FALSE, ike_sa_init, other_nonce, id);
-       
+       octets = keymat->get_auth_octets(keymat, FALSE, this->ike_sa_init,
+                                                                        this->nonce, id);
        if (private->sign(private, scheme, octets, &auth_data))
        {
-               auth_payload_t *payload = auth_payload_create();
-               payload->set_auth_method(payload, auth_method);
-               payload->set_data(payload, auth_data);
-               *auth_payload = payload;
+               auth_payload = auth_payload_create();
+               auth_payload->set_auth_method(auth_payload, auth_method);
+               auth_payload->set_data(auth_payload, auth_data);
                chunk_free(&auth_data);
+               message->add_payload(message, (payload_t*)auth_payload);
                status = SUCCESS;
        }
        DBG1(DBG_IKE, "authentication of '%D' (myself) with %N %s", id,
@@ -189,6 +131,93 @@ static status_t build(private_pubkey_authenticator_t *this, chunk_t ike_sa_init,
        return status;
 }
 
+/**
+ * Implementation of authenticator_t.process for verifier
+ */
+static status_t process(private_pubkey_authenticator_t *this, message_t *message)
+{
+       public_key_t *public;
+       auth_method_t auth_method;
+       auth_payload_t *auth_payload;
+       chunk_t auth_data, octets;
+       identification_t *id;
+       auth_cfg_t *auth, *current_auth;
+       enumerator_t *enumerator;
+       key_type_t key_type = KEY_ECDSA;
+       signature_scheme_t scheme;
+       status_t status = NOT_FOUND;
+       keymat_t *keymat;
+       
+       auth_payload = (auth_payload_t*)message->get_payload(message, AUTHENTICATION);
+       if (!auth_payload)
+       {
+               return FAILED;
+       }
+       auth_method = auth_payload->get_auth_method(auth_payload);
+       switch (auth_method)
+       {
+               case AUTH_RSA:
+                       /* We currently accept SHA1 signatures only
+                        * TODO: allow other hash algorithms and note it in "auth" */
+                       key_type = KEY_RSA;
+                       scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
+                       break;
+               case AUTH_ECDSA_256:
+                       scheme = SIGN_ECDSA_256;
+                       break;
+               case AUTH_ECDSA_384:
+                       scheme = SIGN_ECDSA_384;
+                       break;
+               case AUTH_ECDSA_521:
+                       scheme = SIGN_ECDSA_521;
+                       break;
+               default:
+                       return INVALID_ARG;
+       }
+       auth_data = auth_payload->get_data(auth_payload);
+       id = this->ike_sa->get_other_id(this->ike_sa);
+       keymat = this->ike_sa->get_keymat(this->ike_sa);
+       octets = keymat->get_auth_octets(keymat, TRUE, this->ike_sa_init,
+                                                                        this->nonce, id);
+       auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
+       enumerator = charon->credentials->create_public_enumerator(
+                                                                               charon->credentials, key_type, id, auth);
+       while (enumerator->enumerate(enumerator, &public, &current_auth))
+       {
+               if (public->verify(public, scheme, octets, auth_data))
+               {
+                       DBG1(DBG_IKE, "authentication of '%D' with %N successful",
+                                                  id, auth_method_names, auth_method);
+                       status = SUCCESS;
+                       auth->merge(auth, current_auth, FALSE);
+                       auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
+                       break;
+               }
+               else
+               {
+                       status = FAILED;
+                       DBG1(DBG_IKE, "signature validation failed, looking for another key");
+               }
+       }
+       enumerator->destroy(enumerator);
+       chunk_free(&octets);
+       if (status == NOT_FOUND)
+       {
+               DBG1(DBG_IKE, "no trusted %N public key found for '%D'",
+                        key_type_names, key_type, id);
+       }
+       return status;
+}
+
+/**
+ * Implementation of authenticator_t.process for builder
+ * Implementation of authenticator_t.build for verifier
+ */
+static status_t return_failed()
+{
+       return FAILED;
+}
+
 /**
  * Implementation of authenticator_t.destroy.
  */
@@ -200,17 +229,37 @@ static void destroy(private_pubkey_authenticator_t *this)
 /*
  * Described in header.
  */
-pubkey_authenticator_t *pubkey_authenticator_create(ike_sa_t *ike_sa)
+pubkey_authenticator_t *pubkey_authenticator_create_builder(ike_sa_t *ike_sa,
+                                                                       chunk_t received_nonce, chunk_t sent_init)
+{
+       private_pubkey_authenticator_t *this = malloc_thing(private_pubkey_authenticator_t);
+       
+       this->public.authenticator.build = (status_t(*)(authenticator_t*, message_t *message))build;
+       this->public.authenticator.process = (status_t(*)(authenticator_t*, message_t *message))return_failed;
+       this->public.authenticator.destroy = (void(*)(authenticator_t*))destroy;
+       
+       this->ike_sa = ike_sa;
+       this->ike_sa_init = sent_init;
+       this->nonce = received_nonce;
+       
+       return &this->public;
+}
+
+/*
+ * Described in header.
+ */
+pubkey_authenticator_t *pubkey_authenticator_create_verifier(ike_sa_t *ike_sa,
+                                                                       chunk_t sent_nonce, chunk_t received_init)
 {
        private_pubkey_authenticator_t *this = malloc_thing(private_pubkey_authenticator_t);
        
-       /* public functions */
-       this->public.authenticator_interface.verify = (status_t(*)(authenticator_t*,chunk_t,chunk_t,auth_payload_t*))verify;
-       this->public.authenticator_interface.build = (status_t(*)(authenticator_t*,chunk_t,chunk_t,auth_payload_t**))build;
-       this->public.authenticator_interface.destroy = (void(*)(authenticator_t*))destroy;
+       this->public.authenticator.build = (status_t(*)(authenticator_t*, message_t *message))return_failed;
+       this->public.authenticator.process = (status_t(*)(authenticator_t*, message_t *message))process;
+       this->public.authenticator.destroy = (void(*)(authenticator_t*))destroy;
        
-       /* private data */
        this->ike_sa = ike_sa;
+       this->ike_sa_init = received_init;
+       this->nonce = sent_nonce;
        
        return &this->public;
 }
index 4a2d9e21941c4d9e421e00810327756e47578d87..997b1b5939ed8539a9abe22362a583ef0a271f85 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Tobias Brunner
- * Copyright (C) 2006 Martin Willi
+ * Copyright (C) 2006-2009 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -29,22 +29,36 @@ typedef struct pubkey_authenticator_t pubkey_authenticator_t;
 #include <sa/authenticators/authenticator.h>
 
 /**
- * Implementation of the authenticator_t interface using AUTH_PUBKEY.
+ * Implementation of authenticator_t using public key authenitcation.
  */
 struct pubkey_authenticator_t {
 
        /**
         * Implemented authenticator_t interface.
         */
-       authenticator_t authenticator_interface;
+       authenticator_t authenticator;
 };
 
 /**
- * Creates an authenticator for AUTH_PUBKEY.
+ * Create an authenticator to build public key signatures.
  *
- * @param ike_sa               associated ike_sa
- * @return                             pubkey_authenticator_t object
+ * @param ike_sa                       associated ike_sa
+ * @param received_nonce       nonce received in IKE_SA_INIT
+ * @param sent_init                    sent IKE_SA_INIT message data
+ * @return                                     public key authenticator
  */
-pubkey_authenticator_t *pubkey_authenticator_create(ike_sa_t *ike_sa);
+pubkey_authenticator_t *pubkey_authenticator_create_builder(ike_sa_t *ike_sa,
+                                                                       chunk_t received_nonce, chunk_t sent_init);
+
+/**
+ * Create an authenticator to verify public key signatures.
+ * 
+ * @param ike_sa                       associated ike_sa
+ * @param sent_nonce           nonce sent in IKE_SA_INIT
+ * @param received_init                received IKE_SA_INIT message data
+ * @return                                     public key authenticator
+ */
+pubkey_authenticator_t *pubkey_authenticator_create_verifier(ike_sa_t *ike_sa,
+                                                                       chunk_t sent_nonce, chunk_t received_init);
 
 #endif /** PUBKEY_AUTHENTICATOR_H_ @}*/
index fa5824bf43fc384582fa96bb9736e264296959a0..f597d3550bf290d758a4f990f7a608f89d8c9a07 100644 (file)
@@ -734,11 +734,11 @@ static void build_pairs(check_list_t *checklist)
  */
 static status_t process_payloads(message_t *message, check_t *check)
 {
-       iterator_t *iterator;
+       enumerator_t *enumerator;
        payload_t *payload;
 
-       iterator = message->get_payload_iterator(message);
-       while (iterator->iterate(iterator, (void**)&payload))
+       enumerator = message->create_payload_enumerator(message);
+       while (enumerator->enumerate(enumerator, &payload))
        {
                if (payload->get_type(payload) != NOTIFY)
                {
@@ -796,7 +796,7 @@ static status_t process_payloads(message_t *message, check_t *check)
                                break;
                }
        }
-       iterator->destroy(iterator);
+       enumerator->destroy(enumerator);
        
        if (!check->connect_id.ptr || !check->endpoint || !check->auth.ptr)
        {
index 17ba15e27426c47af4e38040016ed722eefb1015..2a1b96bbb3626c87ed34e5eecf469d2c3c9bf240 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2006-2008 Tobias Brunner
  * Copyright (C) 2006 Daniel Roethlisberger
- * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005-2009 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
@@ -109,14 +109,14 @@ struct private_ike_sa_t {
        peer_cfg_t *peer_cfg;
        
        /**
-        * associated authentication/authorization info for local peer
+        * currently used authentication ruleset, local (as auth_cfg_t)
         */
-       auth_info_t *my_auth;
+       auth_cfg_t *my_auth;
        
        /**
-        * associated authentication/authorization info for remote peer
+        * currently used authentication constraints, remote (as auth_cfg_t)
         */
-       auth_info_t *other_auth;
+       auth_cfg_t *other_auth;
        
        /**
         * Selected IKE proposal
@@ -355,40 +355,23 @@ static void set_peer_cfg(private_ike_sa_t *this, peer_cfg_t *peer_cfg)
        DESTROY_IF(this->peer_cfg);
        peer_cfg->get_ref(peer_cfg);
        this->peer_cfg = peer_cfg;
-
+       
        if (this->ike_cfg == NULL)
        {
                this->ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
                this->ike_cfg->get_ref(this->ike_cfg);
        }
-       /* apply IDs if they are not already set */
-       if (this->my_id->contains_wildcards(this->my_id))
-       {
-               DESTROY_IF(this->my_id);
-               this->my_id = this->peer_cfg->get_my_id(this->peer_cfg);
-               this->my_id = this->my_id->clone(this->my_id);
-       }
-       if (this->other_id->contains_wildcards(this->other_id))
-       {
-               DESTROY_IF(this->other_id);
-               this->other_id = this->peer_cfg->get_other_id(this->peer_cfg);
-               this->other_id = this->other_id->clone(this->other_id);
-       }
-}
-
-/**
- * Implementation of ike_sa_t.get_my_auth.
- */
-static auth_info_t* get_my_auth(private_ike_sa_t *this)
-{
-       return this->my_auth;
 }
 
 /**
- * Implementation of ike_sa_t.get_other_auth.
+ * Implementation of ike_sa_t.get_auth_cfg
  */
-static auth_info_t* get_other_auth(private_ike_sa_t *this)
+static auth_cfg_t* get_auth_cfg(private_ike_sa_t *this, bool local)
 {
+       if (local)
+       {
+               return this->my_auth;
+       }
        return this->other_auth;
 }
 
@@ -1483,14 +1466,6 @@ static status_t process_message(private_ike_sa_t *this, message_t *message)
                status = this->task_manager->process_message(this->task_manager, message);
                if (status != DESTROY_ME)
                {
-                       if (message->get_exchange_type(message) == IKE_AUTH &&
-                               this->state == IKE_ESTABLISHED)
-                       {
-                               /* purge auth items if SA is up, as they contain certs
-                                * and other memory wasting elements */
-                               this->my_auth->purge(this->my_auth);
-                               this->other_auth->purge(this->other_auth);
-                       }
                        return status;
                }
                /* if IKE_SA gets closed for any reasons, reroute routed children */
@@ -2304,9 +2279,9 @@ static void destroy(private_ike_sa_t *this)
        
        DESTROY_IF(this->ike_cfg);
        DESTROY_IF(this->peer_cfg);
-       DESTROY_IF(this->my_auth);
-       DESTROY_IF(this->other_auth);
        DESTROY_IF(this->proposal);
+       this->my_auth->destroy(this->my_auth);
+       this->other_auth->destroy(this->other_auth);
        
        this->ike_sa_id->destroy(this->ike_sa_id);
        free(this);
@@ -2334,8 +2309,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
        this->public.set_ike_cfg = (void (*)(ike_sa_t*,ike_cfg_t*))set_ike_cfg;
        this->public.get_peer_cfg = (peer_cfg_t* (*)(ike_sa_t*))get_peer_cfg;
        this->public.set_peer_cfg = (void (*)(ike_sa_t*,peer_cfg_t*))set_peer_cfg;
-       this->public.get_my_auth = (auth_info_t*(*)(ike_sa_t*))get_my_auth;
-       this->public.get_other_auth = (auth_info_t*(*)(ike_sa_t*))get_other_auth;
+       this->public.get_auth_cfg = (auth_cfg_t*(*)(ike_sa_t*, bool local))get_auth_cfg;
        this->public.get_proposal = (proposal_t*(*)(ike_sa_t*))get_proposal;
        this->public.set_proposal = (void(*)(ike_sa_t*, proposal_t *proposal))set_proposal;
        this->public.get_id = (ike_sa_id_t* (*)(ike_sa_t*)) get_id;
@@ -2416,8 +2390,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
        this->stats[STAT_INBOUND] = this->stats[STAT_OUTBOUND] = time(NULL);
        this->ike_cfg = NULL;
        this->peer_cfg = NULL;
-       this->my_auth = auth_info_create();
-       this->other_auth = auth_info_create();
+       this->my_auth = auth_cfg_create();
+       this->other_auth = auth_cfg_create();
        this->proposal = NULL;
        this->task_manager = task_manager_create(&this->public);
        this->unique_id = ++unique_id;
index 2430f00a0f16f881efd33f691113224eb0d2fe00..6542ffa50bd1c9eef0c234842cad0fe1d355e150 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2006-2008 Tobias Brunner
  * Copyright (C) 2006 Daniel Roethlisberger
- * Copyright (C) 2005-2008 Martin Willi
+ * Copyright (C) 2005-2009 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
@@ -41,7 +41,7 @@ typedef struct ike_sa_t ike_sa_t;
 #include <sa/keymat.h>
 #include <config/peer_cfg.h>
 #include <config/ike_cfg.h>
-#include <credentials/auth_info.h>
+#include <config/auth_cfg.h>
 
 /**
  * Timeout in milliseconds after that a half open IKE_SA gets deleted.
@@ -82,6 +82,11 @@ enum ike_extension_t {
         * peer supports HTTP cert lookups as specified in RFC4306
         */
        EXT_HASH_AND_URL = (1<<2),
+       
+       /**
+        * peer supports multiple authentication exchanges, RFC4739
+        */
+       EXT_MULTIPLE_AUTH = (1<<3),
 };
 
 /**
@@ -110,7 +115,7 @@ enum ike_condition_t {
        COND_NAT_FAKE = (1<<3),
        
        /**
-        * peer has ben authenticated using EAP
+        * peer has been authenticated using EAP at least once
         */
        COND_EAP_AUTHENTICATED = (1<<4),
        
@@ -391,18 +396,12 @@ struct ike_sa_t {
        void (*set_peer_cfg) (ike_sa_t *this, peer_cfg_t *config);
        
        /**
-        * Get authentication/authorization info for local peer.
-        *
-        * @return                              auth_info for me
-        */
-       auth_info_t* (*get_my_auth)(ike_sa_t *this);
-       
-       /**
-        * Get authentication/authorization info for remote peer.
+        * Get the authentication config with rules of the current auth round.
         *
-        * @return                              auth_info for me
+        * @param local                 TRUE for local rules, FALSE for remote constraints
+        * @return                              current cfg
         */
-       auth_info_t* (*get_other_auth)(ike_sa_t *this);
+       auth_cfg_t* (*get_auth_cfg)(ike_sa_t *this, bool local);
        
        /**
         * Get the selected proposal of this IKE_SA.
index 0528e8bbb215c57cb04dbe6cc6f2a478432c3307..f9588c201b9d7c3daa9b30974c61880ad43d3187 100644 (file)
@@ -1042,9 +1042,7 @@ static ike_sa_t* checkout_by_config(private_ike_sa_manager_t *this,
        enumerator_t *enumerator;
        entry_t *entry;
        ike_sa_t *ike_sa = NULL;
-       identification_t *my_id, *other_id;
-       host_t *my_host, *other_host;
-       ike_cfg_t *ike_cfg;
+       peer_cfg_t *current_cfg;
        u_int segment;
        
        if (!this->reuse_ikesa)
@@ -1054,70 +1052,29 @@ static ike_sa_t* checkout_by_config(private_ike_sa_manager_t *this,
                return ike_sa;
        }
        
-       ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
-       my_id = peer_cfg->get_my_id(peer_cfg);
-       other_id = peer_cfg->get_other_id(peer_cfg);
-       my_host = host_create_from_dns(ike_cfg->get_my_addr(ike_cfg), 0, 0);
-       other_host = host_create_from_dns(ike_cfg->get_other_addr(ike_cfg), 0, 0);
-       
-       if (my_host && other_host)
+       enumerator = create_table_enumerator(this);
+       while (enumerator->enumerate(enumerator, &entry, &segment))
        {
-               enumerator = create_table_enumerator(this);
-               while (enumerator->enumerate(enumerator, &entry, &segment))
+               if (!wait_for_entry(this, entry, segment))
                {
-                       identification_t *found_my_id, *found_other_id;
-                       host_t *found_my_host, *found_other_host;
-               
-                       if (!wait_for_entry(this, entry, segment))
-                       {
-                               continue;
-                       }
-               
-                       if (entry->ike_sa->get_state(entry->ike_sa) == IKE_DELETING)
-                       {
-                               /* skip IKE_SAs which are not usable */
-                               continue;
-                       }
-               
-                       found_my_id = entry->ike_sa->get_my_id(entry->ike_sa);
-                       found_other_id = entry->ike_sa->get_other_id(entry->ike_sa);
-                       found_my_host = entry->ike_sa->get_my_host(entry->ike_sa);
-                       found_other_host = entry->ike_sa->get_other_host(entry->ike_sa);
+                       continue;
+               }
+               if (entry->ike_sa->get_state(entry->ike_sa) == IKE_DELETING)
+               {       /* skip IKE_SAs which are not usable */
+                       continue;
+               }
                
-                       if (found_my_id->get_type(found_my_id) == ID_ANY &&
-                               found_other_id->get_type(found_other_id) == ID_ANY)
-                       {
-                               /* IKE_SA has no IDs yet, so we can't use it */
-                               continue;
-                       }
-                       DBG2(DBG_MGR, "candidate IKE_SA for \n"
-                                "  %H[%D]...%H[%D]\n"
-                                "  %H[%D]...%H[%D]",
-                                my_host, my_id, other_host, other_id,
-                                found_my_host, found_my_id, found_other_host, found_other_id);
-                       /* compare ID and hosts. Supplied ID may contain wildcards, and IP
-                        * may be %any. */
-                       if ((my_host->is_anyaddr(my_host) ||
-                                my_host->ip_equals(my_host, found_my_host)) &&
-                               (other_host->is_anyaddr(other_host) ||
-                                other_host->ip_equals(other_host, found_other_host)) &&
-                               found_my_id->matches(found_my_id, my_id) &&
-                               found_other_id->matches(found_other_id, other_id) &&
-                               streq(peer_cfg->get_name(peer_cfg),
-                                         entry->ike_sa->get_name(entry->ike_sa)))
-                       {
-                               /* looks good, we take this one */
-                               DBG2(DBG_MGR, "found an existing IKE_SA for %H[%D]...%H[%D]",
-                                        my_host, my_id, other_host, other_id);
-                               entry->checked_out = TRUE;
-                               ike_sa = entry->ike_sa;
-                               break;
-                       }
+               current_cfg = entry->ike_sa->get_peer_cfg(entry->ike_sa);
+               if (current_cfg && current_cfg->equals(current_cfg, peer_cfg))
+               {
+                       DBG2(DBG_MGR, "found an existing IKE_SA with a '%s' config",
+                                current_cfg->get_name(current_cfg));
+                       entry->checked_out = TRUE;
+                       ike_sa = entry->ike_sa;
+                       break;
                }
-               enumerator->destroy(enumerator);
        }
-       DESTROY_IF(my_host);
-       DESTROY_IF(other_host);
+       enumerator->destroy(enumerator);
        
        if (!ike_sa)
        {       /* no IKE_SA using such a config, hand out a new */
@@ -1326,20 +1283,12 @@ static void checkin(private_ike_sa_manager_t *this, ike_sa_t *ike_sa)
        
        /* apply identities for duplicate test (only as responder) */
        if (!entry->ike_sa_id->is_initiator(entry->ike_sa_id) &&
-                       (!entry->my_id || !entry->other_id))
+               ike_sa->get_state(ike_sa) == IKE_ESTABLISHED &&
+               entry->my_id == NULL && entry->other_id == NULL)
        {
-               if (!entry->my_id && my_id->get_type(my_id) != ID_ANY)
-               {
-                       entry->my_id = my_id->clone(my_id);
-               }
-               if (!entry->other_id && other_id->get_type(other_id) != ID_ANY)
-               {
-                       entry->other_id = other_id->clone(other_id);
-               }
-               if (entry->my_id && entry->other_id)
-               {
-                       put_connected_peers(this, entry);
-               }
+               entry->my_id = my_id->clone(my_id);
+               entry->other_id = other_id->clone(other_id);
+               put_connected_peers(this, entry);
        }
        
        unlock_single_segment(this, segment);
index 7258de5a590d934929161751e66a2f1fe1dfbd31..88fb7984ec18603543d99c3cd5b0968409348d2e 100644 (file)
@@ -650,6 +650,7 @@ static status_t build_response(private_task_manager_t *this, message_t *request)
 static status_t process_request(private_task_manager_t *this,
                                                                message_t *message)
 {
+       enumerator_t *enumerator;
        iterator_t *iterator;
        task_t *task = NULL;
        payload_t *payload;
@@ -688,8 +689,8 @@ static status_t process_request(private_task_manager_t *this,
                case CREATE_CHILD_SA:
                {       /* 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))
+                       enumerator = message->create_payload_enumerator(message);
+                       while (enumerator->enumerate(enumerator, &payload))
                        {
                                switch (payload->get_type(payload))
                                {
@@ -716,7 +717,7 @@ static status_t process_request(private_task_manager_t *this,
                                                break;
                                }
                        }
-                       iterator->destroy(iterator);
+                       enumerator->destroy(enumerator);
                
                        if (ts_found)
                        {
@@ -739,8 +740,8 @@ static status_t process_request(private_task_manager_t *this,
                }
                case INFORMATIONAL:
                {
-                       iterator = message->get_payload_iterator(message);
-                       while (iterator->iterate(iterator, (void**)&payload))
+                       enumerator = message->create_payload_enumerator(message);
+                       while (enumerator->enumerate(enumerator, &payload))
                        {
                                switch (payload->get_type(payload))
                                {
@@ -793,7 +794,7 @@ static status_t process_request(private_task_manager_t *this,
                                        break;
                                }
                        }
-                       iterator->destroy(iterator);
+                       enumerator->destroy(enumerator);
                        
                        if (task == NULL)
                        {
index b3bb1840d763236772b72b32f57aaa72f7202779..1e1624dca83dd0820a2816ed9457109d11df3f6a 100644 (file)
@@ -570,7 +570,7 @@ static void handle_notify(private_child_create_t *this, notify_payload_t *notify
  */
 static void process_payloads(private_child_create_t *this, message_t *message)
 {
-       iterator_t *iterator;
+       enumerator_t *enumerator;
        payload_t *payload;
        sa_payload_t *sa_payload;
        ke_payload_t *ke_payload;
@@ -579,8 +579,8 @@ static void process_payloads(private_child_create_t *this, message_t *message)
        /* defaults to TUNNEL mode */
        this->mode = MODE_TUNNEL;
 
-       iterator = message->get_payload_iterator(message);
-       while (iterator->iterate(iterator, (void**)&payload))
+       enumerator = message->create_payload_enumerator(message);
+       while (enumerator->enumerate(enumerator, &payload))
        {
                switch (payload->get_type(payload))
                {
@@ -616,7 +616,7 @@ static void process_payloads(private_child_create_t *this, message_t *message)
                                break;
                }
        }
-       iterator->destroy(iterator);
+       enumerator->destroy(enumerator);
 }
 
 /**
@@ -643,9 +643,9 @@ static status_t build_i(private_child_create_t *this, message_t *message)
                        }
                        break;
                case IKE_AUTH:
-                       if (!message->get_payload(message, ID_INITIATOR))
+                       if (message->get_message_id(message) != 1)
                        {
-                               /* send only in the first request, not in subsequent EAP  */
+                               /* send only in the first request, not in subsequent rounds */
                                return NEED_MORE;
                        }
                        break;
@@ -737,8 +737,6 @@ static status_t build_i(private_child_create_t *this, message_t *message)
  */
 static status_t process_r(private_child_create_t *this, message_t *message)
 {
-       peer_cfg_t *peer_cfg;
-
        switch (message->get_exchange_type(message))
        {
                case IKE_SA_INIT:
@@ -747,42 +745,17 @@ static status_t process_r(private_child_create_t *this, message_t *message)
                        get_nonce(message, &this->other_nonce);
                        break;
                case IKE_AUTH:
-                       if (message->get_payload(message, ID_INITIATOR) == NULL)
+                       if (message->get_message_id(message) != 1)
                        {
-                               /* wait until extensible authentication completed, if used */
+                               /* only handle first AUTH payload, not additional rounds */
                                return NEED_MORE;
                        }
                default:
                        break;
        }
-
+       
        process_payloads(this, message);
        
-       if (this->tsi == NULL || this->tsr == NULL)
-       {
-               DBG1(DBG_IKE, "TS payload missing in message");
-               return NEED_MORE;
-       }
-                 
-       peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
-       if (peer_cfg)
-       {
-               host_t *me, *other;
-               
-               me = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
-               if (me == NULL)
-               {
-                       me = this->ike_sa->get_my_host(this->ike_sa);
-               }
-               other = this->ike_sa->get_virtual_ip(this->ike_sa, FALSE);
-               if (other == NULL)
-               {
-                       other = this->ike_sa->get_other_host(this->ike_sa);
-               }
-               
-               this->config = peer_cfg->select_child_cfg(peer_cfg, this->tsr,
-                                                                                                 this->tsi, me, other);
-       }
        return NEED_MORE;
 }
 
@@ -810,10 +783,11 @@ static void handle_child_sa_failure(private_child_create_t *this,
  */
 static status_t build_r(private_child_create_t *this, message_t *message)
 {
+       peer_cfg_t *peer_cfg;
        payload_t *payload;
-       iterator_t *iterator;
+       enumerator_t *enumerator;
        bool no_dh = TRUE;
-
+       
        switch (message->get_exchange_type(message))
        {
                case IKE_SA_INIT:
@@ -828,9 +802,8 @@ static status_t build_r(private_child_create_t *this, message_t *message)
                        no_dh = FALSE;
                        break;
                case IKE_AUTH:
-                       if (message->get_payload(message, EXTENSIBLE_AUTHENTICATION))
-                       {
-                               /* wait until extensible authentication completed, if used */
+                       if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED)
+                       {       /* wait until all authentication round completed */
                                return NEED_MORE;
                        }
                default:
@@ -844,6 +817,25 @@ static status_t build_r(private_child_create_t *this, message_t *message)
                return SUCCESS;
        }
        
+       peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
+       if (peer_cfg && this->tsi && this->tsr)
+       {
+               host_t *me, *other;
+               
+               me = this->ike_sa->get_virtual_ip(this->ike_sa, TRUE);
+               if (me == NULL)
+               {
+                       me = this->ike_sa->get_my_host(this->ike_sa);
+               }
+               other = this->ike_sa->get_virtual_ip(this->ike_sa, FALSE);
+               if (other == NULL)
+               {
+                       other = this->ike_sa->get_other_host(this->ike_sa);
+               }
+               this->config = peer_cfg->select_child_cfg(peer_cfg, this->tsr,
+                                                                                                 this->tsi, me, other);
+       }
+       
        if (this->config == NULL)
        {
                DBG1(DBG_IKE, "traffic selectors %#R=== %#R inacceptable",
@@ -854,8 +846,8 @@ static status_t build_r(private_child_create_t *this, message_t *message)
        }
        
        /* check if ike_config_t included non-critical error notifies */
-       iterator = message->get_payload_iterator(message);
-       while (iterator->iterate(iterator, (void**)&payload))
+       enumerator = message->create_payload_enumerator(message);
+       while (enumerator->enumerate(enumerator, &payload))
        {
                if (payload->get_type(payload) == NOTIFY)
                {
@@ -868,7 +860,7 @@ static status_t build_r(private_child_create_t *this, message_t *message)
                                {
                                        DBG1(DBG_IKE,"configuration payload negotation "
                                                 "failed, no CHILD_SA built");
-                                       iterator->destroy(iterator);
+                                       enumerator->destroy(enumerator);
                                        handle_child_sa_failure(this, message);
                                        return SUCCESS;
                                }
@@ -877,7 +869,7 @@ static status_t build_r(private_child_create_t *this, message_t *message)
                        }
                }
        }
-       iterator->destroy(iterator);
+       enumerator->destroy(enumerator);
        
        this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa),
                        this->ike_sa->get_other_host(this->ike_sa), this->config, this->reqid,
@@ -938,7 +930,7 @@ static status_t build_r(private_child_create_t *this, message_t *message)
  */
 static status_t process_i(private_child_create_t *this, message_t *message)
 {
-       iterator_t *iterator;
+       enumerator_t *enumerator;
        payload_t *payload;
        bool no_dh = TRUE;
 
@@ -951,9 +943,8 @@ static status_t process_i(private_child_create_t *this, message_t *message)
                        no_dh = FALSE;
                        break;
                case IKE_AUTH:
-                       if (message->get_payload(message, EXTENSIBLE_AUTHENTICATION))
-                       {
-                               /* wait until extensible authentication completed, if used */
+                       if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED)
+                       {       /* wait until all authentication round completed */
                                return NEED_MORE;
                        }
                default:
@@ -961,8 +952,8 @@ static status_t process_i(private_child_create_t *this, message_t *message)
        }
 
        /* check for erronous notifies */
-       iterator = message->get_payload_iterator(message);
-       while (iterator->iterate(iterator, (void**)&payload))
+       enumerator = message->create_payload_enumerator(message);
+       while (enumerator->enumerate(enumerator, &payload))
        {
                if (payload->get_type(payload) == NOTIFY)
                {
@@ -982,7 +973,7 @@ static status_t process_i(private_child_create_t *this, message_t *message)
                                {
                                        DBG1(DBG_IKE, "received %N notify, no CHILD_SA built",
                                                 notify_type_names, type);
-                                       iterator->destroy(iterator);
+                                       enumerator->destroy(enumerator);
                                        handle_child_sa_failure(this, message);
                                        /* an error in CHILD_SA creation is not critical */
                                        return SUCCESS;
@@ -1000,7 +991,7 @@ static status_t process_i(private_child_create_t *this, message_t *message)
                                                 bad_group, diffie_hellman_group_names, this->dh_group);
                                        
                                        this->public.task.migrate(&this->public.task, this->ike_sa);
-                                       iterator->destroy(iterator);
+                                       enumerator->destroy(enumerator);
                                        return NEED_MORE;
                                }
                                default:
@@ -1008,7 +999,7 @@ static status_t process_i(private_child_create_t *this, message_t *message)
                        }
                }
        }
-       iterator->destroy(iterator);
+       enumerator->destroy(enumerator);
        
        process_payloads(this, message);
        
index 36d260f9905ecf90257dcaec44fe64e6db6a670f..26e9695f90a810476a2d191a922cf097b9f6f880 100644 (file)
@@ -114,15 +114,16 @@ static void build_payloads(private_child_delete_t *this, message_t *message)
  */
 static void process_payloads(private_child_delete_t *this, message_t *message)
 {
-       iterator_t *payloads, *spis;
+       enumerator_t *payloads;
+       iterator_t *spis;
        payload_t *payload;
        delete_payload_t *delete_payload;
        u_int32_t *spi;
        protocol_id_t protocol;
        child_sa_t *child_sa;
        
-       payloads = message->get_payload_iterator(message);
-       while (payloads->iterate(payloads, (void**)&payload))
+       payloads = message->create_payload_enumerator(message);
+       while (payloads->enumerate(payloads, &payload))
        {
                if (payload->get_type(payload) == DELETE)
                {
index 127280efc3ad474f782c23036654f4a6fb250b1a..44a22575ce71eaa655d398eaf8a4194417366b5c 100644 (file)
@@ -103,11 +103,11 @@ static status_t process_i_delete(private_child_rekey_t *this, message_t *message
  */
 static void find_child(private_child_rekey_t *this, message_t *message)
 {
-       iterator_t *iterator;
+       enumerator_t *enumerator;
        payload_t *payload;
        
-       iterator = message->get_payload_iterator(message);
-       while (iterator->iterate(iterator, (void**)&payload))
+       enumerator = message->create_payload_enumerator(message);
+       while (enumerator->enumerate(enumerator, &payload))
        {
                notify_payload_t *notify;
                u_int32_t spi;
@@ -131,7 +131,7 @@ static void find_child(private_child_rekey_t *this, message_t *message)
                break;
                        
        }
-       iterator->destroy(iterator);
+       enumerator->destroy(enumerator);
 }
 
 /**
@@ -220,12 +220,12 @@ static status_t process_i(private_child_rekey_t *this, message_t *message)
        protocol_id_t protocol;
        u_int32_t spi;
        child_sa_t *to_delete;
-       iterator_t *iterator;
+       enumerator_t *enumerator;
        payload_t *payload;
        
        /* handle NO_ADDITIONAL_SAS notify */
-       iterator = message->get_payload_iterator(message);
-       while (iterator->iterate(iterator, (void**)&payload))
+       enumerator = message->create_payload_enumerator(message);
+       while (enumerator->enumerate(enumerator, &payload))
        {
                if (payload->get_type(payload) == NOTIFY)
                {
@@ -239,12 +239,12 @@ static status_t process_i(private_child_rekey_t *this, message_t *message)
                                charon->processor->queue_job(charon->processor,
                                                (job_t*)rekey_ike_sa_job_create(
                                                                        this->ike_sa->get_id(this->ike_sa), TRUE));
-                               iterator->destroy(iterator);
+                               enumerator->destroy(enumerator);
                                return SUCCESS;
                        }
                }
        }
-       iterator->destroy(iterator);
+       enumerator->destroy(enumerator);
        
        if (this->child_create->task.process(&this->child_create->task, message) == NEED_MORE)
        {
index ad16217149838c330c74abdf46379c5a71f71fc2..d594e3baa3d17bb0102fcb0ed040f968791a3ef9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005-2007 Martin Willi
+ * Copyright (C) 2005-2009 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
  *
 #include <string.h>
 
 #include <daemon.h>
-#include <crypto/diffie_hellman.h>
 #include <encoding/payloads/id_payload.h>
 #include <encoding/payloads/auth_payload.h>
 #include <encoding/payloads/eap_payload.h>
 #include <encoding/payloads/nonce_payload.h>
 #include <sa/authenticators/eap_authenticator.h>
 
-
 typedef struct private_ike_auth_t private_ike_auth_t;
 
 /**
@@ -72,220 +70,65 @@ struct private_ike_auth_t {
        packet_t *other_packet;
        
        /**
-        * EAP authenticator when using EAP
+        * completed authentication configs initiated by us (auth_cfg_t)
         */
-       eap_authenticator_t *eap_auth;
+       linked_list_t *my_cfgs;
        
        /**
-        * EAP payload received and ready to process
+        * completed authentication configs initiated by other (auth_cfg_t)
         */
-       eap_payload_t *eap_payload;
+       linked_list_t *other_cfgs;;
        
        /**
-        * has the peer been authenticated successfully?
+        * currently active authenticator, to authenticate us
         */
-       bool peer_authenticated;
-};
-
-/**
- * get the authentication class of a config
- */
-auth_class_t get_auth_class(peer_cfg_t *config)
-{
-       auth_class_t *class;
-       auth_info_t *auth_info;
-       
-       auth_info = config->get_auth(config);
-       if (auth_info->get_item(auth_info, AUTHN_AUTH_CLASS, (void**)&class))
-       {
-               return *class;
-       }
-       /* fallback to pubkey authentication */
-       return AUTH_CLASS_PUBKEY;
-}
-
-/**
- * get the eap type/vendor
- */
-static eap_type_t get_eap_type(peer_cfg_t *config, u_int32_t *vendor)
-{
-       auth_info_t *auth_info;
-       u_int *ptr;
-       
-       *vendor = 0;
-       auth_info = config->get_auth(config);
-       if (auth_info->get_item(auth_info, AUTHN_EAP_VENDOR, (void**)&ptr))
-       {
-               *vendor = *ptr;
-       }
-       if (auth_info->get_item(auth_info, AUTHN_EAP_TYPE, (void**)&ptr))
-       {
-               return *ptr;
-       }
-       return EAP_NAK;
-}
-
-/**
- * build the AUTH payload
- */
-static status_t build_auth(private_ike_auth_t *this, message_t *message)
-{
-       authenticator_t *auth;
-       auth_payload_t *auth_payload;
-       peer_cfg_t *config;
-       status_t status;
+       authenticator_t *my_auth;
        
-       /* create own authenticator and add auth payload */
-       config = this->ike_sa->get_peer_cfg(this->ike_sa);
-       if (!config)
-       {
-               DBG1(DBG_IKE, "unable to authenticate, no peer config found");
-               return FAILED;
-       }
-       
-       auth = authenticator_create_from_class(this->ike_sa, get_auth_class(config));
-       if (auth == NULL)
-       {
-               DBG1(DBG_IKE, "configured authentication class %N not supported",
-                        auth_class_names, get_auth_class(config));
-               return FAILED;
-       }
-       
-       status = auth->build(auth, this->my_packet->get_data(this->my_packet),
-                                                this->other_nonce, &auth_payload);
-       auth->destroy(auth);
-       if (status != SUCCESS)
-       {
-               DBG1(DBG_IKE, "generating authentication data failed");
-               return FAILED;
-       }
-       message->add_payload(message, (payload_t*)auth_payload);
-       return SUCCESS;
-}
-
-/**
- * build ID payload(s)
- */
-static status_t build_id(private_ike_auth_t *this, message_t *message)
-{
-       identification_t *me, *other;
-       id_payload_t *id;
-       peer_cfg_t *config;
-       
-       me = this->ike_sa->get_my_id(this->ike_sa);
-       other = this->ike_sa->get_other_id(this->ike_sa);
-       config = this->ike_sa->get_peer_cfg(this->ike_sa);
-       
-       if (me->contains_wildcards(me))
-       {
-               me = config->get_my_id(config);
-               if (me->contains_wildcards(me))
-               {
-                       DBG1(DBG_IKE, "negotiation of own ID failed");
-                       return FAILED;
-               }
-               this->ike_sa->set_my_id(this->ike_sa, me->clone(me));
-       }
+       /**
+        * currently active authenticator, to authenticate peer
+        */
+       authenticator_t *other_auth;
        
-       id = id_payload_create_from_identification(this->initiator ? ID_INITIATOR : ID_RESPONDER, me);
-       message->add_payload(message, (payload_t*)id);
+       /**
+        * peer_cfg candidates, ordered by priority
+        */
+       linked_list_t *candidates;
        
-       /* as initiator, include other ID if it does not contain wildcards */
-       if (this->initiator && !other->contains_wildcards(other))
-       {
-               id = id_payload_create_from_identification(ID_RESPONDER, other);
-               message->add_payload(message, (payload_t*)id);
-       }
-       return SUCCESS;
-}
-
-/**
- * process AUTH payload
- */
-static status_t process_auth(private_ike_auth_t *this, message_t *message)
-{
-       auth_payload_t *auth_payload;
-       authenticator_t *auth;
-       auth_method_t auth_method;
-       status_t status;
+       /**
+        * selected peer config (might change when using multiple authentications)
+        */
+       peer_cfg_t *peer_cfg;
        
-       auth_payload = (auth_payload_t*)message->get_payload(message, AUTHENTICATION);
+       /**
+        * have we planned an(other) authentication exchange?
+        */
+       bool do_another_auth;
        
-       if (auth_payload == NULL)
-       {
-               /* AUTH payload is missing, client wants to use EAP authentication */
-               return NOT_FOUND;
-       }
+       /**
+        * has the peer announced another authentication exchange?
+        */
+       bool expect_another_auth;
        
-       auth_method = auth_payload->get_auth_method(auth_payload);
-       auth = authenticator_create_from_method(this->ike_sa,
-                                                                       auth_payload->get_auth_method(auth_payload));
-       if (auth == NULL)
-       {
-               DBG1(DBG_IKE, "authentication method %N used by '%D' not supported",
-                       auth_method_names, auth_method,
-                       this->ike_sa->get_other_id(this->ike_sa));
-               return NOT_SUPPORTED;
-       }
-       status = auth->verify(auth, this->other_packet->get_data(this->other_packet), 
-                                                 this->my_nonce, auth_payload);
-       auth->destroy(auth);
-       if (status != SUCCESS)
-       {
-               DBG0(DBG_IKE, "authentication of '%D' with %N failed",
-                        this->ike_sa->get_other_id(this->ike_sa), 
-                        auth_method_names, auth_method);       
-               return FAILED;
-       }
-       return SUCCESS;
-}
+       /**
+        * should we send a AUTHENTICATION_FAILED notify?
+        */
+       bool authentication_failed;
+};
 
 /**
- * process ID payload(s)
+ * check if multiple authentication extension is enabled, configuration-wise
  */
-static status_t process_id(private_ike_auth_t *this, message_t *message)
+static bool multiple_auth_enabled()
 {
-       identification_t *id, *req;
-       id_payload_t *idr, *idi;
-
-       idi = (id_payload_t*)message->get_payload(message, ID_INITIATOR);
-       idr = (id_payload_t*)message->get_payload(message, ID_RESPONDER);
-
-       if ((this->initiator && idr == NULL) || (!this->initiator && idi == NULL))
-       {
-               DBG1(DBG_IKE, "ID payload missing in message");
-               return FAILED;
-       }
-       
-       if (this->initiator)
-       {
-               id = idr->get_identification(idr);
-               req = this->ike_sa->get_other_id(this->ike_sa);
-               if (!id->matches(id, req))
-               {
-                       DBG0(DBG_IKE, "peer ID '%D' unacceptable, '%D' required", id, req);
-                       id->destroy(id);
-                       return FAILED;
-               }
-               this->ike_sa->set_other_id(this->ike_sa, id);
-       }
-       else
-       {
-               id = idi->get_identification(idi);
-               this->ike_sa->set_other_id(this->ike_sa, id);
-               if (idr)
-               {
-                       id = idr->get_identification(idr);
-                       this->ike_sa->set_my_id(this->ike_sa, id);
-               }
-       }
-       return SUCCESS;
+       return lib->settings->get_bool(lib->settings,
+                                                                  "charon.multiple_authentication", TRUE);
 }
 
 /**
  * collect the needed information in the IKE_SA_INIT exchange from our message
  */
-static status_t collect_my_init_data(private_ike_auth_t *this, message_t *message)
+static status_t collect_my_init_data(private_ike_auth_t *this,
+                                                                        message_t *message)
 {
        nonce_payload_t *nonce;
        
@@ -297,7 +140,7 @@ static status_t collect_my_init_data(private_ike_auth_t *this, message_t *messag
        }
        this->my_nonce = nonce->get_nonce(nonce);
        
-       /* pre-generate the message, so we can store it for us */
+       /* pre-generate the message, keep a copy */
        if (this->ike_sa->generate_message(this->ike_sa, message,
                                                                           &this->my_packet) != SUCCESS)
        {
@@ -309,7 +152,8 @@ static status_t collect_my_init_data(private_ike_auth_t *this, message_t *messag
 /**
  * collect the needed information in the IKE_SA_INIT exchange from others message
  */
-static status_t collect_other_init_data(private_ike_auth_t *this, message_t *message)
+static status_t collect_other_init_data(private_ike_auth_t *this,
+                                                                               message_t *message)
 {
        /* we collect the needed information in the IKE_SA_INIT exchange */
        nonce_payload_t *nonce;
@@ -322,184 +166,186 @@ static status_t collect_other_init_data(private_ike_auth_t *this, message_t *mes
        }
        this->other_nonce = nonce->get_nonce(nonce);
        
-       /* pre-generate the message, so we can store it for us */
+       /* keep a copy of the received packet */
        this->other_packet = message->get_packet(message);
        return NEED_MORE; 
 }
 
-
 /**
- * Implementation of task_t.build to create AUTH payload from EAP data
+ * Get the next authentication configuration
  */
-static status_t build_auth_eap(private_ike_auth_t *this, message_t *message)
+static auth_cfg_t *get_auth_cfg(private_ike_auth_t *this, bool local)
 {
-       authenticator_t *auth;
-       auth_payload_t *auth_payload;
+       enumerator_t *e1, *e2;
+       auth_cfg_t *c1, *c2, *next = NULL;
        
-       if (!this->initiator && !this->peer_authenticated)
+       /* find an available config not already done */
+       e1 = this->peer_cfg->create_auth_cfg_enumerator(this->peer_cfg, local);
+       while (e1->enumerate(e1, &c1))
        {
-               message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
-               return FAILED;
-       }
-       
-       auth = (authenticator_t*)this->eap_auth;
-       if (auth->build(auth, this->my_packet->get_data(this->my_packet),
-               this->other_nonce, &auth_payload) != SUCCESS)
-       {
-               DBG1(DBG_IKE, "generating authentication data failed");
-               if (!this->initiator)
+               bool found = FALSE;
+               
+               if (local)
                {
-                       message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
+                       e2 = this->my_cfgs->create_enumerator(this->my_cfgs);
+               }
+               else
+               {
+                       e2 = this->other_cfgs->create_enumerator(this->other_cfgs);
+               }
+               while (e2->enumerate(e2, &c2))
+               {
+                       if (c2->complies(c2, c1, FALSE))
+                       {
+                               found = TRUE;
+                               break;
+                       }
+               }
+               e2->destroy(e2);
+               if (!found)
+               {
+                       next = c1;
+                       break;
                }
-               return FAILED;
-       }
-       message->add_payload(message, (payload_t*)auth_payload);
-       if (!this->initiator)
-       {
-               this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
-               DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%D]...%H[%D]",
-                        this->ike_sa->get_name(this->ike_sa),
-                        this->ike_sa->get_unique_id(this->ike_sa),
-                        this->ike_sa->get_my_host(this->ike_sa),
-                        this->ike_sa->get_my_id(this->ike_sa), 
-                        this->ike_sa->get_other_host(this->ike_sa),
-                        this->ike_sa->get_other_id(this->ike_sa));
-               return SUCCESS;
        }
-       return NEED_MORE;
+       e1->destroy(e1);
+       return next;
 }
 
 /**
- * Implementation of task_t.process to verify AUTH payload after EAP
+ * Check if we have should initiate another authentication round
  */
-static status_t process_auth_eap(private_ike_auth_t *this, message_t *message)
+static bool do_another_auth(private_ike_auth_t *this)
 {
-       auth_payload_t *auth_payload;
-       authenticator_t *auth;
-
-       auth_payload = (auth_payload_t*)message->get_payload(message, AUTHENTICATION);
-       this->peer_authenticated = FALSE;
+       bool do_another = FALSE;
+       enumerator_t *done, *todo;
+       auth_cfg_t *done_cfg, *todo_cfg;
        
-       if (auth_payload)
+       if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MULTIPLE_AUTH))
        {
-               auth = (authenticator_t*)this->eap_auth;
-               if (auth->verify(auth, this->other_packet->get_data(this->other_packet), 
-                                               this->my_nonce, auth_payload) == SUCCESS)
-               {
-                       this->peer_authenticated = TRUE;
-               }
+               return FALSE;
        }
-
-       if (!this->peer_authenticated)
+       
+       done = this->my_cfgs->create_enumerator(this->my_cfgs);
+       todo = this->peer_cfg->create_auth_cfg_enumerator(this->peer_cfg, TRUE);
+       while (todo->enumerate(todo, &todo_cfg))
        {
-               DBG0(DBG_IKE, "authentication of '%D' with %N failed",
-                        this->ike_sa->get_other_id(this->ike_sa), 
-                        auth_class_names, AUTH_CLASS_EAP);
-               if (this->initiator)
+               if (!done->enumerate(done, &done_cfg))
                {
-                       return FAILED;
+                       done_cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
+               }
+               if (!done_cfg->complies(done_cfg, todo_cfg, FALSE))
+               {
+                       do_another = TRUE;
+                       break;
                }
-               return NEED_MORE;
-       }
-       if (this->initiator)
-       {
-               this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
-               DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%D]...%H[%D]",
-                        this->ike_sa->get_name(this->ike_sa),
-                        this->ike_sa->get_unique_id(this->ike_sa),
-                        this->ike_sa->get_my_host(this->ike_sa),
-                        this->ike_sa->get_my_id(this->ike_sa), 
-                        this->ike_sa->get_other_host(this->ike_sa),
-                        this->ike_sa->get_other_id(this->ike_sa));
-               return SUCCESS;
        }
-       return NEED_MORE;
+       done->destroy(done);
+       todo->destroy(todo);
+       return do_another;
 }
 
 /**
- * Implementation of task_t.process for EAP exchanges
+ * Get peer configuration candidates from backends
  */
-static status_t process_eap_i(private_ike_auth_t *this, message_t *message)
+static bool load_cfg_candidates(private_ike_auth_t *this)
 {
-       eap_payload_t *eap;
-
-       eap = (eap_payload_t*)message->get_payload(message, EXTENSIBLE_AUTHENTICATION);
-       if (eap == NULL)
-       {       
-               DBG1(DBG_IKE, "EAP payload missing");
-               return FAILED;
+       enumerator_t *enumerator;
+       peer_cfg_t *peer_cfg;
+       host_t *me, *other;
+       identification_t *my_id, *other_id;
+       
+       me = this->ike_sa->get_my_host(this->ike_sa);
+       other = this->ike_sa->get_other_host(this->ike_sa);
+       my_id = this->ike_sa->get_my_id(this->ike_sa);
+       other_id = this->ike_sa->get_other_id(this->ike_sa);
+       
+       enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
+                                                                                                       me, other, my_id, other_id);
+       while (enumerator->enumerate(enumerator, &peer_cfg))
+       {
+               peer_cfg->get_ref(peer_cfg);
+               if (this->peer_cfg == NULL)
+               {       /* best match */
+                       this->peer_cfg = peer_cfg;
+                       this->ike_sa->set_peer_cfg(this->ike_sa, peer_cfg);
+               }
+               else
+               {
+                       this->candidates->insert_last(this->candidates, peer_cfg);
+               }
        }
-       switch (this->eap_auth->process(this->eap_auth, eap, &eap))
+       enumerator->destroy(enumerator);
+       if (this->peer_cfg)
        {
-               case NEED_MORE:
-                       this->eap_payload = eap;
-                       return NEED_MORE;
-               case SUCCESS:
-                       /* EAP exchange completed, now create and process AUTH */
-                       this->eap_payload = NULL;
-                       this->public.task.build = (status_t(*)(task_t*,message_t*))build_auth_eap;
-                       this->public.task.process = (status_t(*)(task_t*,message_t*))process_auth_eap;
-                       return NEED_MORE;
-               default:
-                       this->eap_payload = NULL;
-                       DBG0(DBG_IKE, "failed to authenticate against '%D' using EAP",
-                               this->ike_sa->get_other_id(this->ike_sa));
-                       return FAILED;
+               DBG1(DBG_CFG, "selected peer config '%s'",
+                        this->peer_cfg->get_name(this->peer_cfg));
+               return TRUE;
        }
+       DBG1(DBG_CFG, "no matching peer config found");
+       return FALSE;
 }
 
 /**
- * Implementation of task_t.process for EAP exchanges
- */
-static status_t process_eap_r(private_ike_auth_t *this, message_t *message)
-{
-       this->eap_payload = (eap_payload_t*)message->get_payload(message, 
-                                                                                                       EXTENSIBLE_AUTHENTICATION);
-       return NEED_MORE;
-}
-
-/**
- * Implementation of task_t.build for EAP exchanges
- */
-static status_t build_eap_i(private_ike_auth_t *this, message_t *message)
-{
-       message->add_payload(message, (payload_t*)this->eap_payload);
-       return NEED_MORE;
-}
-
-/**
- * Implementation of task_t.build for EAP exchanges
+ * update the current peer candidate if necessary, using candidates
  */
-static status_t build_eap_r(private_ike_auth_t *this, message_t *message)
+static bool update_cfg_candidates(private_ike_auth_t *this, bool strict)
 {
-       status_t status = NEED_MORE;
-       eap_payload_t *eap;
-               
-       if (this->eap_payload == NULL)
-       {
-               DBG1(DBG_IKE, "EAP payload missing");
-               return FAILED;
-       }
-       
-       switch (this->eap_auth->process(this->eap_auth, this->eap_payload, &eap))
+       do
        {
-               case NEED_MORE:
+               if (this->peer_cfg)
+               {
+                       bool complies = TRUE;
+                       enumerator_t *e1, *e2, *tmp;
+                       auth_cfg_t *c1, *c2;
                        
-                       break;
-               case SUCCESS:
-                       /* EAP exchange completed, now create and process AUTH */
-                       this->public.task.build = (status_t(*)(task_t*,message_t*))build_auth_eap;
-                       this->public.task.process = (status_t(*)(task_t*,message_t*))process_auth_eap;
-                       break;
-               default:
-                       DBG0(DBG_IKE, "authentication of '%D' with %N failed",
-                                this->ike_sa->get_other_id(this->ike_sa),
-                                auth_class_names, AUTH_CLASS_EAP);
-                       status = FAILED;
-                       break;
+                       e1 = this->other_cfgs->create_enumerator(this->other_cfgs);
+                       e2 = this->peer_cfg->create_auth_cfg_enumerator(this->peer_cfg, FALSE);
+                       
+                       if (strict)
+                       {       /* swap lists in strict mode: all configured rounds must be
+                                * fulfilled. If !strict, we check only the rounds done so far. */
+                               tmp = e1;
+                               e1 = e2;
+                               e2 = tmp;
+                       }
+                       while (e1->enumerate(e1, &c1))
+                       {
+                               /* check if done authentications comply to configured ones */
+                               if ((!e2->enumerate(e2, &c2)) ||
+                                       (!strict && !c1->complies(c1, c2, TRUE)) ||
+                                       (strict && !c2->complies(c2, c1, TRUE)))
+                               {
+                                       complies = FALSE;
+                                       break;
+                               }
+                       }
+                       e1->destroy(e1);
+                       e2->destroy(e2);
+                       if (complies)
+                       {
+                               break;
+                       }
+                       DBG1(DBG_CFG, "selected peer config '%s' inacceptable",
+                                this->peer_cfg->get_name(this->peer_cfg));
+                       this->peer_cfg->destroy(this->peer_cfg);
+               }
+               if (this->candidates->remove_first(this->candidates,
+                                                                               (void**)&this->peer_cfg) != SUCCESS)
+               {
+                       DBG1(DBG_CFG, "no alternative config found");
+                       this->peer_cfg = NULL;
+               }
+               else
+               {
+                       DBG1(DBG_CFG, "switching to peer config '%s'",
+                                this->peer_cfg->get_name(this->peer_cfg));
+                       this->ike_sa->set_peer_cfg(this->ike_sa, this->peer_cfg);
+               }
        }
-       message->add_payload(message, (payload_t*)eap);
-       return status;
+       while (this->peer_cfg);
+       
+       return this->peer_cfg != NULL;
 }
 
 /**
@@ -507,31 +353,103 @@ static status_t build_eap_r(private_ike_auth_t *this, message_t *message)
  */
 static status_t build_i(private_ike_auth_t *this, message_t *message)
 {
-       peer_cfg_t *config;
-
+       auth_cfg_t *cfg;
+       
        if (message->get_exchange_type(message) == IKE_SA_INIT)
        {
                return collect_my_init_data(this, message);
        }
-               
-       if (build_id(this, message) != SUCCESS)
+       
+       if (this->peer_cfg == NULL)
        {
-               return FAILED;
+               this->peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
+               this->peer_cfg->get_ref(this->peer_cfg);
        }
        
-       config = this->ike_sa->get_peer_cfg(this->ike_sa);
-       if (get_auth_class(config) == AUTH_CLASS_EAP)
-       {
-               this->eap_auth = eap_authenticator_create(this->ike_sa);
+       if (message->get_message_id(message) == 1 &&
+               this->ike_sa->supports_extension(this->ike_sa, EXT_MULTIPLE_AUTH))
+       {       /* in the first IKE_AUTH, indicate support for multiple authentication */
+               message->add_notify(message, FALSE, MULTIPLE_AUTH_SUPPORTED, chunk_empty);
        }
-       else
+       
+       if (!this->do_another_auth && !this->my_auth)
+       {       /* we have done our rounds */
+               return NEED_MORE;
+       }
+       
+       /* check if an authenticator is in progress */
+       if (this->my_auth == NULL)
        {
-               if (build_auth(this, message) != SUCCESS)
+               identification_t *id;
+               id_payload_t *id_payload;
+               
+               /* clean up authentication config from a previous round */
+               cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
+               cfg->purge(cfg, TRUE);
+               
+               /* add (optional) IDr */
+               cfg = get_auth_cfg(this, FALSE);
+               if (cfg)
+               {
+                       id = cfg->get(cfg, AUTH_RULE_IDENTITY);
+                       if (id && !id->contains_wildcards(id))
+                       {
+                               this->ike_sa->set_other_id(this->ike_sa, id->clone(id));
+                               id_payload = id_payload_create_from_identification(
+                                                                                                                       ID_RESPONDER, id);
+                               message->add_payload(message, (payload_t*)id_payload);
+                       }
+               }
+               /* add IDi */
+               cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
+               cfg->merge(cfg, get_auth_cfg(this, TRUE), TRUE);
+               id = cfg->get(cfg, AUTH_RULE_IDENTITY);
+               if (!id)
+               {
+                       DBG1(DBG_CFG, "configuration misses IDi");
+                       return FAILED;
+               }
+               this->ike_sa->set_my_id(this->ike_sa, id->clone(id));
+               id_payload = id_payload_create_from_identification(ID_INITIATOR, id);
+               message->add_payload(message, (payload_t*)id_payload);
+               
+               /* build authentication data */
+               this->my_auth = authenticator_create_builder(
+                                                                       this->ike_sa, cfg, this->other_nonce, 
+                                                                       this->my_packet->get_data(this->my_packet));
+               if (!this->my_auth)
                {
                        return FAILED;
                }
        }
-
+       switch (this->my_auth->build(this->my_auth, message))
+       {
+               case SUCCESS:
+                       /* authentication step complete, reset authenticator */
+                       cfg = auth_cfg_create();
+                       cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, TRUE), TRUE);
+                       this->my_cfgs->insert_last(this->my_cfgs, cfg);
+                       this->my_auth->destroy(this->my_auth);
+                       this->my_auth = NULL;
+                       break;
+               case NEED_MORE:
+                       break;
+               default:
+                       return FAILED;
+       }
+       
+       /* check for additional authentication rounds */
+       if (do_another_auth(this))
+       {
+               if (message->get_payload(message, AUTHENTICATION))
+               {
+                       message->add_notify(message, FALSE, ANOTHER_AUTH_FOLLOWS, chunk_empty);
+               }
+       }
+       else
+       {
+               this->do_another_auth = FALSE;
+       }
        return NEED_MORE;
 }
 
@@ -540,45 +458,135 @@ static status_t build_i(private_ike_auth_t *this, message_t *message)
  */
 static status_t process_r(private_ike_auth_t *this, message_t *message)
 {
-       peer_cfg_t *config;
+       auth_cfg_t *cfg, *cand;
+       id_payload_t *id_payload;
+       identification_t *id;
        
        if (message->get_exchange_type(message) == IKE_SA_INIT)
        {
                return collect_other_init_data(this, message);
        }
        
-       if (process_id(this, message) != SUCCESS)
+       if (this->my_auth == NULL && this->do_another_auth)
+       {
+               /* handle (optional) IDr payload, apply proposed identity */
+               id_payload = (id_payload_t*)message->get_payload(message, ID_RESPONDER);
+               if (id_payload)
+               {
+                       id = id_payload->get_identification(id_payload);
+               }
+               else
+               {
+                       id = identification_create_from_encoding(ID_ANY, chunk_empty);
+               }
+               this->ike_sa->set_my_id(this->ike_sa, id);
+       }
+       
+       if (!this->expect_another_auth)
        {
                return NEED_MORE;
        }
+       if (message->get_notify(message, MULTIPLE_AUTH_SUPPORTED))
+       {
+               this->ike_sa->enable_extension(this->ike_sa, EXT_MULTIPLE_AUTH);
+       }
        
-       switch (process_auth(this, message))
+       if (this->other_auth == NULL)
+       {
+               /* handle IDi payload */
+               id_payload = (id_payload_t*)message->get_payload(message, ID_INITIATOR);
+               if (!id_payload)
+               {
+                       DBG1(DBG_IKE, "IDi payload missing");
+                       return FAILED;
+               }
+               id = id_payload->get_identification(id_payload);
+               this->ike_sa->set_other_id(this->ike_sa, id);
+               cfg = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
+               cfg->add(cfg, AUTH_RULE_IDENTITY, id->clone(id));
+               
+               if (this->peer_cfg == NULL)
+               {
+                       if (!load_cfg_candidates(this))
+                       {
+                               this->authentication_failed = TRUE;
+                               return NEED_MORE;
+                       }
+               }
+               if (message->get_payload(message, AUTHENTICATION) == NULL)
+               {       /* before authenticating with EAP, we need a EAP config */
+                       cand = get_auth_cfg(this, FALSE);
+                       while (!cand || (
+                                       (uintptr_t)cand->get(cand, AUTH_RULE_EAP_TYPE) == EAP_NAK &&
+                                       (uintptr_t)cand->get(cand, AUTH_RULE_EAP_VENDOR) == 0))
+                       {       /* peer requested EAP, but current config does not match */
+                               this->peer_cfg->destroy(this->peer_cfg);
+                               this->peer_cfg = NULL;
+                               if (!update_cfg_candidates(this, FALSE))
+                               {
+                                       this->authentication_failed = TRUE;
+                                       return NEED_MORE;
+                               }
+                               cand = get_auth_cfg(this, FALSE);
+                       }
+                       cfg->merge(cfg, cand, TRUE);
+               }
+               
+               /* verify authentication data */
+               this->other_auth = authenticator_create_verifier(
+                                                       this->ike_sa, message, this->my_nonce,
+                                                       this->other_packet->get_data(this->other_packet));
+               if (!this->other_auth)
+               {
+                       this->authentication_failed = TRUE;
+                       return NEED_MORE;
+               }
+       }
+       switch (this->other_auth->process(this->other_auth, message))
        {
                case SUCCESS:
-                       this->peer_authenticated = TRUE;
-                       break;
-               case NOT_FOUND:
-                       /* use EAP if no AUTH payload found */
-                       this->ike_sa->set_condition(this->ike_sa, COND_EAP_AUTHENTICATED, TRUE);
+                       this->other_auth->destroy(this->other_auth);
+                       this->other_auth = NULL;
                        break;
+               case NEED_MORE:
+                       if (message->get_payload(message, AUTHENTICATION))
+                       {       /* AUTH verification successful, but another build() needed */
+                               break;
+                       }
+                       return NEED_MORE;
                default:
+                       this->authentication_failed = TRUE;
                        return NEED_MORE;
        }
-
-       config = charon->backends->get_peer_cfg(charon->backends,
-                                                                       this->ike_sa->get_my_host(this->ike_sa),
-                                                                       this->ike_sa->get_other_host(this->ike_sa),
-                                                                       this->ike_sa->get_my_id(this->ike_sa),
-                                                                       this->ike_sa->get_other_id(this->ike_sa),
-                                                                       this->ike_sa->get_other_auth(this->ike_sa));
-       if (config)
+       
+       /* store authentication information */
+       cfg = auth_cfg_create();
+       cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, FALSE), FALSE);
+       this->other_cfgs->insert_last(this->other_cfgs, cfg);
+       
+       /* another auth round done, invoke authorize hook */
+       if (!charon->bus->authorize(charon->bus, this->other_cfgs, FALSE))
+       {
+               DBG1(DBG_IKE, "round %d authorization hook forbids IKE_SA, cancelling",
+                        this->other_cfgs->get_count(this->other_cfgs));
+               this->authentication_failed = TRUE;
+               return NEED_MORE;
+       }
+       
+       if (!update_cfg_candidates(this, FALSE))
        {
-               this->ike_sa->set_peer_cfg(this->ike_sa, config);
-               config->destroy(config);
+               this->authentication_failed = TRUE;
+               return NEED_MORE;
        }
-       if (!this->peer_authenticated)
-       {       
-               this->eap_auth = eap_authenticator_create(this->ike_sa);
+       
+       if (message->get_notify(message, ANOTHER_AUTH_FOLLOWS) == NULL)
+       {
+               this->expect_another_auth = FALSE;
+               if (!update_cfg_candidates(this, TRUE))
+               {
+                       this->authentication_failed = TRUE;
+                       return NEED_MORE;
+               }
        }
        return NEED_MORE;
 }
@@ -588,52 +596,139 @@ static status_t process_r(private_ike_auth_t *this, message_t *message)
  */
 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;
-
+       auth_cfg_t *cfg;
+       
        if (message->get_exchange_type(message) == IKE_SA_INIT)
        {
+               if (multiple_auth_enabled())
+               {
+                       message->add_notify(message, FALSE, MULTIPLE_AUTH_SUPPORTED,
+                                                               chunk_empty);
+               }
                return collect_my_init_data(this, message);
        }
        
-       if (!this->peer_authenticated && this->eap_auth == NULL)
+       if (this->authentication_failed || this->peer_cfg == NULL)
        {
-               /* peer not authenticated, nor does it want to use EAP */
                message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
                return FAILED;
        }
        
-       config = this->ike_sa->get_peer_cfg(this->ike_sa);
-       if (config == NULL)
+       if (this->my_auth == NULL && this->do_another_auth)
        {
-               DBG1(DBG_IKE, "no matching config found for '%D'...'%D'",
-                        this->ike_sa->get_my_id(this->ike_sa),
-                        this->ike_sa->get_other_id(this->ike_sa));
-               message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
-               return FAILED;
+               identification_t *id, *id_cfg;
+               id_payload_t *id_payload;
+               
+               /* add IDr */
+               cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
+               cfg->purge(cfg, TRUE);
+               cfg->merge(cfg, get_auth_cfg(this, TRUE), TRUE);
+               
+               id_cfg = cfg->get(cfg, AUTH_RULE_IDENTITY);
+               id = this->ike_sa->get_my_id(this->ike_sa);
+               if (id->get_type(id) == ID_ANY)
+               {       /* no IDr received, apply configured ID */
+                       if (!id_cfg || id_cfg->contains_wildcards(id_cfg))
+                       {
+                               DBG1(DBG_CFG, "IDr not configured and negotiation failed");
+                               message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
+                                                                       chunk_empty);
+                               return FAILED;
+                       }
+                       this->ike_sa->set_my_id(this->ike_sa, id_cfg->clone(id_cfg));
+                       id = id_cfg;
+               }
+               else
+               {       /* IDr received, check if it matches configuration */
+                       if (id_cfg && !id->matches(id, id_cfg))
+                       {
+                               DBG1(DBG_CFG, "received IDr %D, but require %D", id, id_cfg);
+                               message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
+                                                                       chunk_empty);
+                               return FAILED;
+                       }
+               }
+               
+               id_payload = id_payload_create_from_identification(ID_RESPONDER, id);
+               message->add_payload(message, (payload_t*)id_payload);
+               
+               /* build authentication data */
+               this->my_auth = authenticator_create_builder(
+                                                               this->ike_sa, cfg, this->other_nonce, 
+                                                               this->my_packet->get_data(this->my_packet));
+               if (!this->my_auth)
+               {
+                       message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
+                       return FAILED;
+               }
        }
        
-       if (build_id(this, message) != SUCCESS ||
-               build_auth(this, message) != SUCCESS)
+       if (this->other_auth)
        {
-               message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
-               return FAILED;
+               switch (this->other_auth->build(this->other_auth, message))
+               {
+                       case SUCCESS:
+                               this->other_auth->destroy(this->other_auth);
+                               this->other_auth = NULL;
+                               break;
+                       case NEED_MORE:
+                               break;
+                       default:
+                               if (!message->get_payload(message, EXTENSIBLE_AUTHENTICATION))
+                               {       /* skip AUTHENTICATION_FAILED if we have EAP_FAILURE */
+                                       message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
+                                                                               chunk_empty);
+                               }
+                               return FAILED;
+               }
        }
-       
-       if (charon->ike_sa_manager->check_uniqueness(charon->ike_sa_manager,
-                                                                                                this->ike_sa))
+       if (this->my_auth)
        {
-               DBG1(DBG_IKE, "cancelling IKE_SA setup due uniqueness policy");
-               message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
-               return FAILED;
+               switch (this->my_auth->build(this->my_auth, message))
+               {
+                       case SUCCESS:
+                               cfg = auth_cfg_create();
+                               cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, TRUE),
+                                                  TRUE);
+                               this->my_cfgs->insert_last(this->my_cfgs, cfg);
+                               this->my_auth->destroy(this->my_auth);
+                               this->my_auth = NULL;
+                               break;
+                       case NEED_MORE:
+                               break;
+                       default:
+                               message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
+                                                                       chunk_empty);
+                               return FAILED;
+               }
        }
        
-       /* use "traditional" authentication if we could authenticate peer */
-       if (this->peer_authenticated)
+       /* check for additional authentication rounds */
+       if (do_another_auth(this))
+       {
+               message->add_notify(message, FALSE, ANOTHER_AUTH_FOLLOWS, chunk_empty);
+       }
+       else
+       {
+               this->do_another_auth = FALSE;
+       }
+       if (!this->do_another_auth && !this->expect_another_auth)
        {
+               if (charon->ike_sa_manager->check_uniqueness(charon->ike_sa_manager,
+                                                                                                        this->ike_sa))
+               {
+                       DBG1(DBG_IKE, "cancelling IKE_SA setup due uniqueness policy");
+                       message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
+                                                               chunk_empty);
+                       return FAILED;
+               }
+               if (!charon->bus->authorize(charon->bus, this->other_cfgs, TRUE))
+               {
+                       DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, cancelling");
+                       message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
+                                                               chunk_empty);
+                       return FAILED;
+               }
                this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
                DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%D]...%H[%D]",
                         this->ike_sa->get_name(this->ike_sa),
@@ -644,21 +739,6 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
                         this->ike_sa->get_other_id(this->ike_sa));
                return SUCCESS;
        }
-       
-       /* initiate EAP authenitcation */
-       eap_type = 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)
-       {
-               DBG1(DBG_IKE, "unable to initiate EAP authentication");
-               return FAILED;
-       }
-       
-       /* switch to EAP methods */
-       this->public.task.build = (status_t(*)(task_t*,message_t*))build_eap_r;
-       this->public.task.process = (status_t(*)(task_t*,message_t*))process_eap_r;
        return NEED_MORE;
 }
 
@@ -667,18 +747,22 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
  */
 static status_t process_i(private_ike_auth_t *this, message_t *message)
 {
-       iterator_t *iterator;
+       enumerator_t *enumerator;
        payload_t *payload;
-       peer_cfg_t *config;
-       auth_info_t *auth;
+       auth_cfg_t *cfg;
        
        if (message->get_exchange_type(message) == IKE_SA_INIT)
        {
+               if (message->get_notify(message, MULTIPLE_AUTH_SUPPORTED) &&
+                       multiple_auth_enabled())
+               {
+                       this->ike_sa->enable_extension(this->ike_sa, EXT_MULTIPLE_AUTH);
+               }
                return collect_other_init_data(this, message);
        }
        
-       iterator = message->get_payload_iterator(message);
-       while (iterator->iterate(iterator, (void**)&payload))
+       enumerator = message->create_payload_enumerator(message);
+       while (enumerator->enumerate(enumerator, &payload))
        {
                if (payload->get_type(payload) == NOTIFY)
                {
@@ -714,7 +798,7 @@ static status_t process_i(private_ike_auth_t *this, message_t *message)
                                        {
                                                DBG1(DBG_IKE, "received %N notify error",
                                                         notify_type_names, type);
-                                               iterator->destroy(iterator);
+                                               enumerator->destroy(enumerator);
                                                return FAILED;  
                                        }
                                        DBG2(DBG_IKE, "received %N notify",
@@ -724,39 +808,115 @@ static status_t process_i(private_ike_auth_t *this, message_t *message)
                        }
                }
        }
-       iterator->destroy(iterator);
+       enumerator->destroy(enumerator);
        
-       if (process_id(this, message) != SUCCESS ||
-               process_auth(this, message) != SUCCESS)
+       if (this->my_auth)
        {
-               return FAILED;
+               switch (this->my_auth->process(this->my_auth, message))
+               {
+                       case SUCCESS:
+                               cfg = auth_cfg_create();
+                               cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, TRUE),
+                                                  TRUE);
+                               this->my_cfgs->insert_last(this->my_cfgs, cfg);
+                               this->my_auth->destroy(this->my_auth);
+                               this->my_auth = NULL;
+                               this->do_another_auth = do_another_auth(this);
+                               break;
+                       case NEED_MORE:
+                               break;
+                       default:
+                               return FAILED;
+               }
        }
        
-       if (this->eap_auth)
+       if (this->expect_another_auth)
        {
-               /* switch to EAP authentication methods */
-               this->public.task.build = (status_t(*)(task_t*,message_t*))build_eap_i;
-               this->public.task.process = (status_t(*)(task_t*,message_t*))process_eap_i;
-               return process_eap_i(this, message);
+               if (this->other_auth == NULL)
+               {
+                       id_payload_t *id_payload;
+                       identification_t *id;
+                       
+                       /* responder is not allowed to do EAP */
+                       if (!message->get_payload(message, AUTHENTICATION))
+                       {
+                               DBG1(DBG_IKE, "AUTH payload missing");
+                               return FAILED;
+                       }
+                       
+                       /* handle IDr payload */
+                       id_payload = (id_payload_t*)message->get_payload(message,
+                                                                                                                        ID_RESPONDER);
+                       if (!id_payload)
+                       {
+                               DBG1(DBG_IKE, "IDr payload missing");
+                               return FAILED;
+                       }
+                       id = id_payload->get_identification(id_payload);
+                       this->ike_sa->set_other_id(this->ike_sa, id);
+                       cfg = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
+                       cfg->add(cfg, AUTH_RULE_IDENTITY, id->clone(id));
+                       
+                       /* verify authentication data */
+                       this->other_auth = authenticator_create_verifier(
+                                                       this->ike_sa, message, this->my_nonce,
+                                                       this->other_packet->get_data(this->other_packet));
+                       if (!this->other_auth)
+                       {
+                               return FAILED;
+                       }
+               }
+               switch (this->other_auth->process(this->other_auth, message))
+               {
+                       case SUCCESS:
+                               break;
+                       case NEED_MORE:
+                               return NEED_MORE;
+                       default:
+                               return FAILED;
+               }
+               /* store authentication information, reset authenticator */
+               cfg = auth_cfg_create();
+               cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, FALSE), FALSE);
+               this->other_cfgs->insert_last(this->other_cfgs, cfg);
+               this->other_auth->destroy(this->other_auth);
+               this->other_auth = NULL;
+               
+               /* another auth round done, invoke authorize hook */
+               if (!charon->bus->authorize(charon->bus, this->other_cfgs, FALSE))
+               {
+                       DBG1(DBG_IKE, "round %d authorization forbids IKE_SA, cancelling",
+                                this->other_cfgs->get_count(this->other_cfgs));
+                       return FAILED;
+               }
        }
        
-       config = this->ike_sa->get_peer_cfg(this->ike_sa);
-       auth = this->ike_sa->get_other_auth(this->ike_sa);
-       if (!auth->complies(auth, config->get_auth(config)))
+       if (message->get_notify(message, ANOTHER_AUTH_FOLLOWS) == NULL)
        {
-               DBG0(DBG_IKE, "authorization of '%D' for config %s failed",
-                       this->ike_sa->get_other_id(this->ike_sa), config->get_name(config));
-               return FAILED;
+               this->expect_another_auth = FALSE;
        }
-       this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
-       DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%D]...%H[%D]",
-                this->ike_sa->get_name(this->ike_sa),
-                this->ike_sa->get_unique_id(this->ike_sa),
-                this->ike_sa->get_my_host(this->ike_sa),
-                this->ike_sa->get_my_id(this->ike_sa),
-                this->ike_sa->get_other_host(this->ike_sa),
-                this->ike_sa->get_other_id(this->ike_sa));
-       return SUCCESS;
+       if (!this->expect_another_auth && !this->do_another_auth && !this->my_auth)
+       {
+               if (!update_cfg_candidates(this, TRUE))
+               {
+                       return FAILED;
+               }
+               if (!charon->bus->authorize(charon->bus, this->other_cfgs, TRUE))
+               {
+                       DBG1(DBG_IKE, "final authorization hook forbids IKE_SA, cancelling");
+                       return FAILED;
+               }
+               this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
+               DBG0(DBG_IKE, "IKE_SA %s[%d] established between %H[%D]...%H[%D]",
+                        this->ike_sa->get_name(this->ike_sa),
+                        this->ike_sa->get_unique_id(this->ike_sa),
+                        this->ike_sa->get_my_host(this->ike_sa),
+                        this->ike_sa->get_my_id(this->ike_sa), 
+                        this->ike_sa->get_other_host(this->ike_sa),
+                        this->ike_sa->get_other_id(this->ike_sa));
+               return SUCCESS;
+       }
+       return NEED_MORE;
 }
 
 /**
@@ -776,28 +936,25 @@ static void migrate(private_ike_auth_t *this, ike_sa_t *ike_sa)
        chunk_free(&this->other_nonce);
        DESTROY_IF(this->my_packet);
        DESTROY_IF(this->other_packet);
-       if (this->eap_auth)
-       {
-               this->eap_auth->authenticator_interface.destroy(
-                                                                       &this->eap_auth->authenticator_interface);
-       }
+       DESTROY_IF(this->peer_cfg);
+       DESTROY_IF(this->my_auth);
+       DESTROY_IF(this->other_auth);
+       this->my_cfgs->destroy_offset(this->my_cfgs, offsetof(auth_cfg_t, destroy));
+       this->other_cfgs->destroy_offset(this->other_cfgs, offsetof(auth_cfg_t, destroy));
+       this->candidates->destroy_offset(this->candidates, offsetof(peer_cfg_t, destroy));
        
        this->my_packet = NULL;
        this->other_packet = NULL;
-       this->peer_authenticated = FALSE;
-       this->eap_auth = NULL;
-       this->eap_payload = NULL;
        this->ike_sa = ike_sa;
-       if (this->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->peer_cfg = NULL;
+       this->my_auth = NULL;
+       this->other_auth = NULL;
+       this->do_another_auth = TRUE;
+       this->expect_another_auth = TRUE;
+       this->authentication_failed = FALSE;
+       this->my_cfgs = linked_list_create();
+       this->other_cfgs = linked_list_create();
+       this->candidates = linked_list_create();
 }
 
 /**
@@ -809,11 +966,12 @@ static void destroy(private_ike_auth_t *this)
        chunk_free(&this->other_nonce);
        DESTROY_IF(this->my_packet);
        DESTROY_IF(this->other_packet);
-       if (this->eap_auth)
-       {
-               this->eap_auth->authenticator_interface.destroy(
-                                                                       &this->eap_auth->authenticator_interface);
-       }
+       DESTROY_IF(this->my_auth);
+       DESTROY_IF(this->other_auth);
+       DESTROY_IF(this->peer_cfg);
+       this->my_cfgs->destroy_offset(this->my_cfgs, offsetof(auth_cfg_t, destroy));
+       this->other_cfgs->destroy_offset(this->other_cfgs, offsetof(auth_cfg_t, destroy));
+       this->candidates->destroy_offset(this->candidates, offsetof(peer_cfg_t, destroy));
        free(this);
 }
 
@@ -823,7 +981,7 @@ static void destroy(private_ike_auth_t *this)
 ike_auth_t *ike_auth_create(ike_sa_t *ike_sa, bool initiator)
 {
        private_ike_auth_t *this = malloc_thing(private_ike_auth_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;
@@ -845,9 +1003,16 @@ ike_auth_t *ike_auth_create(ike_sa_t *ike_sa, bool initiator)
        this->other_nonce = chunk_empty;
        this->my_packet = NULL;
        this->other_packet = NULL;
-       this->peer_authenticated = FALSE;
-       this->eap_auth = NULL;
-       this->eap_payload = NULL;
+       this->peer_cfg = NULL;
+       this->my_cfgs = linked_list_create();
+       this->other_cfgs = linked_list_create();
+       this->candidates = linked_list_create();
+       this->my_auth = NULL;
+       this->other_auth = NULL;
+       this->do_another_auth = TRUE;
+       this->expect_another_auth = TRUE;
+       this->authentication_failed = FALSE;
        
        return &this->public;
 }
+
index 328f11d2c7ed41aae6107ae4ecc2da57f7726c98..a175aa53ae6dee4df1f50fd4462ff741d7997f8a 100644 (file)
@@ -64,12 +64,12 @@ static void add_auth_lifetime(private_ike_auth_lifetime_t *this, message_t *mess
  */
 static void process_payloads(private_ike_auth_lifetime_t *this, message_t *message)
 {
-       iterator_t *iterator;
+       enumerator_t *enumerator;
        payload_t *payload;
        notify_payload_t *notify;
        
-       iterator = message->get_payload_iterator(message);
-       while (iterator->iterate(iterator, (void**)&payload))
+       enumerator = message->create_payload_enumerator(message);
+       while (enumerator->enumerate(enumerator, &payload))
        {
                if (payload->get_type(payload) == NOTIFY)
                {
@@ -88,7 +88,7 @@ static void process_payloads(private_ike_auth_lifetime_t *this, message_t *messa
                        }
                }
        }
-       iterator->destroy(iterator);
+       enumerator->destroy(enumerator);
 }
 
 /**
index 825cf0711f15c00bfc354ffe4a78fe32cdffdb19..da3ee4dce7dc706e66eac61757acd4e549489c0c 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Tobias Brunner
- * Copyright (C) 2006-2008 Martin Willi
+ * Copyright (C) 2006-2009 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -97,71 +97,69 @@ static cert_payload_t *build_cert_payload(private_ike_cert_post_t *this, certifi
        return payload;
 }
 
-/**
- * from ike_auth.c
- */
-auth_class_t get_auth_class(peer_cfg_t *config);
-
 /**
  * add certificates to message
  */
 static void build_certs(private_ike_cert_post_t *this, message_t *message)
 {
        peer_cfg_t *peer_cfg;
+       auth_cfg_t *auth;
        
        peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
-       if (peer_cfg && get_auth_class(peer_cfg) == AUTH_CLASS_PUBKEY)
+       auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
+       if (!peer_cfg ||
+               (uintptr_t)auth->get(auth, AUTH_RULE_AUTH_CLASS) != AUTH_CLASS_PUBKEY)
+       {
+               return;
+       }
+       switch (peer_cfg->get_cert_policy(peer_cfg))
        {
-               switch (peer_cfg->get_cert_policy(peer_cfg))
+               case CERT_NEVER_SEND:
+                       break;
+               case CERT_SEND_IF_ASKED:
+                       if (!this->ike_sa->has_condition(this->ike_sa, COND_CERTREQ_SEEN))
+                       {
+                               break;
+                       }
+                       /* FALL */
+               case CERT_ALWAYS_SEND:
                {
-                       case CERT_NEVER_SEND:
+                       cert_payload_t *payload;
+                       enumerator_t *enumerator;
+                       certificate_t *cert;
+                       auth_rule_t type;
+                       
+                       /* get subject cert first, then issuing certificates */
+                       cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
+                       if (!cert)
+                       {
                                break;
-                       case CERT_SEND_IF_ASKED:
-                               if (!this->ike_sa->has_condition(this->ike_sa, COND_CERTREQ_SEEN))
-                               {
-                                       break;
-                               }
-                               /* FALL */
-                       case CERT_ALWAYS_SEND:
+                       }
+                       payload = build_cert_payload(this, cert);
+                       if (!payload)
                        {
-                               cert_payload_t *payload;
-                               enumerator_t *enumerator;
-                               certificate_t *cert;
-                               auth_info_t *auth;
-                               auth_item_t item;
-                               
-                               auth = this->ike_sa->get_my_auth(this->ike_sa);
-                               /* get subject cert first, then issuing certificates */
-                               if (!auth->get_item(auth, AUTHZ_SUBJECT_CERT, (void**)&cert))
-                               {
-                                       break;
-                               }
-                               payload = build_cert_payload(this, cert);
-                               if (!payload)
-                               {
-                                       break;
-                               }
-                               DBG1(DBG_IKE, "sending end entity cert \"%D\"",
-                                        cert->get_subject(cert));
-                               message->add_payload(message, (payload_t*)payload);
-                               
-                               enumerator = auth->create_item_enumerator(auth);
-                               while (enumerator->enumerate(enumerator, &item, &cert))
+                               break;
+                       }
+                       DBG1(DBG_IKE, "sending end entity cert \"%D\"",
+                                cert->get_subject(cert));
+                       message->add_payload(message, (payload_t*)payload);
+                       
+                       enumerator = auth->create_enumerator(auth);
+                       while (enumerator->enumerate(enumerator, &type, &cert))
+                       {
+                               if (type == AUTH_RULE_IM_CERT)
                                {
-                                       if (item == AUTHZ_IM_CERT)
+                                       payload = cert_payload_create_from_cert(cert);
+                                       if (payload)
                                        {
-                                               payload = cert_payload_create_from_cert(cert);
-                                               if (payload)
-                                               {
-                                                       DBG1(DBG_IKE, "sending issuer cert \"%D\"",
-                                                                cert->get_subject(cert));
-                                                       message->add_payload(message, (payload_t*)payload);
-                                               }
+                                               DBG1(DBG_IKE, "sending issuer cert \"%D\"",
+                                                        cert->get_subject(cert));
+                                               message->add_payload(message, (payload_t*)payload);
                                        }
                                }
-                               enumerator->destroy(enumerator);
-                       }       
-               }
+                       }
+                       enumerator->destroy(enumerator);
+               }       
        }
 }
 
@@ -170,12 +168,11 @@ static void build_certs(private_ike_cert_post_t *this, message_t *message)
  */
 static status_t build_i(private_ike_cert_post_t *this, message_t *message)
 {
-       if (message->get_exchange_type(message) == IKE_SA_INIT)
-       {
-               return NEED_MORE;
+       if (message->get_payload(message, AUTHENTICATION))
+       {       /* CERT payloads are sended along AUTH payloads */
+               build_certs(this, message);
        }
-       build_certs(this, message);
-       return SUCCESS;
+       return NEED_MORE;
 }
 
 /**
@@ -191,11 +188,14 @@ static status_t process_r(private_ike_cert_post_t *this, message_t *message)
  */
 static status_t build_r(private_ike_cert_post_t *this, message_t *message)
 {
-       if (message->get_exchange_type(message) == IKE_SA_INIT)
-       {
+       if (message->get_payload(message, AUTHENTICATION))
+       {       /* CERT payloads are sended along AUTH payloads */
+               build_certs(this, message);
+       }
+       if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED)
+       {       /* stay alive, we might have additional rounds with certs */
                return NEED_MORE;
        }
-       build_certs(this, message);
        return SUCCESS;
 }
 
@@ -204,8 +204,8 @@ static status_t build_r(private_ike_cert_post_t *this, message_t *message)
  */
 static status_t process_i(private_ike_cert_post_t *this, message_t *message)
 {
-       if (message->get_exchange_type(message) == IKE_SA_INIT)
-       {
+       if (this->ike_sa->get_state(this->ike_sa) != IKE_ESTABLISHED)
+       {       /* stay alive, we might have additional rounds with CERTS */
                return NEED_MORE;
        }
        return SUCCESS;
index 79bc4f6e084e1ee66616295b4bd589988d70c996..0ec7004c2e1d142b8f5590f0563561ddb5177f14 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Tobias Brunner
- * Copyright (C) 2006-2007 Martin Willi
+ * Copyright (C) 2006-2009 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -48,9 +48,9 @@ struct private_ike_cert_pre_t {
        bool initiator;
        
        /**
-        * Did we send a HTTP_CERT_LOOKUP_SUPPORTED Notify?
+        * Do we accept HTTP certificate lookup requests
         */
-       bool http_cert_lookup_supported_sent;
+       bool do_http_lookup;
 };
 
 /**
@@ -58,23 +58,22 @@ struct private_ike_cert_pre_t {
  */
 static void process_certreqs(private_ike_cert_pre_t *this, message_t *message)
 {
-       iterator_t *iterator;
+       enumerator_t *enumerator;
        payload_t *payload;
-       auth_info_t *auth;
-       bool ca_found = FALSE;
+       auth_cfg_t *auth;
        
-       auth = this->ike_sa->get_my_auth(this->ike_sa);
+       auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
        
-       iterator = message->get_payload_iterator(message);
-       while (iterator->iterate(iterator, (void**)&payload))
+       enumerator = message->create_payload_enumerator(message);
+       while (enumerator->enumerate(enumerator, &payload))
        {
                switch(payload->get_type(payload))
                {
                        case CERTIFICATE_REQUEST:
                        {
                                certreq_payload_t *certreq = (certreq_payload_t*)payload;
-                               chunk_t keyid;
                                enumerator_t *enumerator;
+                               chunk_t keyid;
                                
                                this->ike_sa->set_condition(this->ike_sa, COND_CERTREQ_SEEN, TRUE);
                                
@@ -98,15 +97,12 @@ static void process_certreqs(private_ike_cert_pre_t *this, message_t *message)
                                        {
                                                DBG1(DBG_IKE, "received cert request for \"%D\"",
                                                         cert->get_subject(cert));
-                                               auth->add_item(auth, AUTHN_CA_CERT, cert);
-                                               cert->destroy(cert);
-                                               ca_found = TRUE;
+                                               auth->add(auth, AUTH_RULE_CA_CERT, cert);
                                        }
                                        else
                                        {
                                                DBG1(DBG_IKE, "received cert request for unknown ca "
                                                                          "with keyid %D", id);
-                                               auth->add_item(auth, AUTHN_CA_CERT_KEYID, id);
                                        }
                                        id->destroy(id);
                                }
@@ -129,7 +125,7 @@ static void process_certreqs(private_ike_cert_pre_t *this, message_t *message)
                                break;
                }
        }
-       iterator->destroy(iterator);
+       enumerator->destroy(enumerator);
 }
 
 /**
@@ -140,6 +136,7 @@ static void process_certreqs(private_ike_cert_pre_t *this, message_t *message)
 static certificate_t *try_get_cert(cert_payload_t *cert_payload)
 {
        certificate_t *cert = NULL;
+       
        switch (cert_payload->get_cert_encoding(cert_payload))
        {
                case ENC_X509_SIGNATURE:
@@ -158,7 +155,7 @@ static certificate_t *try_get_cert(cert_payload_t *cert_payload)
                        }
                        id = identification_create_from_encoding(ID_CERT_DER_SHA1, hash);
                        cert = charon->credentials->get_cert(charon->credentials, 
-                                                                       CERT_X509, KEY_ANY, id, FALSE);
+                                                                                                CERT_X509, KEY_ANY, id, FALSE);
                        id->destroy(id);
                        break;
                }
@@ -175,78 +172,81 @@ static certificate_t *try_get_cert(cert_payload_t *cert_payload)
  */
 static void process_certs(private_ike_cert_pre_t *this, message_t *message)
 {
-       iterator_t *iterator;
+       enumerator_t *enumerator;
        payload_t *payload;
-       auth_info_t *auth;
+       auth_cfg_t *auth;
        bool first = TRUE;
        
-       auth = this->ike_sa->get_other_auth(this->ike_sa);
+       auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
        
-       iterator = message->get_payload_iterator(message);
-       while (iterator->iterate(iterator, (void**)&payload))
+       enumerator = message->create_payload_enumerator(message);
+       while (enumerator->enumerate(enumerator, &payload))
        {
                if (payload->get_type(payload) == CERTIFICATE)
                {
-                       cert_payload_t *cert_payload = (cert_payload_t*)payload;
-                       cert_encoding_t type = cert_payload->get_cert_encoding(cert_payload);
-                       switch (type)
+                       cert_payload_t *cert_payload;
+                       cert_encoding_t encoding;
+                       certificate_t *cert;
+                       char *url;
+                       
+                       cert_payload = (cert_payload_t*)payload;
+                       encoding = cert_payload->get_cert_encoding(cert_payload);
+                       
+                       switch (encoding)
                        {
-                               case ENC_X509_SIGNATURE:
                                case ENC_X509_HASH_AND_URL:
                                {
-                                       if (type == ENC_X509_HASH_AND_URL &&
-                                               !this->http_cert_lookup_supported_sent)
+                                       if (!this->do_http_lookup)
                                        {
                                                DBG1(DBG_IKE, "received hash-and-url encoded cert, but"
                                                                " we don't accept them, ignore");
                                                break;
                                        }
-                                       
-                                       certificate_t *cert = try_get_cert(cert_payload);
-                                       
+                                       /* FALL */
+                               }
+                               case ENC_X509_SIGNATURE:
+                               {
+                                       cert = try_get_cert(cert_payload);
                                        if (cert)
                                        {
-                                               /* we've got a certificate from the payload or the cache */ 
                                                if (first)
-                                               {       /* the first certificate MUST be an end entity one */
+                                               {       /* the first is an end entity certificate */
                                                        DBG1(DBG_IKE, "received end entity cert \"%D\"",
                                                                 cert->get_subject(cert));
-                                                       auth->add_item(auth, AUTHN_SUBJECT_CERT, cert);
+                                                       auth->add(auth, AUTH_HELPER_SUBJECT_CERT, cert);
                                                        first = FALSE;
                                                }
                                                else
                                                {
                                                        DBG1(DBG_IKE, "received issuer cert \"%D\"",
                                                                 cert->get_subject(cert));
-                                                       auth->add_item(auth, AUTHN_IM_CERT, cert);
+                                                       auth->add(auth, AUTH_HELPER_IM_CERT, cert);
                                                }
-                                               cert->destroy(cert);
                                        }
-                                       else if (type == ENC_X509_HASH_AND_URL)
+                                       else if (encoding == ENC_X509_HASH_AND_URL)
                                        {
-                                               /* we received a "Hash and URL" encoded certificate that
-                                                * we haven't fetched yet, we store the URL and fetch
-                                                * it later */
-                                               char *url = cert_payload->get_url(cert_payload);
+                                               /* we fetch the certificate not yet, but only if
+                                                * it is really needed during authentication */
+                                               url = cert_payload->get_url(cert_payload);
                                                if (!url)
                                                {
-                                                       DBG1(DBG_IKE, "received invalid hash-and-url encoded"
-                                                                       " cert, ignore");
+                                                       DBG1(DBG_IKE, "received invalid hash-and-url "
+                                                                "encoded cert, ignore");
                                                        break;
                                                }
-                                               
+                                               url = strdup(url);
                                                if (first)
-                                               {       /* the first certificate MUST be an end entity one */
+                                               {       /* first URL is for an end entity certificate */
                                                        DBG1(DBG_IKE, "received hash-and-url for end"
-                                                                       " entity cert \"%s\"", url);
-                                                       auth->add_item(auth, AUTHN_SUBJECT_HASH_URL, url);
+                                                                " entity cert \"%s\"", url);
+                                                       auth->add(auth, AUTH_HELPER_SUBJECT_HASH_URL, url);
                                                        first = FALSE;
                                                }
                                                else
                                                {
                                                        DBG1(DBG_IKE, "received hash-and-url for issuer"
                                                                        " cert \"%s\"", url);
-                                                       auth->add_item(auth, AUTHN_IM_HASH_URL, url);
+                                                       auth->add(auth, AUTH_HELPER_IM_HASH_URL, url);
                                                }
                                        }
                                        break;
@@ -264,31 +264,23 @@ static void process_certs(private_ike_cert_pre_t *this, message_t *message)
                                case ENC_OCSP_CONTENT:
                                default:
                                        DBG1(DBG_ENC, "certificate encoding %N not supported",
-                                                cert_encoding_names, cert_payload->get_cert_encoding(cert_payload));
+                                                cert_encoding_names, encoding);
                        }
                }
        }
-       iterator->destroy(iterator);
+       enumerator->destroy(enumerator);
 }
 
 /**
- * add a certificate request to the message, building request payload if required.
+ * add the keyid of a certificate to the certificate request payload
  */
-static void add_certreq_payload(message_t *message, certreq_payload_t **reqp, 
-                                                               certificate_t *cert)
+static void add_certreq(certreq_payload_t **req, certificate_t *cert)
 {
-       public_key_t *public;
-       certreq_payload_t *req;
-
-       public = cert->get_public_key(cert);
-       if (!public)
-       {
-               return;
-       }
        switch (cert->get_type(cert))
        {
                case CERT_X509:
                {
+                       public_key_t *public;
                        identification_t *keyid;
                        x509_t *x509 = (x509_t*)cert;
                        
@@ -296,14 +288,18 @@ static void add_certreq_payload(message_t *message, certreq_payload_t **reqp,
                        {       /* no CA cert, skip */
                                break;
                        }
-                       if (*reqp == NULL)
+                       public = cert->get_public_key(cert);
+                       if (!public)
+                       {
+                               break;
+                       }
+                       if (*req == NULL)
                        {
-                               *reqp = certreq_payload_create_type(CERT_X509);
-                               message->add_payload(message, (payload_t*)*reqp);
+                               *req = certreq_payload_create_type(CERT_X509);
                        }
-                       req = *reqp;
                        keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
-                       req->add_keyid(req, keyid->get_encoding(keyid));
+                       (*req)->add_keyid(*req, keyid->get_encoding(keyid));
+                       public->destroy(public);
                        DBG1(DBG_IKE, "sending cert request for \"%D\"",
                                 cert->get_subject(cert));
                        break;
@@ -311,7 +307,30 @@ static void add_certreq_payload(message_t *message, certreq_payload_t **reqp,
                default:
                        break;
        }
-       public->destroy(public);
+}
+
+/**
+ * add a auth_cfg's CA certificates to the certificate request
+ */
+static void add_certreqs(certreq_payload_t **req, auth_cfg_t *auth)
+{
+       enumerator_t *enumerator;
+       auth_rule_t type;
+       void *value;
+       
+       enumerator = auth->create_enumerator(auth);
+       while (enumerator->enumerate(enumerator, &type, &value))
+       {
+               switch (type)
+               {
+                       case AUTH_RULE_CA_CERT:
+                               add_certreq(req, (certificate_t*)value);
+                               break;
+                       default:
+                               break;
+               }
+       }
+       enumerator->destroy(enumerator);
 }
 
 /**
@@ -319,75 +338,53 @@ static void add_certreq_payload(message_t *message, certreq_payload_t **reqp,
  */
 static void build_certreqs(private_ike_cert_pre_t *this, message_t *message)
 {
+       enumerator_t *enumerator;
        ike_cfg_t *ike_cfg;
        peer_cfg_t *peer_cfg;
-       enumerator_t *enumerator;
        certificate_t *cert;
-       bool restricted = FALSE;
-       certreq_payload_t *x509_req = NULL;
+       auth_cfg_t *auth;
+       certreq_payload_t *req = NULL;
        
        ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
        if (!ike_cfg->send_certreq(ike_cfg))
        {
                return;
        }
-
+       
        /* check if we require a specific CA for that peer */
        peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
        if (peer_cfg)
        {
-               void *ptr;
-               identification_t *id;
-               auth_item_t item;
-               auth_info_t *auth = peer_cfg->get_auth(peer_cfg);
-               enumerator_t *auth_enumerator = auth->create_item_enumerator(auth);
-
-               while (auth_enumerator->enumerate(auth_enumerator, &item, &ptr))
+               enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, FALSE);
+               while (enumerator->enumerate(enumerator, &auth))
                {
-                       switch (item)
-                       {
-                               case AUTHZ_CA_CERT:
-                                       cert = (certificate_t *)ptr;
-                                       add_certreq_payload(message, &x509_req, cert);
-                                       restricted = TRUE;
-                                       break;
-                               case AUTHZ_CA_CERT_NAME:
-                                       id = (identification_t *)ptr;
-                                       enumerator = charon->credentials->create_cert_enumerator(
-                                                       charon->credentials, CERT_ANY, KEY_ANY, id, TRUE);
-                                       while (enumerator->enumerate(enumerator, &cert, TRUE))
-                                       {
-                                               add_certreq_payload(message, &x509_req, cert);
-                                               restricted = TRUE;
-                                       }
-                                       enumerator->destroy(enumerator);
-                                       break;
-                               default:
-                                       break;
-                       }
+                       add_certreqs(&req, auth);
                }
-               auth_enumerator->destroy(auth_enumerator);
+               enumerator->destroy(enumerator);
        }
-               
-       if (!restricted)
+       
+       if (!req)
        {
-               /* otherwise include all trusted CA certificates */
+               /* otherwise add all trusted CA certificates */
                enumerator = charon->credentials->create_cert_enumerator(
                                                        charon->credentials, CERT_ANY, KEY_ANY, NULL, TRUE);
-               while (enumerator->enumerate(enumerator, &cert, TRUE))
+               while (enumerator->enumerate(enumerator, &cert))
                {
-                       add_certreq_payload(message, &x509_req, cert);
+                       add_certreq(&req, cert);
                }
                enumerator->destroy(enumerator);
        }
        
-       /* if we've added at least one certreq, we notify our peer that we support
-        * "Hash and URL" for the requested certificates */
-       if (lib->settings->get_bool(lib->settings, "charon.hash_and_url", FALSE) &&
-               message->get_payload(message, CERTIFICATE_REQUEST))
+       if (req)
        {
-               message->add_notify(message, FALSE, HTTP_CERT_LOOKUP_SUPPORTED, chunk_empty);
-               this->http_cert_lookup_supported_sent = TRUE;
+               message->add_payload(message, (payload_t*)req);
+               
+               if (lib->settings->get_bool(lib->settings, "charon.hash_and_url", FALSE))
+               {
+                       message->add_notify(message, FALSE, HTTP_CERT_LOOKUP_SUPPORTED,
+                                                               chunk_empty);
+                       this->do_http_lookup = TRUE;
+               }
        }
 }
 
@@ -396,11 +393,10 @@ static void build_certreqs(private_ike_cert_pre_t *this, message_t *message)
  */
 static status_t build_i(private_ike_cert_pre_t *this, message_t *message)
 {      
-       if (message->get_exchange_type(message) == IKE_SA_INIT)
-       {
-               return NEED_MORE;
+       if (message->get_message_id(message) == 1)
+       {       /* initiator sends CERTREQs in first IKE_AUTH */
+               build_certreqs(this, message);
        }
-       build_certreqs(this, message);
        return NEED_MORE;
 }
 
@@ -408,13 +404,12 @@ static status_t build_i(private_ike_cert_pre_t *this, message_t *message)
  * Implementation of task_t.process for responder
  */
 static status_t process_r(private_ike_cert_pre_t *this, message_t *message)
-{      
-       if (message->get_exchange_type(message) == IKE_SA_INIT)
-       {
-               return NEED_MORE;
+{
+       if (message->get_exchange_type(message) != IKE_SA_INIT)
+       {       /* handle certreqs/certs in any IKE_AUTH, just in case */
+               process_certreqs(this, message);
+               process_certs(this, message);
        }
-       process_certreqs(this, message);
-       process_certs(this, message);
        return NEED_MORE;
 }
 
@@ -426,9 +421,12 @@ static status_t build_r(private_ike_cert_pre_t *this, message_t *message)
        if (message->get_exchange_type(message) == IKE_SA_INIT)
        {
                build_certreqs(this, message);
-               return NEED_MORE;
        }
-       return SUCCESS;
+       if (this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
+       {
+               return SUCCESS;
+       }
+       return NEED_MORE;
 }
 
 /**
@@ -439,10 +437,38 @@ static status_t process_i(private_ike_cert_pre_t *this, message_t *message)
        if (message->get_exchange_type(message) == IKE_SA_INIT)
        {
                process_certreqs(this, message);
-               return NEED_MORE;
        }
        process_certs(this, message);
-       return SUCCESS;
+       
+       /* as ike_auth is not processed yet, we don't know if authentication
+        * is complete (and we can return SUCCESS). Therefore we check for
+        * an AUTH payload without a ANOTHER_AUTH_FOLLOWS notify. */
+       if (message->get_payload(message, AUTHENTICATION))
+       {
+               enumerator_t *enumerator;
+               payload_t *payload;
+               notify_payload_t *notify;
+               bool done = TRUE;
+               
+               enumerator = message->create_payload_enumerator(message);
+               while (enumerator->enumerate(enumerator, &payload))
+               {
+                       if (payload->get_type(payload) == NOTIFY)
+                       {
+                               notify = (notify_payload_t*)payload;
+                               if (notify->get_notify_type(notify) == ANOTHER_AUTH_FOLLOWS)
+                               {
+                                       done = FALSE;
+                               }
+                       }
+               }
+               enumerator->destroy(enumerator);
+               if (done)
+               {
+                       return SUCCESS;
+               }
+       }
+       return NEED_MORE;
 }
 
 /**
@@ -493,7 +519,7 @@ ike_cert_pre_t *ike_cert_pre_create(ike_sa_t *ike_sa, bool initiator)
        
        this->ike_sa = ike_sa;
        this->initiator = initiator;
-       this->http_cert_lookup_supported_sent = FALSE;
+       this->do_http_lookup = FALSE;
        
        return &this->public;
 }
index 04c9e57b8cbc958c47517aa3cacd524da6cec954..cb769f9b457ad8c0bce7a9f76b981bab62545064 100644 (file)
@@ -260,11 +260,12 @@ static void process_attribute(private_ike_config_t *this,
  */
 static void process_payloads(private_ike_config_t *this, message_t *message)
 {
-       iterator_t *iterator, *attributes;
+       enumerator_t *enumerator;
+       iterator_t *attributes;
        payload_t *payload;
        
-       iterator = message->get_payload_iterator(message);
-       while (iterator->iterate(iterator, (void**)&payload))
+       enumerator = message->create_payload_enumerator(message);
+       while (enumerator->enumerate(enumerator, &payload))
        {
                if (payload->get_type(payload) == CONFIGURATION)
                {
@@ -290,7 +291,7 @@ static void process_payloads(private_ike_config_t *this, message_t *message)
                        }
                }
        }
-       iterator->destroy(iterator);
+       enumerator->destroy(enumerator);
 }
 
 /**
@@ -298,9 +299,8 @@ static void process_payloads(private_ike_config_t *this, message_t *message)
  */
 static status_t build_i(private_ike_config_t *this, message_t *message)
 {
-       if (message->get_exchange_type(message) == IKE_AUTH &&
-               message->get_payload(message, ID_INITIATOR))
-       {
+       if (message->get_message_id(message) == 1)
+       {       /* in first IKE_AUTH only */
                peer_cfg_t *config;
                host_t *vip;
                
@@ -327,9 +327,8 @@ static status_t build_i(private_ike_config_t *this, message_t *message)
  */
 static status_t process_r(private_ike_config_t *this, message_t *message)
 {
-       if (message->get_exchange_type(message) == IKE_AUTH &&
-               message->get_payload(message, ID_INITIATOR))
-       {
+       if (message->get_message_id(message) == 1)
+       {       /* in first IKE_AUTH only */
                process_payloads(this, message);
        }
        return NEED_MORE;
@@ -340,9 +339,8 @@ static status_t process_r(private_ike_config_t *this, message_t *message)
  */
 static status_t build_r(private_ike_config_t *this, message_t *message)
 {
-       if (message->get_exchange_type(message) == IKE_AUTH &&
-               message->get_payload(message, EXTENSIBLE_AUTHENTICATION) == NULL)
-       {
+       if (this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
+       {       /* in last IKE_AUTH exchange */
                peer_cfg_t *config = this->ike_sa->get_peer_cfg(this->ike_sa);
                
                if (config && this->virtual_ip)
@@ -355,7 +353,6 @@ static status_t build_r(private_ike_config_t *this, message_t *message)
                                ip = charon->attributes->acquire_address(charon->attributes, 
                                                                        config->get_pool(config),
                                                                        this->ike_sa->get_other_id(this->ike_sa),
-                                                                       this->ike_sa->get_other_auth(this->ike_sa),
                                                                        this->virtual_ip);
                        }
                        if (ip == NULL)
@@ -384,9 +381,8 @@ static status_t build_r(private_ike_config_t *this, message_t *message)
  */
 static status_t process_i(private_ike_config_t *this, message_t *message)
 {
-       if (message->get_exchange_type(message) == IKE_AUTH &&
-               !message->get_payload(message, EXTENSIBLE_AUTHENTICATION))
-       {
+       if (this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
+       {       /* in last IKE_AUTH exchange */
                host_t *ip;
                peer_cfg_t *config;
                
index 4f28909dadb502277efa5431043b06fb407f9c11..2aac7b02e16f9c8721efb0e18f84b7521057702c 100644 (file)
@@ -170,11 +170,11 @@ static void build_payloads(private_ike_init_t *this, message_t *message)
  */
 static void process_payloads(private_ike_init_t *this, message_t *message)
 {
-       iterator_t *iterator;
+       enumerator_t *enumerator;
        payload_t *payload;
-
-       iterator = message->get_payload_iterator(message);
-       while (iterator->iterate(iterator, (void**)&payload))
+       
+       enumerator = message->create_payload_enumerator(message);
+       while (enumerator->enumerate(enumerator, &payload))
        {
                switch (payload->get_type(payload))
                {
@@ -182,7 +182,7 @@ static void process_payloads(private_ike_init_t *this, message_t *message)
                        {
                                sa_payload_t *sa_payload = (sa_payload_t*)payload;
                                linked_list_t *proposal_list;
-       
+                               
                                proposal_list = sa_payload->get_proposals(sa_payload);
                                this->proposal = this->config->select_proposal(this->config,
                                                                                                                           proposal_list);
@@ -225,7 +225,7 @@ static void process_payloads(private_ike_init_t *this, message_t *message)
                                break;
                }
        }
-       iterator->destroy(iterator);
+       enumerator->destroy(enumerator);
 }
 
 /**
@@ -317,12 +317,12 @@ static status_t process_r(private_ike_init_t *this, message_t *message)
 #ifdef ME
        {
                chunk_t connect_id = chunk_empty;
-               iterator_t *iterator;
+               enumerator_t *enumerator;
                payload_t *payload;
-       
+               
                /* check for a ME_CONNECTID notify */
-               iterator = message->get_payload_iterator(message);
-               while (iterator->iterate(iterator, (void**)&payload))
+               enumerator = message->create_payload_enumerator(message);
+               while (enumerator->enumerate(enumerator, &payload))
                {
                        if (payload->get_type(payload) == NOTIFY)
                        {
@@ -353,7 +353,7 @@ static status_t process_r(private_ike_init_t *this, message_t *message)
                                }
                        }
                }
-               iterator->destroy(iterator);
+               enumerator->destroy(enumerator);
                
                if (connect_id.ptr)
                {
@@ -458,12 +458,12 @@ static status_t build_r(private_ike_init_t *this, message_t *message)
  */
 static status_t process_i(private_ike_init_t *this, message_t *message)
 {
-       iterator_t *iterator;
+       enumerator_t *enumerator;
        payload_t *payload;
-
+       
        /* check for erronous notifies */
-       iterator = message->get_payload_iterator(message);
-       while (iterator->iterate(iterator, (void**)&payload))
+       enumerator = message->create_payload_enumerator(message);
+       while (enumerator->enumerate(enumerator, &payload))
        {
                if (payload->get_type(payload) == NOTIFY)
                {
@@ -489,19 +489,22 @@ static status_t process_i(private_ike_init_t *this, message_t *message)
                                                this->ike_sa->reset(this->ike_sa);
                                        }
                                        
-                                       iterator->destroy(iterator);
+                                       enumerator->destroy(enumerator);
                                        return NEED_MORE;
                                }
                                case NAT_DETECTION_SOURCE_IP:
                                case NAT_DETECTION_DESTINATION_IP:
                                        /* skip, handled in ike_natd_t */
                                        break;
+                               case MULTIPLE_AUTH_SUPPORTED:
+                                       /* handled in ike_auth_t */
+                                       break;
                                case COOKIE:
                                {
                                        chunk_free(&this->cookie);
                                        this->cookie = chunk_clone(notify->get_notification_data(notify));
                                        this->ike_sa->reset(this->ike_sa);
-                                       iterator->destroy(iterator);
+                                       enumerator->destroy(enumerator);
                                        DBG2(DBG_IKE, "received %N notify", notify_type_names, type);
                                        return NEED_MORE;
                                }
@@ -511,7 +514,7 @@ static status_t process_i(private_ike_init_t *this, message_t *message)
                                        {
                                                DBG1(DBG_IKE, "received %N notify error",
                                                         notify_type_names, type);
-                                               iterator->destroy(iterator);
+                                               enumerator->destroy(enumerator);
                                                return FAILED;  
                                        }
                                        DBG2(DBG_IKE, "received %N notify",
@@ -521,7 +524,7 @@ static status_t process_i(private_ike_init_t *this, message_t *message)
                        }
                }
        }
-       iterator->destroy(iterator);
+       enumerator->destroy(enumerator);
        
        process_payloads(this, message);
 
index 32c264c43e968a272aaaf4102e854e11c32135c1..07dfb20a516f900d617eb84af36200ef3e264824 100644 (file)
@@ -166,11 +166,11 @@ static void gather_and_add_endpoints(private_ike_me_t *this, message_t *message)
  */
 static void process_payloads(private_ike_me_t *this, message_t *message)
 {
-       iterator_t *iterator;
+       enumerator_t *enumerator;
        payload_t *payload;
-
-       iterator = message->get_payload_iterator(message);
-       while (iterator->iterate(iterator, (void**)&payload))
+       
+       enumerator = message->create_payload_enumerator(message);
+       while (enumerator->enumerate(enumerator, &payload))
        {
                if (payload->get_type(payload) != NOTIFY)
                {
@@ -237,7 +237,7 @@ static void process_payloads(private_ike_me_t *this, message_t *message)
                                break;
                }
        }
-       iterator->destroy(iterator);
+       enumerator->destroy(enumerator);
 }
 
 /**
index b2ef2731fd11a392ff9f7465c8922d58b3342702..29bb6173057fb792dafa6507c9e2627e372cf2bb 100644 (file)
@@ -97,12 +97,12 @@ static void flush_additional_addresses(private_ike_mobike_t *this)
  */
 static void process_payloads(private_ike_mobike_t *this, message_t *message)
 {
-       iterator_t *iterator;
+       enumerator_t *enumerator;
        payload_t *payload;
        bool first = TRUE;
        
-       iterator = message->get_payload_iterator(message);
-       while (iterator->iterate(iterator, (void**)&payload))
+       enumerator = message->create_payload_enumerator(message);
+       while (enumerator->enumerate(enumerator, &payload))
        {
                int family = AF_INET;
                notify_payload_t *notify;
@@ -181,7 +181,7 @@ static void process_payloads(private_ike_mobike_t *this, message_t *message)
                                break;
                }
        }
-       iterator->destroy(iterator);
+       enumerator->destroy(enumerator);
 }
 
 /**
@@ -332,9 +332,8 @@ 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, ID_INITIATOR))
-       {
+       if (message->get_message_id(message) == 1)
+       {       /* only in first IKE_AUTH */
                message->add_notify(message, FALSE, MOBIKE_SUPPORTED, chunk_empty);
                build_address_list(this, message);
        }
@@ -381,9 +380,8 @@ 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, ID_INITIATOR))
-       {
+       if (message->get_message_id(message) == 1)
+       {       /* only first IKE_AUTH */
                process_payloads(this, message);
        }
        else if (message->get_exchange_type(message) == INFORMATIONAL)
index a20af7ce7b57aa93be512fa1803ff9af108a3486..f6bb2d43bbd14285798593bcb4cc3cdba36838b4 100644 (file)
@@ -166,7 +166,7 @@ static notify_payload_t *build_natd_payload(private_ike_natd_t *this,
  */
 static void process_payloads(private_ike_natd_t *this, message_t *message)
 {
-       iterator_t *iterator;
+       enumerator_t *enumerator;
        payload_t *payload;
        notify_payload_t *notify;
        chunk_t hash, src_hash, dst_hash;
@@ -184,8 +184,8 @@ static void process_payloads(private_ike_natd_t *this, message_t *message)
        DBG3(DBG_IKE, "precalculated src_hash %B", &src_hash);
        DBG3(DBG_IKE, "precalculated dst_hash %B", &dst_hash);
        
-       iterator = message->get_payload_iterator(message);
-       while (iterator->iterate(iterator, (void**)&payload))
+       enumerator = message->create_payload_enumerator(message);
+       while (enumerator->enumerate(enumerator, &payload))
        {
                if (payload->get_type(payload) != NOTIFY)
                {
@@ -235,7 +235,7 @@ static void process_payloads(private_ike_natd_t *this, message_t *message)
                                break;
                }
        }
-       iterator->destroy(iterator);
+       enumerator->destroy(enumerator);
        
        chunk_free(&src_hash);
        chunk_free(&dst_hash);
index 6dbad5ff62cdf4ca9af67477008353e34ab6eba1..3c49f329a666da7aece5b77c7b2ab78c700ecf08 100644 (file)
@@ -194,12 +194,12 @@ static status_t build_r(private_ike_rekey_t *this, message_t *message)
 static status_t process_i(private_ike_rekey_t *this, message_t *message)
 {
        ike_sa_id_t *to_delete;
-       iterator_t *iterator;
+       enumerator_t *enumerator;
        payload_t *payload;
-
+       
        /* handle NO_ADDITIONAL_SAS notify */
-       iterator = message->get_payload_iterator(message);
-       while (iterator->iterate(iterator, (void**)&payload))
+       enumerator = message->create_payload_enumerator(message);
+       while (enumerator->enumerate(enumerator, &payload))
        {
                if (payload->get_type(payload) == NOTIFY)
                {
@@ -213,12 +213,12 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message)
                                charon->processor->queue_job(charon->processor,
                                                (job_t*)rekey_ike_sa_job_create(
                                                                        this->ike_sa->get_id(this->ike_sa), TRUE));
-                               iterator->destroy(iterator);
+                               enumerator->destroy(enumerator);
                                return SUCCESS;
                        }
                }
        }
-       iterator->destroy(iterator);
+       enumerator->destroy(enumerator);
        
        switch (this->ike_init->task.process(&this->ike_init->task, message))
        {
index d916fca1714838871a9a99f9063d3ed1dc46b549..190a8c892f223dee17e5ac8c53632cab331e9f5c 100644 (file)
@@ -12,7 +12,11 @@ libfreeswan_a_SOURCES = addrtoa.c addrtot.c addrtypeof.c anyaddr.c atoaddr.c ato
                        satot.c subnetof.c subnettoa.c subnettot.c \
                        subnettypeof.c ttoaddr.c ttodata.c ttoprotoport.c ttosa.c ttosubnet.c ttoul.c \
                        ultoa.c ultot.c version.c
-INCLUDES = -I$(top_srcdir)/src/pluto
+
+INCLUDES = \
+-I$(top_srcdir)/src/libstrongswan \
+-I$(top_srcdir)/src/pluto
+
 dist_man3_MANS = anyaddr.3 atoaddr.3 atoasr.3 atosa.3 atoul.3 goodmask.3 initaddr.3 initsubnet.3 \
                  keyblobtoid.3 optionsfrom.3 portof.3 prng.3 rangetosubnet.3 sameaddr.3 subnetof.3 \
                  ttoaddr.3 ttodata.3 ttosa.3 ttoul.3 version.3
index cf1f7b83281b07599762328e2f25b95403d396e0..56b9893b0478d86a99cd1288d735f35230caa2dd 100644 (file)
@@ -44,7 +44,7 @@
 #endif /* __KERNEL__ */
 
 #include <ipsec_param.h>
-
+#include <utils.h>
 
 /*
  * Grab the kernel version to see if we have NET_21, and therefore 
@@ -147,7 +147,6 @@ struct sa_id {                      /* old v4-only version */
 };
 
 /* misc */
-typedef const char *err_t;     /* error message, or NULL for success */
 struct prng {                  /* pseudo-random-number-generator guts */
        unsigned char sbox[256];
        int i, j;
@@ -446,7 +445,6 @@ bitstomask(
 /* option pickup from files (userland only because of use of FILE) */
 const char *optionsfrom(const char *filename, int *argcp, char ***argvp,
                                                int optind, FILE *errorreport);
-#define ignore_result(call) { if (call); }
 #endif
 
 /*
index 1a83bdf4cdd04bc2965d71737a781ac5d24ba998..3437d5ad89a597d6329d3e9c8cad699bcef590c6 100644 (file)
@@ -31,11 +31,11 @@ ENUM(certificate_type_names, CERT_ANY, CERT_PGP,
        "PGP",
 );
 
-ENUM(cert_validation_names, VALIDATION_GOOD, VALIDATION_SKIPPED,
-       "VALIDATION_GOOD",
-       "VALIDATION_STALE",
-       "VALIDATION_REVOKED",
-       "VALIDATION_FAILED",
-       "VALIDATION_SKIPPED",
+ENUM(cert_validation_names, VALIDATION_GOOD, VALIDATION_REVOKED,
+       "GOOD",
+       "SKIPPED",
+       "STALE",
+       "FAILED",
+       "REVOKED",
 );
 
index 1fb151d9f607b330744962c5f97e09db46e9767d..81fce55087e228e9d8817e4289c1f874de1cc302 100644 (file)
@@ -58,18 +58,20 @@ extern enum_name_t *certificate_type_names;
 
 /**
  * Result of a certificate validation.
+ *
+ * Order of values is relevant, sorted from good to bad.
  */
 enum cert_validation_t {
        /** certificate has been validated successfully */
-       VALIDATION_GOOD,
+       VALIDATION_GOOD = 0,
+       /** validation has been skipped due to missing validation information */
+       VALIDATION_SKIPPED,
        /** certificate has been validated, but check based on stale information */
        VALIDATION_STALE,
-       /** certificate has been revoked */
-       VALIDATION_REVOKED,
        /** validation failed due to a processing error */
        VALIDATION_FAILED,
-       /** validation has been skipped due to missing validation information */
-       VALIDATION_SKIPPED,
+       /** certificate has been revoked */
+       VALIDATION_REVOKED,
 };
 
 /**
index eac3b07a2b8210c4b440bf6946f48c9552f00518..b213c7b47c569379a87d46a382fa2cd40d9aa394 100644 (file)
@@ -35,7 +35,7 @@ struct private_curl_fetcher_t {
         * Public data
         */
        curl_fetcher_t public;
-
+       
        /**
         * CURL handle
         */
@@ -52,15 +52,15 @@ struct private_curl_fetcher_t {
  */
 static size_t append(void *ptr, size_t size, size_t nmemb, chunk_t *data)
 {
-    size_t realsize = size * nmemb;
-
-    data->ptr = (u_char*)realloc(data->ptr, data->len + realsize);
-    if (data->ptr)
-    {
+       size_t realsize = size * nmemb;
+       
+       data->ptr = (u_char*)realloc(data->ptr, data->len + realsize);
+       if (data->ptr)
+       {
                memcpy(&data->ptr[data->len], ptr, realsize);
                data->len += realsize;
-    }
-    return realsize;
+       }
+       return realsize;
 }
 
 /**
@@ -91,7 +91,7 @@ static status_t fetch(private_curl_fetcher_t *this, char *uri, chunk_t *result)
                headers = curl_slist_append(headers, buf);
                curl_easy_setopt(this->curl, CURLOPT_HTTPHEADER, headers);
        }
-
+       
        DBG2("sending http request to '%s'...", uri);
        switch (curl_easy_perform(this->curl))
        {
@@ -102,7 +102,7 @@ static status_t fetch(private_curl_fetcher_t *this, char *uri, chunk_t *result)
                        status = SUCCESS;
                        break;
                default:
-               DBG1("libcurl http request failed: %s", error);
+                       DBG1("libcurl http request failed: %s", error);
                        status = FAILED;
                        break;
        }
@@ -158,7 +158,7 @@ static void destroy(private_curl_fetcher_t *this)
 curl_fetcher_t *curl_fetcher_create()
 {
        private_curl_fetcher_t *this = malloc_thing(private_curl_fetcher_t);
-
+       
        this->curl = curl_easy_init();
        if (this->curl == NULL)
        {
@@ -166,11 +166,11 @@ curl_fetcher_t *curl_fetcher_create()
                return NULL;
        }
        this->request_type = NULL;
-
+       
        this->public.interface.fetch = (status_t(*)(fetcher_t*,char*,chunk_t*))fetch;
        this->public.interface.set_option = (bool(*)(fetcher_t*, fetcher_option_t option, ...))set_option;
        this->public.interface.destroy = (void (*)(fetcher_t*))destroy;
-
+       
        return &this->public;
 }
 
index c487f77753c7fe0b26b852f9171125610bef4c8c..1434b410c69d8ffbcfe46ab43bb94d857cb36fec 100644 (file)
@@ -25,7 +25,7 @@
 
 typedef struct settings_t settings_t;
 
-#include <library.h>
+#include <utils.h>
 #include <utils/enumerator.h>
 
 /**
index 5899194a59fffb077a8950184448509e19e35c81..8af45ec109d7ccd3364dcf24342b2c6ede13503c 100644 (file)
@@ -25,7 +25,7 @@
 
 typedef struct enumerator_t enumerator_t;
 
-#include <library.h>
+#include <utils.h>
 
 /**
  * Enumerate is simpler, but more flexible than iterator.
index 9497f35695b7aab176e5e248fbbba6acd7f99e44..213642e9af7d82f2903413b34e4b31bba98e5ff2 100644 (file)
@@ -208,34 +208,22 @@ static void update_chunk(chunk_t *ch, int n)
  * Remove any malicious characters from a chunk. We are very restrictive, but
  * whe use these strings only to present it to the user.
  */
-static chunk_t sanitize_chunk(chunk_t chunk)
+static bool sanitize_chunk(chunk_t chunk, chunk_t *clone)
 {
        char *pos;
-       chunk_t clone = chunk_clone(chunk);
+       bool all_printable = TRUE;
        
-       for (pos = clone.ptr; pos < (char*)(clone.ptr + clone.len); pos++)
+       *clone = chunk_clone(chunk);
+       
+       for (pos = clone->ptr; pos < (char*)(clone->ptr + clone->len); pos++)
        {
-               switch (*pos)
+               if (!isprint(*pos))
                {
-                       case '\0':
-                       case ' ':
-                       case '*':
-                       case '-':
-                       case '.':
-                       case '/':
-                       case '0' ... '9':
-                       case ':':
-                       case '=':
-                       case '@':
-                       case 'A' ... 'Z':
-                       case '_':
-                       case 'a' ... 'z':
-                               break;
-                       default:
-                               *pos = '?';
+                       *pos = '?';
+                       all_printable = FALSE;
                }
        }
-       return clone;
+       return all_printable;
 }
 
 /**
@@ -404,7 +392,7 @@ static bool dntoa(chunk_t dn, chunk_t *str)
                        update_chunk(str, snprintf(str->ptr,str->len,"%s", oid_names[oid_code].name));
                }
                /* print value */
-               proper = sanitize_chunk(value);
+               sanitize_chunk(value, &proper);
                update_chunk(str, snprintf(str->ptr,str->len,"=%.*s", (int)proper.len, proper.ptr));
                chunk_free(&proper);
        }
@@ -945,9 +933,8 @@ int identification_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
                case ID_FQDN:
                case ID_RFC822_ADDR:
                case ID_DER_ASN1_GN_URI:
-               case ID_EAP:
                case ID_IETF_ATTR_STRING:
-                       proper = sanitize_chunk(this->encoded);
+                       sanitize_chunk(this->encoded, &proper);
                        snprintf(buf, sizeof(buf), "%.*s", proper.len, proper.ptr);
                        chunk_free(&proper);
                        break;
@@ -961,6 +948,16 @@ int identification_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
                        snprintf(buf, sizeof(buf), "(ASN.1 general Name");
                        break;
                case ID_KEY_ID:
+                       if (sanitize_chunk(this->encoded, &proper))
+                       {       /* fully printable, use ascii version */
+                               snprintf(buf, sizeof(buf), "%.*s", proper.len, proper.ptr);
+                       }
+                       else
+                       {       /* not printable, hex dump */
+                               snprintf(buf, sizeof(buf), "%#B", &this->encoded);
+                       }
+                       chunk_free(&proper);
+                       break;
                case ID_PUBKEY_INFO_SHA1:
                case ID_PUBKEY_SHA1:
                case ID_CERT_DER_SHA1:
@@ -1043,8 +1040,9 @@ identification_t *identification_create_from_string(char *string)
                 */
                if (atodn(string, &this->encoded) != SUCCESS)
                {
-                       free(this);
-                       return NULL;
+                       this->type = ID_KEY_ID;
+                       this->encoded = chunk_clone(chunk_create(string, strlen(string)));
+                       return &this->public;
                }
                this->type = ID_DER_ASN1_DN;
                this->public.equals = (bool (*) (identification_t*,identification_t*))equals_dn;
@@ -1084,11 +1082,11 @@ identification_t *identification_create_from_string(char *string)
                                                (identification_t*,identification_t*))matches_string;
                                        this->public.equals = (bool (*)
                                                (identification_t*,identification_t*))equals_strcasecmp;
-                                       return &(this->public);
+                                       return &this->public;
                                }
                                this->encoded = chunk_clone(chunk);
                                this->type = ID_IPV4_ADDR;
-                               return &(this->public);
+                               return &this->public;
                        }
                        else
                        {
@@ -1098,12 +1096,14 @@ identification_t *identification_create_from_string(char *string)
                                
                                if (inet_pton(AF_INET6, string, &address) <= 0)
                                {
-                                       free(this);
-                                       return NULL;
+                                       this->type = ID_KEY_ID;
+                                       this->encoded = chunk_clone(chunk_create(string,
+                                                                                                                        strlen(string)));
+                                       return &this->public;
                                }
                                this->encoded = chunk_clone(chunk);
                                this->type = ID_IPV6_ADDR;
-                               return &(this->public);
+                               return &this->public;
                        }
                }
        }
@@ -1117,7 +1117,7 @@ identification_t *identification_create_from_string(char *string)
                                this->type = ID_KEY_ID;
                                this->encoded = chunk_from_hex(
                                                                        chunk_create(string, strlen(string)), NULL);
-                               return &(this->public);
+                               return &this->public;
                        }
                        else
                        {
@@ -1128,7 +1128,7 @@ identification_t *identification_create_from_string(char *string)
                                                (identification_t*,identification_t*))matches_string;
                                this->public.equals = (bool (*)
                                                        (identification_t*,identification_t*))equals_strcasecmp;
-                               return &(this->public);
+                               return &this->public;
                        }
                }
                else
@@ -1140,7 +1140,7 @@ identification_t *identification_create_from_string(char *string)
                                        (identification_t*,identification_t*))matches_string;
                        this->public.equals = (bool (*)
                                                (identification_t*,identification_t*))equals_strcasecmp;
-                       return &(this->public);
+                       return &this->public;
                }
        }
 }
@@ -1180,7 +1180,6 @@ identification_t *identification_create_from_encoding(id_type_t type, chunk_t en
                case ID_PUBKEY_INFO_SHA1:
                case ID_PUBKEY_SHA1:
                case ID_CERT_DER_SHA1:
-               case ID_EAP:
                case ID_IETF_ATTR_STRING:
                default:
                        break;
index 6cfc7c473c7907df5c412ecb007160cd5128e2ff..90eadb6253d3c7428d927d7de13bb42c3c62ef54 100644 (file)
@@ -143,16 +143,11 @@ enum id_type_t {
         * SHA1 hash of the binary DER encoding of a certificate
         */
        ID_CERT_DER_SHA1 = 204,
-       
-       /**
-        * Generic EAP identity
-        */
-       ID_EAP = 205,
 
        /**
         * IETF Attribute Syntax String (RFC 3281)
         */
-       ID_IETF_ATTR_STRING = 206,
+       ID_IETF_ATTR_STRING = 205,
 };
 
 /**
@@ -257,8 +252,11 @@ struct identification_t {
  * N, G, I, ID, EN, EmployeeNumber, E, Email, emailAddress, UN, 
  * unstructuredName, TCGID.
  * 
+ * This constructor never returns NULL. If it does not find a suitable
+ * conversion function, it will copy the string to an ID_KEY_ID.
+ * 
  * @param string       input string, which will be converted
- * @return                     created identification_t, NULL if not supported.
+ * @return                     identification_t
  */
 identification_t * identification_create_from_string(char *string);
 
index b7152500cca2d8592e556244d971e82160760251..7c388f76474ec751b12348e41a70b7dc9e7fc0a5 100644 (file)
@@ -27,7 +27,6 @@
 
 typedef struct linked_list_t linked_list_t;
 
-#include <library.h>
 #include <utils/iterator.h>
 #include <utils/enumerator.h>
 
index f788bc3d156e207f835c30fe5371da3ed1c1c37a..d3e7ddc8905c6a398eae5c422d8e57762acc001b 100644 (file)
@@ -84,11 +84,12 @@ AM_CFLAGS = \
 -DIPSEC_CONFDIR=\"${confdir}\" \
 -DIPSEC_PIDDIR=\"${piddir}\" \
 -DSHARED_SECRETS_FILE=\"${confdir}/ipsec.secrets\" \
+-DSTRONGSWAN_CONF=\"${strongswan_conf}\" \
 -DKERNEL26_SUPPORT -DKERNEL26_HAS_KAME_DUPLICATES \
 -DPLUTO -DKLIPS -DDEBUG
 
 pluto_LDADD = \
-oid.o \
+oid.o debug.o linked_list.o enumerator.o settings.o \
 $(LIBFREESWANDIR)/libfreeswan.a \
 $(LIBCRYPTODIR)/libcrypto.a \
 -lgmp -lresolv -lpthread -ldl
@@ -99,9 +100,22 @@ $(LIBFREESWANDIR)/libfreeswan.a \
 
 dist_man_MANS = pluto.8 ipsec.secrets.5
 
+# Copy functions from libstrongswan
 oid.o :        $(LIBSTRONGSWANDIR)/asn1/oid.c $(LIBSTRONGSWANDIR)/asn1/oid.h
                $(COMPILE) -c -o $@ $<
 
+debug.o : $(LIBSTRONGSWANDIR)/debug.c $(LIBSTRONGSWANDIR)/debug.h
+               $(COMPILE) -c -o $@ $<
+
+linked_list.o : $(LIBSTRONGSWANDIR)/utils/linked_list.c $(LIBSTRONGSWANDIR)/utils/linked_list.h
+               $(COMPILE) -c -o $@ $<
+
+enumerator.o : $(LIBSTRONGSWANDIR)/utils/enumerator.c $(LIBSTRONGSWANDIR)/utils/enumerator.h
+               $(COMPILE) -c -o $@ $<
+
+settings.o : $(LIBSTRONGSWANDIR)/settings.c $(LIBSTRONGSWANDIR)/settings.h
+               $(COMPILE) -c -o $@ $<
+
 # This compile option activates the sending of a strongSwan VID
 if USE_VENDORID
   AM_CFLAGS += -DVENDORID
index 12f4f68d8b4ee6c79fa72e71f838983754bd69f3..171f6edec06aa53acf02e184804a7c341d831196 100644 (file)
@@ -321,7 +321,7 @@ static bool
 same_attribute(const ietfAttr_t *a, const ietfAttr_t *b)
 {
     return (a->kind == b->kind && a->value.len == b->value.len
-          && memcmp(a->value.ptr, b->value.ptr, b->value.len) == 0);
+          && memeq(a->value.ptr, b->value.ptr, b->value.len));
 }
 
 bool
index c998e54e981cd9dde1cd4cbd1529965994e07119..ba2fead7ab42c5a6f4a82b5133e7e2a22b45f97d 100644 (file)
@@ -171,12 +171,15 @@ static int
 ealg_getbyname_esp(const char *const str, int len)
 {
     if (!str || !*str)
+    {
        return -1;
+    }
 
     /* leave special case for eg:  "id248" string */
-    if (strcmp("id", str) == 0)
+    if (streq("id", str))
+    {
        return ESP_MAGIC_ID;
-
+    }
     return enum_search_prefix(&esp_transformid_names, "ESP_", str, len);
 }
 
index 70215441b640acb82470807f84c93a9004b6d9fc..7ae04e0c46203f1960e6771bff57763c7dcec68e 100644 (file)
@@ -1208,14 +1208,20 @@ enum_search(enum_names *ed, const char *str)
     unsigned en;
 
     for (p = ed; p != NULL; p = p->en_next_range)
+    {
        for (en = p->en_first; en <= p->en_last ;en++)
        {
            ptr = p->en_names[en - p->en_first];
-           if (ptr == 0) continue;
-           /* if (strncmp(ptr, str, strlen(ptr))==0) */
-           if (strcmp(ptr, str) == 0)
-                   return en;
+           if (ptr == 0)
+           {
+               continue;
+           }
+           if (streq(ptr, str))
+           {
+               return en;
+           }
        }
+    }
     return -1;
 }
 
index 13251dc3b05bca0e28ea2652d46ec858a4038e92..60f431049b2048ac66825a4fba4a9f97a017380a 100644 (file)
@@ -19,6 +19,8 @@
 #ifndef _CONSTANTS_H
 #define _CONSTANTS_H
 
+#include <utils.h>
+
 extern const char compile_time_interop_options[];
 
 extern void init_constants(void);
@@ -39,17 +41,10 @@ extern void init_constants(void);
  * <freeswan.h> defines err_t for this return type.
  */
 
-typedef int bool;
-#define FALSE  0
-#define TRUE   1
-
 #define NULL_FD        (-1)    /* NULL file descriptor */
 #define dup_any(fd) ((fd) == NULL_FD? NULL_FD : dup(fd))
 #define close_any(fd) { if ((fd) != NULL_FD) { close(fd); (fd) = NULL_FD; } }
 
-#define BITS_PER_BYTE  8
-
-#define streq(a, b) (strcmp((a), (b)) == 0)    /* clearer shorthand */
 #define strcaseeq(a, b) (strcasecmp((a), (b)) == 0)    /* clearer shorthand */
 
 /* set type with room for at least 64 elements for ALG opts (was 32 in stock FS) */
index 70d0752631eb23bb54bf29b9c253bd3ada7e1f2e..add131ca9f73ac4bd6dcf2eed415f5ee7901c950 100644 (file)
@@ -536,7 +536,7 @@ check_revocation(const x509crl_t *crl, chunk_t serial
     {
        /* compare serial numbers */
        if (revokedCert->userCertificate.len == serial.len &&
-           memcmp(revokedCert->userCertificate.ptr, serial.ptr, serial.len) == 0)
+           memeq(revokedCert->userCertificate.ptr, serial.ptr, serial.len))
        {
            *revocationDate = revokedCert->revocationDate;
            *revocationReason = revokedCert->revocationReason;
index 44e012665ae94bbb6a3a7f3a2d28cce523738877..30a152120e9bf51627eb73d3c7a35e1a2664b5c2 100644 (file)
 # define USED_BY_DEBUG UNUSED
 #endif
 
-/* Length of temporary buffers */
-
-#define BUF_LEN              512
-
 /* type of serial number of a state object
  * Needed in connections.h and state.h; here to simplify dependencies.
  */
@@ -118,9 +114,6 @@ typedef struct {
     int fd;
 } prompt_pass_t;
 
-/* no time defined in time_t */
-#define UNDEFINED_TIME 0
-
 /* size of timetoa string buffer */
 #define TIMETOA_BUF    30
 
index 4a28367e1351fb68e53b130bbdf4259ddf5e83be..94a7f714d98d0faea1b5483c8cdcd6da35542767 100644 (file)
@@ -1713,7 +1713,7 @@ process_packet(struct msg_digest **mdp)
     if (st != NULL
     && st->st_rpacket.ptr != NULL
     && st->st_rpacket.len == pbs_room(&md->packet_pbs)
-    && memcmp(st->st_rpacket.ptr, md->packet_pbs.start, st->st_rpacket.len) == 0)
+    && memeq(st->st_rpacket.ptr, md->packet_pbs.start, st->st_rpacket.len))
     {
        if (smc->flags & SMF_RETRANSMIT_ON_DUPLICATE)
        {
index 284ade0d1b3102a5f684aff2262375a7bc42a02c..e33de6168a214f3c668e1b539a43dfb1dc35713f 100644 (file)
@@ -905,7 +905,7 @@ add_distribution_points(const generalName_t *newPoints ,generalName_t **distribu
            {
                if (gn->kind == newPoints->kind
                && gn->name.len == newPoints->name.len
-               && memcmp(gn->name.ptr, newPoints->name.ptr, gn->name.len) == 0)
+               && memeq(gn->name.ptr, newPoints->name.ptr, gn->name.len))
                {
                    /* skip if the distribution point is already present */
                    add = FALSE;
index 6c27baac0aeb6e51f4701b91303f0e807c08ad85..c21bab7b23a03aa26b64f1b98b92846d8cd7b062 100644 (file)
@@ -423,7 +423,7 @@ same_id(const struct id *a, const struct id *b)
 
     case ID_KEY_ID:
        return a->name.len == b->name.len
-           && memcmp(a->name.ptr, b->name.ptr, a->name.len) == 0;
+           && memeq(a->name.ptr, b->name.ptr, a->name.len);
 
     default:
        bad_case(a->kind);
index 4f8b88170f206b1c7d1da35b28014aac39567fad..5e34b272dac7f0ae967087fc15df4ed9d7676dd4 100644 (file)
@@ -464,8 +464,8 @@ ike_hash_test(const struct hash_desc *desc)
            desc->hash_update(&ctx, desc->hash_testvectors[i].msg
                                   ,desc->hash_testvectors[i].msg_size);
            desc->hash_final(digest, &ctx);
-           result = memcmp(digest, desc->hash_testvectors[i].msg_digest
-                                 , desc->hash_digest_size) == 0;
+           result = memeq(digest, desc->hash_testvectors[i].msg_digest
+                                 , desc->hash_digest_size);
            DBG(DBG_CRYPT,
                DBG_log("  hash testvector %d: %s", i, result ? "ok":"failed")
            )
@@ -495,8 +495,8 @@ ike_hash_test(const struct hash_desc *desc)
            hmac_update(&ctx, desc->hmac_testvectors[i].msg
                             ,desc->hmac_testvectors[i].msg_size);
            hmac_final(digest, &ctx);
-           result = memcmp(digest, desc->hmac_testvectors[i].hmac
-                                 , desc->hash_digest_size) == 0;
+           result = memeq(digest, desc->hmac_testvectors[i].hmac
+                                 , desc->hash_digest_size);
            DBG(DBG_CRYPT,
                DBG_log("  hmac testvector %d: %s", i, result ? "ok":"failed")
            )
index 09b4bbaaf6580b5e23799c1d85b29d8deaf28c09..98841bcee604a993bcdabff5ba5f7c1caaa677c8 100644 (file)
@@ -2955,7 +2955,7 @@ was_eroute_idle(struct state *st, time_t idle_max, time_t *idle_time)
                break;
            }
 
-           if (strncmp(line, text_said, strlen(text_said)) == 0)
+           if (strneq(line, text_said, strlen(text_said)))
            {
                /* we found a match, now try to find idle= */
                char *p = strstr(line, idle);
index 6cdf169d8b054211b5b24696d47fe3fcb8df3640..0c9f53929a2451265c369b21581fb12caf02efd7 100644 (file)
@@ -253,7 +253,7 @@ get_secret(const struct connection *c, enum PrivateKeyKind kind, bool asym)
                    {
                    case PPK_PSK:
                        same = s->u.preshared_secret.len == best->u.preshared_secret.len
-                           && memcmp(s->u.preshared_secret.ptr, best->u.preshared_secret.ptr, s->u.preshared_secret.len) == 0;
+                           && memeq(s->u.preshared_secret.ptr, best->u.preshared_secret.ptr, s->u.preshared_secret.len);
                        break;
                    case PPK_RSA:
                        /* Dirty trick: since we have code to compare
index 967a0b2a5147297ad9ab1ff167afc2c897286bb9..45c7230bc88b40f03cbf88bad437da464d40dd2c 100644 (file)
@@ -26,6 +26,7 @@
 #include <string.h>
 
 #include <freeswan.h>
+#include <settings.h>
 
 #include "constants.h"
 #include "defs.h"
@@ -42,6 +43,8 @@
 #include "xauth.h"
 
 #define MAX_XAUTH_TRIES                3
+#define DNS_SERVER_MAX         2
+#define NBNS_SERVER_MAX                2
 
 #define SUPPORTED_ATTR_SET   ( LELEM(INTERNAL_IP4_ADDRESS)         \
                              | LELEM(INTERNAL_IP4_NETMASK)         \
@@ -54,6 +57,8 @@
 
 #define UNITY_BANNER_STR    "Welcome to strongSwan - the Linux VPN Solution!\n"
 
+extern settings_t *settings;
+
 /*
  * Addresses assigned (usually via ModeCfg) to the Initiator
  */
@@ -67,8 +72,8 @@ struct internal_addr
 
     /* ModeCfg variables */
     ip_address ipaddr;
-    ip_address dns[2];
-    ip_address wins[2];
+    ip_address dns[DNS_SERVER_MAX];
+    ip_address nbns[NBNS_SERVER_MAX];
 
     char *unity_banner;
 
@@ -84,6 +89,8 @@ struct internal_addr
 static void
 init_internal_addr(internal_addr_t *ia)
 {
+    int i;
+
     ia->attr_set = LEMPTY;
     ia->xauth_attr_set = LEMPTY;
     ia->xauth_secret.user_name = empty_chunk;
@@ -94,10 +101,18 @@ init_internal_addr(internal_addr_t *ia)
     ia->unity_banner = NULL;
 
     anyaddr(AF_INET, &ia->ipaddr);
-    anyaddr(AF_INET, &ia->dns[0]);
-    anyaddr(AF_INET, &ia->dns[1]);
-    anyaddr(AF_INET, &ia->wins[0]);
-    anyaddr(AF_INET, &ia->wins[1]);
+
+    /* initialize DNS server information */
+    for (i = 0; i < DNS_SERVER_MAX; i++)
+    {
+       anyaddr(AF_INET, &ia->dns[i]);
+    }
+
+    /* initialize WINS server information */
+    for (i = 0; i < NBNS_SERVER_MAX; i++)
+    {
+       anyaddr(AF_INET, &ia->nbns[i]);
+    }
 }
 
 /*
@@ -106,6 +121,8 @@ init_internal_addr(internal_addr_t *ia)
 static void
 get_internal_addr(struct connection *c, internal_addr_t *ia)
 {
+    int i, dns_idx = 0, nbns_idx = 0;
+
     if (isanyaddr(&c->spd.that.host_srcip))
     {
        /* not defined in connection - fetch it from LDAP */
@@ -130,13 +147,60 @@ get_internal_addr(struct connection *c, internal_addr_t *ia)
                     | LELEM(INTERNAL_IP4_NETMASK);
     }
 
-    if (!isanyaddr(&ia->dns[0]))       /* We got DNS addresses, send them */
-       ia->attr_set |= LELEM(INTERNAL_IP4_DNS);
+    /* assign DNS servers */
+    for (i = 1; i <= DNS_SERVER_MAX; i++)
+    {
+       char dns_key[16], *dns_str;
+
+       snprintf(dns_key, sizeof(dns_key), "pluto.dns%d", i);
+       dns_str = settings->get_str(settings, dns_key, NULL);
+       if (dns_str)
+       {
+           err_t ugh;
+           sa_family_t family = strchr(dns_str, ':') ? AF_INET6 : AF_INET;
 
-    if (!isanyaddr(&ia->wins[0]))      /* We got WINS addresses, send them */
-       ia->attr_set |= LELEM(INTERNAL_IP4_NBNS);
+           ugh = ttoaddr(dns_str, 0, family, &ia->dns[dns_idx]);
+           if (ugh != NULL)
+           {
+               plog("error in DNS server address: %s", ugh);
+               continue;
+           }
+           plog("assigning DNS server %s to peer", dns_str);
+
+           /* differentiate between IP4 and IP6 in modecfg_build_msg() */ 
+           ia->attr_set |= LELEM(INTERNAL_IP4_DNS);
+           dns_idx++;
+       }
+    }
+
+    /* assign WINS servers */
+    for (i = 1; i <= NBNS_SERVER_MAX; i++)
+    {
+       char nbns_key[16], *nbns_str;
+
+       snprintf(nbns_key, sizeof(nbns_key), "pluto.nbns%d", i);
+       nbns_str = settings->get_str(settings, nbns_key, NULL);
+       if (nbns_str)
+       {
+           err_t ugh;
+           sa_family_t family = strchr(nbns_str, ':') ? AF_INET6 : AF_INET;
+
+           ugh = ttoaddr(nbns_str, 0, family, &ia->nbns[nbns_idx]);
+           if (ugh != NULL)
+           {
+               plog("error in WINS server address: %s", ugh);
+               continue;
+           }
+           plog("assigning NBNS server %s to peer", nbns_str);
+
+           /* differentiate between IP4 and IP6 in modecfg_build_msg() */ 
+           ia->attr_set |= LELEM(INTERNAL_IP4_NBNS);
+           nbns_idx++;
+       }
+    }
 }
 
+
 /*
  * Set srcip and client subnet to internal IP address
  */
@@ -218,8 +282,8 @@ modecfg_build_msg(struct state *st, pb_stream *rbody
        struct isakmp_mode_attr attrh;
        struct isakmp_attribute attr;
        pb_stream strattr,attrval;
-       int attr_type;
-       int dns_idx, wins_idx;
+       int attr_type, dns_attr_type, nbns_attr_type;
+       int dns_idx, nbns_idx;
        bool dont_advance;
        bool is_xauth_attr_set = ia->xauth_attr_set != LEMPTY;
        bool is_unity_attr_set = ia->unity_attr_set != LEMPTY;
@@ -230,11 +294,12 @@ modecfg_build_msg(struct state *st, pb_stream *rbody
        attrh.isama_identifier = ap_id;
 
        if (!out_struct(&attrh, &isakmp_attr_desc, rbody, &strattr))
+       {
            return STF_INTERNAL_ERROR;
-
+       }
        attr_type = 0;
        dns_idx = 0;
-       wins_idx = 0;
+       nbns_idx = 0;
 
        while (attr_set != LEMPTY || is_xauth_attr_set || is_unity_attr_set)
        {
@@ -272,6 +337,20 @@ modecfg_build_msg(struct state *st, pb_stream *rbody
                    attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TV;
                    attr.isaat_lv = ia->xauth_status;
                }
+               else if (attr_type == INTERNAL_IP4_DNS && !isanyaddr(&ia->dns[dns_idx]))
+               {
+                   dns_attr_type = (addrtypeof(&ia->dns[dns_idx]) == AF_INET) ?
+                                       INTERNAL_IP4_DNS : INTERNAL_IP6_DNS;
+                   attr.isaat_af_type = dns_attr_type | ISAKMP_ATTR_AF_TLV;
+
+               }
+               else if (attr_type == INTERNAL_IP4_NBNS && !isanyaddr(&ia->nbns[nbns_idx]))
+               {
+                   nbns_attr_type = (addrtypeof(&ia->nbns[nbns_idx]) == AF_INET) ?
+                                       INTERNAL_IP4_NBNS : INTERNAL_IP6_NBNS;
+                   attr.isaat_af_type = nbns_attr_type | ISAKMP_ATTR_AF_TLV;
+
+               }
                else
                {
                    attr.isaat_af_type = attr_type | ISAKMP_ATTR_AF_TLV;
@@ -303,10 +382,14 @@ modecfg_build_msg(struct state *st, pb_stream *rbody
                        }
 #endif                             
                        if (st->st_connection->spd.this.client.maskbits == 0)
+                       {
                            mask = 0;
+                       }
                        else
+                       {
                            mask = 0xffffffff * 1;
                            out_raw(&mask, 4, &attrval, "IP4_mask");
+                       }
                    }
                    break;
                case INTERNAL_IP4_SUBNET:
@@ -318,13 +401,12 @@ modecfg_build_msg(struct state *st, pb_stream *rbody
 
                        for (t = 0; t < 4; t++)
                        {
-                           if (m < 8)
-                               mask[t] = bits[m];
-                           else
-                               mask[t] = 0xff;
+                           mask[t] = (m < 8) ? bits[m] : 0xff;
                            m -= 8;
                            if (m < 0)
+                           {
                                m = 0;
+                           }
                        }
                        len = addrbytesptr(&st->st_connection->spd.this.client.addr, &byte_ptr);
                        out_raw(byte_ptr, len, &attrval, "IP4_subnet");
@@ -332,23 +414,25 @@ modecfg_build_msg(struct state *st, pb_stream *rbody
                    }
                    break;
                case INTERNAL_IP4_DNS:
+               case INTERNAL_IP6_DNS:
                    if (!isanyaddr(&ia->dns[dns_idx]))
                    {
                        len = addrbytesptr(&ia->dns[dns_idx++], &byte_ptr);
-                       out_raw(byte_ptr, len, &attrval, "IP4_dns");
+                       out_raw(byte_ptr, len, &attrval, "IP_dns");
                    }
-                   if (dns_idx < 2 && !isanyaddr(&ia->dns[dns_idx]))
+                   if (dns_idx < DNS_SERVER_MAX && !isanyaddr(&ia->dns[dns_idx]))
                    {
                        dont_advance = TRUE;
                    }
                    break;
                case INTERNAL_IP4_NBNS:
-                   if (!isanyaddr(&ia->wins[wins_idx]))
+               case INTERNAL_IP6_NBNS:
+                   if (!isanyaddr(&ia->nbns[nbns_idx]))
                    {
-                       len = addrbytesptr(&ia->wins[wins_idx++], &byte_ptr);
-                       out_raw(byte_ptr, len, &attrval, "IP4_wins");
+                       len = addrbytesptr(&ia->nbns[nbns_idx++], &byte_ptr);
+                       out_raw(byte_ptr, len, &attrval, "IP_nbns");
                    }
-                   if (wins_idx < 2 && !isanyaddr(&ia->wins[wins_idx]))
+                   if (nbns_idx < NBNS_SERVER_MAX && !isanyaddr(&ia->nbns[nbns_idx]))
                    {
                        dont_advance = TRUE;
                    }
@@ -619,7 +703,9 @@ modecfg_parse_msg(struct msg_digest *md, int isama_type, u_int16_t *isama_id
            stat = modecfg_parse_attributes(&p->pbs, &ia_candidate);
        }
        if (stat != STF_OK)
+       {
            return stat;
+       }
     }
     return STF_IGNORE;
 }
@@ -642,7 +728,9 @@ modecfg_send_request(struct state *st)
     st->st_state = STATE_MODE_CFG_I1;
     stat = modecfg_send_msg(st, ISAKMP_CFG_REQUEST, &ia);
     if (stat == STF_OK)
+    {
        st->st_modecfg.started = TRUE;
+    }
     return stat;
 }
 
@@ -662,10 +750,11 @@ modecfg_inR0(struct msg_digest *md)
 
     stat = modecfg_parse_msg(md, ISAKMP_CFG_REQUEST, &isama_id, &ia);
     if (stat != STF_OK)
+    {
        return stat;
+    }
 
     want_unity_banner = (ia.unity_attr_set & LELEM(UNITY_BANNER - UNITY_BASE)) != LEMPTY;
-
     init_internal_addr(&ia);
     get_internal_addr(st->st_connection, &ia);
 
@@ -682,8 +771,9 @@ modecfg_inR0(struct msg_digest *md)
                                     , &ia
                                     , isama_id);
     if (stat_build != STF_OK)
+    {
        return stat_build;
-
+    }
     st->st_msgid = 0;
     return STF_OK;
 }
@@ -705,8 +795,9 @@ modecfg_inI1(struct msg_digest *md)
 
     stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, &ia);
     if (stat != STF_OK)
+    {
        return stat;
-
+    }
     st->st_modecfg.vars_set = set_internal_addr(st->st_connection, &ia);
     st->st_msgid = 0;
     return STF_OK;
@@ -734,7 +825,9 @@ modecfg_send_set(struct state *st)
     st->st_state = STATE_MODE_CFG_R3;
     stat = modecfg_send_msg(st, ISAKMP_CFG_SET, &ia);
     if (stat == STF_OK)
+    {
        st->st_modecfg.started = TRUE;
+    }
     return stat;
 }
 
@@ -756,8 +849,9 @@ modecfg_inI0(struct msg_digest *md)
 
     stat = modecfg_parse_msg(md, ISAKMP_CFG_SET, &isama_id, &ia);
     if (stat != STF_OK)
+    {
        return stat;
-
+    }
     st->st_modecfg.vars_set = set_internal_addr(st->st_connection, &ia);
 
     /* prepare ModeCfg ack which sends zero length attributes */
@@ -774,8 +868,9 @@ modecfg_inI0(struct msg_digest *md)
                                     , &ia
                                     , isama_id);
     if (stat_build != STF_OK)
+    {
        return stat_build;
-
+    }
     st->st_msgid = 0;
     return STF_OK;
 }
@@ -797,8 +892,9 @@ modecfg_inR3(struct msg_digest *md)
 
     stat = modecfg_parse_msg(md, ISAKMP_CFG_ACK, &isama_id, &ia);
     if (stat != STF_OK)
+    {
        return stat;
-
+    }
     st->st_msgid = 0;
     return STF_OK;
 }
@@ -820,7 +916,9 @@ xauth_send_request(struct state *st)
     st->st_state = STATE_XAUTH_R1;
     stat = modecfg_send_msg(st, ISAKMP_CFG_REQUEST, &ia);
     if (stat == STF_OK)
+    {
        st->st_xauth.started = TRUE;
+    }
     return stat;
 }
 
@@ -842,8 +940,10 @@ xauth_inI0(struct msg_digest *md)
 
     stat = modecfg_parse_msg(md, ISAKMP_CFG_REQUEST, &isama_id, &ia);
     if (stat != STF_OK)
+    {
        return stat;
+    }
+
     /* check XAUTH attributes */
     xauth_type_present = (ia.xauth_attr_set & LELEM(XAUTH_TYPE - XAUTH_BASE)) != LEMPTY;
 
@@ -890,7 +990,9 @@ xauth_inI0(struct msg_digest *md)
        ia.xauth_attr_set = LELEM(XAUTH_USER_NAME     - XAUTH_BASE)
                          | LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE);
         if (xauth_type_present)
+       {
            ia.xauth_attr_set |= LELEM(XAUTH_TYPE - XAUTH_BASE);
+       }
     }
     else
     {
@@ -905,8 +1007,9 @@ xauth_inI0(struct msg_digest *md)
                                     , &ia
                                     , isama_id);
     if (stat_build != STF_OK)
+    {
        return stat_build;
-
+    }
     if (stat == STF_OK)
     {
        st->st_xauth.started = TRUE;
@@ -942,8 +1045,10 @@ xauth_inR1(struct msg_digest *md)
 
     stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, &ia);
     if (stat != STF_OK)
+    {
        return stat;
+    }
+
     /* did the client return an XAUTH FAIL status? */
     if ((ia.xauth_attr_set & LELEM(XAUTH_STATUS - XAUTH_BASE)) != LEMPTY)
     {
@@ -997,7 +1102,9 @@ xauth_inR1(struct msg_digest *md)
 
     stat_build = modecfg_send_msg(st, ISAKMP_CFG_SET, &ia);
     if (stat_build != STF_OK)
+    {
        return stat_build;
+    }
     return STF_OK;
 }
 
@@ -1033,8 +1140,9 @@ xauth_inI1(struct msg_digest *md)
                                     , &ia
                                     , isama_id);
     if (stat_build != STF_OK)
+    {
        return stat_build;
+    }
     if (st->st_xauth.status)
     {
        st->st_msgid = 0;
@@ -1069,8 +1177,9 @@ xauth_inR2(struct msg_digest *md)
 
     stat = modecfg_parse_msg(md, ISAKMP_CFG_ACK, &isama_id, &ia);
     if (stat != STF_OK)
+    {
        return stat;
-
+    }
     st->st_msgid = 0;
     if (st->st_xauth.status)
     {
index 5566d3d2537a05358db8c6a4a9dbcee535a55dbd..1a5085eeb3cbe06b1ee1fc81687c0af9d449b2e9 100644 (file)
@@ -237,7 +237,7 @@ void nat_traversal_natd_lookup(struct msg_digest *md)
        &(md->iface->addr), ntohs(st->st_connection->spd.this.host_port));
 
     if (!(pbs_left(&p->pbs) == st->st_oakley.hasher->hash_digest_len &&
-         memcmp(p->pbs.cur, hash, st->st_oakley.hasher->hash_digest_len) == 0))
+         memeq(p->pbs.cur, hash, st->st_oakley.hasher->hash_digest_len)))
     {
 #ifdef NAT_D_DEBUG
        DBG(DBG_NATT,
@@ -258,7 +258,7 @@ void nat_traversal_natd_lookup(struct msg_digest *md)
     for (p = p->next, i=0 ; p != NULL; p = p->next)
     {
        if (pbs_left(&p->pbs) == st->st_oakley.hasher->hash_digest_len &&
-           memcmp(p->pbs.cur, hash, st->st_oakley.hasher->hash_digest_len) == 0)
+           memeq(p->pbs.cur, hash, st->st_oakley.hasher->hash_digest_len))
        {
            i++;
        }
index 14792d49fa9f322c34a0388ddfe837f5219cb7a0..396eb3d1c830ad9d1b5f060fac47d39d442f55b7 100644 (file)
@@ -45,7 +45,7 @@ present(const char* pattern, chunk_t* ch)
 {
     u_int pattern_len = strlen(pattern);
 
-    if (ch->len >= pattern_len && strncmp(ch->ptr, pattern, pattern_len) == 0)
+    if (ch->len >= pattern_len && strneq(ch->ptr, pattern, pattern_len))
     {
        ch->ptr += pattern_len;
        ch->len -= pattern_len;
@@ -60,8 +60,7 @@ present(const char* pattern, chunk_t* ch)
 static bool
 match(const char *pattern, const chunk_t *ch)
 {
-    return ch->len == strlen(pattern) &&
-          strncmp(pattern, ch->ptr, ch->len) == 0;
+    return ch->len == strlen(pattern) && strneq(pattern, ch->ptr, ch->len);
 }
 
 /*
index aab9bff67db137fafb45ca7fc7701783ebc50ef5..f6744fd8a71be33569960621ac9ef4f34f0dc3c7 100644 (file)
@@ -521,7 +521,7 @@ static bool
 same_pgpcert(pgpcert_t *a, pgpcert_t *b)
 {
     return a->certificate.len == b->certificate.len &&
-       memcmp(a->certificate.ptr, b->certificate.ptr, b->certificate.len) == 0;
+       memeq(a->certificate.ptr, b->certificate.ptr, b->certificate.len);
 }
 
 /*
@@ -531,7 +531,9 @@ void
 share_pgpcert(pgpcert_t *cert)
 {
     if (cert != NULL)
+    {
        cert->count++;
+    }
 }
 
 /*
index b7bb8df985fa9017cb594d0235d8b34d96c9f528..eedbf253236dea5bb1ba95c7632b66e3b3b06723 100644 (file)
@@ -38,6 +38,7 @@
 #endif /* CAPABILITIES */
 
 #include <freeswan.h>
+#include <settings.h>
 
 #include <pfkeyv2.h>
 #include <pfkey.h>
@@ -197,6 +198,9 @@ delete_lock(void)
     }
 }
 
+/* settings defined by strongswan.conf */
+settings_t *settings;
+
 /* by default pluto sends certificate requests to its peers */
 bool no_cr_send = FALSE;
 
@@ -239,6 +243,9 @@ main(int argc, char **argv)
     int keep[] = { CAP_NET_ADMIN, CAP_NET_BIND_SERVICE };
 #endif /* CAPABILITIES */
 
+    /* getting settings from strongswan.conf */
+    settings = settings_create(STRONGSWAN_CONF);
+
     /* handle arguments */
     for (;;)
     {
@@ -703,6 +710,7 @@ exit_pluto(int status)
     free_ifaces();
     scx_finalize();            /* finalize and unload PKCS #11 module */
     xauth_finalize();          /* finalize and unload XAUTH module */
+    settings->destroy(settings);
     stop_adns();
     free_md_pool();
     delete_lock();
index c14f72698f3972f6336ad111948c432f392520af..cae16294ec84e064640beff4505f4e69782adf74 100644 (file)
@@ -544,8 +544,10 @@ process_raw_ifaces(struct raw_iface *rifaces)
        struct raw_iface *vfp;
 
        /* ignore if virtual (ipsec*) interface */
-       if (strncmp(ifp->name, IPSECDEVPREFIX, sizeof(IPSECDEVPREFIX)-1) == 0)
+       if (strneq(ifp->name, IPSECDEVPREFIX, sizeof(IPSECDEVPREFIX)-1))
+       {
            continue;
+       }
 
        for (vfp = rifaces; vfp != NULL; vfp = vfp->next)
        {
@@ -558,7 +560,7 @@ process_raw_ifaces(struct raw_iface *rifaces)
                /* Different entries with matching IP addresses.
                 * Many interesting cases.
                 */
-               if (strncmp(vfp->name, IPSECDEVPREFIX, sizeof(IPSECDEVPREFIX)-1) == 0)
+               if (strneq(vfp->name, IPSECDEVPREFIX, sizeof(IPSECDEVPREFIX)-1))
                {
                    if (v != NULL  && !streq(v->name, vfp->name))
                    {
index a458d528aa6c9afd00982976a6d62ca58bbd11d0..64c36c7c910449617d4d8e777cb5d7257b8374ff 100644 (file)
@@ -787,7 +787,7 @@ scx_finalize(void)
 bool
 scx_on_smartcard(const char *filename)
 {
-    return strncmp(filename, SCX_TOKEN, strlen(SCX_TOKEN)) == 0;
+    return strneq(filename, SCX_TOKEN, strlen(SCX_TOKEN));
 }
 
 #ifdef SMARTCARD
@@ -1619,7 +1619,7 @@ scx_op_via_whack(const char* msg, int inbase, int outbase, sc_op_t op
 
     if (keyid != NULL)
     {
-       number_slot_id = (strncmp(keyid, SCX_TOKEN, strlen(SCX_TOKEN)) == 0)
+       number_slot_id = (strneq(keyid, SCX_TOKEN, strlen(SCX_TOKEN)))
                         ? keyid + strlen(SCX_TOKEN) : keyid;
     }
 
index d1587a1a5d2f0bea6edb1d58bdc3028cf3fcd52b..0b223e615ca358728585cd675d49b2c5f6fa5ae9 100644 (file)
@@ -578,14 +578,19 @@ find_state(const u_char *icookie
     struct state *st = *state_hash(icookie, rcookie, peer);
 
     while (st != (struct state *) NULL)
+    {
        if (sameaddr(peer, &st->st_connection->spd.that.host_addr)
-       && memcmp(icookie, st->st_icookie, COOKIE_SIZE) == 0
-       && memcmp(rcookie, st->st_rcookie, COOKIE_SIZE) == 0
+       && memeq(icookie, st->st_icookie, COOKIE_SIZE)
+       && memeq(rcookie, st->st_rcookie, COOKIE_SIZE)
        && msgid == st->st_msgid)
+       {
            break;
+       }
        else
+       {
            st = st->st_hashchain_next;
-
+       }
+    }
     DBG(DBG_CONTROL,
        if (st == NULL)
            DBG_log("state object not found");
@@ -607,13 +612,20 @@ find_sender(size_t packet_len, u_char *packet)
     struct state *st;
 
     if (packet_len >= sizeof(struct isakmp_hdr))
+    {
        for (i = 0; i < STATE_TABLE_SIZE; i++)
+       {
            for (st = statetable[i]; st != NULL; st = st->st_hashchain_next)
+           {
                if (st->st_tpacket.ptr != NULL
                && st->st_tpacket.len == packet_len
-               && memcmp(st->st_tpacket.ptr, packet, packet_len) == 0)
+               && memeq(st->st_tpacket.ptr, packet, packet_len))
+               {
                    return st;
-
+               }
+           }
+       }
+    }
     return NULL;
 }
 
index 4f0e6d43a052a7806f8acd97b8377f90bb538613..609366452b83663a87012b03ac1cb79f44cf2313 100644 (file)
@@ -497,7 +497,7 @@ handle_vendorid (struct msg_digest *md, const char *vid, size_t len)
        {
            if (pvid->vid_len == len)
            {
-               if (memcmp(pvid->vid, vid, len) == 0)
+               if (memeq(pvid->vid, vid, len))
                {
                    handle_known_vendorid(md, vid, len, pvid);
                    return;
@@ -505,7 +505,7 @@ handle_vendorid (struct msg_digest *md, const char *vid, size_t len)
            }
            else if ((pvid->vid_len < len) && (pvid->flags & VID_SUBSTRING))
            {
-               if (memcmp(pvid->vid, vid, pvid->vid_len) == 0)
+               if (memeq(pvid->vid, vid, pvid->vid_len))
                {
                    handle_known_vendorid(md, vid, len, pvid);
                    return;
index cf036cc7b2be04cabdd8165d8604746d729da3b9..9deceb22491c9d064d4bad425c5f658b04f915fc 100644 (file)
@@ -54,11 +54,11 @@ _read_subnet(const char *src, size_t len, ip_subnet *dst, ip_subnet *dstko,
     bool ok;
     int af;
 
-    if ((len > 4) && (strncmp(src, "%v4:", 4)==0))
+    if ((len > 4) && (strneq(src, "%v4:", 4)))
     {
        af = AF_INET;
     }
-    else if ((len > 4) && (strncmp(src, "%v6:", 4)==0))
+    else if ((len > 4) && (strneq(src, "%v6:", 4)))
     {
        af = AF_INET6;
     }
@@ -196,12 +196,12 @@ struct virtual_t
     if (!string || string[0] == '\0')
        return NULL;
 
-    if (strlen(string) >= 6 && strncmp(string,"vhost:",6) == 0)
+    if (strlen(string) >= 6 && strneq(string,"vhost:",6))
     {
        flags |= F_VIRTUAL_HOST;
        str += 6;
     }
-    else if (strlen(string) >= 5 && strncmp(string,"vnet:",5) == 0)
+    else if (strlen(string) >= 5 && strneq(string,"vnet:",5))
        str += 5;
     else
        goto fail;
@@ -213,17 +213,17 @@ struct virtual_t
     {
        next = strchr(str,',');
        if (!next) next = str + strlen(str);
-       if (next-str == 3 && strncmp(str, "%no", 3) == 0)
+       if (next-str == 3 && strneq(str, "%no", 3))
            flags |= F_VIRTUAL_NO;
 #if 0
-       else if (next-str == 4 && strncmp(str, "%ike", 4) == 0)
+       else if (next-str == 4 && strneq(str, "%ike", 4))
            flags |= F_VIRTUAL_IKE_CONFIG;
-       else if (next-str == 5 && strncmp(str, "%dhcp", 5) == 0)
+       else if (next-str == 5 && strneq(str, "%dhcp", 5))
            flags |= F_VIRTUAL_DHCP;
 #endif
-       else if (next-str == 5 && strncmp(str, "%priv", 5) == 0)
+       else if (next-str == 5 && strneq(str, "%priv", 5))
            flags |= F_VIRTUAL_PRIVATE;
-       else if (next-str == 4 && strncmp(str, "%all", 4) == 0)
+       else if (next-str == 4 && strneq(str, "%all", 4))
            flags |= F_VIRTUAL_ALL;
        else if (_read_subnet(str, next-str, &sub, NULL, NULL))
        {
index 3c6d85f0713d87ab0b8ae23ca5e7102b8e6d7209..e6f7b24e0bccfec91194d99f345f74cbfecb10df 100644 (file)
@@ -423,8 +423,9 @@ init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *next)
     rdn->len = asn1_length(&dn);
 
     if (rdn->len == ASN1_INVALID_LENGTH)
+    {
        return "Invalid RDN length";
-
+    }
     rdn->ptr = dn.ptr;
 
     /* are there any RDNs ? */
@@ -451,13 +452,15 @@ get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, chunk_t *value
     {
        /* an RDN is a SET OF attributeTypeAndValue */
        if (*rdn->ptr != ASN1_SET)
+       {
            return "RDN is not a SET";
-
+       }
        attribute->len = asn1_length(rdn);
        
        if (attribute->len == ASN1_INVALID_LENGTH)
+       {
            return "Invalid attribute length";
-
+       }
        attribute->ptr = rdn->ptr;
 
        /* advance to start of next RDN */
@@ -467,14 +470,17 @@ get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, chunk_t *value
 
     /* an attributeTypeAndValue is a SEQUENCE */
     if (*attribute->ptr != ASN1_SEQUENCE)
+    {
        return "attributeTypeAndValue is not a SEQUENCE";
+    }
 
     /* extract the attribute body */
     body.len = asn1_length(attribute);
     
     if (body.len == ASN1_INVALID_LENGTH)
+    {
        return "Invalid attribute body length";
-
+    }
     body.ptr = attribute->ptr;
     
     /* advance to start of next attribute */
@@ -483,14 +489,17 @@ get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, chunk_t *value
 
     /* attribute type is an OID */
     if (*body.ptr != ASN1_OID)
+    {
        return "attributeType is not an OID";
+    }
 
     /* extract OID */
     oid->len = asn1_length(&body);
     
-    if (oid->len == ASN1_INVALID_LENGTH)
+    if (oid->len == ASN1_INVALID_LENGTH)  
+    {
        return "Invalid attribute OID length";
-
+    }
     oid->ptr = body.ptr;
 
     /* advance to the attribute value */
@@ -504,8 +513,9 @@ get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, chunk_t *value
     value->len = asn1_length(&body);
     
     if (value->len == ASN1_INVALID_LENGTH)
+    {
        return "Invalid attribute string length";
-
+    }
     value->ptr = body.ptr;
 
     /* are there any RDNs left? */
@@ -529,27 +539,39 @@ dn_parse(chunk_t dn, chunk_t *str)
     err_t ugh = init_rdn(dn, &rdn, &attribute, &next);
 
     if (ugh != NULL) /* a parsing error has occured */
+    {
         return ugh;
+    }
 
     while (next)
     {
        ugh = get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next);
 
        if (ugh != NULL) /* a parsing error has occured */
+       {
            return ugh;
+       }
 
        if (first)              /* first OID/value pair */
+       {
            first = FALSE;
+       }
        else                    /* separate OID/value pair by a comma */
+       {
            update_chunk(str, snprintf(str->ptr,str->len,", "));
+       }
 
        /* print OID */
        oid_code = known_oid(oid);
        if (oid_code == OID_UNKNOWN)    /* OID not found in list */
+       {
            hex_str(oid, str);
+       }
        else
+       {
            update_chunk(str, snprintf(str->ptr,str->len,"%s",
                              oid_names[oid_code].name));
+       }
 
        /* print value */
        update_chunk(str, snprintf(str->ptr,str->len,"=%.*s",
@@ -572,16 +594,22 @@ dn_count_wildcards(chunk_t dn)
     err_t ugh = init_rdn(dn, &rdn, &attribute, &next);
 
     if (ugh != NULL) /* a parsing error has occured */
+    {
         return -1;
+    }
 
     while (next)
     {
        ugh = get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next);
 
        if (ugh != NULL) /* a parsing error has occured */
+       {
            return -1;
+       }
        if (value.len == 1 && *value.ptr == '*')
+       {
            wildcards++; /* we have found a wildcard RDN */
+       }
     }
     return wildcards;
 }
@@ -631,9 +659,13 @@ int
 dntoa_or_null(char *dst, size_t dstlen, chunk_t dn, const char* null_dn)
 {
     if (dn.ptr == NULL)
+    {
        return snprintf(dst, dstlen, "%s", null_dn);
+    }
     else
+    {
        return dntoa(dst, dstlen, dn);
+    }
 }
 
 /*  Converts an LDAP-style human-readable ASCII-encoded
@@ -692,14 +724,18 @@ atodn(char *src, chunk_t *dn)
            break;
        case READ_OID:
            if (*src != ' ' && *src != '=')
+           {
                oid.len++;
+           }
            else
            {
                for (pos = 0; pos < X501_RDN_ROOF; pos++)
                {
                    if (strlen(x501rdns[pos].name) == oid.len &&
                        strncasecmp(x501rdns[pos].name, oid.ptr, oid.len) == 0)
+                   {
                        break; /* found a valid OID */
+                   }
                }
                if (pos == X501_RDN_ROOF)
                {
@@ -728,9 +764,13 @@ atodn(char *src, chunk_t *dn)
            {
                name.len++;
                if (*src == ' ')
+               {
                    whitespace++;
+               }
                else
+               {
                    whitespace = 0;
+               }
            }
            else
            {
@@ -796,16 +836,22 @@ same_dn(chunk_t a, chunk_t b)
 
     /* same lengths for the DNs */
     if (a.len != b.len)
+    {
        return FALSE;
+    }
 
     /* try a binary comparison first */
-    if (memcmp(a.ptr, b.ptr, b.len) == 0)
+    if (memeq(a.ptr, b.ptr, b.len))
+    {
        return TRUE;
+    }
+
     /* initialize DN parsing */
     if (init_rdn(a, &rdn_a, &attribute_a, &next_a) != NULL
     ||  init_rdn(b, &rdn_b, &attribute_b, &next_b) != NULL)
+    {
        return FALSE;
+    }
 
     /* fetch next RDN pair */
     while (next_a && next_b)
@@ -819,28 +865,38 @@ same_dn(chunk_t a, chunk_t b)
 
        /* OIDs must agree */
        if (oid_a.len != oid_b.len || memcmp(oid_a.ptr, oid_b.ptr, oid_b.len) != 0)
+       {
            return FALSE;
+       }
 
        /* same lengths for values */
        if (value_a.len != value_b.len)
+       {
            return FALSE;
+       }
 
        /* printableStrings and email RDNs require uppercase comparison */
        if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING ||
           (type_a == ASN1_IA5STRING && known_oid(oid_a) == OID_PKCS9_EMAIL)))
        {
            if (strncasecmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
+           {
                return FALSE;
+           }
        }
        else
        {
            if (strncmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
+           {
                return FALSE;
+           }
        }
     }
     /* both DNs must have same number of RDNs */
     if (next_a || next_b)
+    {
        return FALSE;
+    }
 
     /* the two DNs are equal! */
     return TRUE;
@@ -864,7 +920,9 @@ match_dn(chunk_t a, chunk_t b, int *wildcards)
     /* initialize DN parsing */
     if (init_rdn(a, &rdn_a, &attribute_a, &next_a) != NULL
     ||  init_rdn(b, &rdn_b, &attribute_b, &next_b) != NULL)
+    {
        return FALSE;
+    }
 
     /* fetch next RDN pair */
     while (next_a && next_b)
@@ -878,7 +936,9 @@ match_dn(chunk_t a, chunk_t b, int *wildcards)
 
        /* OIDs must agree */
        if (oid_a.len != oid_b.len || memcmp(oid_a.ptr, oid_b.ptr, oid_b.len) != 0)
+       {
            return FALSE;
+       }
 
        /* does rdn_b contain a wildcard? */
        if (value_b.len == 1 && *value_b.ptr == '*')
@@ -889,24 +949,33 @@ match_dn(chunk_t a, chunk_t b, int *wildcards)
 
        /* same lengths for values */
        if (value_a.len != value_b.len)
+       {
            return FALSE;
+       }
 
        /* printableStrings and email RDNs require uppercase comparison */
        if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING ||
           (type_a == ASN1_IA5STRING && known_oid(oid_a) == OID_PKCS9_EMAIL)))
        {
            if (strncasecmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
+           {
                return FALSE;
+           }
        }
        else
        {
            if (strncmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
+           {
                return FALSE;
+           }
        }
     }
+
     /* both DNs must have same number of RDNs */
     if (next_a || next_b)
+    {
        return FALSE;
+    }
 
     /* the two DNs match! */
     return TRUE;
@@ -928,7 +997,9 @@ void
 share_x509cert(x509cert_t *cert)
 {
     if (cert != NULL)
+    {
        cert->count++;
+    }
 }
 
 /*
@@ -1009,8 +1080,9 @@ bool
 same_keyid(chunk_t a, chunk_t b)
 {
     if (a.ptr == NULL || b.ptr == NULL)
+    {
        return FALSE;
-
+    }
     return same_chunk(a, b);
 }
 
@@ -1022,8 +1094,9 @@ same_serial(chunk_t a, chunk_t b)
 {
     /* do not compare serial numbers if one of them is not defined */
     if (a.ptr == NULL || b.ptr == NULL)
+    {
        return TRUE;
-
+    }
     return same_chunk(a, b);
 }
 
@@ -1175,7 +1248,9 @@ release_x509cert(x509cert_t *cert)
     {
        x509cert_t **pp = &x509certs;
        while (*pp != cert)
+       {
            pp = &(*pp)->next;
+       }
         *pp = cert->next;
        free_x509cert(cert);
     }
@@ -1215,7 +1290,9 @@ store_x509certs(x509cert_t **firstcert, bool strict)
            }
        }
        else
+       {
            pp = &cert->next;
+       }
     }
 
     /* now verify the candidate CA certs */
@@ -1330,9 +1407,13 @@ check_signature(chunk_t tbs, chunk_t sig, int digest_alg, int enc_alg
 
     DBG(DBG_PARSING,
        if (digest_alg != OID_UNKNOWN)
+       {
            DBG_log("signature digest algorithm: '%s'",oid_names[digest_alg].name);
+       }
        else
+       {
            DBG_log("unknown signature digest algorithm");
+       }
     )
 
     if (!compute_digest(tbs, digest_alg, &digest))
@@ -1349,9 +1430,13 @@ check_signature(chunk_t tbs, chunk_t sig, int digest_alg, int enc_alg
 
     DBG(DBG_PARSING,
        if (enc_alg != OID_UNKNOWN)
+       {
            DBG_log("signature encryption algorithm: '%s'",oid_names[enc_alg].name);
+       }
        else
+       {
            DBG_log("unknown signature encryption algorithm");
+       }
     )
 
     if (!decrypt_sig(sig, enc_alg, issuer_cert, &decrypted))
@@ -1361,7 +1446,7 @@ check_signature(chunk_t tbs, chunk_t sig, int digest_alg, int enc_alg
     }
 
     /* check if digests are equal */
-    return !memcmp(decrypted.ptr, digest.ptr, digest.len);
+    return memeq(decrypted.ptr, digest.ptr, digest.len);
 }
 
 /*
@@ -1382,8 +1467,9 @@ parse_basicConstraints(chunk_t blob, int level0)
 
        if (!extract_object(basicConstraintsObjects, &objectID,
                            &object,&level, &ctx))
+       {
             break;
-
+       }
        if (objectID == BASIC_CONSTRAINTS_CA)
        {
            isCA = object.len && *object.ptr;
@@ -1460,7 +1546,9 @@ parse_otherName(chunk_t blob, int level0)
     while (objectID < ON_OBJ_ROOF)
     {
        if (!extract_object(otherNameObjects, &objectID, &object, &level, &ctx))
+       {
             return FALSE;
+       }
 
        switch (objectID)
        {
@@ -1505,7 +1593,9 @@ parse_generalName(chunk_t blob, int level0)
        bool valid_gn = FALSE;
        
        if (!extract_object(generalNameObjects, &objectID, &object, &level, &ctx))
+       {
             return NULL;
+       }
 
        switch (objectID) {
        case GN_OBJ_RFC822_NAME:
@@ -1574,8 +1664,9 @@ parse_generalNames(chunk_t blob, int level0, bool implicit)
     while (objectID < GENERAL_NAMES_ROOF)
     {
        if (!extract_object(generalNamesObjects, &objectID, &object, &level, &ctx))
+       {
             return NULL;
-            
+       }
        if (objectID == GENERAL_NAMES_GN)
        {
            generalName_t *gn = parse_generalName(object, level+1);
@@ -1599,10 +1690,10 @@ chunk_t get_directoryName(chunk_t blob, int level, bool implicit)
     generalName_t * gn = parse_generalNames(blob, level, implicit);
 
     if (gn != NULL && gn->kind == GN_DIRECTORY_NAME)
+    {
        name= gn->name;
-
+    }
     free_generalNames(gn, FALSE);
-
     return name;
 }
 
@@ -1622,8 +1713,9 @@ parse_time(chunk_t blob, int level0)
     while (objectID < TIME_ROOF)
     {
        if (!extract_object(timeObjects, &objectID, &object, &level, &ctx))
+       {
             return UNDEFINED_TIME;
-
+       }
        if (objectID == TIME_UTC || objectID == TIME_GENERALIZED)
        {
            return asn1totime(&object, (objectID == TIME_UTC)
@@ -1668,9 +1760,11 @@ parse_authorityKeyIdentifier(chunk_t blob, int level0
     while (objectID < AUTH_KEY_ID_ROOF)
     {
        if (!extract_object(authorityKeyIdentifierObjects, &objectID, &object, &level, &ctx))
+       {
             return;
-
-       switch (objectID) {
+       }
+       switch (objectID)
+       {
        case AUTH_KEY_ID_KEY_ID:
            *authKeyID = parse_keyIdentifier(object, level+1, TRUE);
            break;
@@ -1708,9 +1802,12 @@ parse_authorityInfoAccess(chunk_t blob, int level0, chunk_t *accessLocation)
     while (objectID < AUTH_INFO_ACCESS_ROOF)
     {
        if (!extract_object(authorityInfoAccessObjects, &objectID, &object, &level, &ctx))
+       {
             return;
+       }
 
-       switch (objectID) {
+       switch (objectID)
+       {
        case AUTH_INFO_ACCESS_METHOD:
            accessMethod = known_oid(object);
            break;
@@ -1722,8 +1819,9 @@ parse_authorityInfoAccess(chunk_t blob, int level0, chunk_t *accessLocation)
                    if (*object.ptr == ASN1_CONTEXT_S_6)
                    {
                        if (asn1_length(&object) == ASN1_INVALID_LENGTH)
+                       {
                            return;
-
+                       }
                        DBG(DBG_PARSING,
                            DBG_log("  '%.*s'",(int)object.len, object.ptr)
                        )
@@ -1768,11 +1866,14 @@ parse_extendedKeyUsage(chunk_t blob, int level0)
     {
        if (!extract_object(extendedKeyUsageObjects, &objectID
                            , &object, &level, &ctx))
+       {
             return FALSE;
-
+       }
        if (objectID == EXT_KEY_USAGE_PURPOSE_ID
        && known_oid(object) == OID_OCSP_SIGNING)
+       {
            return TRUE;
+       }
        objectID++;
     }
     return FALSE;
@@ -1798,8 +1899,9 @@ parse_crlDistributionPoints(chunk_t blob, int level0)
     {
        if (!extract_object(crlDistributionPointsObjects, &objectID,
                            &object, &level, &ctx))
+       {
             return NULL;
-
+       }
        if (objectID == CRL_DIST_POINTS_FULLNAME)
        {
            generalName_t *gn = parse_generalNames(object, level+1, TRUE);
@@ -1836,7 +1938,9 @@ parse_x509cert(chunk_t blob, u_int level0, x509cert_t *cert)
     while (objectID < X509_OBJ_ROOF)
     {
        if (!extract_object(certObjects, &objectID, &object, &level, &ctx))
+       {
             return FALSE;
+       }
 
        /* those objects which will parsed further need the next higher level */
        level++;
@@ -1882,7 +1986,9 @@ parse_x509cert(chunk_t blob, u_int level0, x509cert_t *cert)
            break;
        case X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM:
            if (parse_algorithmIdentifier(object, level, NULL) == OID_RSA_ENCRYPTION)
+           {
                cert->subjectPublicKeyAlgorithm = PUBKEY_ALG_RSA;
+           }
            else
            {
                plog("  unsupported public key algorithm");
@@ -2003,14 +2109,22 @@ check_validity(const x509cert_t *cert, time_t *until)
        DBG_log("  not after   : %s", timetoa(&cert->notAfter, TRUE));
     )
 
-    if (cert->notAfter < *until) *until = cert->notAfter;
-
+    if (cert->notAfter < *until)
+    {
+       *until = cert->notAfter;
+    }
     if (current_time < cert->notBefore)
+    {
        return "certificate is not valid yet";
+    }
     if (current_time > cert->notAfter)
+    {
        return "certificate has expired";
+    }
     else
+    {
        return NULL;
+    }
 }
 
 /*
@@ -2126,7 +2240,9 @@ verify_x509cert(const x509cert_t *cert, bool strict, time_t *until)
                 * lifetime as the validity of the ocsp status or crl lifetime
                 */
                if (strict && nextUpdate < *until)
+               {
                    *until = nextUpdate;
+               }
                break;
            case CERT_REVOKED:
                plog("certificate was revoked on %s, reason: %s"
index 8a9ba54c93a0714576735d8ef0d895e762fad227..e9c707c2b1045b6f6712d926a7c80e52b9c4221d 100644 (file)
@@ -5,7 +5,14 @@ starterstroke.h interfaces.c invokepluto.h confread.h interfaces.h args.c \
 keywords.c files.h keywords.h cmp.c starter.c cmp.h exec.c invokecharon.c \
 exec.h invokecharon.h lex.yy.c loglite.c klips.c klips.h
 
-INCLUDES = -I${linuxdir} -I$(top_srcdir)/src/libfreeswan -I$(top_srcdir)/src/pluto -I$(top_srcdir)/src/whack -I$(top_srcdir)/src/stroke
+INCLUDES = \
+-I${linuxdir} \
+-I$(top_srcdir)/src/libstrongswan \
+-I$(top_srcdir)/src/libfreeswan \
+-I$(top_srcdir)/src/pluto \
+-I$(top_srcdir)/src/whack \
+-I$(top_srcdir)/src/stroke
+
 AM_CFLAGS = -DIPSEC_DIR=\"${ipsecdir}\" -DIPSEC_CONFDIR=\"${confdir}\" -DIPSEC_PIDDIR=\"${piddir}\" -DIPSEC_EAPDIR=\"${eapdir}\" -DDEBUG
 starter_LDADD = defs.o $(top_builddir)/src/libfreeswan/libfreeswan.a
 EXTRA_DIST = parser.l parser.y keywords.txt ipsec.conf
index b5f716069bc64be090237d9f630f3bde12d9f35a..825824586368be4d4af2717f1580052838957ec8 100644 (file)
@@ -249,11 +249,16 @@ static const token_info_t token_info[] =
     { ARG_ENUM, offsetof(starter_end_t, hostaccess), LST_bool                      },
     { ARG_ENUM, offsetof(starter_end_t, allow_any), LST_bool                       },
     { ARG_STR,  offsetof(starter_end_t, updown), NULL                              },
+    { ARG_STR,  offsetof(starter_end_t, auth), NULL                                },
+    { ARG_STR,  offsetof(starter_end_t, auth2), NULL                               },
     { ARG_STR,  offsetof(starter_end_t, id), NULL                                  },
+    { ARG_STR,  offsetof(starter_end_t, id2), NULL                                 },
     { ARG_STR,  offsetof(starter_end_t, rsakey), NULL                              },
     { ARG_STR,  offsetof(starter_end_t, cert), NULL                                },
+    { ARG_STR,  offsetof(starter_end_t, cert2), NULL                               },
     { ARG_ENUM, offsetof(starter_end_t, sendcert), LST_sendcert                    },
     { ARG_STR,  offsetof(starter_end_t, ca), NULL                                  },
+    { ARG_STR,  offsetof(starter_end_t, ca2), NULL                                 },
     { ARG_STR,  offsetof(starter_end_t, groups), NULL                              },
     { ARG_STR,  offsetof(starter_end_t, iface), NULL                               }
 };
index ed344fe6fb44b4be7c1fb164918af7b4a170684e..3d4829ea18eb5ab06fd78fd39a09283d68e251b9 100644 (file)
@@ -20,7 +20,6 @@
 
 #ifndef _FREESWAN_H
 #include <freeswan.h>
-#include "../pluto/constants.h"
 #endif
 
 #include "parser.h"
@@ -57,10 +56,15 @@ typedef struct starter_end starter_end_t;
 
 struct starter_end {
        lset_t          seen;
+       char            *auth;
+       char            *auth2;
        char            *id;
+       char            *id2;
        char            *rsakey;
        char            *cert;
+       char            *cert2;
        char            *ca;
+       char            *ca2;
        char            *groups;
        char            *iface;
        ip_address      addr;
index 1cce4e41d8f1d613e055d0d891471af972c137d3..a511f55ddeb7333a32cd59e0ca2a8ca242eda0cd 100644 (file)
@@ -109,7 +109,7 @@ starter_stop_charon (void)
 
 
 int
-starter_start_charon (starter_config_t *cfg, bool no_fork)
+starter_start_charon (starter_config_t *cfg, bool no_fork, bool attach_gdb)
 {
     struct stat stb;
     int pid, i;
@@ -121,7 +121,14 @@ starter_start_charon (starter_config_t *cfg, bool no_fork)
        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
     };
-
+    
+    if (attach_gdb)
+    {
+       argc = 0;
+       arg[argc++] = "/usr/bin/gdb";
+       arg[argc++] = "--args";
+       arg[argc++] = CHARON_CMD;
+       }
     if (!no_fork)
     {
        arg[argc++] = "--use-syslog";
index f62221da631223d5e2a15cc49926205916abc296..03c592f1e00569e98547d45f54461681fc253ad6 100644 (file)
@@ -25,7 +25,7 @@
 extern void starter_charon_sigchild (pid_t pid);
 extern pid_t starter_charon_pid (void);
 extern int starter_stop_charon (void);
-extern int starter_start_charon(struct starter_config *cfg, bool debug);
+extern int starter_start_charon(struct starter_config *cfg, bool no_fork, bool attach_gdb);
 
 #endif /* _STARTER_CHARON_H_ */
 
index 6fdf46ffdd337cd6a7c358cfef9ae6ed6b66802b..5e840bac2edfe7778197408353df43652dca3360 100644 (file)
@@ -121,7 +121,7 @@ starter_stop_pluto (void)
        }
 
 int
-starter_start_pluto (starter_config_t *cfg, bool no_fork)
+starter_start_pluto (starter_config_t *cfg, bool no_fork, bool attach_gdb)
 {
     struct stat stb;
     int i;
@@ -137,7 +137,15 @@ starter_start_pluto (starter_config_t *cfg, bool no_fork)
        };
 
     printf ("starter_start_pluto entered\n");
-
+    
+    if (attach_gdb)
+    {
+       argc = 0;
+       arg[argc++] = "/usr/bin/gdb";
+       arg[argc++] = "--args";
+       arg[argc++] = PLUTO_CMD;
+       arg[argc++] = "--nofork";
+       }
     if (cfg->setup.plutostderrlog || no_fork)
     {
        arg[argc++] = "--stderrlog";
index 6366d1f50c35561065eac39443b78d98f55d0a92..768bec28cce9116dac6d0ab5cd2e0b403fba6c34 100644 (file)
@@ -22,7 +22,7 @@
 extern void starter_pluto_sigchild (pid_t pid);
 extern pid_t starter_pluto_pid (void);
 extern int starter_stop_pluto (void);
-extern int starter_start_pluto (struct starter_config *cfg, bool debug);
+extern int starter_start_pluto (struct starter_config *cfg, bool no_fork, bool attach_gdb);
 
 #endif /* _STARTER_PLUTO_H_ */
 
index c9074868a9e6084993e42b78e71aea6ad8d68325..2567dfe7e646bb6cde9b33aacd633ccf1a0c8f2f 100644 (file)
@@ -246,20 +246,17 @@ for RSA digital signatures (the default),
 for either, and
 .B never
 if negotiation is never to be attempted or accepted (useful for shunt-only conns).
-Digital signatures are superior in every way to shared secrets. In IKEv2, the
-two ends must not agree on this parameter, it is relevant for the
-outbound authentication method only.
+Digital signatures are superior in every way to shared secrets. 
 IKEv1 additionally supports the values
 .B xauthpsk
 and
 .B xauthrsasig
 that will enable eXtended AUTHentication (XAUTH) in addition to IKEv1 main mode
 based on shared secrets  or digital RSA signatures, respectively.
-IKEv2 additionally supports the value
-.B eap,
-which indicates an initiator to request EAP authentication. The EAP method to 
-use is selected by the server (see
-.B eap).
+This parameter is deprecated for IKEv2 connections, as two peers do not need
+to agree on an authentication method. Use the 
+.B leftauth
+parameter instead to define authentication methods in IKEv2.
 .TP
 .B auto
 what operation, if any, should be done automatically at IPsec startup;
@@ -350,25 +347,9 @@ 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 propose as server if the client has 
-.B authby=eap
-selected. Acceptable values are
-.B aka
-for EAP-AKA,
-.B sim
-for EAP-SIM,
-.B gtc
-for EAP-GTC,
-.B md5
-for EAP-MD5, and
-.B mschapv2
-for EAP-MS-CHAPv2.
-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.
+defines the EAP type to propose as server if the client requests EAP
+authentication. This parameter is deprecated in the favour of
+.B leftauth.
 
 To forward EAP authentication to a RADIUS server using the EAP-RADIUS plugin,
 set 
@@ -509,11 +490,46 @@ and
 .B no
 (the default).
 .TP
+.B leftauth
+Authentication method to use (local) or require (remote) in this connection.
+This parameter is supported in IKEv2 only. Acceptable values are 
+.B pubkey
+for public key authentication (RSA/ECDSA), 
+.B psk
+for pre-shared key authentication and
+.B eap
+to (require the) use of the Extensible Authentication Protocol. In the case
+of 
+.B eap,
+an optional EAP method can be appended. Currently defined methods are
+.B eap-aka, eap-sim, eap-gtc, eap-md5
+and
+.B eap-mschapv2.
+Alternatively, IANA assigned EAP method numbers are accepted. Vendor specific
+EAP methods are defined in the form
+.B eap-type-vendor
+(e.g.
+.B eap-7-12345
+).
+.TP
+.B leftauth2
+Same as 
+.B leftauth,
+but defines an additional authentication exchange. IKEv2 supports multiple
+authentication rounds using "Multiple Authentication Exchanges" defined
+in RFC4739. This allows, for example, separated authentication
+of host and user (IKEv2 only).
+.TP
 .B leftca
 the distinguished name of a certificate authority which is required to
 lie in the trust path going from the left participant's certificate up
 to the root certification authority. 
 .TP
+.B leftca2
+Same as
+.B leftca,
+but for the second authentication round (IKEv2 only).
+.TP
 .B leftcert
 the path to the left participant's X.509 certificate. The file can be coded either in
 PEM or DER format. OpenPGP certificates are supported as well.
@@ -529,6 +545,11 @@ The left participant's ID can be overriden by specifying a
 .B leftid
 value which must be certified by the certificate, though.
 .TP
+.B leftcert2
+Same as
+.B leftcert,
+but for the second authentication round (IKEv2 only).
+.TP
 .B leftfirewall
 whether the left participant is doing forwarding-firewalling
 (including masquerading) using iptables for traffic from \fIleftsubnet\fR,
@@ -594,6 +615,11 @@ or a fully-qualified domain name preceded by
 .B @
 (which is used as a literal string and not resolved).
 .TP
+.B leftid2
+identity to use for a second authentication for the left participant
+(IKEv2 only); defaults to
+.BR leftid .
+.TP
 .B leftnexthop
 this parameter is not needed any more because the NETKEY IPsec stack does
 not require explicit routing entries for the traffic to be tunneled.
index 17789d9bd1a70bab2f6854f9976f6bd004018ebc..3b6704450e35c0d85d2874d36a8fb8629413a5aa 100644 (file)
@@ -147,11 +147,16 @@ typedef enum {
     KW_LEFTHOSTACCESS,
     KW_LEFTALLOWANY,
     KW_LEFTUPDOWN,
+    KW_LEFTAUTH,
+    KW_LEFTAUTH2,
     KW_LEFTID,
+    KW_LEFTID2,
     KW_LEFTRSASIGKEY,
     KW_LEFTCERT,
+    KW_LEFTCERT2,
     KW_LEFTSENDCERT,
     KW_LEFTCA,
+    KW_LEFTCA2,
     KW_LEFTGROUPS,
 
 #define KW_LEFT_FIRST  KW_LEFT
@@ -169,11 +174,16 @@ typedef enum {
     KW_RIGHTHOSTACCESS,
     KW_RIGHTALLOWANY,
     KW_RIGHTUPDOWN,
+    KW_RIGHTAUTH,
+    KW_RIGHTAUTH2,
     KW_RIGHTID,
+    KW_RIGHTID2,
     KW_RIGHTRSASIGKEY,
     KW_RIGHTCERT,
+    KW_RIGHTCERT2,
     KW_RIGHTSENDCERT,
     KW_RIGHTCA,
+    KW_RIGHTCA2,
     KW_RIGHTGROUPS,
 
 #define KW_RIGHT_FIRST KW_RIGHT
index d834fe42590024b7d93245695c3b8f0b37bd103c..be8f305feaa18206f4234cb0bee2448eb09d9988 100644 (file)
@@ -104,10 +104,15 @@ lefthostaccess,    KW_LEFTHOSTACCESS
 leftallowany,      KW_LEFTALLOWANY
 leftupdown,        KW_LEFTUPDOWN
 leftid,            KW_LEFTID
+leftid2,           KW_LEFTID2
+leftauth,          KW_LEFTAUTH
+leftauth2,         KW_LEFTAUTH2
 leftrsasigkey,     KW_LEFTRSASIGKEY
 leftcert,          KW_LEFTCERT,
+leftcert2,         KW_LEFTCERT2,
 leftsendcert,      KW_LEFTSENDCERT
 leftca,            KW_LEFTCA
+leftca2,           KW_LEFTCA2
 leftgroups,        KW_LEFTGROUPS
 right,             KW_RIGHT
 rightnexthop,      KW_RIGHTNEXTHOP
@@ -121,10 +126,15 @@ righthostaccess,   KW_RIGHTHOSTACCESS
 rightallowany,     KW_RIGHTALLOWANY
 rightupdown,       KW_RIGHTUPDOWN
 rightid,           KW_RIGHTID
+rightid2,          KW_RIGHTID2
+rightauth,         KW_RIGHTAUTH
+rightauth2,        KW_RIGHTAUTH2
 rightrsasigkey,    KW_RIGHTRSASIGKEY
 rightcert,         KW_RIGHTCERT
+rightcert2,        KW_RIGHTCERT2
 rightsendcert,     KW_RIGHTSENDCERT
 rightca,           KW_RIGHTCA
+rightca2,          KW_RIGHTCA2
 rightgroups,       KW_RIGHTGROUPS
 also,              KW_ALSO
 auto,              KW_AUTO
index de85675839aaf5dd3535f13b0630f869b504fcde..a299d5671118f5ba28121ace420091c70ca518b3 100644 (file)
@@ -224,6 +224,7 @@ int main (int argc, char **argv)
     unsigned long auto_update = 0;
     time_t last_reload;
     bool no_fork = FALSE;
+    bool attach_gdb = FALSE;
 
     /* global variables defined in log.h */
     log_to_stderr = TRUE;
@@ -248,6 +249,11 @@ int main (int argc, char **argv)
        {
            no_fork = TRUE;
        }
+       else if (streq(argv[i], "--attach-gdb"))
+       {
+           no_fork = TRUE;
+           attach_gdb = TRUE;
+       }
        else if (streq(argv[i], "--auto-update") && i+1 < argc)
        {
            auto_update = atoi(argv[++i]);
@@ -571,7 +577,7 @@ int main (int argc, char **argv)
                    DBG_log("Attempting to start pluto...")
                   );
 
-               if (starter_start_pluto(cfg, no_fork) == 0)
+               if (starter_start_pluto(cfg, no_fork, attach_gdb) == 0)
                {
                    starter_whack_listen();
                }
@@ -606,7 +612,7 @@ int main (int argc, char **argv)
                DBG(DBG_CONTROL,
                    DBG_log("Attempting to start charon...")
                   );
-               if (starter_start_charon(cfg, no_fork))
+               if (starter_start_charon(cfg, no_fork, attach_gdb))
                {
                    /* schedule next try */
                    alarm(PLUTO_RESTART_DELAY);
index 9ce7edee3b7aecc231c7635f8578d772efd34f32..a695feb46335d4ac5c75caebb0e6036978859fbf 100644 (file)
@@ -164,9 +164,14 @@ static void starter_stroke_add_end(stroke_msg_t *msg, stroke_end_t *msg_end, sta
 {
        char buffer[INET6_ADDRSTRLEN];
        
+       msg_end->auth = push_string(msg, conn_end->auth);
+       msg_end->auth2 = push_string(msg, conn_end->auth2);
        msg_end->id = push_string(msg, conn_end->id);
+       msg_end->id2 = push_string(msg, conn_end->id2);
        msg_end->cert = push_string(msg, conn_end->cert);
+       msg_end->cert2 = push_string(msg, conn_end->cert2);
        msg_end->ca = push_string(msg, conn_end->ca);
+       msg_end->ca2 = push_string(msg, conn_end->ca2);
        msg_end->groups = push_string(msg, conn_end->groups);
        msg_end->updown = push_string(msg, conn_end->updown);
        ip_address2string(&conn_end->addr, buffer, sizeof(buffer));
index 3061e2da5058b44003eff2aaf6c6a9348aa5ceb2..42cbf97a1c8927276159381279fb5cd143b49f5b 100644 (file)
@@ -123,9 +123,15 @@ typedef struct stroke_end_t stroke_end_t;
  * definition of a peer in a stroke message
  */
 struct stroke_end_t {
+       char *auth;
+       char *auth2;
        char *id;
+       char *id2;
+       char *eap_id;
        char *cert;
+       char *cert2;
        char *ca;
+       char *ca2;
        char *groups;
        char *updown;
        char *address;
@@ -206,6 +212,7 @@ struct stroke_msg_t {
                struct {
                        char *name;
                        int ikev2;
+                       /* next three are deprecated, use stroke_end_t.auth instead */
                        int auth_method;
                        u_int32_t eap_type;
                        u_int32_t eap_vendor;
index 985245026751a8f08a4cb4d645bbf67619caffb5..69cc11afe7df0d8b3edc681d4be38bf5c96e2579 100644 (file)
@@ -1,7 +1,12 @@
 ipsec_PROGRAMS = whack
 
 whack_SOURCES = whack.c whack.h
-INCLUDES = -I$(top_srcdir)/src/libfreeswan -I$(top_srcdir)/src/pluto
+
+INCLUDES = \
+-I$(top_srcdir)/src/libstrongswan \
+-I$(top_srcdir)/src/libfreeswan \
+-I$(top_srcdir)/src/pluto
+
 whack_LDADD = $(top_builddir)/src/libfreeswan/libfreeswan.a
 
 AM_CFLAGS = -DDEBUG
index 64b725536e4888b6cdc3e42d8d7eeef0c3da7470..9e5194ebc2cf25190f30f1a928498b79d8c231ff 100644 (file)
@@ -18,3 +18,4 @@ V     111007121250Z           11      unknown /C=CH/O=Linux strongSwan/OU=SHA-384/CN=carol@strongs
 V      111007122112Z           12      unknown /C=CH/O=Linux strongSwan/OU=SHA-512/CN=dave@strongswan.org
 V      120224075857Z           13      unknown /C=CH/O=Linux strongSwan/OU=OCSP/CN=carol@strongswan.org
 V      120425210745Z           14      unknown /C=CH/O=Linux strongSwan/CN=winnetou.strongswan.org
+V      140406120117Z           15      unknown /C=CH/O=Linux strongSwan/OU=Research/serialNumber=002/CN=carol@strongswan.org
index 12025d75c960295ba1fe428a24699fe904af6188..64b725536e4888b6cdc3e42d8d7eeef0c3da7470 100644 (file)
@@ -11,9 +11,10 @@ V    091231214318Z           0A      unknown /C=CH/O=Linux strongSwan/OU=Research/CN=carol@strong
 V      100216084430Z           0B      unknown /C=CH/O=Linux strongSwan/OU=Authorization Authority/CN=aa@strongswan.org
 R      140321062536Z   050621195214Z   0C      unknown /C=CH/O=Linux strongSwan/OU=Research/CN=Research CA
 V      140321062916Z           0D      unknown /C=CH/O=Linux strongSwan/OU=Sales/CN=Sales CA
-V      100607191714Z           0E      unknown /C=CH/O=Linux strongSwan/CN=winnetou.strongswan.org
+R      100607191714Z   070427213122Z   0E      unknown /C=CH/O=Linux strongSwan/CN=winnetou.strongswan.org
 V      100620195806Z           0F      unknown /C=CH/O=Linux strongSwan/OU=Research/CN=Research CA
 V      111007105811Z           10      unknown /C=CH/O=Linux strongSwan/OU=SHA-256/CN=moon.strongswan.org
 V      111007121250Z           11      unknown /C=CH/O=Linux strongSwan/OU=SHA-384/CN=carol@strongswan.org
 V      111007122112Z           12      unknown /C=CH/O=Linux strongSwan/OU=SHA-512/CN=dave@strongswan.org
 V      120224075857Z           13      unknown /C=CH/O=Linux strongSwan/OU=OCSP/CN=carol@strongswan.org
+V      120425210745Z           14      unknown /C=CH/O=Linux strongSwan/CN=winnetou.strongswan.org
diff --git a/testing/hosts/winnetou/etc/openssl/newcerts/15.pem b/testing/hosts/winnetou/etc/openssl/newcerts/15.pem
new file mode 100644 (file)
index 0000000..4ebebba
--- /dev/null
@@ -0,0 +1,25 @@
+-----BEGIN CERTIFICATE-----
+MIIEMDCCAxigAwIBAgIBFTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJDSDEZ
+MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEbMBkGA1UEAxMSc3Ryb25nU3dhbiBS
+b290IENBMB4XDTA5MDQwNzEyMDExN1oXDTE0MDQwNjEyMDExN1owaDELMAkGA1UE
+BhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xETAPBgNVBAsTCFJlc2Vh
+cmNoMQwwCgYDVQQFEwMwMDIxHTAbBgNVBAMUFGNhcm9sQHN0cm9uZ3N3YW4ub3Jn
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtXtFcjNbEEK76mVv1j3c
+6YWBeunBl7V9Qf1bPpzwTTUIKFDkg6HtWaNa7fxhTtHlPFHH8hdgiEZTQt626GoH
+8DKE1MaBOgvnW01vh2p1j8jW3VXSwBWBCM9vNnaxGic94Qiix6z+cAulCo1pzyY1
+XaJSGAvwG3Jap9/gChClAv65zg34mLWZpcXddUGoaOMu3JaRgVaNEiY4wGweMM3n
+hgxJ7+3q9vX+z5EqUQB59WBzVz7fU9FygLgfeAD1McrvMQOjo/PtkpEBOJipnjq9
+0k/+Z3gKIHbi6YIoIXDs7bOSaw8myvD5Bi4vNr5tKPr7bdLBU+AyAzRlJWV4GBw/
+rQIDAQABo4IBBjCCAQIwCQYDVR0TBAIwADALBgNVHQ8EBAMCA6gwHQYDVR0OBBYE
+FABqD2vvGFgP2xX2Qqjx26Mz1RR5MG0GA1UdIwRmMGSAFF2n3XAGUTJ+57Zts7Xl
+4GDqLk3voUmkRzBFMQswCQYDVQQGEwJDSDEZMBcGA1UEChMQTGludXggc3Ryb25n
+U3dhbjEbMBkGA1UEAxMSc3Ryb25nU3dhbiBSb290IENBggEAMB8GA1UdEQQYMBaB
+FGNhcm9sQHN0cm9uZ3N3YW4ub3JnMDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly9j
+cmwuc3Ryb25nc3dhbi5vcmcvc3Ryb25nc3dhbi5jcmwwDQYJKoZIhvcNAQEFBQAD
+ggEBAGuatpu8jxc22Iqglx5UIa8fkNSjfyLgO0RugCB+kPPilGttGWly+raLggQM
+Hu1qdt4l0cj60pe03Dc4GuUwJCW9J4ntVvCp1/SLcifvd3pMTtlrdSMpj105L5ma
+/nVksJ7UZPzcBLMq/8FtEg68H2WM+ixrmlm2cZiFDytMODEuAPCwWHOSP4WJNDzS
+KKc95ONxwTsD1VDm/ShcKw083XgvT7oHoei2RRDYp70CkatWOOJ7eMxdKdICl8nu
+9RlBLG8CJqcy7cJ4V7GOk6EOtGpGL/GR2gpLpvUnmWP9MUHYu8rVTzKQdW9A2Wjx
+fmSZH0LzbAm+7XFrP71rBSJUaUI=
+-----END CERTIFICATE-----
index 60d3b2f4a4cd5f1637eba020358bfe5ecb5edcf2..b6a7d89c68e0ca66e96a9a51892cc33db66fb8a3 100644 (file)
@@ -1 +1 @@
-15
+16
index 8351c19397f4fcd5238d10034fa7fa384f14d580..60d3b2f4a4cd5f1637eba020358bfe5ecb5edcf2 100644 (file)
@@ -1 +1 @@
-14
+15
index 22fce327c16e032d1efc55a5ea8c872d35d97c8d..917c972c7db8596d36166480919f8b223ef65195 100755 (executable)
@@ -83,3 +83,47 @@ function searchandreplace {
     rm -f "$TMPFILE"
 
 }
+
+#############################################
+# add a bridge
+#
+
+function umlbr_add {
+       brctl addbr     "umlbr$1"
+       brctl setfd     "umlbr$1" 0
+       brctl setageing "umlbr$1" 3600
+       brctl stp       "umlbr$1" off
+       ifconfig        "umlbr$1" "$2" netmask "$3" up 
+}
+
+#############################################
+# delete a bridge
+#
+
+function umlbr_del {
+       ifconfig    "umlbr$1" down                     &> /dev/null 2>&1
+       brctl delbr "umlbr$1"                          &> /dev/null 2>&1
+}
+
+#############################################
+# add a tap interface to a bridge
+#
+
+function umlbr_add_tap {
+       tunctl -t "tap$1_$2"                           &> /dev/null 2>&1
+       ifconfig "tap$1_$2" 0.0.0.0 promisc up         &> /dev/null 2>&1
+       brctl addif "umlbr$1" "tap$1_$2"               &> /dev/null 2>&1
+       cecho-n "$2.."
+ }
+
+#############################################
+# delete a tap interface from a bridge
+#
+
+function umlbr_del_tap {
+       ifconfig "umlbr$2" down                        &> /dev/null 2>&1
+       brctl delif "umlbr$1" "tap$1_$2"               &> /dev/null 2>&1
+       tunctl -d "tap$1_$2"                           &> /dev/null 2>&1
+       cecho-n "$2.."
+ }
+
diff --git a/testing/scripts/start-bridges b/testing/scripts/start-bridges
new file mode 100755 (executable)
index 0000000..676f809
--- /dev/null
@@ -0,0 +1,66 @@
+#!/bin/bash
+# start the UML bridges in the kernel using the brctl command
+#
+# Copyright (C) 2009  Andreas Steffen
+# HSR Hochschule fuer Technik Rapperswil
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# RCSID $Id: $
+
+DIR=`dirname $0`
+
+source $DIR/function.sh
+
+# create umlbr1 and its taps 
+#
+if [ `brctl show | grep umlbr1 | wc -l` -eq 1 ]
+then
+       cecho " * Great, umlbr1 is already running!"
+else
+       cecho-n " * Starting umlbr1 with taps.."
+       umlbr_add     1 10.1.0.254 255.255.0.0
+       umlbr_add_tap 1 alice
+       umlbr_add_tap 1 venus
+       umlbr_add_tap 1 moon
+       cgecho "done"
+fi
+
+# create umlbr0 and its taps
+#
+if [ `brctl show | grep umlbr0 | wc -l` -eq 1 ]
+then
+       cecho " * Great, umlbr0 is already running!"
+else
+       cecho-n " * Starting umlbr0 with taps.."
+       umlbr_add     0 192.168.0.254 255.255.255.0
+       umlbr_add_tap 0 alice
+       umlbr_add_tap 0 moon
+       umlbr_add_tap 0 carol
+       umlbr_add_tap 0 winnetou
+       umlbr_add_tap 0 dave
+       umlbr_add_tap 0 sun
+       cgecho "done"
+fi
+
+# create umlbr2 and its taps
+#
+if [ `brctl show | grep umlbr2 | wc -l` -eq 1 ]
+then
+       cecho " * Great, umlbr2 is already running!"
+else
+       cecho-n " * Starting umlbr2 with taps.."
+       umlbr_add     2 10.2.0.254 255.255.0.0
+       umlbr_add_tap 2 sun
+       umlbr_add_tap 2 bob
+       cgecho "done"
+fi
+
diff --git a/testing/scripts/start-switches b/testing/scripts/start-switches
deleted file mode 100755 (executable)
index 1a6c9d8..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/bash
-# starts the UML switches
-#
-# Copyright (C) 2004  Eric Marchionni, Patrik Rayo
-# Zuercher Hochschule Winterthur
-#
-# 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.
-#
-# RCSID $Id$
-
-DIR=`dirname $0`
-
-source $DIR/function.sh
-
-[ -f $DIR/../testing.conf ] || die "Configuration file 'testing.conf' not found"
-
-source $DIR/../testing.conf
-
-for n in 0 1 2
-do
-    if [ `ps aux | grep uml_switch | grep umlswitch$n | wc -l` -eq 1 ]
-    then
-       cecho " * Great, umlswitch$n is already running!"
-    else
-       cecho-n " * Starting umlswitch$n.."
-       uml_switch -tap tap$n -unix /tmp/umlswitch$n -daemon >/dev/null 2>&1 </dev/null
-       sleep 2
-       eval ifconfig "tap$n \$IFCONFIG_$n up"
-       cgecho "done"
-    fi
-done
diff --git a/testing/scripts/stop-bridges b/testing/scripts/stop-bridges
new file mode 100755 (executable)
index 0000000..9633bfa
--- /dev/null
@@ -0,0 +1,51 @@
+#!/bin/bash
+# stop the UML bridges in the kernel using the brctl command
+#
+# Copyright (C) 2009  Andreas Steffen
+# HSR Hochschule fuer Technik Rapperswil
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# RCSID $Id: $
+
+DIR=`dirname $0`
+
+source $DIR/function.sh
+
+# stop umlbr1 and its taps 
+#
+cecho-n " * Stopping umlbr1 with taps.."
+umlbr_del_tap 1 alice
+umlbr_del_tap 1 venus
+umlbr_del_tap 1 moon
+umlbr_del     1
+cgecho "done"
+
+# stop umlbr0 and its taps
+#
+cecho-n " * Stopping umlbr0 with taps.."
+umlbr_del_tap 0 alice
+umlbr_del_tap 0 moon
+umlbr_del_tap 0 carol
+umlbr_del_tap 0 winnetou
+umlbr_del_tap 0 dave
+umlbr_del_tap 0 sun
+umlbr_del     0
+cgecho "done"
+
+# stop umlbr2 and its taps
+#
+cecho-n " * Stopping umlbr2 with taps.."
+umlbr_del_tap 2 sun
+umlbr_del_tap 2 bob
+umlbr_del     2
+cgecho "done"
+
index 53bf464a4b6e6d8023a31168566daeca8d6d88c3..fb60bcc5c4dff967895796594a67378128678969 100755 (executable)
@@ -33,10 +33,10 @@ else
 fi
 
 #####################################################
-# start the uml switches
+# start the uml bridges
 #
-cecho "Start the uml switches  (scripts/start-switches)"
-$DIR/scripts/start-switches
+cecho "Start the uml bridges  (scripts/start-bridges)"
+$DIR/scripts/start-bridges
 
 
 #####################################################
index 5dc67af966d73394f305bcb288f6bd00dcde55b3..e12e975b28d5fc6576abce26ab8a11cd454b00cf 100755 (executable)
@@ -42,10 +42,9 @@ done
 cgecho "done"
 
 #####################################################
-# Shutting down the uml switches
+# Shutting down the uml bridhges
 #
-cecho-n " * Stopping the UML switches.."
-killall uml_switch &> /dev/null
-rm -f /tmp/umlswitch[012] &> /dev/null 2>&1
-cgecho "done"
+cecho "Stop the uml bridges  (scripts/stop-bridges)"
+$DIR/scripts/stop-bridges
+
 
index 11cb5a65885562e6ef4569da34fd2b91af043b7d..a9e15bc542d5ce2af640c79d7dd3cf1454eed4e3 100755 (executable)
@@ -30,10 +30,10 @@ KERNELVERSION=`basename $KERNEL .tar.bz2 | sed -e 's/linux-//'`
 KERNELCONFIG=$UMLTESTDIR/.config-2.6.29
 
 # Bzipped uml patch for kernel
-#UMLPATCH=$UMLTESTDIR/uml-2.6.26.patch.bz2
+#UMLPATCH=$UMLTESTDIR/aead_init.patch.bz2
 
 # Bzipped source of strongSwan
-STRONGSWAN=$UMLTESTDIR/strongswan-4.2.14.tar.bz2
+STRONGSWAN=$UMLTESTDIR/strongswan-4.3.0.tar.bz2
 
 # strongSwan compile options (use "yes" or "no")
 USE_LIBCURL="yes"
@@ -50,6 +50,7 @@ USE_OPENSSL="yes"
 USE_KERNEL_PFKEY="yes"
 USE_INTEGRITY_TEST="yes"
 USE_LEAK_DETECTIVE="yes"
+USE_LOAD_TESTS="yes"
 
 # Gentoo linux root filesystem
 ROOTFS=$UMLTESTDIR/gentoo-fs-20090325.tar.bz2
@@ -74,7 +75,7 @@ TESTRESULTSDIR=$UMLTESTDIR/testresults
 # Path to a full strongswan tree on the host system, which is
 # mounted into /root/strongswan-shared. This gives us an easy
 # way to apply and test changes instantly.
-SHAREDTREE=/home/martin/strongswan/trunk
+#SHAREDTREE=/home/martin/strongswan/trunk
 
 # Timezone for the UMLs, look in /usr/share/zoneinfo!
 TZUML="Europe/Zurich"
@@ -89,13 +90,13 @@ ENABLE_BUILD_HOSTCONFIG="yes"
 ENABLE_BUILD_UMLROOTFS="yes"
 ENABLE_BUILD_UMLHOSTFS="yes"
 ENABLE_START_TESTING="yes"
-ENABLE_DO_TESTS="yes"
+ENABLE_DO_TESTS="no"
 ENABLE_STOP_TESTING="no"
 
 ##############################################################
 # How to start the UMLs?
 #
-# Start the UML instance in KDE konsole (requires KDE)
+# Start the UML instance in KDE konsole (requires KDE)
 # UMLSTARTMODE="konsole"
 # Start the UML instance in a gnome-terminal (requires gnome)
 UMLSTARTMODE="gnome-terminal"
@@ -166,14 +167,14 @@ IFCONFIG_2="10.2.0.254 netmask 255.255.0.0"
 ##############################################################
 # Network interfaces of the UML instances
 #
-SWITCH_alice="eth0=daemon,fe:fd:0a:01:00:0a,unix,/tmp/umlswitch1 \
-              eth1=daemon,fe:fd:c0:a8:00:32,unix,/tmp/umlswitch0"
-SWITCH_venus="eth0=daemon,fe:fd:0a:01:00:14,unix,/tmp/umlswitch1"
-SWITCH_moon="eth0=daemon,fe:fd:c0:a8:00:01,unix,/tmp/umlswitch0 \
-             eth1=daemon,fe:fd:0a:01:00:01,unix,/tmp/umlswitch1"
-SWITCH_carol="eth0=daemon,fe:fd:c0:a8:00:64,unix,/tmp/umlswitch0"
-SWITCH_winnetou="eth0=daemon,fe:fd:c0:a8:00:96,unix,/tmp/umlswitch0"
-SWITCH_dave="eth0=daemon,fe:fd:c0:a8:00:c8,unix,/tmp/umlswitch0"
-SWITCH_sun="eth0=daemon,fe:fd:c0:a8:00:02,unix,/tmp/umlswitch0 \
-            eth1=daemon,fe:fd:0a:02:00:01,unix,/tmp/umlswitch2"
-SWITCH_bob="eth0=daemon,fe:fd:0a:02:00:0a,unix,/tmp/umlswitch2"
+SWITCH_alice="eth0=tuntap,tap1_alice,fe:fd:0a:01:00:0a \
+              eth1=tuntap,tap0_alice,fe:fd:c0:a8:00:32"
+SWITCH_venus="eth0=tuntap,tap1_venus,fe:fd:0a:01:00:14"
+SWITCH_moon="eth0=tuntap,tap0_moon,fe:fd:c0:a8:00:01 \
+             eth1=tuntap,tap1_moon,fe:fd:0a:01:00:01"
+SWITCH_carol="eth0=tuntap,tap0_carol,fe:fd:c0:a8:00:64"
+SWITCH_winnetou="eth0=tuntap,tap0_winnetou,fe:fd:c0:a8:00:96"
+SWITCH_dave="eth0=tuntap,tap0_dave,fe:fd:c0:a8:00:c8"
+SWITCH_sun="eth0=tuntap,tap0_sun,fe:fd:c0:a8:00:02 \
+            eth1=tuntap,tap2_sun,fe:fd:0a:02:00:01"
+SWITCH_bob="eth0=tuntap,tap2_bob,fe:fd:0a:02:00:0a"
index 016524dd9f0f6207d907b078557152cce9f2f4f7..c35a8019e6c710860c4cefd85c09fca0fcb7d804 100644 (file)
@@ -6,5 +6,5 @@ moon::cat /var/log/auth.log::inserting event EVENT_DPD::YES
 moon::cat /var/log/auth.log::DPD: No response from peer - declaring peer dead::YES
 moon::cat /var/log/auth.log::DPD: Terminating all SAs using this connection::YES
 moon::cat /var/log/auth.log::DPD: Restarting connection::YES
-moon::sleep 5::no output expected::NO
+moon::sleep 10::no output expected::NO
 moon::ipsec status::STATE_MAIN_I4 (ISAKMP SA established)::YES
index 759295675195f162656184857f0a4df51125ae55..b266d86d8c93e4a5b0ea1b181484634f0d40d598 100644 (file)
@@ -1,5 +1,5 @@
-carol::ping -c 2 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_seq::YES
-carol::ping -c 2 PH_IP_MOON1::64 bytes from PH_IP_MOON1: icmp_seq::YES
+carol::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_seq::YES
+carol::ping -c 1 PH_IP_MOON1::64 bytes from PH_IP_MOON1: icmp_seq::YES
 carol::ssh PH_IP_ALICE hostname::alice::YES
 carol::cat /var/log/auth.log::initiate on demand::YES
 carol::ipsec status::home.*STATE_QUICK_I2.*IPsec SA established::YES
index f233ad48f5a38b5c9845115c5718dbbdac204d9b..b1fc81827c291ea7bf14fb5ce056d5e1081d1785 100644 (file)
@@ -2,5 +2,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::ssh -o ConnectTimeout=5 PH_IP_ALICE hostname
+carol::ping -c 1 PH_IP_ALICE > /dev/null
 carol::sleep 2
-carol::ssh PH_IP_ALICE hostname
index ef63f7262208e36da70b71c5b815595434f3e46c..66a6137cb30181b1873e07e63088c4503f7ad05b 100644 (file)
@@ -2,4 +2,5 @@
 
 charon {
   load = curl aes des sha1 sha2 md5 gmp random x509 pubkey hmac xcbc stroke kernel-netlink
+  multiple_authentication = no
 }
index ef63f7262208e36da70b71c5b815595434f3e46c..66a6137cb30181b1873e07e63088c4503f7ad05b 100644 (file)
@@ -2,4 +2,5 @@
 
 charon {
   load = curl aes des sha1 sha2 md5 gmp random x509 pubkey hmac xcbc stroke kernel-netlink
+  multiple_authentication = no
 }
index ef63f7262208e36da70b71c5b815595434f3e46c..66a6137cb30181b1873e07e63088c4503f7ad05b 100644 (file)
@@ -2,4 +2,5 @@
 
 charon {
   load = curl aes des sha1 sha2 md5 gmp random x509 pubkey hmac xcbc stroke kernel-netlink
+  multiple_authentication = no
 }
index ef63f7262208e36da70b71c5b815595434f3e46c..66a6137cb30181b1873e07e63088c4503f7ad05b 100644 (file)
@@ -2,4 +2,5 @@
 
 charon {
   load = curl aes des sha1 sha2 md5 gmp random x509 pubkey hmac xcbc stroke kernel-netlink
+  multiple_authentication = no
 }
index 2242746dbb8149c1eb93b2a47d7bd5823d1594a1..62ed8676a0fda467a794cadb868111bb3fd97d2d 100644 (file)
@@ -1,5 +1,4 @@
 moon::cat /var/log/daemon.log::certificate was revoked::YES
-moon::cat /var/log/daemon.log::authentication of.*carol@strongswan.org.*failed::YES
 carol::cat /var/log/daemon.log::received AUTHENTICATION_FAILED notify error::YES
 moon::ipsec status::rw.*ESTABLISHED::NO
 carol::ipsec status::home.*ESTABLISHED::NO
index 40eb84b8a4b0955a4216536da5f36e00f3df5dfb..4731a81d2b4fc8282a5448f0ea3f7c675baadc1e 100644 (file)
@@ -2,4 +2,5 @@
 
 charon {
   load = curl aes des sha1 sha2 md5 gmp random x509 pubkey hmac xcbc stroke kernel-netlink updown
+  multiple_authentication = no
 }
index 40eb84b8a4b0955a4216536da5f36e00f3df5dfb..4731a81d2b4fc8282a5448f0ea3f7c675baadc1e 100644 (file)
@@ -2,4 +2,5 @@
 
 charon {
   load = curl aes des sha1 sha2 md5 gmp random x509 pubkey hmac xcbc stroke kernel-netlink updown
+  multiple_authentication = no
 }
diff --git a/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/description.txt b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/description.txt
new file mode 100644 (file)
index 0000000..3641d09
--- /dev/null
@@ -0,0 +1,17 @@
+The roadwarrior <b>carol</b> sets up a connection to gateway <b>moon</b>
+using multiple authentication exchanges (RFC 4739). In a first round 
+both <b>carol</b> and <b>moon</b> authenticate themselves by sending 
+an IKEv2 <b>RSA signature</b> accompanied by a certificate.
+<p>
+In a second round <b>carol</b> then uses the <i>Extensible Authentication Protocol</i>
+in association with a <i>GSM Subscriber Identity Module</i> (<b>EAP-SIM</b>) to
+authenticate herself against the remote RADIUS server <b>alice</b>. 
+In this scenario, triplets from the file <b>/etc/ipsec.d/triplets.dat</b>
+are used instead of a physical SIM card on the client <b>carol</b>.
+The gateway forwards all EAP messages to the RADIUS server <b>alice</b>
+which also uses a static triplets file.
+<p>
+The roadwarrior <b>dave</b> also uses multiple authentication and succeeds
+in the first round but sends wrong EAP-SIM triplets in the second round.
+As a consequence the radius server <b>alice</b> returns an <b>Access-Reject</b>
+message and the gateway <b>moon</b> sends back an <b>EAP_FAILURE</b>.  
diff --git a/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/evaltest.dat b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/evaltest.dat
new file mode 100644 (file)
index 0000000..d64b3da
--- /dev/null
@@ -0,0 +1,21 @@
+moon::cat /var/log/daemon.log::parsed IKE_AUTH request.*N(AUTH_FOLLOWS)::YES
+moon::cat /var/log/daemon.log::authentication of .*carol@strongswan.org.* with RSA signature successful::YES
+carol::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with RSA signature successful::YES
+carol::cat /var/log/daemon.log::server requested EAP_SIM authentication::YES
+moon::cat /var/log/daemon.log::received EAP identity .*228060123456001::YES
+moon::cat /var/log/daemon.log::authentication of .*228060123456001@strongswan.org.* with EAP successful::YES
+moon::ipsec statusall::rw-mult.*ESTABLISHED.*228060123456001@strongswan.org::YES
+carol::ipsec statusall::home.*ESTABLISHED.*228060123456001@strongswan.org::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
+moon::cat /var/log/daemon.log::authentication of .*dave@strongswan.org.* with RSA signature successful::YES
+dave::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with RSA signature successful::YES
+dave::cat /var/log/daemon.log::server requested EAP_SIM authentication::YES
+moon::cat /var/log/daemon.log::received EAP identity .*228060123456002::YES
+moon::cat /var/log/daemon.log::received Access-Reject from RADIUS server::YES
+moon::cat /var/log/daemon.log::EAP method EAP_SIM failed for peer 228060123456002@strongswan.org::YES
+moon::ipsec statusall::rw-mult.*ESTABLISHED.*228060123456002@strongswan.org::NO
+dave::cat /var/log/daemon.log::received EAP_FAILURE, EAP authentication failed::YES
+dave::ipsec statusall::home.*ESTABLISHED::NO
+dave::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_seq=1::NO
diff --git a/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/alice/etc/raddb/clients.conf b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/alice/etc/raddb/clients.conf
new file mode 100644 (file)
index 0000000..f4e179a
--- /dev/null
@@ -0,0 +1,4 @@
+client PH_IP_MOON1 {
+  secret    = gv6URkSs 
+  shortname = moon
+}
diff --git a/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/alice/etc/raddb/eap.conf b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/alice/etc/raddb/eap.conf
new file mode 100644 (file)
index 0000000..a202042
--- /dev/null
@@ -0,0 +1,5 @@
+eap {
+  default_eap_type = sim 
+  sim {
+  }
+}
diff --git a/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/alice/etc/raddb/proxy.conf b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/alice/etc/raddb/proxy.conf
new file mode 100644 (file)
index 0000000..23cba8d
--- /dev/null
@@ -0,0 +1,5 @@
+realm strongswan.org {
+  type     = radius
+  authhost = LOCAL
+  accthost = LOCAL
+}
diff --git a/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/alice/etc/raddb/radiusd.conf b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/alice/etc/raddb/radiusd.conf
new file mode 100644 (file)
index 0000000..d77b818
--- /dev/null
@@ -0,0 +1,123 @@
+# radiusd.conf -- FreeRADIUS server configuration file.
+
+prefix = /usr
+exec_prefix = ${prefix}
+sysconfdir = /etc
+localstatedir = /var
+sbindir = ${exec_prefix}/sbin
+logdir = ${localstatedir}/log/radius
+raddbdir = ${sysconfdir}/raddb
+radacctdir = ${logdir}/radacct
+
+#  name of the running server.  See also the "-n" command-line option.
+name = radiusd
+
+#  Location of config and logfiles.
+confdir = ${raddbdir}
+run_dir = ${localstatedir}/run/radiusd
+
+# Should likely be ${localstatedir}/lib/radiusd
+db_dir = ${raddbdir}
+
+# libdir: Where to find the rlm_* modules.
+libdir = ${exec_prefix}/lib
+
+#  pidfile: Where to place the PID of the RADIUS server.
+pidfile = ${run_dir}/${name}.pid
+
+#  max_request_time: The maximum time (in seconds) to handle a request.
+max_request_time = 30
+
+#  cleanup_delay: The time to wait (in seconds) before cleaning up
+cleanup_delay = 5
+
+#  max_requests: The maximum number of requests which the server keeps
+max_requests = 1024
+
+#  listen: Make the server listen on a particular IP address, and send
+listen {
+  type = auth
+  ipaddr = PH_IP_ALICE 
+  port = 0
+}
+
+#  This second "listen" section is for listening on the accounting
+#  port, too.
+#
+listen {
+  type  = acct
+  ipaddr = PH_IP_ALICE 
+  port = 0
+}
+
+#  hostname_lookups: Log the names of clients or just their IP addresses
+hostname_lookups = no
+
+#  Core dumps are a bad thing.  This should only be set to 'yes'
+allow_core_dumps = no
+
+#  Regular expressions
+regular_expressions = yes
+extended_expressions = yes
+
+#  Logging section.  The various "log_*" configuration items
+log {
+  destination = files
+  file = ${logdir}/radius.log
+  syslog_facility = daemon
+  stripped_names = no
+  auth = yes 
+  auth_badpass = yes 
+  auth_goodpass = yes 
+}
+
+#  The program to execute to do concurrency checks.
+checkrad = ${sbindir}/checkrad
+
+#  Security considerations
+security {
+  max_attributes = 200
+  reject_delay = 1
+  status_server = yes
+}
+
+# PROXY CONFIGURATION
+proxy_requests = yes
+$INCLUDE proxy.conf
+
+# CLIENTS CONFIGURATION
+$INCLUDE clients.conf
+
+# THREAD POOL CONFIGURATION
+thread pool {
+  start_servers = 5
+  max_servers = 32
+  min_spare_servers = 3
+  max_spare_servers = 10
+  max_requests_per_server = 0
+}
+
+# MODULE CONFIGURATION
+modules {
+  $INCLUDE ${confdir}/modules/
+  $INCLUDE eap.conf
+  $INCLUDE sql.conf
+  $INCLUDE sql/mysql/counter.conf
+  sim_files {
+    simtriplets = "/etc/raddb/triplets.dat"
+  }
+}
+
+# Instantiation
+instantiate {
+  exec
+  expr
+  expiration
+  logintime
+}
+
+# Policies
+$INCLUDE policy.conf
+
+# Include all enabled virtual hosts
+$INCLUDE sites-enabled/
diff --git a/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/alice/etc/raddb/sites-available/default b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/alice/etc/raddb/sites-available/default
new file mode 100644 (file)
index 0000000..dfceb03
--- /dev/null
@@ -0,0 +1,62 @@
+authorize {
+  preprocess
+  chap
+  mschap
+  sim_files
+  suffix
+  eap {
+    ok = return
+  }
+  unix
+  files
+  expiration
+  logintime
+  pap
+}
+
+authenticate {
+  Auth-Type PAP {
+    pap
+  }
+  Auth-Type CHAP {
+    chap
+  }
+  Auth-Type MS-CHAP {
+    mschap
+  }
+  unix
+  eap
+}
+
+preacct {
+  preprocess
+  acct_unique
+  suffix
+  files
+}
+
+accounting {
+  detail
+  unix
+  radutmp
+  attr_filter.accounting_response
+}
+
+session {
+  radutmp
+}
+
+post-auth {
+  exec
+  Post-Auth-Type REJECT {
+    attr_filter.access_reject
+  }
+}
+
+pre-proxy {
+}
+
+post-proxy {
+  eap
+}
+
diff --git a/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/alice/etc/raddb/triplets.dat b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/alice/etc/raddb/triplets.dat
new file mode 100644 (file)
index 0000000..002ee94
--- /dev/null
@@ -0,0 +1,7 @@
+228060123456001,30000000000000000000000000000000,30112233,305566778899AABB
+228060123456001,31000000000000000000000000000000,31112233,315566778899AABB
+228060123456001,32000000000000000000000000000000,32112233,325566778899AABB
+228060123456002,33000000000000000000000000000000,33112233,335566778899AABB
+228060123456002,34000000000000000000000000000000,34112233,345566778899AABB
+228060123456002,35000000000000000000000000000000,35112233,355566778899AABB
+
diff --git a/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/alice/etc/raddb/users b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/alice/etc/raddb/users
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/carol/etc/ipsec.conf b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/carol/etc/ipsec.conf
new file mode 100755 (executable)
index 0000000..26cc0cd
--- /dev/null
@@ -0,0 +1,26 @@
+# /etc/ipsec.conf - strongSwan IPsec configuration file
+
+config setup
+       plutostart=no
+
+conn %default
+       ikelifetime=60m
+       keylife=20m
+       rekeymargin=3m
+       keyingtries=1
+       keyexchange=ikev2
+
+conn home
+       left=PH_IP_CAROL
+       leftfirewall=yes
+       leftauth=pubkey
+       leftid=carol@strongswan.org
+       leftcert=carolCert.pem
+       leftauth2=eap
+       leftid2=228060123456001@strongswan.org
+       eap_identity=228060123456001
+       right=PH_IP_MOON
+       rightsubnet=10.1.0.0/16
+       rightauth=pubkey
+       rightid=@moon.strongswan.org
+       auto=add
diff --git a/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/carol/etc/ipsec.d/triplets.dat b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/carol/etc/ipsec.d/triplets.dat
new file mode 100644 (file)
index 0000000..c167ba9
--- /dev/null
@@ -0,0 +1,3 @@
+228060123456001,30000000000000000000000000000000,30112233,305566778899AABB
+228060123456001,31000000000000000000000000000000,31112233,315566778899AABB
+228060123456001,32000000000000000000000000000000,32112233,325566778899AABB
diff --git a/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/carol/etc/ipsec.secrets b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/carol/etc/ipsec.secrets
new file mode 100644 (file)
index 0000000..6a2aea8
--- /dev/null
@@ -0,0 +1,3 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: RSA carolKey.pem "nH5ZQEWtku0RJEZ6"
similarity index 63%
rename from testing/tests/ikev2/two-certs/hosts/dave/etc/strongswan.conf
rename to testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/carol/etc/strongswan.conf
index 40eb84b8a4b0955a4216536da5f36e00f3df5dfb..cc451fc8d785084ce81df8b2c8e34059e0075ace 100644 (file)
@@ -1,5 +1,5 @@
 # /etc/strongswan.conf - strongSwan configuration file
 
 charon {
-  load = curl aes des sha1 sha2 md5 gmp random x509 pubkey hmac xcbc stroke kernel-netlink updown
+  load = curl aes des sha1 sha2 md5 gmp random x509 pubkey hmac xcbc stroke kernel-netlink fips-prf eapsim eapsim-file eapidentity updown
 }
diff --git a/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/dave/etc/ipsec.conf b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/dave/etc/ipsec.conf
new file mode 100755 (executable)
index 0000000..f8c52be
--- /dev/null
@@ -0,0 +1,27 @@
+# /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_DAVE
+       leftfirewall=yes
+       leftauth=pubkey
+       leftid=dave@strongswan.org
+       leftcert=daveCert.pem
+       leftauth2=eap
+       leftid2=228060123456002@strongswan.org
+       eap_identity=228060123456002
+       right=PH_IP_MOON
+       rightsubnet=10.1.0.0/16
+       rightauth=pubkey
+       rightid=@moon.strongswan.org
+       auto=add
diff --git a/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/dave/etc/ipsec.d/triplets.dat b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/dave/etc/ipsec.d/triplets.dat
new file mode 100644 (file)
index 0000000..b8b86c8
--- /dev/null
@@ -0,0 +1,3 @@
+228060123456002,33000000000000000000000000000000,33112244,335566778899AABB
+228060123456002,34000000000000000000000000000000,34112244,345566778899AABB
+228060123456002,35000000000000000000000000000000,35112244,355566778899AABB
diff --git a/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/dave/etc/ipsec.secrets b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/dave/etc/ipsec.secrets
new file mode 100644 (file)
index 0000000..9031f32
--- /dev/null
@@ -0,0 +1,3 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: RSA daveKey.pem
diff --git a/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/dave/etc/strongswan.conf b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/dave/etc/strongswan.conf
new file mode 100644 (file)
index 0000000..cc451fc
--- /dev/null
@@ -0,0 +1,5 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  load = curl aes des sha1 sha2 md5 gmp random x509 pubkey hmac xcbc stroke kernel-netlink fips-prf eapsim eapsim-file eapidentity updown
+}
diff --git a/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/moon/etc/init.d/iptables b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/moon/etc/init.d/iptables
new file mode 100755 (executable)
index 0000000..56587b2
--- /dev/null
@@ -0,0 +1,84 @@
+#!/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/ipv4/ip_forward
+       
+       # 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 MobIKE
+       iptables -A INPUT  -i eth0 -p udp --sport 4500 --dport 4500 -j ACCEPT
+       iptables -A OUTPUT -o eth0 -p udp --dport 4500 --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 RADIUS protocol with alice
+       iptables -A INPUT  -i eth1 -p udp --sport 1812 -s PH_IP_ALICE -j ACCEPT
+       iptables -A OUTPUT -o eth1 -p udp --dport 1812 -d PH_IP_ALICE -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/ikev2/mult-auth-rsa-eap-sim-id/hosts/moon/etc/ipsec.conf b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/moon/etc/ipsec.conf
new file mode 100755 (executable)
index 0000000..37d23b1
--- /dev/null
@@ -0,0 +1,26 @@
+# /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-mult
+       left=PH_IP_MOON
+       leftsubnet=10.1.0.0/16
+       leftfirewall=yes
+       leftauth=pubkey
+       leftid=@moon.strongswan.org
+       leftcert=moonCert.pem
+       right=%any
+       rightauth=pubkey
+       rightid=*@strongswan.org
+       rightauth2=eap-radius
+       eap_identity=%any
+       auto=add
diff --git a/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/moon/etc/ipsec.secrets b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/moon/etc/ipsec.secrets
new file mode 100644 (file)
index 0000000..e86d6aa
--- /dev/null
@@ -0,0 +1,3 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: RSA moonKey.pem
diff --git a/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/moon/etc/strongswan.conf b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/hosts/moon/etc/strongswan.conf
new file mode 100644 (file)
index 0000000..10414b2
--- /dev/null
@@ -0,0 +1,11 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  load = curl aes des sha1 sha2 md5 gmp random x509 pubkey hmac xcbc stroke kernel-netlink fips-prf eapradius eapidentity updown
+  plugins {
+    eap_radius {
+      secret = gv6URkSs 
+      server = PH_IP_ALICE
+    }
+  }
+}
diff --git a/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/posttest.dat b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/posttest.dat
new file mode 100644 (file)
index 0000000..dbe5601
--- /dev/null
@@ -0,0 +1,7 @@
+moon::ipsec stop
+carol::ipsec stop
+dave::ipsec stop
+alice::/etc/init.d/radiusd 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
diff --git a/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/pretest.dat b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/pretest.dat
new file mode 100644 (file)
index 0000000..b3fd4cb
--- /dev/null
@@ -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::cat /etc/raddb/clients.conf
+alice::cat /etc/raddb/eap.conf
+alice::cat /etc/raddb/proxy.conf
+alice::cat /etc/raddb/triplets.dat
+alice::/etc/init.d/radiusd start
+moon::ipsec start
+carol::ipsec start
+dave::ipsec start
+carol::sleep 1
+carol::ipsec up home
+dave::ipsec up home
+dave::sleep 1
diff --git a/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/test.conf b/testing/tests/ikev2/mult-auth-rsa-eap-sim-id/test.conf
new file mode 100644 (file)
index 0000000..7041682
--- /dev/null
@@ -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.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"
index 0ace2573124bab99c769dda2bcf3714e1b337cdf..602d026c2da9a54d6188e845c78fd2d8d47316fd 100644 (file)
@@ -1,8 +1,6 @@
-The VPN gateway <b>moon</b> controls the access to the hosts <b>alice</b> and
-<b>venus</b> by means of two different Intermediate CAs. Access to
-<b>alice</b> is granted to users presenting a certificate issued by the Research CA
-whereas <b>venus</b> can only be reached with a certificate issued by the
-Sales CA. The hosts <b>carol</b> and <b>dave</b> have certificates from
-the Research CA and Sales CA, respectively. Initiator <b>moon</b> does not possess
+The VPN gateway <b>moon</b> grants access to the hosts <b>alice</b> and
+<b>venus</b> to anyone presenting a certificate belonging to a trust chain anchored
+in the strongSwan Root CA.  The hosts <b>carol</b> and <b>dave</b> have certificates from
+the intermediate Research CA and Sales CA, respectively. Initiator <b>moon</b> does not possess
 copies of the Research and Sales CA certificates and must therefore request them from
-the initiators <b>carol</b> and <b>dave</b>, respectively.
+the responders <b>carol</b> and <b>dave</b>, respectively.
index 12f0c95bf3a19156fde8f8f127b7697a2aba56b5..4c84d183b5338a137bb6a2fbdafe9984ebed8496 100755 (executable)
@@ -25,12 +25,12 @@ conn alice
        leftsubnet=PH_IP_ALICE/32
        right=PH_IP_CAROL
        rightid=carol@strongswan.org
-       rightca="C=CH, O=Linux strongSwan, OU=Research, CN=Research CA"
+       rightca="C=CH, O=Linux strongSwan, CN=strongSwan Root CA"
        auto=add
        
 conn venus
        leftsubnet=PH_IP_VENUS/32
        right=PH_IP_DAVE
        rightid=dave@strongswan.org
-       rightca="C=CH, O=Linux strongSwan, OU=Sales, CN=Sales CA"
+       rightca="C=CH, O=Linux strongSwan, CN=strongSwan Root CA"
        auto=add
index b26c8c5d055bf4584ec897255e7cfcaef47f3cc7..06f9f6b9171d5d7a08b5858f3c1f0237f186f3af 100644 (file)
@@ -1,8 +1,6 @@
-The VPN gateway <b>moon</b> controls the access to the hosts <b>alice</b> and
-<b>venus</b> by means of two different Intermediate CAs. Access to
-<b>alice</b> is granted to users presenting a certificate issued by the Research CA
-whereas <b>venus</b> can only be reached with a certificate issued by the
-Sales CA. The roadwarriors <b>carol</b> and <b>dave</b> have certificates from
-the Research CA and Sales CA, respectively. Responder <b>moon</b> does not possess
+The VPN gateway <b>moon</b> grants access to the hosts <b>alice</b> and
+<b>venus</b> to anyone presenting a certificate belonging to a trust chain anchored
+in the strongSwan Root CA.  The hosts <b>carol</b> and <b>dave</b> have certificates from
+the intermediate Research CA and Sales CA, respectively. Responder <b>moon</b> does not possess
 copies of the Research and Sales CA certificates and must therefore request them from
-the initiators <b>carol</b> and <b>dave</b>.
+the initiators <b>carol</b> and <b>dave</b>, respectively.
index d2453bbeed84e4435761e97bb31f09149374d32f..4b827b4dd362271b6074038941e01739024a2f92 100644 (file)
@@ -7,6 +7,6 @@ moon::cat /var/log/daemon.log::crl correctly signed by.*Sales CA::YES
 moon::cat /var/log/daemon.log::fetching crl from.*http.*strongswan.crl::YES
 moon::cat /var/log/daemon.log::crl correctly signed by.*strongSwan Root CA::YES
 carol::ipsec status::alice.*INSTALLED::YES
-moon::ipsec status::alice.*ESTABLISHED.*carol@strongswan.org::YES
+moon::ipsec status::alice.*INSTALLED::YES
 dave::ipsec status::venus.*INSTALLED::YES
-moon::ipsec status::venus.*ESTABLISHED.*dave@strongswan.org::YES
+moon::ipsec status::venus.*INSTALLED::YES
index d0240a333bed21f38566424e1dd78acc90d77560..75138581ed117f66f602ce410a3af7f7151b19db 100755 (executable)
@@ -24,11 +24,11 @@ conn %default
 conn alice
        leftsubnet=PH_IP_ALICE/32
        right=%any
-       rightca="C=CH, O=Linux strongSwan, OU=Research, CN=Research CA"
+       rightca="C=CH, O=Linux strongSwan, CN=strongSwan Root CA"
        auto=add
        
 conn venus
        leftsubnet=PH_IP_VENUS/32
        right=%any
-       rightca="C=CH, O=Linux strongSwan, OU=Sales, CN=Sales CA"
+       rightca="C=CH, O=Linux strongSwan, CN=strongSwan Root CA"
        auto=add
index 8656c8e3aca2a483ff5a47e64ac63899eb136557..4a1c7208bf1bfb65ca099a95c7a46194368722d4 100644 (file)
@@ -8,11 +8,12 @@ carol::ipsec status::alice.*INSTALLED::YES
 moon::ipsec status::alice.*ESTABLISHED.*carol@strongswan.org::YES
 carol::cat /var/log/daemon.log::received TS_UNACCEPTABLE notify, no CHILD_SA built::YES
 carol::ipsec status::venus.*INSTALLED::NO
-moon::cat /var/log/daemon.log::constraint check failed: peer not authenticated by.*Sales CA::YES
 moon::ipsec status::venus.*ESTABLISHED.*carol@strongswan.org::NO
+moon::cat /var/log/daemon.log::constraint check failed: peer not authenticated by.*Research CA::YES
+moon::cat /var/log/daemon.log::selected peer config.*alice.*inacceptable::YES
+moon::cat /var/log/daemon.log::switching to peer config.*venus::YES
 dave::ipsec status::venus.*INSTALLED::YES
 moon::ipsec status::venus.*ESTABLISHED.*dave@strongswan.org::YES
 dave::cat /var/log/daemon.log::received TS_UNACCEPTABLE notify, no CHILD_SA built::YES
 dave::ipsec status::alice.*INSTALLED::NO
-moon::cat /var/log/daemon.log::constraint check failed: peer not authenticated by.*Research CA::YES
 moon::ipsec status::alice.*ESTABLISHED.*dave@strongswan.org::NO
index c60f722ec20bb2a0ff51402cdb716621d685db6f..0b7b02801283533b9450e71962ecad26210e1d89 100644 (file)
@@ -1,4 +1,4 @@
 moon::cat /var/log/daemon.log::maximum ca path length of 7 levels reached::YES
-moon::cat /var/log/daemon.log::authentication of.*carol@strongswan.org.*failed::YES
+carol::cat /var/log/daemon.log::received AUTHENTICATION_FAILED notify error::YES
 carol::ipsec status::alice.*INSTALLED::NO
 moon::ipsec status::alice.*ESTABLISHED.*carol@strongswan.org::NO
index 3ac0adbb5134e94647d278d77f6760ee57db85d4..182f9e0fc88773a2d4048e90855baa03d3b7df2b 100644 (file)
@@ -1,5 +1,4 @@
 moon::cat /var/log/daemon.log::certificate was revoked::YES
-moon::cat /var/log/daemon.log::authentication of.*carol@strongswan.org.*failed::YES
 carol::cat /var/log/daemon.log::received AUTHENTICATION_FAILED notify error::YES
 moon::ipsec status::alice.*ESTABLISHED::NO
 carol::ipsec status::home.*INSTALLED::NO
index 86cbbc58bdfc12719ce837087fbeae48ad07dbf1..6467d5222d1c623af82e8dcb512a7a00b1ea3cb5 100644 (file)
@@ -2,6 +2,6 @@ By setting <b>strictcrlpolicy=yes</b>, a <b>strict CRL policy</b> is enforced
 on all peers.
 The VPN gateway <b>moon</b> grants access to the hosts <b>alice</b> and
 <b>venus</b> to anyone presenting a certificate belonging to a trust
-chain anchored in strongSwan Root CA. Therefore both road warriors
+chain anchored in the strongSwan Root CA. Therefore both road warriors
 <b>carol</b> and <b>dave</b>, holding certificates from the Research CA
 and Sales CA, respectively, can reach both <b>alice</b> and <b>venus</b>.
index 8ba69ff9bab304067949d54f9c3ae68d7a56440c..b0814556dd598903eea036e9ed3260e0faed7ffa 100644 (file)
@@ -8,11 +8,12 @@ carol::ipsec status::alice.*INSTALLED::YES
 moon::ipsec status::alice.*ESTABLISHED.*carol@strongswan.org::YES
 carol::cat /var/log/daemon.log::received TS_UNACCEPTABLE notify, no CHILD_SA built::YES
 carol::ipsec status::venus.*INSTALLED::NO
-moon::cat /var/log/daemon.log::constraint check failed: peer not authenticated by.*Sales CA::YES
 moon::ipsec status::venus.*ESTABLISHED.*carol@strongswan.org::NO
+moon::cat /var/log/daemon.log::constraint check failed: peer not authenticated by.*Research CA::YES
+moon::cat /var/log/daemon.log::selected peer config.*alice.*inacceptable::YES
+moon::cat /var/log/daemon.log::switching to peer config.*venus::YES
 dave::ipsec status::venus.*INSTALLED::YES
 moon::ipsec status::venus.*ESTABLISHED.*dave@strongswan.org::YES
 dave::cat /var/log/daemon.log::received TS_UNACCEPTABLE notify, no CHILD_SA built::YES
 dave::ipsec status::alice.*INSTALLED::NO
-moon::cat /var/log/daemon.log::constraint check failed: peer not authenticated by.*Research CA::YES
 moon::ipsec status::alice.*ESTABLISHED.*dave@strongswan.org::NO
index 40eb84b8a4b0955a4216536da5f36e00f3df5dfb..4731a81d2b4fc8282a5448f0ea3f7c675baadc1e 100644 (file)
@@ -2,4 +2,5 @@
 
 charon {
   load = curl aes des sha1 sha2 md5 gmp random x509 pubkey hmac xcbc stroke kernel-netlink updown
+  multiple_authentication = no
 }
index 40eb84b8a4b0955a4216536da5f36e00f3df5dfb..4731a81d2b4fc8282a5448f0ea3f7c675baadc1e 100644 (file)
@@ -2,4 +2,5 @@
 
 charon {
   load = curl aes des sha1 sha2 md5 gmp random x509 pubkey hmac xcbc stroke kernel-netlink updown
+  multiple_authentication = no
 }
index 20c58007c0b6b9635733cf091f8216b0558e5b34..454aed12c8c1b524fb29a5004641846e3770c765 100644 (file)
@@ -2,4 +2,5 @@
 
 charon {
   load = aes des sha1 sha2 md5 gmp random hmac xcbc stroke kernel-netlink updown
+  multiple_authentication = no
 }
index 20c58007c0b6b9635733cf091f8216b0558e5b34..454aed12c8c1b524fb29a5004641846e3770c765 100644 (file)
@@ -2,4 +2,5 @@
 
 charon {
   load = aes des sha1 sha2 md5 gmp random hmac xcbc stroke kernel-netlink updown
+  multiple_authentication = no
 }
index 40eb84b8a4b0955a4216536da5f36e00f3df5dfb..4731a81d2b4fc8282a5448f0ea3f7c675baadc1e 100644 (file)
@@ -2,4 +2,5 @@
 
 charon {
   load = curl aes des sha1 sha2 md5 gmp random x509 pubkey hmac xcbc stroke kernel-netlink updown
+  multiple_authentication = no
 }
index 40eb84b8a4b0955a4216536da5f36e00f3df5dfb..4731a81d2b4fc8282a5448f0ea3f7c675baadc1e 100644 (file)
@@ -2,4 +2,5 @@
 
 charon {
   load = curl aes des sha1 sha2 md5 gmp random x509 pubkey hmac xcbc stroke kernel-netlink updown
+  multiple_authentication = no
 }
index 40eb84b8a4b0955a4216536da5f36e00f3df5dfb..4731a81d2b4fc8282a5448f0ea3f7c675baadc1e 100644 (file)
@@ -2,4 +2,5 @@
 
 charon {
   load = curl aes des sha1 sha2 md5 gmp random x509 pubkey hmac xcbc stroke kernel-netlink updown
+  multiple_authentication = no
 }
index 40eb84b8a4b0955a4216536da5f36e00f3df5dfb..4731a81d2b4fc8282a5448f0ea3f7c675baadc1e 100644 (file)
@@ -2,4 +2,5 @@
 
 charon {
   load = curl aes des sha1 sha2 md5 gmp random x509 pubkey hmac xcbc stroke kernel-netlink updown
+  multiple_authentication = no
 }
index 939817d5852a715503096021c1e84917f00ee46b..a0a045ce8582f2c85249ab40a07694a9d66d4d4d 100644 (file)
@@ -1,6 +1,7 @@
 moon::cat /var/log/daemon.log::requesting ocsp status from::YES
 moon::cat /var/log/daemon.log::ocsp response verification failed::YES
 moon::cat /var/log/daemon.log::certificate status is not available::YES
-moon::cat /var/log/daemon.log::constraint check failed.*VALIDATION_FAILED.*VALIDATION_GOOD::YES
+moon::cat /var/log/daemon.log::constraint check failed: RULE_CRL_VALIDATION is FAILED, but requires at least GOOD::YES
 moon::ipsec status::rw.*ESTABLISHED::NO
+carol::cat /var/log/daemon.log::received AUTHENTICATION_FAILED notify error::YES
 carol::ipsec status::home.*ESTABLISHED::NO
index 9f20ee81c7394a7907c2e146a7b418bbe25e740b..2e0f059c65f5401f2525d0705c9965ee6606c50c 100644 (file)
@@ -1,7 +1,7 @@
 moon::cat /var/log/daemon.log::authentication of.*carol.*successful::YES
 moon::cat /var/log/daemon.log::libcurl http request failed::YES
 moon::cat /var/log/daemon.log::certificate status is not available::YES
-moon::cat /var/log/daemon.log::constraint check failed.*VALIDATION_FAILED.*VALIDATION_SKIPPED::YES
+moon::cat /var/log/daemon.log::constraint check failed: RULE_CRL_VALIDATION is FAILED, but requires at least SKIPPED::YES
 moon::ipsec status::ESTABLISHED.*carol::YES
 moon::ipsec status::ESTABLISHED.*dave::NO
 carol::ipsec status::ESTABLISHED::YES
index b47403756e911411ba83bc00a11c5366648c6ee8..45c6ce7c5a9e25e275bc6e50b66f5a036ca4e363 100644 (file)
@@ -2,6 +2,6 @@ moon::cat /var/log/daemon.log::requesting ocsp status from::YES
 moon::cat /var/log/daemon.log::self-signed certificate.*is not trusted::YES
 moon::cat /var/log/daemon.log::ocsp response verification failed::YES
 moon::cat /var/log/daemon.log::certificate status is not available::YES
-moon::cat /var/log/daemon.log::constraint check failed.*VALIDATION_FAILED.*VALIDATION_GOOD::YES
+moon::cat /var/log/daemon.log::constraint check failed: RULE_CRL_VALIDATION is FAILED, but requires at least GOOD::YES
 moon::ipsec status::rw.*ESTABLISHED::NO
 carol::ipsec status::home.*ESTABLISHED::NO
index 7ce2bf1477c231e5fc199a54c2fd94ab4dd4bdeb..7f083a05e0ccbef109f58b13eefe901c233a7c48 100644 (file)
@@ -1,7 +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::cat /var/log/daemon.log::received AUTH_LIFETIME of 3600s, reauthentication already scheduled 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
index d5cbbdbf7e4c048bb68cabce85e929b5647ccda3..661e6cfe7f9e6c72f33bca0d1464382f21d20df2 100644 (file)
@@ -1,6 +1,7 @@
 carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+carol::cat /var/log/daemon.log::server requested EAP_AKA authentication::YES
 carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with EAP successful::YES
-moon::cat /var/log/daemon.log::using EAP identity.*carol::YES
+moon::cat /var/log/daemon.log::received EAP identity.*carol::YES
 moon::cat /var/log/daemon.log::authentication of 'carol@strongswan.org' with EAP successful::YES
 moon::ipsec statusall::rw-eap.*ESTABLISHED::YES
 carol::ipsec statusall::home.*ESTABLISHED::YES
index 5de841c03543f97806ba740e3e51fc503aed10ca..e12643ef7e0d3059cee06a40ea6e117804edd765 100644 (file)
@@ -1,4 +1,5 @@
 carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
+carol::cat /var/log/daemon.log::server requested EAP_AKA authentication::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
index 6c73054d7478e51f9b1b2a4798a39932acccfc03..2ee440cdb5c42e56a422f36820f2190bce9d30aa 100644 (file)
@@ -1,8 +1,8 @@
-carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
-moon::cat /var/log/daemon.log::using EAP identity .*carol"::YES
-carol::cat /var/log/daemon.log::EAP server requested EAP_MD5 authentication::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
+carol::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with RSA signature successful::YES
+moon::cat /var/log/daemon.log::received EAP identity .*carol::YES
+carol::cat /var/log/daemon.log::server requested EAP_MD5 authentication::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-eap.*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
index 444362a86787aae515e8849e5a646ef4d0d0f944..5e8dce9cf57fed94cf8d0405f85934515c007197 100644 (file)
@@ -1,5 +1,5 @@
 carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
-carol::cat /var/log/daemon.log::EAP server requested EAP_MD5 authentication::YES
+carol::cat /var/log/daemon.log::server requested EAP_MD5 authentication::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-eap.*ESTABLISHED::YES
index d8708d122780dea5b85fd6b95cadedc573dd3bbd..5b632bfe8a22fd1ef24095e7dbc0c7e8f680bc47 100644 (file)
@@ -1,7 +1,8 @@
-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::using EAP identity.*carol::YES
-moon::cat /var/log/daemon.log::authentication of 'PH_IP_CAROL' with EAP successful::YES
+carol::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with RSA signature successful::YES
+carol::cat /var/log/daemon.log::server requested EAP_MSCHAPV2 authentication::YES
+carol::cat /var/log/daemon.log::authentication of .*moon.strongswan.org.* with EAP successful::YES
+moon::cat /var/log/daemon.log::received EAP identity.*carol::YES
+moon::cat /var/log/daemon.log::authentication of .*PH_IP_CAROL.* with EAP successful::YES
 moon::ipsec statusall::rw-eap.*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
index 887d3f467c7d60489206a6c8b24ef97728f99ae7..0531a559f2d65ea61e0c66b2595eb91406a3f9a1 100644 (file)
@@ -9,5 +9,5 @@ are used instead of a physical SIM card on the client <b>carol</b> and
 the gateway forwards all EAP messages to the RADIUS server <b>alice</b>
 which also uses static triplets. In addition to her IKEv2 identity
 <b>carol@strongswan.org</b>, roadwarrior <b>carol</b> uses the EAP
-identity <b>232420100000015</b>.
+identity <b>228060123456001</b>.
 
index 4e7cbcc4ccdcb68e0d1f6ffd93ad643567accbcd..4305a1400376bf4962d452f5a3e75a7afb45358e 100644 (file)
@@ -1,6 +1,6 @@
 carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
-moon::cat /var/log/daemon.log::using EAP identity .*232420100000015::YES
-carol::cat /var/log/daemon.log::EAP server requested EAP_SIM authentication::YES
+moon::cat /var/log/daemon.log::received EAP identity .*228060123456001::YES
+carol::cat /var/log/daemon.log::server requested EAP_SIM authentication::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-eap.*ESTABLISHED::YES
index 2a750029f8a8d40a39141ed351f41fed97515c67..c167ba940effecfb48e43f6ed553fc8e55e4c399 100644 (file)
@@ -1,3 +1,3 @@
-232420100000015,30000000000000000000000000000000,30112233,305566778899AABB
-232420100000015,31000000000000000000000000000000,31112233,315566778899AABB
-232420100000015,32000000000000000000000000000000,32112233,325566778899AABB
+228060123456001,30000000000000000000000000000000,30112233,305566778899AABB
+228060123456001,31000000000000000000000000000000,31112233,315566778899AABB
+228060123456001,32000000000000000000000000000000,32112233,325566778899AABB
index 4045893488b7b3b66f7b1bc02965b25368f7523e..94186cfa9ade59146de33fd31ceb47e8200ab54c 100755 (executable)
@@ -16,7 +16,7 @@ conn home
        leftnexthop=%direct
        leftid=carol@strongswan.org
        leftfirewall=yes
-       eap_identity=232420100000015
+       eap_identity=228060123456001
        right=PH_IP_MOON
        rightid=@moon.strongswan.org
        rightsubnet=10.1.0.0/16
index cd4b43cca081fbf97859c05a6c8893a5f12a63d9..5fae7ecd594721681d523a90764ca30ecfb2263b 100644 (file)
@@ -1,5 +1,5 @@
 carol::cat /var/log/daemon.log::authentication of 'moon.strongswan.org' with RSA signature successful::YES
-carol::cat /var/log/daemon.log::EAP server requested EAP_SIM authentication::YES
+carol::cat /var/log/daemon.log::server requested EAP_SIM authentication::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-eap.*ESTABLISHED.*carol@strongswan.org::YES
@@ -8,7 +8,7 @@ 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
 moon::cat /var/log/daemon.log::received Access-Reject from RADIUS server::YES
-moon::cat /var/log/daemon.log::authentication of 'dave@strongswan.org' with EAP failed::YES
+moon::cat /var/log/daemon.log::EAP method EAP_SIM failed for peer dave@strongswan.org::YES
 moon::ipsec statusall::rw-eap.*ESTABLISHED.*dave@strongswan.org::NO
 dave::cat /var/log/daemon.log::received EAP_FAILURE, EAP authentication failed::YES
 dave::ipsec statusall::home.*ESTABLISHED::NO
index 46ca8fec1b1fd8bb5068555ffe3be3fda24d59a7..94ffaa487175390bad1904704f24c63e23e025f0 100644 (file)
@@ -1,6 +1,7 @@
-The roadwarriors <b>carol</b> and <b>dave</b> set up a connection each 
-to gateway <b>moon</b>. The authentication is based on <b>X.509 certificates</b>.
-Gateway <b>moon</b> has already loaded a revoked certificate for <b>carol</b>
-and a self-signed certificate for <b>dave</b> locally but gets actual certificates
-as CERT payloads from both peers. The RSA signature verification process tries all
-candidate peer certificates until it finds a valid one with a matching public key.
+The roadwarrior <b>carol</b> possesses two different X.509 certificates plus
+matching RSA private keys. With the first certificate <b>carol</b> authenticates
+a tunnel connection to gateway <b>moon</b> in order to reach client <b>alice</b>
+and presents the second certificate in order to reach client <b>venus</b> using
+the identity <b>carol@strongswan.org</b> for both IKE security associations.
+Therefore the RSA signature verification process on <b>moon</b> tries all
+candidate peer certificates until it finds the correct RSA public key.
index 0598e1fb2275397c8a804e340ad6ea9dafa36ee0..d32e32660144bdd4122c7765949210e52aa75444 100644 (file)
@@ -1,15 +1,12 @@
-moon::cat /var/log/daemon.log::certificate was revoked::YES
-moon::cat /var/log/daemon.log::authentication of.*carol@strongswan.org.*with RSA signature successful::YES
-moon::cat /var/log/daemon.log::signature validation failed, looking for another key::YES
-moon::cat /var/log/daemon.log::authentication of.*dave@strongswan.org.*with RSA signature successful::YES
-moon::ipsec statusall::carol.*ESTABLISHED::YES
-moon::ipsec statusall::dave.*ESTABLISHED::YES
-carol::ipsec statusall::home.*ESTABLISHED::YES
-dave::ipsec statusall::home.*ESTABLISHED::YES
+moon::cat /var/log/daemon.log::using certificate.*OU=Research, CN=carol@strongswan.org::YES
+moon::ipsec statusall::alice.*INSTALLED::YES
+carol::ipsec statusall::alice.*ESTABLISHED::YES
 carol::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_seq=1::YES
-dave::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_seq=1::YES
+moon::cat /var/log/daemon.log::signature validation failed, looking for another key::YES
+moon::cat /var/log/daemon.log::using certificate.*OU=Research, SN=002, CN=carol@strongswan.org::YES
+moon::ipsec statusall::venus.*INSTALLED::YES
+carol::ipsec statusall::venus.*ESTABLISHED::YES
+carol::ping -c 1 PH_IP_VENUS::64 bytes from PH_IP_VENUS: 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
-moon::tcpdump::IP dave.strongswan.org > moon.strongswan.org: ESP::YES
-moon::tcpdump::IP moon.strongswan.org > dave.strongswan.org: ESP::YES
 
index bcdb8641bb417e5cdb59e31c250faa9df599b7ee..9129f160b53eb9ce1851e58a22c71f8aeb229413 100755 (executable)
@@ -2,7 +2,7 @@
 
 config setup
         crlcheckinterval=180
-       strictcrlpolicy=no
+       strictcrlpolicy=yes
        plutostart=no
 
 conn %default
@@ -10,14 +10,20 @@ conn %default
        keylife=20m
        rekeymargin=3m
        keyingtries=1
-
-conn home
+       keyexchange=ikev2
        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
+
+conn alice 
+       leftcert=carolCert.pem
+       rightsubnet=10.1.0.10/32
+       auto=add
+
+conn venus
+       leftcert=carolCert-002.pem
+       rightsubnet=10.1.0.20/32
        auto=add
+
diff --git a/testing/tests/ikev2/two-certs/hosts/carol/etc/ipsec.d/certs/carolCert-002.pem b/testing/tests/ikev2/two-certs/hosts/carol/etc/ipsec.d/certs/carolCert-002.pem
new file mode 100644 (file)
index 0000000..4ebebba
--- /dev/null
@@ -0,0 +1,25 @@
+-----BEGIN CERTIFICATE-----
+MIIEMDCCAxigAwIBAgIBFTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJDSDEZ
+MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEbMBkGA1UEAxMSc3Ryb25nU3dhbiBS
+b290IENBMB4XDTA5MDQwNzEyMDExN1oXDTE0MDQwNjEyMDExN1owaDELMAkGA1UE
+BhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xETAPBgNVBAsTCFJlc2Vh
+cmNoMQwwCgYDVQQFEwMwMDIxHTAbBgNVBAMUFGNhcm9sQHN0cm9uZ3N3YW4ub3Jn
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtXtFcjNbEEK76mVv1j3c
+6YWBeunBl7V9Qf1bPpzwTTUIKFDkg6HtWaNa7fxhTtHlPFHH8hdgiEZTQt626GoH
+8DKE1MaBOgvnW01vh2p1j8jW3VXSwBWBCM9vNnaxGic94Qiix6z+cAulCo1pzyY1
+XaJSGAvwG3Jap9/gChClAv65zg34mLWZpcXddUGoaOMu3JaRgVaNEiY4wGweMM3n
+hgxJ7+3q9vX+z5EqUQB59WBzVz7fU9FygLgfeAD1McrvMQOjo/PtkpEBOJipnjq9
+0k/+Z3gKIHbi6YIoIXDs7bOSaw8myvD5Bi4vNr5tKPr7bdLBU+AyAzRlJWV4GBw/
+rQIDAQABo4IBBjCCAQIwCQYDVR0TBAIwADALBgNVHQ8EBAMCA6gwHQYDVR0OBBYE
+FABqD2vvGFgP2xX2Qqjx26Mz1RR5MG0GA1UdIwRmMGSAFF2n3XAGUTJ+57Zts7Xl
+4GDqLk3voUmkRzBFMQswCQYDVQQGEwJDSDEZMBcGA1UEChMQTGludXggc3Ryb25n
+U3dhbjEbMBkGA1UEAxMSc3Ryb25nU3dhbiBSb290IENBggEAMB8GA1UdEQQYMBaB
+FGNhcm9sQHN0cm9uZ3N3YW4ub3JnMDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly9j
+cmwuc3Ryb25nc3dhbi5vcmcvc3Ryb25nc3dhbi5jcmwwDQYJKoZIhvcNAQEFBQAD
+ggEBAGuatpu8jxc22Iqglx5UIa8fkNSjfyLgO0RugCB+kPPilGttGWly+raLggQM
+Hu1qdt4l0cj60pe03Dc4GuUwJCW9J4ntVvCp1/SLcifvd3pMTtlrdSMpj105L5ma
+/nVksJ7UZPzcBLMq/8FtEg68H2WM+ixrmlm2cZiFDytMODEuAPCwWHOSP4WJNDzS
+KKc95ONxwTsD1VDm/ShcKw083XgvT7oHoei2RRDYp70CkatWOOJ7eMxdKdICl8nu
+9RlBLG8CJqcy7cJ4V7GOk6EOtGpGL/GR2gpLpvUnmWP9MUHYu8rVTzKQdW9A2Wjx
+fmSZH0LzbAm+7XFrP71rBSJUaUI=
+-----END CERTIFICATE-----
diff --git a/testing/tests/ikev2/two-certs/hosts/carol/etc/ipsec.d/private/carolKey-002.pem b/testing/tests/ikev2/two-certs/hosts/carol/etc/ipsec.d/private/carolKey-002.pem
new file mode 100644 (file)
index 0000000..aec8e7a
--- /dev/null
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAtXtFcjNbEEK76mVv1j3c6YWBeunBl7V9Qf1bPpzwTTUIKFDk
+g6HtWaNa7fxhTtHlPFHH8hdgiEZTQt626GoH8DKE1MaBOgvnW01vh2p1j8jW3VXS
+wBWBCM9vNnaxGic94Qiix6z+cAulCo1pzyY1XaJSGAvwG3Jap9/gChClAv65zg34
+mLWZpcXddUGoaOMu3JaRgVaNEiY4wGweMM3nhgxJ7+3q9vX+z5EqUQB59WBzVz7f
+U9FygLgfeAD1McrvMQOjo/PtkpEBOJipnjq90k/+Z3gKIHbi6YIoIXDs7bOSaw8m
+yvD5Bi4vNr5tKPr7bdLBU+AyAzRlJWV4GBw/rQIDAQABAoIBAFekBUCGPobWw2sJ
+u32J+IIpgAL8mgoKkkfo80SEg6O1ZZAaqJBNBZNRSRs+0zs+L+b2U4m88lg9Jf5Y
+EZqhgd3kd7NNfaCrmPnFpoONzOI4ClNvG8y5VcwMaNezcAmCQ+bFxd6J04IGjZhP
+/HYWLJVgSybjtPt8OP1zJv2VVirgSb1rHOzI9j1CsaIl6m1gcXU2hA3A2/BIOd6Y
+UgCxJKu8G7NsmW14TSbJshcI1tUFOfbxFlAhmeAD57Kw6eC2GVwuBhghAYCNbpx0
+TYcQeTsBUjubna30K7+8lU1uiblKNLDqAzWynHz8xm1QEo0Z7txP9RRJUZDzlpmx
+u9iCMp0CgYEA6ZSexI3igJ68bdTOBwdbFtA9wqUTbYj6MULfUkFwqGLswLpNhhGv
+Y9X8YHUjcWEEoLXZb9QftmQc1R/nFCWC2slBBrKw9oERUUVYoczNpbkqJI1fjVfJ
+lNFgPXqQlRGIgSzSZr0CdBVs2VZKp19izQRQQI8d3ATD+Q4503dorgMCgYEAxuaC
+jow+vgcNt0DxlVWiV9rYGR7sDPJhdDyWgZ+yfaG0lVaX/81cEVxalUKTGHeHrhFs
+tIrZbRaIo9+XINzqCBNqfgauAZRFCvDv/BQPoGW+XKe+nH7DcC5PH8lcH6k1uGlq
+1KaRPymLRF8/PMmQ92o5Gk6H+Ah523hOJSv5BI8CgYBXH91cmUO8D/leyjqS+pZq
+WwA+Yw5tE+Omjjf4WXppBIUkmhkigeQ2y/FYFTlEKBjuzQWupaOyh4MNp9msdRVr
+ABhmJC7Hs3q/IqudpmOqhfeHLMhQU0dYYASSye21/JU7AXn1YljQ7dDs/DfaWETl
+Dc/VVMyhbZGfi0PccbS0+wKBgQC686+DjQ7sTnT16nUoiHUvXuP/uLDm+mvfdZOC
+AzkiHPw/4kS8i6oeJ1B9OzZHqRI+6uHiUSBNCQEmBuNmYD8ZmCZgjqa/lT3QKudn
+aPPHL9rd/E2NixjoOJ7mob2VhNaZn3xqpKWhWMsuWNh3qn44D//cWjQzTsQ7JblN
+9yb4wQKBgQCUs7wKhD/c45ST7bWH3C/iXBXsUwJrVPLKrCxl5vzkKTiDevMDVndo
+/jRAVk5UQEGO+R2eaqsgEujsS+ypGG1EWAdDyQ/6v8/34I7UF/bh5lZYOh1dXr6F
+PIROdfotGWYq2ituq1IbJMKFwhZLM7CRqnr0qsb9UaZeeuhqB3PAKQ==
+-----END RSA PRIVATE KEY-----
diff --git a/testing/tests/ikev2/two-certs/hosts/carol/etc/ipsec.secrets b/testing/tests/ikev2/two-certs/hosts/carol/etc/ipsec.secrets
new file mode 100644 (file)
index 0000000..2181f94
--- /dev/null
@@ -0,0 +1,5 @@
+# /etc/ipsec.secrets - strongSwan IPsec secrets file
+
+: RSA carolKey.pem "nH5ZQEWtku0RJEZ6"
+
+: RSA carolKey-002.pem 
index 8800c7ad59d7b3c0bbb111552e886ebd641b9362..a93ccbc9a8481282b24debbd4d35ed6e8368f156 100755 (executable)
@@ -3,8 +3,14 @@
 config setup
         crlcheckinterval=180
        strictcrlpolicy=yes
+       uniqueids=no
        plutostart=no
 
+ca strongswan
+        cacert=strongswanCert.pem
+        crluri=http://crl.strongswan.org/strongswan.crl
+        auto=add
+
 conn %default
        ikelifetime=60m
        keylife=20m
@@ -13,19 +19,16 @@ conn %default
        left=PH_IP_MOON
        leftcert=moonCert.pem
        leftid=@moon.strongswan.org
-       leftsubnet=10.1.0.0/16
        leftfirewall=yes
        right=%any
+       rightid=carol@strongswan.org
        keyexchange=ikev2
 
-conn carol
-       rightid=carol@strongswan.org
-       rightcert=carolRevokedCert.pem
+conn alice 
+       leftsubnet=10.1.0.10/32
        auto=add
 
-conn dave
-       rightid=dave@strongswan.org
-       rightcert=daveCert.der
-       rightca=%any
+conn venus 
+       leftsubnet=10.1.0.20/32
        auto=add
 
diff --git a/testing/tests/ikev2/two-certs/hosts/moon/etc/ipsec.d/certs/carolRevokedCert.pem b/testing/tests/ikev2/two-certs/hosts/moon/etc/ipsec.d/certs/carolRevokedCert.pem
deleted file mode 100644 (file)
index 5b742fc..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIEIjCCAwqgAwIBAgIBBzANBgkqhkiG9w0BAQQFADBFMQswCQYDVQQGEwJDSDEZ
-MBcGA1UEChMQTGludXggc3Ryb25nU3dhbjEbMBkGA1UEAxMSc3Ryb25nU3dhbiBS
-b290IENBMB4XDTA0MDkxMDExMjU0OFoXDTA5MDkwOTExMjU0OFowWjELMAkGA1UE
-BhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xETAPBgNVBAsTCFJlc2Vh
-cmNoMR0wGwYDVQQDFBRjYXJvbEBzdHJvbmdzd2FuLm9yZzCCASIwDQYJKoZIhvcN
-AQEBBQADggEPADCCAQoCggEBAM5413q1B2EF3spcYD1u0ce9AtIHdxmU3+1E0hqV
-mLqpIQtyp4SLbrRunxpoVUuEpHWXgLb3C/ljjlKCMWWmhw4wja1rBTjMNJLPj6Bo
-5Qn4Oeuqm7/kLHPGbveQGtcSsJCk6iLqFTbq0wsji5Ogq7kmjWgQv0nM2jpofHLv
-VOAtWVSj+x2b3OHdl/WpgTgTw1HHjYo7/NOkARdTcZ2/wxxM3z1Abp9iylc45GLN
-IL/OzHkT8b5pdokdMvVijz8IslkkewJYXrVQaCNMZg/ydlXOOAEKz0YqnvXQaYs5
-K+s8XvQ2RFCr5oO0fRT2VbiI9TgHnbcnfUi25iHl6txsXg0CAwEAAaOCAQYwggEC
-MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgOoMB0GA1UdDgQWBBTbA2TH3ca8tgCGkYy9
-OV/MqUTHAzBtBgNVHSMEZjBkgBRdp91wBlEyfue2bbO15eBg6i5N76FJpEcwRTEL
-MAkGA1UEBhMCQ0gxGTAXBgNVBAoTEExpbnV4IHN0cm9uZ1N3YW4xGzAZBgNVBAMT
-EnN0cm9uZ1N3YW4gUm9vdCBDQYIBADAfBgNVHREEGDAWgRRjYXJvbEBzdHJvbmdz
-d2FuLm9yZzA5BgNVHR8EMjAwMC6gLKAqhihodHRwOi8vY3JsLnN0cm9uZ3N3YW4u
-b3JnL3N0cm9uZ3N3YW4uY3JsMA0GCSqGSIb3DQEBBAUAA4IBAQC9acuCUPEBOrWB
-56vS8N9bksQwv/XcYIFYqV73kFBAzOPLX2a9igFGvBPdCxFu/t8JCswzE6to4LFM
-2+6Z2QJf442CLPcJKxITahrjJXSxGbzMlmaDvZ5wFCJAlyin+yuInpTwl8rMZe/Q
-O5JeJjzGDgWJtnGdkLUk/l2r6sZ/Cmk5rZpuO0hcUHVztMLQYPzqTpuMvC5p4JzL
-LWGWhKRhJs53NmxXXodck/ZgaqiTWuQFYlbamJRvzVBfX7c1SWHRJvxSSOPKGIg3
-wphkO2naj/SQD+BNuWTRmZ9YCiLOQ64ybLpJzRZISETdqtLBPKsIqosUZwkxlR1N
-9IcgYi5x
------END CERTIFICATE-----
diff --git a/testing/tests/ikev2/two-certs/hosts/moon/etc/ipsec.d/certs/daveCert.der b/testing/tests/ikev2/two-certs/hosts/moon/etc/ipsec.d/certs/daveCert.der
deleted file mode 100644 (file)
index 6c4f37c..0000000
Binary files a/testing/tests/ikev2/two-certs/hosts/moon/etc/ipsec.d/certs/daveCert.der and /dev/null differ
index 195065a5f0589a84be88b422ade9fdb976243290..a1f0678389c1884ee57121e5609e8200385fbcec 100644 (file)
@@ -1,7 +1,6 @@
 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
-moon::rm /etc/ipsec.d/certs/*
+carol::rm /etc/ipsec.d/private/*
+carol::rm /etc/ipsec.d/certs/*
index 42e9d7c242fe5979b4aba4366d70b10b0c171bc6..716cf71e81e9fc16d49259e1cd4bcb6353c4a04e 100644 (file)
@@ -1,9 +1,8 @@
 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
 moon::ipsec start
 carol::ipsec start
-dave::ipsec start
 carol::sleep 1
-carol::ipsec up home
-dave::ipsec up home
+carol::ipsec up alice
+carol::ipsec up venus
+carol::sleep 1
index 70416826e6c16a1fc1eab5839a81efe0550dc7e7..d0306cd25ace3bac792e5d275114b661fccb7a6e 100644 (file)
@@ -5,11 +5,11 @@
 
 # All UML instances that are required for this test
 #
-UMLHOSTS="alice moon carol winnetou dave"
+UMLHOSTS="alice venus moon carol winnetou"
 
 # Corresponding block diagram
 #
-DIAGRAM="a-m-c-w-d.png"
+DIAGRAM="a-v-m-c-w-d.png"
 
 # UML instances on which tcpdump is to be started
 #
@@ -18,4 +18,4 @@ TCPDUMPHOSTS="moon"
 # UML instances on which IPsec is started
 # Used for IPsec logging purposes
 #
-IPSECHOSTS="moon carol dave"
+IPSECHOSTS="moon carol"
diff --git a/testing/tests/openssl/alg-blowfish/description.txt b/testing/tests/openssl/alg-blowfish/description.txt
new file mode 100644 (file)
index 0000000..d30d9d2
--- /dev/null
@@ -0,0 +1,11 @@
+The roadwarriors <b>carol</b> and <b>dave</b> as well as the gateway <b>moon</b>
+use the <b>openssl</b> plugin based on the <b>OpenSSL</b> library for all
+cryptographical functions, thus making the <b>Blowfish</b> available as an IKEv2 cipher.
+<p>
+The roadwarriors <b>carol</b> and <b>dave</b> set up a connection each 
+to gateway <b>moon</b> using <b>Blowfish</b> for both IKE and ESP
+encryption.  Upon the successful establishment of the IPsec tunnels, <b>leftfirewall=yes</b>
+automatically inserts iptables-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> ping
+the client <b>alice</b> behind the gateway <b>moon</b>.
+
diff --git a/testing/tests/openssl/alg-blowfish/evaltest.dat b/testing/tests/openssl/alg-blowfish/evaltest.dat
new file mode 100644 (file)
index 0000000..547e967
--- /dev/null
@@ -0,0 +1,16 @@
+moon::ipsec statusall::rw.*ESTABLISHED::YES
+carol::ipsec statusall::home.*ESTABLISHED::YES
+carol::ipsec statusall::IKE proposal: BLOWFISH-256::YES
+carol::ipsec statusall::BLOWFISH-192.*,::YES
+carol::ip -s xfrm state::enc cbc(blowfish).*(192 bits)::YES
+dave::ipsec statusall::home.*ESTABLISHED::YES
+dave::ipsec statusall::IKE proposal: BLOWFISH-128::YES
+dave::ipsec statusall::BLOWFISH-128.*,::YES
+dave::ip -s xfrm state::enc cbc(blowfish).*(128 bits)::YES
+carol::ping -c 1 PH_IP_ALICE::64 bytes from PH_IP_ALICE: icmp_seq=1::YES
+dave::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
+moon::tcpdump::IP dave.strongswan.org > moon.strongswan.org: ESP::YES
+moon::tcpdump::IP moon.strongswan.org > dave.strongswan.org: ESP::YES
+
diff --git a/testing/tests/openssl/alg-blowfish/hosts/carol/etc/ipsec.conf b/testing/tests/openssl/alg-blowfish/hosts/carol/etc/ipsec.conf
new file mode 100755 (executable)
index 0000000..62e1810
--- /dev/null
@@ -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
+       ike=blowfish256-sha512-modp2048!
+       esp=blowfish192-sha256!
+
+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
+       auto=add
diff --git a/testing/tests/openssl/alg-blowfish/hosts/carol/etc/strongswan.conf b/testing/tests/openssl/alg-blowfish/hosts/carol/etc/strongswan.conf
new file mode 100644 (file)
index 0000000..e102303
--- /dev/null
@@ -0,0 +1,5 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  load = curl openssl random x509 pubkey hmac stroke kernel-netlink updown
+}
similarity index 87%
rename from testing/tests/ikev2/two-certs/hosts/dave/etc/ipsec.conf
rename to testing/tests/openssl/alg-blowfish/hosts/dave/etc/ipsec.conf
index ea8bc92a7c96212cf3c493454c1f92615674c920..26f3f3a0402b71d2bfcdae5ade0885793a231421 100755 (executable)
@@ -10,6 +10,9 @@ conn %default
        keylife=20m
        rekeymargin=3m
        keyingtries=1
+       keyexchange=ikev2
+       ike=blowfish128-sha256-modp1536!
+       esp=blowfish128-sha1!
 
 conn home
        left=PH_IP_DAVE
@@ -19,5 +22,4 @@ conn home
        right=PH_IP_MOON
        rightid=@moon.strongswan.org
        rightsubnet=10.1.0.0/16
-       keyexchange=ikev2
        auto=add
diff --git a/testing/tests/openssl/alg-blowfish/hosts/dave/etc/strongswan.conf b/testing/tests/openssl/alg-blowfish/hosts/dave/etc/strongswan.conf
new file mode 100644 (file)
index 0000000..e102303
--- /dev/null
@@ -0,0 +1,5 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  load = curl openssl random x509 pubkey hmac stroke kernel-netlink updown
+}
diff --git a/testing/tests/openssl/alg-blowfish/hosts/moon/etc/ipsec.conf b/testing/tests/openssl/alg-blowfish/hosts/moon/etc/ipsec.conf
new file mode 100755 (executable)
index 0000000..31a00f7
--- /dev/null
@@ -0,0 +1,24 @@
+# /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
+       ike=blowfish256-sha512-modp2048,blowfish128-sha256-modp1536!
+       esp=blowfish192-sha256,blowfish128-sha1!
+
+conn rw
+       left=PH_IP_MOON
+       leftcert=moonCert.pem
+       leftid=@moon.strongswan.org
+       leftsubnet=10.1.0.0/16
+       leftfirewall=yes
+       right=%any
+       auto=add
diff --git a/testing/tests/openssl/alg-blowfish/hosts/moon/etc/strongswan.conf b/testing/tests/openssl/alg-blowfish/hosts/moon/etc/strongswan.conf
new file mode 100644 (file)
index 0000000..1887f76
--- /dev/null
@@ -0,0 +1,6 @@
+# /etc/strongswan.conf - strongSwan configuration file
+
+charon {
+  dh_exponent_ansi_x9_42 = no
+  load = curl openssl random x509 pubkey hmac stroke kernel-netlink updown
+}
diff --git a/testing/tests/openssl/alg-blowfish/posttest.dat b/testing/tests/openssl/alg-blowfish/posttest.dat
new file mode 100644 (file)
index 0000000..7cebd7f
--- /dev/null
@@ -0,0 +1,6 @@
+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
diff --git a/testing/tests/openssl/alg-blowfish/pretest.dat b/testing/tests/openssl/alg-blowfish/pretest.dat
new file mode 100644 (file)
index 0000000..42e9d7c
--- /dev/null
@@ -0,0 +1,9 @@
+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
+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/openssl/alg-blowfish/test.conf b/testing/tests/openssl/alg-blowfish/test.conf
new file mode 100644 (file)
index 0000000..7041682
--- /dev/null
@@ -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.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"
index e10230384b4226e185b0113f309bfd7d101f7b22..1887f76070c33d708494f2ab049c4f60eb1e4e46 100644 (file)
@@ -1,5 +1,6 @@
 # /etc/strongswan.conf - strongSwan configuration file
 
 charon {
+  dh_exponent_ansi_x9_42 = no
   load = curl openssl random x509 pubkey hmac stroke kernel-netlink updown
 }
index f160fe1d79307737758db0cfe880142466ba70bc..2ea4f598f1866502e8da7269a10f6c2340836fc0 100644 (file)
@@ -24,18 +24,6 @@ INSERT INTO identities (
   2, X'6d6f6f6e2e7374726f6e677377616e2e6f7267'
  );
 
-INSERT INTO identities (
-  type, data
-) VALUES ( /* carol@strongswan.org as an EAP identity */
-  205, X'6361726f6c407374726f6e677377616e2e6f7267'
- );
-
-INSERT INTO identities (
-  type, data
-) VALUES ( /* moon.strongswan.org as an EAP identity */
-  205, X'6d6f6f6e2e7374726f6e677377616e2e6f7267'
- );
-
 /* Certificates */
 
 INSERT INTO certificates (
@@ -67,13 +55,13 @@ INSERT INTO shared_secrets (
 INSERT INTO shared_secret_identity (
   shared_secret, identity
 ) VALUES (
-  1, 5
+  1, 
 );
 
 INSERT INTO shared_secret_identity (
   shared_secret, identity
 ) VALUES (
-  1, 6
+  1, 
 );
 
 /* Configurations */
index 153c454a9cc46e83db4f13567d3ba1293e04a812..5d262877f25fbc1a421cfb6b1133516a65831554 100644 (file)
@@ -32,14 +32,8 @@ INSERT INTO identities (
 
 INSERT INTO identities (
   type, data
-) VALUES ( /* moon.strongswan.org as an EAP identity */
-  205, X'6d6f6f6e2e7374726f6e677377616e2e6f7267'
- );
-
-INSERT INTO identities (
-  type, data
-) VALUES ( /* carol@strongswan.org as an EAP identity */
-  205, X'6361726f6c407374726f6e677377616e2e6f7267'
+) VALUES ( /* carol@strongswan.org */
+  3, X'6361726f6c407374726f6e677377616e2e6f7267'
  );
 
 /* Certificates */
@@ -111,13 +105,13 @@ INSERT INTO shared_secrets (
 INSERT INTO shared_secret_identity (
   shared_secret, identity
 ) VALUES (
-  1, 6
+  1, 
 );
 
 INSERT INTO shared_secret_identity (
   shared_secret, identity
 ) VALUES (
-  1, 7
+  1, 
 );
 
 /* Configurations */