]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
Merge branch 'android-app'
authorTobias Brunner <tobias@strongswan.org>
Mon, 13 Aug 2012 10:07:52 +0000 (12:07 +0200)
committerTobias Brunner <tobias@strongswan.org>
Mon, 13 Aug 2012 10:07:52 +0000 (12:07 +0200)
This branch introduces a userland IPsec implementation (libipsec) and an
Android App which targets the VpnService API that is provided by Android 4+.

The implementation is based on the bachelor thesis 'Userland IPsec for
Android 4' by Giuliano Grassi and Ralf Sager.

28 files changed:
NEWS
configure.in
man/strongswan.conf.5.in
src/libcharon/Makefile.am
src/libcharon/plugins/eap_gtc/Makefile.am
src/libcharon/plugins/eap_gtc/eap_gtc.c
src/libcharon/plugins/tnccs_11/tnccs_11.c
src/libcharon/plugins/tnccs_20/state_machine/pb_tnc_state_machine.h
src/libcharon/plugins/tnccs_20/tnccs_20.c
src/libcharon/plugins/xauth_pam/Makefile.am [new file with mode: 0644]
src/libcharon/plugins/xauth_pam/xauth_pam.c [new file with mode: 0644]
src/libcharon/plugins/xauth_pam/xauth_pam.h [new file with mode: 0644]
src/libcharon/plugins/xauth_pam/xauth_pam_plugin.c [new file with mode: 0644]
src/libcharon/plugins/xauth_pam/xauth_pam_plugin.h [new file with mode: 0644]
src/libcharon/sa/ikev1/tasks/aggressive_mode.c
src/libstrongswan/crypto/aead.h
src/libstrongswan/crypto/crypters/crypter.h
src/libstrongswan/crypto/hashers/hasher.h
src/libstrongswan/crypto/mac.h
src/libstrongswan/crypto/nonce_gen.h
src/libstrongswan/crypto/prf_plus.h
src/libstrongswan/crypto/prfs/prf.h
src/libstrongswan/crypto/rngs/rng.h
src/libstrongswan/crypto/signers/signer.h
src/libstrongswan/printf_hook.h
src/libstrongswan/threading/spinlock.c
src/libstrongswan/utils/leak_detective.c
src/libtls/tls_fragmentation.c

diff --git a/NEWS b/NEWS
index f412db8cd2820df7c6f61eecb809d50334e3e3c4..3a308178b61afc3365606accf0d782f6e1a38849 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,11 @@ strongswan-5.0.1
   a second authentication round, for example during XAuth authentication
   against a RADIUS server.
 
+- The xauth-pam backend can authenticate IKEv1 XAuth and Hybrid authenticated
+  clients against any PAM service. The IKEv2 eap-gtc plugin does not use
+  PAM directly anymore, but can use any XAuth backend to verify credentials,
+  including xauth-pam.
+
 - The autotools build has been migrated to use a config.h header. strongSwan
   development headers will get installed during "make install" if
   --with-dev-headers has been passed to ./configure.
index 4555c75d60d7bb38238d5896dba7588a23fc66c1..3b9b5c244c803b15b103debd78307e3961896bdf 100644 (file)
@@ -148,7 +148,7 @@ ARG_ENABL_SET([eap-simaka-pseudonym], [enable EAP-SIM/AKA pseudonym storage plug
 ARG_ENABL_SET([eap-simaka-reauth],    [enable EAP-SIM/AKA reauthentication data storage plugin.])
 ARG_ENABL_SET([eap-identity],   [enable EAP module providing EAP-Identity helper.])
 ARG_ENABL_SET([eap-md5],        [enable EAP MD5 (CHAP) authentication module.])
-ARG_ENABL_SET([eap-gtc],        [enable PAM based EAP GTC authentication module.])
+ARG_ENABL_SET([eap-gtc],        [enable EAP GTC authentication module.])
 ARG_ENABL_SET([eap-mschapv2],   [enable EAP MS-CHAPv2 authentication module.])
 ARG_ENABL_SET([eap-tls],        [enable EAP TLS authentication module.])
 ARG_ENABL_SET([eap-ttls],       [enable EAP TTLS authentication module.])
@@ -157,6 +157,7 @@ ARG_ENABL_SET([eap-tnc],        [enable EAP TNC trusted network connect module.]
 ARG_ENABL_SET([eap-radius],     [enable RADIUS proxy authentication module.])
 ARG_DISBL_SET([xauth-generic],  [disable generic XAuth backend.])
 ARG_ENABL_SET([xauth-eap],      [enable XAuth backend using EAP methods to verify passwords.])
+ARG_ENABL_SET([xauth-pam],      [enable XAuth backend using PAM to verify passwords.])
 ARG_ENABL_SET([tnc-ifmap],      [enable TNC IF-MAP module.])
 ARG_ENABL_SET([tnc-pdp],        [enable TNC policy decision point module.])
 ARG_ENABL_SET([tnc-imc],        [enable TNC IMC module.])
@@ -771,7 +772,7 @@ if test x$nm = xtrue; then
        AC_SUBST(nm_LIBS)
 fi
 
-if test x$eap_gtc = xtrue; then
+if test x$xauth_pam = xtrue; then
        AC_HAVE_LIBRARY([pam],[LIBS="$LIBS"],[AC_MSG_ERROR([PAM library not found])])
        AC_CHECK_HEADER([security/pam_appl.h],,[AC_MSG_ERROR([PAM header security/pam_appl.h not found!])])
 fi
@@ -926,6 +927,7 @@ ADD_PLUGIN([eap-peap],             [c charon nm])
 ADD_PLUGIN([eap-tnc],              [c charon])
 ADD_PLUGIN([xauth-generic],        [c charon])
 ADD_PLUGIN([xauth-eap],            [c charon])
+ADD_PLUGIN([xauth-pam],            [c charon])
 ADD_PLUGIN([tnc-ifmap],            [c charon])
 ADD_PLUGIN([tnc-pdp],              [c charon])
 ADD_PLUGIN([tnc-imc],              [c charon])
@@ -1054,6 +1056,7 @@ AM_CONDITIONAL(USE_EAP_TNC, test x$eap_tnc = xtrue)
 AM_CONDITIONAL(USE_EAP_RADIUS, test x$eap_radius = xtrue)
 AM_CONDITIONAL(USE_XAUTH_GENERIC, test x$xauth_generic = xtrue)
 AM_CONDITIONAL(USE_XAUTH_EAP, test x$xauth_eap = xtrue)
+AM_CONDITIONAL(USE_XAUTH_PAM, test x$xauth_pam = xtrue)
 AM_CONDITIONAL(USE_TNC_IFMAP, test x$tnc_ifmap = xtrue)
 AM_CONDITIONAL(USE_TNC_PDP, test x$tnc_pdp = xtrue)
 AM_CONDITIONAL(USE_TNC_IMC, test x$tnc_imc = xtrue)
@@ -1234,6 +1237,7 @@ AC_OUTPUT(
        src/libcharon/plugins/eap_radius/Makefile
        src/libcharon/plugins/xauth_generic/Makefile
        src/libcharon/plugins/xauth_eap/Makefile
+       src/libcharon/plugins/xauth_pam/Makefile
        src/libcharon/plugins/tnc_ifmap/Makefile
        src/libcharon/plugins/tnc_pdp/Makefile
        src/libcharon/plugins/tnc_imc/Makefile
index 0c75bd0263ea4b3c2e4d4ca7668f0a53f8b2b659..4fba2344b5ac6bd9bb9aa2a0e40e69fc4c361cb3 100644 (file)
@@ -303,9 +303,8 @@ enable loaded duplicheck plugin
 .BR charon.plugins.eap-aka-3ggp2.seq_check
 
 .TP
-.BR charon.plugins.eap-gtc.pam_service " [login]"
-PAM service to be used for authentication
-
+.BR charon.plugins.eap-gtc.backend " [pam]"
+XAuth backend to be used for credential verification
 .TP
 .BR charon.plugins.eap-peap.fragment_size " [1024]"
 Maximum size of an EAP-PEAP packet
@@ -512,13 +511,13 @@ certificates even if they don't contain a CA basic constraint.
 .BR charon.plugins.stroke.max_concurrent " [4]"
 Maximum number of stroke messages handled concurrently
 .TP
-.BR charon.plugins.tnccs-11.max_msg_size " [45000]"
+.BR charon.plugins.tnccs-11.max_message_size " [45000]"
 Maximum size of a PA-TNC message (XML & Base64 encoding)
 .TP
 .BR charon.plugins.tnccs-20.max_batch_size " [65522]"
 Maximum size of a PB-TNC batch (upper limit via PT-EAP = 65529)
 .TP
-.BR charon.plugins.tnccs-20.max_msg_size " [65490]"
+.BR charon.plugins.tnccs-20.max_message_size " [65490]"
 Maximum size of a PA-TNC message (upper limit via PT-EAP = 65497)
 .TP
 .BR charon.plugins.tnc-ifmap.device_name
@@ -556,6 +555,9 @@ name of the strongSwan PDP as contained in the AAA certificate
 .TP
 .BR charon.plugins.whitelist.enable " [yes]"
 enable loaded whitelist plugin
+.TP
+.BR charon.plugins.xauth-pam.pam_service " [login]"
+PAM service to be used for authentication
 .SS libstrongswan section
 .TP
 .BR libstrongswan.crypto_test.bench " [no]"
index cd2c9de14702bae81cfbb25ff26590d3adb7db99..eada68bf57ab86a4fcec72bef0a7bdefc309ec45 100644 (file)
@@ -553,3 +553,10 @@ if MONOLITHIC
   libcharon_la_LIBADD += plugins/xauth_eap/libstrongswan-xauth-eap.la
 endif
 endif
+
+if USE_XAUTH_PAM
+  SUBDIRS += plugins/xauth_pam
+if MONOLITHIC
+  libcharon_la_LIBADD += plugins/xauth_pam/libstrongswan-xauth-pam.la
+endif
+endif
index d8722bf9d99a0c8f281ffe2879d7fb98722e898b..e4234fab2b358eca2b60107763ee763dde42f6e6 100644 (file)
@@ -13,4 +13,4 @@ endif
 libstrongswan_eap_gtc_la_SOURCES = \
        eap_gtc_plugin.h eap_gtc_plugin.c eap_gtc.h eap_gtc.c
 
-libstrongswan_eap_gtc_la_LDFLAGS = -module -avoid-version -lpam
+libstrongswan_eap_gtc_la_LDFLAGS = -module -avoid-version
index 9c262131e304c4ab20b0669753a5add806adf259..f090e94a8003d504d4b4b0cdf86e8b4f592e6dd2 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2007 Martin Willi
+ * Copyright (C) 2007-2012 Martin Willi
+ * Copyright (C) 2012 revosec AG
  * Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
 
 #include <daemon.h>
 #include <library.h>
-#include <crypto/hashers/hasher.h>
-
-#include <security/pam_appl.h>
 
 #define GTC_REQUEST_MSG "password"
-#define GTC_PAM_SERVICE "login"
 
 typedef struct private_eap_gtc_t private_eap_gtc_t;
 
@@ -77,63 +74,6 @@ METHOD(eap_method_t, initiate_peer, status_t,
        return FAILED;
 }
 
-/**
- * PAM conv callback function
- */
-static int auth_conv(int num_msg, const struct pam_message **msg,
-                                        struct pam_response **resp, char *password)
-{
-       struct pam_response *response;
-
-       if (num_msg != 1)
-       {
-               return PAM_CONV_ERR;
-       }
-       response = malloc(sizeof(struct pam_response));
-       response->resp = strdup(password);
-       response->resp_retcode = 0;
-       *resp = response;
-       return PAM_SUCCESS;
-}
-
-/**
- * Authenticate a username/password using PAM
- */
-static bool authenticate(char *service, char *user, char *password)
-{
-       pam_handle_t *pamh = NULL;
-       static struct pam_conv conv;
-       int ret;
-
-       conv.conv = (void*)auth_conv;
-       conv.appdata_ptr = password;
-
-       ret = pam_start(service, user, &conv, &pamh);
-       if (ret != PAM_SUCCESS)
-       {
-               DBG1(DBG_IKE, "EAP-GTC pam_start failed: %s",
-                        pam_strerror(pamh, ret));
-               return FALSE;
-       }
-       ret = pam_authenticate(pamh, 0);
-       if (ret == PAM_SUCCESS)
-       {
-               ret = pam_acct_mgmt(pamh, 0);
-               if (ret != PAM_SUCCESS)
-               {
-                       DBG1(DBG_IKE, "EAP-GTC pam_acct_mgmt failed: %s",
-                                pam_strerror(pamh, ret));
-               }
-       }
-       else
-       {
-               DBG1(DBG_IKE, "EAP-GTC pam_authenticate failed: %s",
-                        pam_strerror(pamh, ret));
-       }
-       pam_end(pamh, ret);
-       return ret == PAM_SUCCESS;
-}
-
 METHOD(eap_method_t, initiate_server, status_t,
        private_eap_gtc_t *this, eap_payload_t **out)
 {
@@ -192,40 +132,57 @@ METHOD(eap_method_t, process_peer, status_t,
 METHOD(eap_method_t, process_server, status_t,
        private_eap_gtc_t *this, eap_payload_t *in, eap_payload_t **out)
 {
-       chunk_t data, encoding;
-       char *user, *password, *service, *pos;
-
-       data = chunk_skip(in->get_data(in), 5);
-       if (this->identifier != in->get_identifier(in) || !data.len)
+       status_t status = FAILED;
+       chunk_t user, pass;
+       xauth_method_t *xauth;
+       cp_payload_t *ci, *co;
+       char *backend;
+
+       user = this->peer->get_encoding(this->peer);
+       pass = chunk_skip(in->get_data(in), 5);
+       if (this->identifier != in->get_identifier(in) || !pass.len)
        {
                DBG1(DBG_IKE, "received invalid EAP-GTC message");
                return FAILED;
        }
 
-       encoding = this->peer->get_encoding(this->peer);
-       /* if a RFC822_ADDR id is provided, we use the username part only */
-       pos = memchr(encoding.ptr, '@', encoding.len);
-       if (pos)
+       /* get XAuth backend to use for credential verification. Default to PAM
+        * to support legacy EAP-GTC configurations */
+       backend = lib->settings->get_str(lib->settings,
+                                                       "%s.plugins.eap-gtc.backend", "pam", charon->name);
+       xauth = charon->xauth->create_instance(charon->xauth, backend, XAUTH_SERVER,
+                                                                                  this->server, this->peer);
+       if (!xauth)
        {
-               encoding.len = (u_char*)pos - encoding.ptr;
+               DBG1(DBG_IKE, "creating EAP-GTC XAuth backend '%s' failed", backend);
+               return FAILED;
        }
-       user = alloca(encoding.len + 1);
-       memcpy(user, encoding.ptr, encoding.len);
-       user[encoding.len] = '\0';
-
-       password = alloca(data.len + 1);
-       memcpy(password, data.ptr, data.len);
-       password[data.len] = '\0';
-
-       service = lib->settings->get_str(lib->settings,
-                                                       "%s.plugins.eap-gtc.pam_service", GTC_PAM_SERVICE,
-                                                       charon->name);
-
-       if (!authenticate(service, user, password))
+       if (xauth->initiate(xauth, &co) == NEED_MORE)
        {
-               return FAILED;
+               /* assume that "out" contains username/password attributes */
+               co->destroy(co);
+               ci = cp_payload_create_type(CONFIGURATION_V1, CFG_REPLY);
+               ci->add_attribute(ci, configuration_attribute_create_chunk(
+                                       CONFIGURATION_ATTRIBUTE_V1, XAUTH_USER_NAME, user));
+               ci->add_attribute(ci, configuration_attribute_create_chunk(
+                                       CONFIGURATION_ATTRIBUTE_V1, XAUTH_USER_PASSWORD, pass));
+               switch (xauth->process(xauth, ci, &co))
+               {
+                       case SUCCESS:
+                               status = SUCCESS;
+                               break;
+                       case NEED_MORE:
+                               /* TODO: multiple exchanges currently not supported */
+                               co->destroy(co);
+                               break;
+                       case FAILED:
+                       default:
+                               break;
+               }
+               ci->destroy(ci);
        }
-       return SUCCESS;
+       xauth->destroy(xauth);
+       return status;
 }
 
 METHOD(eap_method_t, get_type, eap_type_t,
index ba7214a057d3aef8ce6983953933e69f815c3de1..eeb4c1ac99054d4cdb6a43c8cca427ebe00c8852 100644 (file)
@@ -554,7 +554,7 @@ tls_t *tnccs_11_create(bool is_server)
                .is_server = is_server,
                .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
                .max_msg_len = lib->settings->get_int(lib->settings,
-                                                               "%s.plugins.tnccs-11.max_msg_size", 45000,
+                                                               "%s.plugins.tnccs-11.max_message_size", 45000,
                                                                charon->name),
        );
 
index d13f20df4142771c5935cea8e4422ea7ed091623..aa317041e971d2e6e214beccb6806d08e2149016 100644 (file)
@@ -82,7 +82,7 @@ struct pb_tnc_state_machine_t {
        /**
         * Store information whether the received PB-TNC CDATA Batch was empty
         *
-        * @bool empty                  set to TRUE if received PB-TNC CDATA Batch was empty
+        * @param empty                 set to TRUE if received PB-TNC CDATA Batch was empty
         */
        void (*set_empty_cdata)(pb_tnc_state_machine_t *this, bool empty);
 
index 68a14551e00f3c575b1a7140ea6b58ec4d440319..cd7f149f6cae9bed3d49893a8b795f26b04f35fa 100644 (file)
@@ -805,7 +805,7 @@ tls_t *tnccs_20_create(bool is_server)
                                                                "%s.plugins.tnccs-20.max_batch_size", 65522,
                                                                charon->name),
                .max_msg_len = lib->settings->get_int(lib->settings,
-                                                               "%s.plugins.tnccs-20.max_msg_size", 65490,
+                                                               "%s.plugins.tnccs-20.max_message_size", 65490,
                                                                charon->name),
        );
 
diff --git a/src/libcharon/plugins/xauth_pam/Makefile.am b/src/libcharon/plugins/xauth_pam/Makefile.am
new file mode 100644 (file)
index 0000000..47521a3
--- /dev/null
@@ -0,0 +1,17 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+       -I$(top_srcdir)/src/libcharon
+
+AM_CFLAGS = -rdynamic
+
+if MONOLITHIC
+noinst_LTLIBRARIES = libstrongswan-xauth-pam.la
+else
+plugin_LTLIBRARIES = libstrongswan-xauth-pam.la
+endif
+
+libstrongswan_xauth_pam_la_SOURCES = \
+       xauth_pam_plugin.h xauth_pam_plugin.c \
+       xauth_pam.h xauth_pam.c
+
+libstrongswan_xauth_pam_la_LDFLAGS = -module -avoid-version -lpam
diff --git a/src/libcharon/plugins/xauth_pam/xauth_pam.c b/src/libcharon/plugins/xauth_pam/xauth_pam.c
new file mode 100644 (file)
index 0000000..98c1a97
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2012 Martin Willi
+ * Copyright (C) 2012 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "xauth_pam.h"
+
+#include <daemon.h>
+#include <library.h>
+
+#include <security/pam_appl.h>
+
+typedef struct private_xauth_pam_t private_xauth_pam_t;
+
+/**
+ * Private data of an xauth_pam_t object.
+ */
+struct private_xauth_pam_t {
+
+       /**
+        * Public interface.
+        */
+       xauth_pam_t public;
+
+       /**
+        * ID of the peer
+        */
+       identification_t *peer;
+};
+
+METHOD(xauth_method_t, initiate, status_t,
+       private_xauth_pam_t *this, cp_payload_t **out)
+{
+       cp_payload_t *cp;
+
+       cp = cp_payload_create_type(CONFIGURATION_V1, CFG_REQUEST);
+       cp->add_attribute(cp, configuration_attribute_create_chunk(
+                               CONFIGURATION_ATTRIBUTE_V1, XAUTH_USER_NAME, chunk_empty));
+       cp->add_attribute(cp, configuration_attribute_create_chunk(
+                               CONFIGURATION_ATTRIBUTE_V1, XAUTH_USER_PASSWORD, chunk_empty));
+       *out = cp;
+       return NEED_MORE;
+}
+
+/**
+ * PAM conv callback function
+ */
+static int auth_conv(int num_msg, const struct pam_message **msg,
+                                        struct pam_response **resp, char *password)
+{
+       struct pam_response *response;
+
+       if (num_msg != 1)
+       {
+               return PAM_CONV_ERR;
+       }
+       response = malloc(sizeof(struct pam_response));
+       response->resp = strdup(password);
+       response->resp_retcode = 0;
+       *resp = response;
+       return PAM_SUCCESS;
+}
+
+/**
+ * Authenticate a username/password using PAM
+ */
+static bool authenticate(char *service, char *user, char *password)
+{
+       pam_handle_t *pamh = NULL;
+       static struct pam_conv conv;
+       int ret;
+
+       conv.conv = (void*)auth_conv;
+       conv.appdata_ptr = password;
+
+       ret = pam_start(service, user, &conv, &pamh);
+       if (ret != PAM_SUCCESS)
+       {
+               DBG1(DBG_IKE, "XAuth pam_start for '%s' failed: %s",
+                        user, pam_strerror(pamh, ret));
+               return FALSE;
+       }
+       ret = pam_authenticate(pamh, 0);
+       if (ret == PAM_SUCCESS)
+       {
+               ret = pam_acct_mgmt(pamh, 0);
+               if (ret != PAM_SUCCESS)
+               {
+                       DBG1(DBG_IKE, "XAuth pam_acct_mgmt for '%s' failed: %s",
+                                user, pam_strerror(pamh, ret));
+               }
+       }
+       else
+       {
+               DBG1(DBG_IKE, "XAuth pam_authenticate for '%s' failed: %s",
+                        user, pam_strerror(pamh, ret));
+       }
+       pam_end(pamh, ret);
+       return ret == PAM_SUCCESS;
+}
+
+/**
+ * Convert configuration attribute content to a null-terminated string
+ */
+static void attr2string(char *buf, size_t len, chunk_t chunk)
+{
+       if (chunk.len && chunk.len < len)
+       {
+               snprintf(buf, len, "%.*s", (int)chunk.len, chunk.ptr);
+       }
+}
+
+METHOD(xauth_method_t, process, status_t,
+       private_xauth_pam_t *this, cp_payload_t *in, cp_payload_t **out)
+{
+       char *service, user[128] = "", pass[128] = "", *pos;
+       configuration_attribute_t *attr;
+       enumerator_t *enumerator;
+       chunk_t chunk;
+
+       enumerator = in->create_attribute_enumerator(in);
+       while (enumerator->enumerate(enumerator, &attr))
+       {
+               switch (attr->get_type(attr))
+               {
+                       case XAUTH_USER_NAME:
+                               /* trim to username part if email address given */
+                               chunk = attr->get_chunk(attr);
+                               pos = memchr(chunk.ptr, '@', chunk.len);
+                               if (pos)
+                               {
+                                       chunk.len = (u_char*)pos - chunk.ptr;
+                               }
+                               attr2string(user, sizeof(user), chunk);
+                               break;
+                       case XAUTH_USER_PASSWORD:
+                               attr2string(pass, sizeof(pass), attr->get_chunk(attr));
+                               break;
+                       default:
+                               break;
+               }
+       }
+       enumerator->destroy(enumerator);
+
+       if (!user[0] || !pass[0])
+       {
+               DBG1(DBG_IKE, "peer did not respond to our XAuth request");
+               return FAILED;
+       }
+
+       this->peer->destroy(this->peer);
+       this->peer = identification_create_from_string(user);
+
+       /* Look for PAM service, with a legacy fallback for the eap-gtc plugin.
+        * Default to "login". */
+       service = lib->settings->get_str(lib->settings,
+                               "%s.plugins.xauth-pam.pam_service",
+                                       lib->settings->get_str(lib->settings,
+                                               "%s.plugins.eap-gtc.pam_service",
+                                               "login", charon->name),
+                               charon->name);
+
+       if (authenticate(service, user, pass))
+       {
+               DBG1(DBG_IKE, "PAM authentication of '%s' successful", user);
+               return SUCCESS;
+       }
+       return FAILED;
+}
+
+METHOD(xauth_method_t, get_identity, identification_t*,
+       private_xauth_pam_t *this)
+{
+       return this->peer;
+}
+
+METHOD(xauth_method_t, destroy, void,
+       private_xauth_pam_t *this)
+{
+       this->peer->destroy(this->peer);
+       free(this);
+}
+
+/*
+ * Described in header.
+ */
+xauth_pam_t *xauth_pam_create_server(identification_t *server,
+                                                                        identification_t *peer)
+{
+       private_xauth_pam_t *this;
+
+       INIT(this,
+               .public = {
+                       .xauth_method = {
+                               .initiate = _initiate,
+                               .process = _process,
+                               .get_identity = _get_identity,
+                               .destroy = _destroy,
+                       },
+               },
+               .peer = peer->clone(peer),
+       );
+
+       return &this->public;
+}
diff --git a/src/libcharon/plugins/xauth_pam/xauth_pam.h b/src/libcharon/plugins/xauth_pam/xauth_pam.h
new file mode 100644 (file)
index 0000000..f2d310c
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2012 Martin Willi
+ * Copyright (C) 2012 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup xauth_pam_i xauth_pam
+ * @{ @ingroup xauth_pam
+ */
+
+#ifndef XAUTH_PAM_H_
+#define XAUTH_PAM_H_
+
+typedef struct xauth_pam_t xauth_pam_t;
+
+#include <sa/xauth/xauth_method.h>
+
+/**
+ * XAuth plugin using Pluggable Authentication Modules to verify credentials.
+ */
+struct xauth_pam_t {
+
+       /**
+        * Implemented xauth_method_t interface.
+        */
+       xauth_method_t xauth_method;
+};
+
+/**
+ * Creates the XAuth method using PAM, acting as server.
+ *
+ * @param server       ID of the XAuth server
+ * @param peer         ID of the XAuth client
+ * @return                     xauth_pam_t object
+ */
+xauth_pam_t *xauth_pam_create_server(identification_t *server,
+                                                                        identification_t *peer);
+
+#endif /** XAUTH_PAM_H_ @}*/
diff --git a/src/libcharon/plugins/xauth_pam/xauth_pam_plugin.c b/src/libcharon/plugins/xauth_pam/xauth_pam_plugin.c
new file mode 100644 (file)
index 0000000..363aaf0
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2012 Martin Willi
+ * Copyright (C) 2012 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "xauth_pam_plugin.h"
+#include "xauth_pam.h"
+
+#include <daemon.h>
+
+METHOD(plugin_t, get_name, char*,
+       xauth_pam_plugin_t *this)
+{
+       return "xauth-pam";
+}
+
+METHOD(plugin_t, get_features, int,
+       xauth_pam_plugin_t *this, plugin_feature_t *features[])
+{
+       static plugin_feature_t f[] = {
+               PLUGIN_CALLBACK(xauth_method_register, xauth_pam_create_server),
+                       PLUGIN_PROVIDE(XAUTH_SERVER, "pam"),
+       };
+       *features = f;
+       return countof(f);
+}
+
+METHOD(plugin_t, destroy, void,
+       xauth_pam_plugin_t *this)
+{
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *xauth_pam_plugin_create()
+{
+       xauth_pam_plugin_t *this;
+
+       INIT(this,
+               .plugin = {
+                       .get_name = _get_name,
+                       .get_features = _get_features,
+                       .destroy = _destroy,
+               },
+       );
+
+       return &this->plugin;
+}
diff --git a/src/libcharon/plugins/xauth_pam/xauth_pam_plugin.h b/src/libcharon/plugins/xauth_pam/xauth_pam_plugin.h
new file mode 100644 (file)
index 0000000..b752688
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012 Martin Willi
+ * Copyright (C) 2012 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup xauth_pam xauth_pam
+ * @ingroup cplugins
+ *
+ * @defgroup xauth_pam_plugin xauth_pam_plugin
+ * @{ @ingroup xauth_pam
+ */
+
+#ifndef XAUTH_PAM_PLUGIN_H_
+#define XAUTH_PAM_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct xauth_pam_plugin_t xauth_pam_plugin_t;
+
+/**
+ * XAuth plugin using Pluggable Authentication Modules to verify credentials.
+ */
+struct xauth_pam_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+#endif /** XAUTH_PAM_PLUGIN_H_ @}*/
index 9b5ad18b4aa723ce66c2e70892feb06a3c576c31..38962fc6024879e00f6949ef77eb9508f2abb43c 100644 (file)
@@ -385,8 +385,9 @@ METHOD(task_t, process_r, status_t,
                                case AUTH_XAUTH_INIT_PSK:
                                case AUTH_XAUTH_RESP_PSK:
                                case AUTH_PSK:
-                                       if (!lib->settings->get_bool(lib->settings, "charon.i_dont_"
-                                               "care_about_security_and_use_aggressive_mode_psk", FALSE))
+                                       if (!lib->settings->get_bool(lib->settings, "%s.i_dont_care"
+                                               "_about_security_and_use_aggressive_mode_psk",
+                                               FALSE, charon->name))
                                        {
                                                DBG1(DBG_IKE, "Aggressive Mode PSK disabled for "
                                                         "security reasons");
index 522996e806b14b441bc317cabe1f262c85affad9..ec526a3d97241acca47c7de06737acd2f857539b 100644 (file)
@@ -47,9 +47,8 @@ struct aead_t {
         * @param encrypted             allocated encryption result
         * @return                              TRUE if successfully encrypted
         */
-       __attribute__((warn_unused_result))
        bool (*encrypt)(aead_t *this, chunk_t plain, chunk_t assoc, chunk_t iv,
-                                       chunk_t *encrypted);
+                                       chunk_t *encrypted) __attribute__((warn_unused_result));
 
        /**
         * Decrypt and verify data, verify associated data.
@@ -102,8 +101,8 @@ struct aead_t {
         * @param key                   encryption and authentication key
         * @return                              TRUE if key set successfully
         */
-       __attribute__((warn_unused_result))
-       bool (*set_key)(aead_t *this, chunk_t key);
+       bool (*set_key)(aead_t *this,
+                                       chunk_t key) __attribute__((warn_unused_result));
 
        /**
         * Destroy a aead_t.
index 4c273059b2c6b4c4674c8bef85afb494592b3b49..fe854f53d25f7f49f2cf0891480a1044877def28 100644 (file)
@@ -92,9 +92,8 @@ struct crypter_t {
         * @param encrypted             chunk to allocate encrypted data, or NULL
         * @return                              TRUE if encryption successful
         */
-       __attribute__((warn_unused_result))
-       bool (*encrypt) (crypter_t *this, chunk_t data, chunk_t iv,
-                                        chunk_t *encrypted);
+       bool (*encrypt)(crypter_t *this, chunk_t data, chunk_t iv,
+                                       chunk_t *encrypted) __attribute__((warn_unused_result));
 
        /**
         * Decrypt a chunk of data and allocate space for the decrypted value.
@@ -108,9 +107,8 @@ struct crypter_t {
         * @param encrypted             chunk to allocate decrypted data, or NULL
         * @return                              TRUE if decryption successful
         */
-       __attribute__((warn_unused_result))
-       bool (*decrypt) (crypter_t *this, chunk_t data, chunk_t iv,
-                                        chunk_t *decrypted);
+       bool (*decrypt)(crypter_t *this, chunk_t data, chunk_t iv,
+                                       chunk_t *decrypted) __attribute__((warn_unused_result));
 
        /**
         * Get the block size of the crypto algorithm.
@@ -121,7 +119,7 @@ struct crypter_t {
         *
         * @return                              block size in bytes
         */
-       size_t (*get_block_size) (crypter_t *this);
+       size_t (*get_block_size)(crypter_t *this);
 
        /**
         * Get the IV size of the crypto algorithm.
@@ -139,7 +137,7 @@ struct crypter_t {
         *
         * @return                              key size in bytes
         */
-       size_t (*get_key_size) (crypter_t *this);
+       size_t (*get_key_size)(crypter_t *this);
 
        /**
         * Set the key.
@@ -149,13 +147,13 @@ struct crypter_t {
         * @param key                   key to set
         * @return                              TRUE if key set successfully
         */
-       __attribute__((warn_unused_result))
-       bool (*set_key) (crypter_t *this, chunk_t key);
+       bool (*set_key)(crypter_t *this,
+                                       chunk_t key) __attribute__((warn_unused_result));
 
        /**
         * Destroys a crypter_t object.
         */
-       void (*destroy) (crypter_t *this);
+       void (*destroy)(crypter_t *this);
 };
 
 /**
index fa5ff69f17ecadd826e3d0a60d30421a9c459f6b..759f6a23c86c7002e7f96ccbe00a056acadb9b6b 100644 (file)
@@ -87,8 +87,8 @@ struct hasher_t {
         * @param hash          pointer where the hash will be written
         * @return                      TRUE if hash created successfully
         */
-       __attribute__((warn_unused_result))
-       bool (*get_hash) (hasher_t *this, chunk_t data, u_int8_t *hash);
+       bool (*get_hash)(hasher_t *this, chunk_t data,
+                                        u_int8_t *hash) __attribute__((warn_unused_result));
 
        /**
         * Hash data and allocate space for the hash.
@@ -101,28 +101,27 @@ struct hasher_t {
         * @param hash          chunk which will hold allocated hash
         * @return                      TRUE if hash allocated successfully
         */
-       __attribute__((warn_unused_result))
-       bool (*allocate_hash) (hasher_t *this, chunk_t data, chunk_t *hash);
+       bool (*allocate_hash)(hasher_t *this, chunk_t data,
+                                                 chunk_t *hash) __attribute__((warn_unused_result));
 
        /**
         * Get the size of the resulting hash.
         *
         * @return                      hash size in bytes
         */
-       size_t (*get_hash_size) (hasher_t *this);
+       size_t (*get_hash_size)(hasher_t *this);
 
        /**
         * Resets the hasher's state.
         *
         * @return                      TRUE if hasher reset successfully
         */
-       __attribute__((warn_unused_result))
-       bool (*reset) (hasher_t *this);
+       bool (*reset)(hasher_t *this) __attribute__((warn_unused_result));
 
        /**
         * Destroys a hasher object.
         */
-       void (*destroy) (hasher_t *this);
+       void (*destroy)(hasher_t *this);
 };
 
 /**
index 4f952a2ad3c54a3e2287b152923e854f15ea0697..f7b43ba39eea48dbf6bd0652cdc1b6723754ebf9 100644 (file)
@@ -46,8 +46,8 @@ struct mac_t {
         * @param out           pointer where the generated bytes will be written
         * @return                      TRUE if mac generated successfully
         */
-       __attribute__((warn_unused_result))
-       bool (*get_mac)(mac_t *this, chunk_t data, u_int8_t *out);
+       bool (*get_mac)(mac_t *this, chunk_t data,
+                                       u_int8_t *out) __attribute__((warn_unused_result));
 
        /**
         * Get the size of the resulting MAC.
@@ -64,8 +64,8 @@ struct mac_t {
         * @param key           key to set
         * @return                      TRUE if key set successfully
         */
-       __attribute__((warn_unused_result))
-       bool (*set_key) (mac_t *this, chunk_t key);
+       bool (*set_key)(mac_t *this,
+                                       chunk_t key) __attribute__((warn_unused_result));
 
        /**
         * Destroys a mac_t object.
index 8461c4aa05e555bd3d61a1b01842539c14e6d479..50f3c0090ce39f39085926d32eb5a942dfb7311d 100644 (file)
@@ -37,8 +37,8 @@ struct nonce_gen_t {
         * @param buffer        pointer where the generated nonce will be written
         * @return                      TRUE if nonce allocation was succesful, FALSE otherwise
         */
-       __attribute__((warn_unused_result))
-       bool (*get_nonce) (nonce_gen_t *this, size_t size, u_int8_t *buffer);
+       bool (*get_nonce)(nonce_gen_t *this, size_t size,
+                                         u_int8_t *buffer) __attribute__((warn_unused_result));
 
        /**
         * Generates a nonce and allocates space for it.
@@ -47,13 +47,13 @@ struct nonce_gen_t {
         * @param chunk         chunk which will hold the generated nonce
         * @return                      TRUE if nonce allocation was succesful, FALSE otherwise
         */
-       __attribute__((warn_unused_result))
-       bool (*allocate_nonce) (nonce_gen_t *this, size_t size, chunk_t *chunk);
+       bool (*allocate_nonce)(nonce_gen_t *this, size_t size,
+                                                  chunk_t *chunk) __attribute__((warn_unused_result));
 
        /**
         * Destroys a nonce generator object.
         */
-       void (*destroy) (nonce_gen_t *this);
+       void (*destroy)(nonce_gen_t *this);
 };
 
 #endif /** NONCE_GEN_H_ @}*/
index 92f5dd76df1b6172397863937047895c6e74e778..f994dce1646d947e3d3795f37108e78574f24fd9 100644 (file)
@@ -38,8 +38,8 @@ struct prf_plus_t {
         * @param buffer        pointer where the generated bytes will be written
         * @return                      TRUE if bytes generated successfully
         */
-       __attribute__((warn_unused_result))
-       bool (*get_bytes) (prf_plus_t *this, size_t length, u_int8_t *buffer);
+       bool (*get_bytes)(prf_plus_t *this, size_t length,
+                                         u_int8_t *buffer) __attribute__((warn_unused_result));
 
        /**
         * Allocate pseudo random bytes.
@@ -48,13 +48,13 @@ struct prf_plus_t {
         * @param chunk         chunk which will hold generated bytes
         * @return                      TRUE if bytes allocated successfully
         */
-       __attribute__((warn_unused_result))
-       bool (*allocate_bytes) (prf_plus_t *this, size_t length, chunk_t *chunk);
+       bool (*allocate_bytes)(prf_plus_t *this, size_t length,
+                                                  chunk_t *chunk) __attribute__((warn_unused_result));
 
        /**
         * Destroys a prf_plus_t object.
         */
-       void (*destroy) (prf_plus_t *this);
+       void (*destroy)(prf_plus_t *this);
 };
 
 /**
index a360a968a52b5808200a792555c161e09d85846c..46e23b2443a13476c8a70e595ca723dcb5599bdd 100644 (file)
@@ -79,8 +79,8 @@ struct prf_t {
         * @param buffer        pointer where the generated bytes will be written
         * @return                      TRUE if bytes generated successfully
         */
-       __attribute__((warn_unused_result))
-       bool (*get_bytes) (prf_t *this, chunk_t seed, u_int8_t *buffer);
+       bool (*get_bytes)(prf_t *this, chunk_t seed,
+                                         u_int8_t *buffer) __attribute__((warn_unused_result));
 
        /**
         * Generates pseudo random bytes and allocate space for them.
@@ -89,15 +89,15 @@ struct prf_t {
         * @param chunk         chunk which will hold generated bytes
         * @return                      TRUE if bytes allocated and generated successfully
         */
-       __attribute__((warn_unused_result))
-       bool (*allocate_bytes) (prf_t *this, chunk_t seed, chunk_t *chunk);
+       bool (*allocate_bytes)(prf_t *this, chunk_t seed,
+                                                  chunk_t *chunk) __attribute__((warn_unused_result));
 
        /**
         * Get the block size of this prf_t object.
         *
         * @return                      block size in bytes
         */
-       size_t (*get_block_size) (prf_t *this);
+       size_t (*get_block_size)(prf_t *this);
 
        /**
         * Get the key size of this prf_t object.
@@ -107,7 +107,7 @@ struct prf_t {
         *
         * @return                      key size in bytes
         */
-       size_t (*get_key_size) (prf_t *this);
+       size_t (*get_key_size)(prf_t *this);
 
        /**
         * Set the key for this prf_t object.
@@ -115,13 +115,13 @@ struct prf_t {
         * @param key           key to set
         * @return                      TRUE if key set successfully
         */
-       __attribute__((warn_unused_result))
-       bool (*set_key) (prf_t *this, chunk_t key);
+       bool (*set_key)(prf_t *this,
+                                       chunk_t key) __attribute__((warn_unused_result));
 
        /**
         * Destroys a prf object.
         */
-       void (*destroy) (prf_t *this);
+       void (*destroy)(prf_t *this);
 };
 
 #endif /** PRF_H_ @}*/
index c72509b5459d0782f3084056d31cdcd97349bc5d..aee829d71abb82c706208b13ed875ce5dd38c18b 100644 (file)
@@ -56,8 +56,8 @@ struct rng_t {
         * @param buffer        pointer where the generated bytes will be written
         * @return                      TRUE if bytes successfully written
         */
-       __attribute__((warn_unused_result))
-       bool (*get_bytes) (rng_t *this, size_t len, u_int8_t *buffer);
+       bool (*get_bytes)(rng_t *this, size_t len,
+                                         u_int8_t *buffer) __attribute__((warn_unused_result));
 
        /**
         * Generates random bytes and allocate space for them.
@@ -66,13 +66,13 @@ struct rng_t {
         * @param chunk         chunk which will hold generated bytes
         * @return                      TRUE if allocation succeeded
         */
-       __attribute__((warn_unused_result))
-       bool (*allocate_bytes) (rng_t *this, size_t len, chunk_t *chunk);
+       bool (*allocate_bytes)(rng_t *this, size_t len,
+                                                  chunk_t *chunk) __attribute__((warn_unused_result));
 
        /**
         * Destroys a rng object.
         */
-       void (*destroy) (rng_t *this);
+       void (*destroy)(rng_t *this);
 };
 
 /**
@@ -82,10 +82,11 @@ struct rng_t {
  * @param rng                  rng_t object
  * @param len                  number of bytes to get
  * @param buffer               pointer where the generated bytes will be written
- * @param all                  TRUE if all bytes have to be non-zero
+ * @param all                  TRUE if all bytes have to be non-zero, FALSE for first
  * @return                             TRUE if bytes successfully written
  */
-bool rng_get_bytes_not_zero(rng_t *rng, size_t len, u_int8_t *buffer, bool all);
+bool rng_get_bytes_not_zero(rng_t *rng, size_t len, u_int8_t *buffer,
+                                                       bool all) __attribute__((warn_unused_result));
 
 /**
  * Wrapper around rng_t.allocate_bytes() ensuring that either all bytes or at
@@ -93,12 +94,12 @@ bool rng_get_bytes_not_zero(rng_t *rng, size_t len, u_int8_t *buffer, bool all);
  *
  * @param rng                  rng_t object
  * @param len                  number of bytes to get
- * @param buffer               pointer where the generated bytes will be written
- * @param all                  TRUE if all bytes have to be non-zero
+ * @param chunk                        chunk that stores the generated bytes (allocated)
+ * @param all                  TRUE if all bytes have to be non-zero, FALSE for first
  * @return                             TRUE if bytes successfully written
  */
 bool rng_allocate_bytes_not_zero(rng_t *rng, size_t len, chunk_t *chunk,
-                                                                bool all);
+                                                                bool all) __attribute__((warn_unused_result));
 
 
 
index 812a674eed556a5544f1f63c9cda1ea06d045786..9b6bd479a8c7f0b6695cc97b158d3a2c21967a3e 100644 (file)
@@ -93,8 +93,8 @@ struct signer_t {
         * @param buffer        pointer where the signature will be written
         * @return                      TRUE if signature created successfully
         */
-       __attribute__((warn_unused_result))
-       bool (*get_signature) (signer_t *this, chunk_t data, u_int8_t *buffer);
+       bool (*get_signature)(signer_t *this, chunk_t data,
+                                                 u_int8_t *buffer) __attribute__((warn_unused_result));
 
        /**
         * Generate a signature and allocate space for it.
@@ -106,8 +106,8 @@ struct signer_t {
         * @param chunk         chunk which will hold the allocated signature
         * @return                      TRUE if signature allocated successfully
         */
-       __attribute__((warn_unused_result))
-       bool (*allocate_signature) (signer_t *this, chunk_t data, chunk_t *chunk);
+       bool (*allocate_signature)(signer_t *this, chunk_t data,
+                                                 chunk_t *chunk) __attribute__((warn_unused_result));
 
        /**
         * Verify a signature.
@@ -120,21 +120,21 @@ struct signer_t {
         * @param signature     a chunk containing the signature
         * @return                      TRUE, if signature is valid, FALSE otherwise
         */
-       bool (*verify_signature) (signer_t *this, chunk_t data, chunk_t signature);
+       bool (*verify_signature)(signer_t *this, chunk_t data, chunk_t signature);
 
        /**
         * Get the block size of this signature algorithm.
         *
         * @return                      block size in bytes
         */
-       size_t (*get_block_size) (signer_t *this);
+       size_t (*get_block_size)(signer_t *this);
 
        /**
         * Get the key size of the signature algorithm.
         *
         * @return                      key size in bytes
         */
-       size_t (*get_key_size) (signer_t *this);
+       size_t (*get_key_size)(signer_t *this);
 
        /**
         * Set the key for this object.
@@ -142,13 +142,13 @@ struct signer_t {
         * @param key           key to set
         * @return                      TRUE if key set
         */
-       __attribute__((warn_unused_result))
-       bool (*set_key) (signer_t *this, chunk_t key);
+       bool (*set_key)(signer_t *this,
+                                       chunk_t key) __attribute__((warn_unused_result));
 
        /**
         * Destroys a signer_t object.
         */
-       void (*destroy) (signer_t *this);
+       void (*destroy)(signer_t *this);
 };
 
 #endif /** SIGNER_H_ @}*/
index 96e5a19afe3a9824a486d634b50f62ad14ca8b19..b162e6d97b032150dbcd2e3051c756212c600435 100644 (file)
@@ -97,6 +97,37 @@ int vstr_wrapper_vsprintf(char *str, const char *format, va_list ap);
 int vstr_wrapper_vsnprintf(char *str, size_t size, const char *format, va_list ap);
 int vstr_wrapper_vasprintf(char **str, const char *format, va_list ap);
 
+#ifdef printf
+#undef printf
+#endif
+#ifdef fprintf
+#undef fprintf
+#endif
+#ifdef sprintf
+#undef sprintf
+#endif
+#ifdef snprintf
+#undef snprintf
+#endif
+#ifdef asprintf
+#undef asprintf
+#endif
+#ifdef vprintf
+#undef vprintf
+#endif
+#ifdef vfprintf
+#undef vfprintf
+#endif
+#ifdef vsprintf
+#undef vsprintf
+#endif
+#ifdef vsnprintf
+#undef vsnprintf
+#endif
+#ifdef vasprintf
+#undef vasprintf
+#endif
+
 #define printf vstr_wrapper_printf
 #define fprintf vstr_wrapper_fprintf
 #define sprintf vstr_wrapper_sprintf
index 14ac49eb42784fe1638a46c219edd8c9f0f379e1..812cf696bd21d149540eab8c6f947aec66f9156d 100644 (file)
 #include "mutex.h"
 #include "lock_profiler.h"
 
+#if defined(_POSIX_SPIN_LOCKS) && _POSIX_SPIN_LOCKS == -1
+#undef _POSIX_SPIN_LOCKS
+#endif
+
 typedef struct private_spinlock_t private_spinlock_t;
 
 /**
index ed0899da2cffa951f052188c154bfe00f996f8ba..cface05380dce64bfcc228d78774eccd27f14d61 100644 (file)
@@ -225,6 +225,7 @@ char *whitelist[] = {
        "getpwent_r",
        "setpwent",
        "endpwent",
+       "getspnam_r",
        /* ignore dlopen, as we do not dlclose to get proper leak reports */
        "dlopen",
        "dlerror",
index eb9976884573e4e2028eabc53bae4d39ab1182c5..f2fa77cfd50426ed9348b4cbb3a4a4be0a10d27d 100644 (file)
@@ -197,6 +197,12 @@ static status_t process_handshake(private_tls_fragmentation_t *this,
 static status_t process_application(private_tls_fragmentation_t *this,
                                                                        bio_reader_t *reader)
 {
+       if (!this->handshake->finished(this->handshake))
+       {
+               DBG1(DBG_TLS, "received TLS application data, "
+                        "but handshake not finished");
+               return FAILED;
+       }
        while (reader->remaining(reader))
        {
                status_t status;