Merge branch 'eap-client-select'
authorTobias Brunner <tobias@strongswan.org>
Fri, 31 Aug 2012 10:23:38 +0000 (12:23 +0200)
committerTobias Brunner <tobias@strongswan.org>
Fri, 31 Aug 2012 10:25:41 +0000 (12:25 +0200)
This brings support for EAP-Nak payloads on the client (to select a
specific or supported method), and the server (via the eap-dynamic
plugin which selects a method supported/requested by the client).

13 files changed:
configure.in
src/frontends/android/res/values-pl/strings.xml [new file with mode: 0644]
src/libcharon/config/child_cfg.c
src/libcharon/config/ike_cfg.c
src/libcharon/network/sender.c
src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.c
src/libcharon/plugins/tnccs_20/messages/pb_pa_msg.h
src/libcharon/plugins/tnccs_20/tnccs_20.c
src/libcharon/sa/ikev1/phase1.c
src/libipsec/esp_context.c
src/libipsec/ip_packet.c
src/libstrongswan/utils/tun_device.c
src/starter/ipsec.conf

index a1c777a..f233b0a 100644 (file)
@@ -16,7 +16,7 @@ dnl ===========================
 dnl  initialize & set some vars
 dnl ===========================
 
-AC_INIT(strongSwan,5.0.1dr3)
+AC_INIT(strongSwan,5.0.1dr4)
 AM_INIT_AUTOMAKE(tar-ustar)
 AC_CONFIG_MACRO_DIR([m4/config])
 AC_CONFIG_HEADERS([config.h])
diff --git a/src/frontends/android/res/values-pl/strings.xml b/src/frontends/android/res/values-pl/strings.xml
new file mode 100644 (file)
index 0000000..e7d4670
--- /dev/null
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2012 Giuliano Grassi
+    Copyright (C) 2012 Ralf Sager
+    Copyright (C) 2012 Andreas Steffen
+    HSR Hochschule fuer Technik Rapperswil
+
+    Copyright (C) 2012 Ewa Steffen-Zolkiewicz
+
+    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.
+-->
+<resources>
+
+    <!-- Application -->
+    <string name="app_name">strongSwan klient VPN</string>
+    <string name="main_activity_name">strongSwan</string>
+    <string name="reload_trusted_certs">Przeładuj certyfikaty CA</string>
+    <string name="show_log">Pokaż log</string>
+    <string name="search">Szukaj</string>
+    <string name="vpn_not_supported_title">Nie obsługiwany VPN</string>
+    <string name="vpn_not_supported">Urządzenie nie obsługuje aplikacji VPN.\nProszę skontaktować się z producentem.</string>
+
+    <!-- Log view -->
+    <string name="log_title">Log</string>
+    <string name="send_log">Prześlij log</string>
+    <string name="empty_log">Log jest pusty</string>
+    <string name="log_mail_subject">strongSwan %1$s Log</string>
+
+    <!-- VPN profile list -->
+    <string name="no_profiles">Brak profilu VPN</string>
+    <string name="add_profile">Dodaj profil VPN</string>
+    <string name="edit_profile">Edytuj</string>
+    <string name="delete_profile">Usuń</string>
+    <string name="select_profiles">Wybierz profile</string>
+    <string name="profiles_deleted">Wybrane profile usunięte</string>
+    <string name="no_profile_selected">Nie wybrano profilu</string>
+    <string name="one_profile_selected">Wybrano jeden profil</string>
+    <string name="x_profiles_selected">Wzbrano %1$d profile"</string>
+
+    <!-- VPN profile details -->
+    <string name="profile_edit_save">Zapisz</string>
+    <string name="profile_edit_cancel">Anuluj</string>
+    <string name="profile_name_label">Nazwa profilu:</string>
+    <string name="profile_name_hint">(użyj adresu bramki)</string>
+    <string name="profile_gateway_label">Bramka:</string>
+    <string name="profile_username_label">Użytkownik:</string>
+    <string name="profile_password_label">Hasło:</string>
+    <string name="profile_password_hint">(w razie potrzebz zapromptuj)</string>
+    <string name="profile_ca_label">Certyfikat CA:</string>
+    <string name="profile_ca_auto_label">Wybierz automatycznie</string>
+    <string name="profile_ca_select_certificate_label">Wybierz certyfikat CA</string>
+    <string name="profile_ca_select_certificate">Wybierz określony certyfikat CA</string>
+    <!-- Warnings/Notifications in the details view -->
+    <string name="alert_text_no_input_gateway">Wprowadź adres bramki</string>
+    <string name="alert_text_no_input_username">Wprowadź swoją nazwę użytkownika</string>
+    <string name="alert_text_nocertfound_title">Nie wybrano żadnego certyfikatu CA</string>
+    <string name="alert_text_nocertfound">Wybierz lub uaktywnij jeden <i>Wybierz automatycznie</i></string>
+
+    <!-- Trusted certificate selection -->
+    <string name="trusted_certs_title">Certyfikaty CA</string>
+    <string name="no_certificates">Brak certyfikatów</string>
+    <string name="system_tab">System</string>
+    <string name="user_tab">Użytkownik</string>
+
+    <!-- VPN state fragment -->
+    <string name="state_label">Status:</string>
+    <string name="profile_label">Profil:</string>
+    <string name="disconnect">Rozłącz</string>
+    <string name="state_connecting">Łączenie&#8230;</string>
+    <string name="state_connected">Połączony</string>
+    <string name="state_disconnecting">Przerywam połączenie&#8230;</string>
+    <string name="state_disabled">Brak aktywnego VPN</string>
+    <string name="state_error">Błąd</string>
+
+    <!-- Dialogs -->
+    <string name="login_title">Wprowadż hasło</string>
+    <string name="login_confirm">Połącz</string>
+    <string name="error_introduction">Nie udało się utworzyć tunelu VPN:</string>
+    <string name="error_lookup_failed">Nie znaleziono adresu bramki</string>
+    <string name="error_unreachable">Bramka jest nieosiągalna</string>
+    <string name="error_peer_auth_failed">Błąd przy weryfikacji bramki</string>
+    <string name="error_auth_failed">Błąd przy autoryzacji użytkownika</string>
+    <string name="error_generic">Nieznany błąd w czasie połączenia</string>
+    <string name="connecting_title">Łączenie: %1$s</string>
+    <string name="connecting_message">Tworzenie tunelu VPN z \""%1$s\".</string>
+
+</resources>
index 74949be..1598ce0 100644 (file)
@@ -171,6 +171,8 @@ METHOD(child_cfg_t, get_proposals, linked_list_t*,
        }
        enumerator->destroy(enumerator);
 
+       DBG2(DBG_CFG, "configured proposals: %#P", proposals);
+
        return proposals;
 }
 
index 5055a93..acf4b61 100644 (file)
@@ -150,6 +150,8 @@ METHOD(ike_cfg_t, get_proposals, linked_list_t*,
        }
        enumerator->destroy(enumerator);
 
+       DBG2(DBG_CFG, "configured proposals: %#P", proposals);
+
        return proposals;
 }
 
index 5787b9a..059f24b 100644 (file)
@@ -83,6 +83,22 @@ struct private_sender_t {
 METHOD(sender_t, send_no_marker, void,
        private_sender_t *this, packet_t *packet)
 {
+       this->mutex->lock(this->mutex);
+       this->list->insert_last(this->list, packet);
+       this->got->signal(this->got);
+       this->mutex->unlock(this->mutex);
+}
+
+METHOD(sender_t, send_, void,
+       private_sender_t *this, packet_t *packet)
+{
+       host_t *src, *dst;
+
+       /* if neither source nor destination port is 500 we add a Non-ESP marker */
+       src = packet->get_source(packet);
+       dst = packet->get_destination(packet);
+       DBG1(DBG_NET, "sending packet: from %#H to %#H", src, dst);
+
        if (this->send_delay)
        {
                message_t *message;
@@ -104,22 +120,6 @@ METHOD(sender_t, send_no_marker, void,
                message->destroy(message);
        }
 
-       this->mutex->lock(this->mutex);
-       this->list->insert_last(this->list, packet);
-       this->got->signal(this->got);
-       this->mutex->unlock(this->mutex);
-}
-
-METHOD(sender_t, send_, void,
-       private_sender_t *this, packet_t *packet)
-{
-       host_t *src, *dst;
-
-       /* if neither source nor destination port is 500 we add a Non-ESP marker */
-       src = packet->get_source(packet);
-       dst = packet->get_destination(packet);
-       DBG1(DBG_NET, "sending packet: from %#H to %#H", src, dst);
-
        if (dst->get_port(dst) != IKEV2_UDP_PORT &&
                src->get_port(src) != IKEV2_UDP_PORT)
        {
index 4d5f983..bbad9bf 100644 (file)
@@ -68,14 +68,9 @@ struct private_pb_pa_msg_t {
        bool excl;
 
        /**
-        * PA Message Vendor ID
+        * Vendor-specific PA Subtype
         */
-       u_int32_t vendor_id;
-
-       /**
-        * PA Subtype
-        */
-       u_int32_t subtype;
+       pen_type_t subtype;
 
        /**
         * Posture Validator Identifier
@@ -124,8 +119,8 @@ METHOD(pb_tnc_msg_t, build, void,
        /* build message header */
        writer = bio_writer_create(64);
        writer->write_uint8 (writer, this->excl ? PA_FLAG_EXCL : PA_FLAG_NONE);
-       writer->write_uint24(writer, this->vendor_id);
-       writer->write_uint32(writer, this->subtype);
+       writer->write_uint24(writer, this->subtype.vendor_id);
+       writer->write_uint32(writer, this->subtype.type);
        writer->write_uint16(writer, this->collector_id);
        writer->write_uint16(writer, this->validator_id);
        msg_header = writer->get_buf(writer);
@@ -145,8 +140,8 @@ METHOD(pb_tnc_msg_t, process, status_t,
        /* process message header */
        reader = bio_reader_create(this->encoding);
        reader->read_uint8 (reader, &flags);
-       reader->read_uint24(reader, &this->vendor_id);
-       reader->read_uint32(reader, &this->subtype);
+       reader->read_uint24(reader, &this->subtype.vendor_id);
+       reader->read_uint32(reader, &this->subtype.type);
        reader->read_uint16(reader, &this->collector_id);
        reader->read_uint16(reader, &this->validator_id);
        this->excl = ((flags & PA_FLAG_EXCL) != PA_FLAG_NONE);
@@ -160,14 +155,14 @@ METHOD(pb_tnc_msg_t, process, status_t,
        }
        reader->destroy(reader);
 
-       if (this->vendor_id == PEN_RESERVED)
+       if (this->subtype.vendor_id == PEN_RESERVED)
        {
                DBG1(DBG_TNC, "Vendor ID 0x%06x is reserved", PEN_RESERVED);
                *offset = 1;
                return FAILED;
        }
 
-       if (this->subtype == PA_RESERVED_SUBTYPE)
+       if (this->subtype.type == PA_RESERVED_SUBTYPE)
        {
                DBG1(DBG_TNC, "PA Subtype 0x%08x is reserved", PA_RESERVED_SUBTYPE);
                *offset = 4;
@@ -184,11 +179,10 @@ METHOD(pb_tnc_msg_t, destroy, void,
        free(this);
 }
 
-METHOD(pb_pa_msg_t, get_vendor_id, u_int32_t,
-       private_pb_pa_msg_t *this, u_int32_t *subtype)
+METHOD(pb_pa_msg_t, get_subtype, pen_type_t,
+       private_pb_pa_msg_t *this)
 {
-       *subtype = this->subtype;
-       return this->vendor_id;
+       return this->subtype;
 }
 
 METHOD(pb_pa_msg_t, get_collector_id, u_int16_t,
@@ -230,7 +224,7 @@ pb_tnc_msg_t *pb_pa_msg_create_from_data(chunk_t data)
                                .process = _process,
                                .destroy = _destroy,
                        },
-                       .get_vendor_id = _get_vendor_id,
+                       .get_subtype = _get_subtype,
                        .get_collector_id = _get_collector_id,
                        .get_validator_id = _get_validator_id,
                        .get_body = _get_body,
@@ -261,15 +255,14 @@ pb_tnc_msg_t *pb_pa_msg_create(u_int32_t vendor_id, u_int32_t subtype,
                                .process = _process,
                                .destroy = _destroy,
                        },
-                       .get_vendor_id = _get_vendor_id,
+                       .get_subtype= _get_subtype,
                        .get_collector_id = _get_collector_id,
                        .get_validator_id = _get_validator_id,
                        .get_body = _get_body,
                        .get_exclusive_flag = _get_exclusive_flag,
                },
                .type = PB_MSG_PA,
-               .vendor_id = vendor_id,
-               .subtype = subtype,
+               .subtype = { vendor_id, subtype },
                .collector_id = collector_id,
                .validator_id = validator_id,
                .excl = excl,
index d9db9a1..5c9b7c0 100644 (file)
@@ -25,6 +25,8 @@ typedef struct pb_pa_msg_t pb_pa_msg_t;
 
 #include "pb_tnc_msg.h"
 
+#include <pen/pen.h>
+
 /**
  * Class representing the PB-PA message type.
  */
@@ -38,10 +40,9 @@ struct pb_pa_msg_t {
        /**
         * Get PA Message Vendor ID and Subtype
         *
-        * @param subtype               PA Subtype
-        * @return                              PA Message Vendor ID
+        * @return                              Vendor-specific PA Subtype
         */
-       u_int32_t (*get_vendor_id)(pb_pa_msg_t *this, u_int32_t *subtype);
+       pen_type_t (*get_subtype)(pb_pa_msg_t *this);
 
        /**
         * Get Posture Collector ID
index cd7f149..26edcb5 100644 (file)
@@ -208,30 +208,31 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg)
                case PB_MSG_PA:
                {
                        pb_pa_msg_t *pa_msg;
-                       u_int32_t msg_vid, msg_subtype;
+                       pen_type_t msg_subtype;
                        u_int16_t imc_id, imv_id;
                        chunk_t msg_body;
                        bool excl;
                        enum_name_t *pa_subtype_names;
 
                        pa_msg = (pb_pa_msg_t*)msg;
-                       msg_vid = pa_msg->get_vendor_id(pa_msg, &msg_subtype);
+                       msg_subtype = pa_msg->get_subtype(pa_msg);
                        msg_body = pa_msg->get_body(pa_msg);
                        imc_id = pa_msg->get_collector_id(pa_msg);
                        imv_id = pa_msg->get_validator_id(pa_msg);
                        excl = pa_msg->get_exclusive_flag(pa_msg);
 
-                       pa_subtype_names = get_pa_subtype_names(msg_vid);
+                       pa_subtype_names = get_pa_subtype_names(msg_subtype.vendor_id);
                        if (pa_subtype_names)
                        {
                                DBG2(DBG_TNC, "handling PB-PA message type '%N/%N' 0x%06x/0x%08x",
-                                        pen_names, msg_vid, pa_subtype_names, msg_subtype,
-                                        msg_vid, msg_subtype);
+                                        pen_names, msg_subtype.vendor_id, pa_subtype_names,
+                                        msg_subtype.type, msg_subtype.vendor_id, msg_subtype.type);
                        }
                        else
                        {
                                DBG2(DBG_TNC, "handling PB-PA message type '%N' 0x%06x/0x%08x",
-                                        pen_names, msg_vid, msg_vid, msg_subtype);
+                                        pen_names, msg_subtype.vendor_id, msg_subtype.vendor_id,
+                                        msg_subtype.type);
                        }
 
                        this->send_msg = TRUE;
@@ -239,13 +240,15 @@ static void handle_message(private_tnccs_20_t *this, pb_tnc_msg_t *msg)
                        {
                                tnc->imvs->receive_message(tnc->imvs, this->connection_id,
                                                                                   excl, msg_body.ptr, msg_body.len,
-                                                                                  msg_vid, msg_subtype, imc_id, imv_id);
+                                                                                  msg_subtype.vendor_id,
+                                                                                  msg_subtype.type, imc_id, imv_id);
                        }
                        else
                        {
                                tnc->imcs->receive_message(tnc->imcs, this->connection_id,
                                                                                   excl, msg_body.ptr, msg_body.len,
-                                                                                  msg_vid, msg_subtype, imv_id, imc_id);
+                                                                                  msg_subtype.vendor_id,
+                                                                                  msg_subtype.type, imv_id, imc_id);
                        }
                        this->send_msg = FALSE;
                        break;
index fee304e..e5a48ec 100644 (file)
@@ -587,14 +587,26 @@ METHOD(phase1_t, select_config, peer_cfg_t*,
 METHOD(phase1_t, get_id, identification_t*,
        private_phase1_t *this, peer_cfg_t *peer_cfg, bool local)
 {
+       identification_t *id = NULL;
        auth_cfg_t *auth;
 
        auth = get_auth_cfg(peer_cfg, local);
        if (auth)
        {
-               return auth->get(auth, AUTH_RULE_IDENTITY);
+               id = auth->get(auth, AUTH_RULE_IDENTITY);
+               if (local && (!id || id->get_type(id) == ID_ANY))
+               {       /* no ID configured, use local IP address */
+                       host_t *me;
+
+                       me = this->ike_sa->get_my_host(this->ike_sa);
+                       if (!me->is_anyaddr(me))
+                       {
+                               id = identification_create_from_sockaddr(me->get_sockaddr(me));
+                               auth->add(auth, AUTH_RULE_IDENTITY, id);
+                       }
+               }
        }
-       return NULL;
+       return id;
 }
 
 METHOD(phase1_t, save_sa_payload, bool,
index c7fb7ab..dc3ad3f 100644 (file)
@@ -16,6 +16,7 @@
  */
 
 #include <limits.h>
+#include <stdint.h>
 
 #include "esp_context.h"
 
index 4593ba5..52aeaa2 100644 (file)
@@ -130,19 +130,19 @@ ip_packet_t *ip_packet_create(chunk_t packet)
        {
                case 4:
                {
-                       struct iphdr *ip;
+                       struct ip *ip;
 
-                       if (packet.len < sizeof(struct iphdr))
+                       if (packet.len < sizeof(struct ip))
                        {
                                DBG1(DBG_ESP, "IPv4 packet too short");
                                goto failed;
                        }
-                       ip = (struct iphdr*)packet.ptr;
+                       ip = (struct ip*)packet.ptr;
                        src = host_create_from_chunk(AF_INET,
-                                                                                chunk_from_thing(ip->saddr), 0);
+                                                                                chunk_from_thing(ip->ip_src), 0);
                        dst = host_create_from_chunk(AF_INET,
-                                                                                chunk_from_thing(ip->daddr), 0);
-                       next_header = ip->protocol;
+                                                                                chunk_from_thing(ip->ip_dst), 0);
+                       next_header = ip->ip_p;
                        break;
                }
 #ifdef HAVE_NETINET_IP6_H
index 889fe62..36f3359 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright (C) 2012 Giuliano Grassi
  * Copyright (C) 2012 Ralf Sager
  * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2012 Martin Willi
  *
  * 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
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <unistd.h>
-#include <linux/if.h>
+#include <net/if.h>
+
+#ifdef __APPLE__
+#include <net/if_utun.h>
+#include <netinet/in_var.h>
+#include <sys/kern_control.h>
+#elif defined(__linux__)
 #include <linux/if_tun.h>
+#else
+#include <net/if_tun.h>
+#endif
 
 #include "tun_device.h"
 
@@ -127,6 +137,14 @@ METHOD(tun_device_t, set_address, bool,
                         this->if_name, strerror(errno));
                return FALSE;
        }
+#ifdef __APPLE__
+       if (ioctl(this->sock, SIOCSIFDSTADDR, &ifr) < 0)
+       {
+               DBG1(DBG_LIB, "failed to set dest address on %s: %s",
+                        this->if_name, strerror(errno));
+               return FALSE;
+       }
+#endif /* __APPLE__ */
 
        set_netmask(&ifr, family, netmask);
 
@@ -176,6 +194,8 @@ METHOD(tun_device_t, set_mtu, bool,
 
        if (ioctl(this->sock, SIOCSIFMTU, &ifr) < 0)
        {
+               DBG1(DBG_LIB, "failed to set MTU on %s: %s", this->if_name,
+                        strerror(errno));
                return FALSE;
        }
        this->mtu = mtu;
@@ -269,6 +289,20 @@ METHOD(tun_device_t, destroy, void,
        if (this->tunfd > 0)
        {
                close(this->tunfd);
+#ifdef __FreeBSD__
+               /* tun(4) says the following: "These network interfaces persist until
+                * the if_tun.ko module is unloaded, or until removed with the
+                * ifconfig(8) command."  So simply closing the FD is not enough. */
+               struct ifreq ifr;
+
+               memset(&ifr, 0, sizeof(ifr));
+               strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ);
+               if (ioctl(this->sock, SIOCIFDESTROY, &ifr) < 0)
+               {
+                       DBG1(DBG_LIB, "failed to destroy %s: %s", this->if_name,
+                                strerror(errno));
+               }
+#endif /* __FreeBSD__ */
        }
        if (this->sock > 0)
        {
@@ -278,18 +312,70 @@ METHOD(tun_device_t, destroy, void,
 }
 
 /**
- * Allocate a TUN device
+ * Initialize the tun device
  */
-static int tun_alloc(char dev[IFNAMSIZ])
+static bool init_tun(private_tun_device_t *this, const char *name_tmpl)
 {
+#ifdef __APPLE__
+
+       struct ctl_info info;
+       struct sockaddr_ctl addr;
+       socklen_t size = IFNAMSIZ;
+
+       memset(&info, 0, sizeof(info));
+       memset(&addr, 0, sizeof(addr));
+
+       this->tunfd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
+       if (this->tunfd < 0)
+       {
+               DBG1(DBG_LIB, "failed to open tundevice PF_SYSTEM socket: %s",
+                        strerror(errno));
+               return FALSE;
+       }
+
+       /* get a control identifier for the utun kernel extension */
+       strncpy(info.ctl_name, UTUN_CONTROL_NAME, strlen(UTUN_CONTROL_NAME));
+       if (ioctl(this->tunfd, CTLIOCGINFO, &info) < 0)
+       {
+               DBG1(DBG_LIB, "failed to ioctl tundevice: %s", strerror(errno));
+               close(this->tunfd);
+               return FALSE;
+       }
+
+       addr.sc_id = info.ctl_id;
+       addr.sc_len = sizeof(addr);
+       addr.sc_family = AF_SYSTEM;
+       addr.ss_sysaddr = AF_SYS_CONTROL;
+       /* allocate identifier dynamically */
+       addr.sc_unit = 0;
+
+       if (connect(this->tunfd, (struct sockaddr*)&addr, sizeof(addr)) < 0)
+       {
+               DBG1(DBG_LIB, "failed to connect tundevice: %s", strerror(errno));
+               close(this->tunfd);
+               return FALSE;
+       }
+       if (getsockopt(this->tunfd, SYSPROTO_CONTROL, UTUN_OPT_IFNAME,
+                                  this->if_name, &size) < 0)
+       {
+               DBG1(DBG_LIB, "getting tundevice name failed: %s", strerror(errno));
+               close(this->tunfd);
+               return FALSE;
+       }
+       return TRUE;
+
+#elif defined(IFF_TUN)
+
        struct ifreq ifr;
-       int fd;
 
-       fd = open("/dev/net/tun", O_RDWR);
-       if (fd < 0)
+       strncpy(this->if_name, name_tmpl ?: "tun%d", IFNAMSIZ);
+       this->if_name[IFNAMSIZ-1] = '\0';
+
+       this->tunfd = open("/dev/net/tun", O_RDWR);
+       if (this->tunfd < 0)
        {
                DBG1(DBG_LIB, "failed to open /dev/net/tun: %s", strerror(errno));
-               return fd;
+               return FALSE;
        }
 
        memset(&ifr, 0, sizeof(ifr));
@@ -297,16 +383,42 @@ static int tun_alloc(char dev[IFNAMSIZ])
        /* TUN device, no packet info */
        ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
 
-       strncpy(ifr.ifr_name, dev, IFNAMSIZ);
-
-       if (ioctl(fd, TUNSETIFF, (void*)&ifr) < 0)
+       strncpy(ifr.ifr_name, this->if_name, IFNAMSIZ);
+       if (ioctl(this->tunfd, TUNSETIFF, (void*)&ifr) < 0)
        {
                DBG1(DBG_LIB, "failed to configure TUN device: %s", strerror(errno));
-               close(fd);
-               return -1;
+               close(this->tunfd);
+               return FALSE;
+       }
+       strncpy(this->if_name, ifr.ifr_name, IFNAMSIZ);
+       return TRUE;
+
+#else /* !IFF_TUN */
+
+       /* this works on FreeBSD and might also work on Linux with older TUN
+        * driver versions (no IFF_TUN) */
+       char devname[IFNAMSIZ];
+       int i;
+
+       if (name_tmpl)
+       {
+               DBG1(DBG_LIB, "arbitrary naming of TUN devices is not supported");
        }
-       strncpy(dev, ifr.ifr_name, IFNAMSIZ);
-       return fd;
+
+       for (i = 0; i < 256; i++)
+       {
+               snprintf(devname, IFNAMSIZ, "/dev/tun%d", i);
+               this->tunfd = open(devname, O_RDWR);
+               if (this->tunfd > 0)
+               {       /* for ioctl(2) calls only the interface name is used */
+                       snprintf(this->if_name, IFNAMSIZ, "tun%d", i);
+                       break;
+               }
+               DBG1(DBG_LIB, "failed to open %s: %s", this->if_name, strerror(errno));
+       }
+       return this->tunfd > 0;
+
+#endif /* !__APPLE__ */
 }
 
 /*
@@ -331,13 +443,9 @@ tun_device_t *tun_device_create(const char *name_tmpl)
                .sock = -1,
        );
 
-       strncpy(this->if_name, name_tmpl ?: "tun%d", IFNAMSIZ);
-       this->if_name[IFNAMSIZ-1] = '\0';
-
-       this->tunfd = tun_alloc(this->if_name);
-       if (this->tunfd < 0)
+       if (!init_tun(this, name_tmpl))
        {
-               destroy(this);
+               free(this);
                return NULL;
        }
        DBG1(DBG_LIB, "created TUN device: %s", this->if_name);
index b1e5d5e..a33d68c 100644 (file)
@@ -3,20 +3,14 @@
 # basic configuration
 
 config setup
-       # plutodebug=all
-       # crlcheckinterval=600
        # strictcrlpolicy=yes
-       # cachecrls=yes
-       # nat_traversal=yes
-       # charonstart=no
-       # plutostart=no
+       # uniqueids = no
 
 # Add connections here.
 
 # Sample VPN connections
 
 #conn sample-self-signed
-#      left=%defaultroute
 #      leftsubnet=10.1.0.0/16
 #      leftcert=selfCert.der
 #      leftsendcert=never
@@ -26,11 +20,9 @@ config setup
 #      auto=start
 
 #conn sample-with-ca-cert
-#      left=%defaultroute
 #      leftsubnet=10.1.0.0/16
 #      leftcert=myCert.pem
 #      right=192.168.0.2
 #      rightsubnet=10.2.0.0/16
 #      rightid="C=CH, O=Linux strongSwan CN=peer name"
-#      keyexchange=ikev2
 #      auto=start