Merge branch 'android-ndk'

This branch comes with some preliminary changes for the user-land IPsec
implementation and the Android App.

One important change is that the UDP ports used by the socket-default plugin
were made configurable (either via ./configure or strongswan.conf).
Also, the plugin does randomly allocate a port if it is configured to 0,
which is useful for client implementations.  A consequence of these
changes is that the local UDP port used when creating ike_cfg_t objects has
to be fetched from the socket.
This commit is contained in:
Tobias Brunner
2012-08-13 10:45:39 +02:00
82 changed files with 1462 additions and 332 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
/Android.mk
/Android.common.mk
Makefile
Makefile.in
aclocal.m4
+19
View File
@@ -0,0 +1,19 @@
# some common definitions used by the main and the NDK-specific Android.mk
# include this after strongswan_PLUGINS has been defined
# helper macros to only add source files for plugins included in the list above
# source files are relative to the android.mk that called the macro
plugin_enabled = $(filter $(1), $(strongswan_PLUGINS))
add_plugin = $(if $(call plugin_enabled,$(1)), \
$(patsubst $(LOCAL_PATH)/%,%, \
$(wildcard \
$(subst %,$(subst -,_,$(strip $(1))), \
$(LOCAL_PATH)/plugins/%/%*.c \
) \
) \
) \
)
# strongSwan version, replaced by top Makefile
strongswan_VERSION := "@PACKAGE_VERSION@"
+4 -15
View File
@@ -16,8 +16,8 @@ include $(CLEAR_VARS)
# this is the list of plugins that are built into libstrongswan and charon
# also these plugins are loaded by default (if not changed in strongswan.conf)
strongswan_CHARON_PLUGINS := openssl fips-prf random nonce pubkey pkcs1 \
pem xcbc hmac kernel-netlink socket-default android \
strongswan_CHARON_PLUGINS := android-log openssl fips-prf random nonce pubkey \
pkcs1 pem xcbc hmac kernel-netlink socket-default android \
stroke eap-identity eap-mschapv2 eap-md5
ifneq ($(strongswan_BUILD_SCEPCLIENT),)
@@ -32,27 +32,16 @@ strongswan_PLUGINS := $(sort $(strongswan_CHARON_PLUGINS) \
$(strongswan_STARTER_PLUGINS) \
$(strongswan_SCEPCLIENT_PLUGINS))
# helper macros to only add source files for plugins included in the list above
# source files are relative to the android.mk that called the macro
plugin_enabled = $(findstring $(1), $(strongswan_PLUGINS))
add_plugin = $(if $(call plugin_enabled,$(1)), \
$(patsubst $(LOCAL_PATH)/%,%, \
$(wildcard \
$(subst %,$(subst -,_,$(strip $(1))), \
$(LOCAL_PATH)/plugins/%/%*.c \
) \
) \
) \
)
include $(LOCAL_PATH)/Android.common.mk
# includes
strongswan_PATH := $(LOCAL_PATH)
libvstr_PATH := external/strongswan-support/vstr/include
libcurl_PATH := external/strongswan-support/libcurl/include
libgmp_PATH := external/strongswan-support/gmp
openssl_PATH := external/openssl/include
# some definitions
strongswan_VERSION := "@PACKAGE_VERSION@"
strongswan_DIR := "/system/bin"
strongswan_SBINDIR := "/system/bin"
strongswan_PIDDIR := "/data/misc/vpn"
+1
View File
@@ -530,6 +530,7 @@ WARN_LOGFILE =
INPUT = @SRC_DIR@/src/libstrongswan \
@SRC_DIR@/src/libhydra \
@SRC_DIR@/src/libcharon \
@SRC_DIR@/src/libipsec \
@SRC_DIR@/src/libsimaka \
@SRC_DIR@/src/libtls \
@SRC_DIR@/src/libradius \
+4 -4
View File
@@ -6,17 +6,17 @@ endif
ACLOCAL_AMFLAGS = -I m4/config
EXTRA_DIST = Doxyfile.in LICENSE Android.mk.in Android.mk
EXTRA_DIST = Doxyfile.in LICENSE Android.common.mk.in Android.common.mk Android.mk
CLEANFILES = Doxyfile
BUILT_SOURCES = Android.mk
MAINTAINERCLEANFILES = Android.mk
BUILT_SOURCES = Android.common.mk
MAINTAINERCLEANFILES = Android.common.mk
if USE_DEV_HEADERS
config_includedir = $(ipseclibdir)/include
nodist_config_include_HEADERS = config.h
endif
Android.mk : Android.mk.in configure.in
Android.common.mk : Android.common.mk.in configure.in
sed \
-e "s:\@PACKAGE_VERSION\@:$(PACKAGE_VERSION):" \
$(srcdir)/$@.in > $@
+30
View File
@@ -71,6 +71,29 @@ AC_ARG_WITH(
[AC_SUBST(ipsecgroup, "root")]
)
AC_ARG_WITH(
[charon-udp-port],
AS_HELP_STRING([--with-charon-udp-port=port],[UDP port used by charon locally (default 500). Set to 0 to allocate randomly.]),
[AC_DEFINE_UNQUOTED(CHARON_UDP_PORT, [$withval], [UDP port used by charon locally])
AC_SUBST(charon_udp_port, [$withval])],
[AC_SUBST(charon_udp_port, 500)]
)
AC_ARG_WITH(
[charon-natt-port],
AS_HELP_STRING([--with-charon-natt-port=port],[UDP port used by charon locally in case a NAT is detected (must be different from charon-udp-port, default 4500). Set to 0 to allocate randomly.]),
[AC_DEFINE_UNQUOTED(CHARON_NATT_PORT, [$withval], [UDP post used by charon locally in case a NAT is detected])
AC_SUBST(charon_natt_port, [$withval])],
[AC_SUBST(charon_natt_port, 4500)]
)
AC_MSG_CHECKING([configured UDP ports ($charon_udp_port, $charon_natt_port)])
if test x$charon_udp_port != x0 -a x$charon_udp_port = x$charon_natt_port; then
AC_MSG_ERROR(the ports have to be different)
else
AC_MSG_RESULT(ok)
fi
# convert script name to uppercase
AC_SUBST(ipsec_script_upper, [`echo -n "$ipsec_script" | tr a-z A-Z`])
@@ -152,6 +175,7 @@ ARG_DISBL_SET([kernel-netlink], [disable the netlink kernel interface.])
ARG_ENABL_SET([kernel-pfkey], [enable the PF_KEY kernel interface.])
ARG_ENABL_SET([kernel-pfroute], [enable the PF_ROUTE kernel interface.])
ARG_ENABL_SET([kernel-klips], [enable the KLIPS kernel interface.])
ARG_ENABL_SET([libipsec], [enable user space IPsec implementation.])
ARG_DISBL_SET([socket-default], [disable default socket implementation for charon.])
ARG_ENABL_SET([socket-raw], [enable raw socket implementation of charon])
ARG_ENABL_SET([socket-dynamic], [enable dynamic socket implementation for charon])
@@ -184,6 +208,7 @@ ARG_ENABL_SET([gcm], [enables the GCM AEAD wrapper crypto plugin.])
ARG_ENABL_SET([addrblock], [enables RFC 3779 address block constraint support.])
ARG_ENABL_SET([uci], [enable OpenWRT UCI configuration plugin.])
ARG_ENABL_SET([android], [enable Android specific plugin.])
ARG_ENABL_SET([android-log], [enable Android specific logger plugin.])
ARG_ENABL_SET([maemo], [enable Maemo specific plugin.])
ARG_ENABL_SET([nm], [enable NetworkManager backend.])
ARG_ENABL_SET([ha], [enable high availability cluster plugin.])
@@ -914,6 +939,7 @@ ADD_PLUGIN([medsrv], [c charon])
ADD_PLUGIN([medcli], [c charon])
ADD_PLUGIN([dhcp], [c charon])
ADD_PLUGIN([android], [c charon])
ADD_PLUGIN([android-log], [c charon])
ADD_PLUGIN([ha], [c charon])
ADD_PLUGIN([whitelist], [c charon])
ADD_PLUGIN([certexpire], [c charon])
@@ -995,6 +1021,7 @@ AM_CONDITIONAL(USE_MEDSRV, test x$medsrv = xtrue)
AM_CONDITIONAL(USE_MEDCLI, test x$medcli = xtrue)
AM_CONDITIONAL(USE_UCI, test x$uci = xtrue)
AM_CONDITIONAL(USE_ANDROID, test x$android = xtrue)
AM_CONDITIONAL(USE_ANDROID_LOG, test x$android_log = xtrue)
AM_CONDITIONAL(USE_MAEMO, test x$maemo = xtrue)
AM_CONDITIONAL(USE_SMP, test x$smp = xtrue)
AM_CONDITIONAL(USE_SQL, test x$sql = xtrue)
@@ -1081,6 +1108,7 @@ AM_CONDITIONAL(USE_CONFTEST, test x$conftest = xtrue)
AM_CONDITIONAL(USE_LIBSTRONGSWAN, test x$charon = xtrue -o x$tools = xtrue -o x$conftest = xtrue -o x$fast = xtrue -o x$imcv = xtrue -o x$nm = xtrue)
AM_CONDITIONAL(USE_LIBHYDRA, test x$charon = xtrue -o x$nm = xtrue)
AM_CONDITIONAL(USE_LIBCHARON, test x$charon = xtrue -o x$conftest = xtrue -o x$nm = xtrue)
AM_CONDITIONAL(USE_LIBIPSEC, test x$libipsec = xtrue)
AM_CONDITIONAL(USE_LIBTNCIF, test x$tnc_tnccs = xtrue -o x$imcv = xtrue)
AM_CONDITIONAL(USE_LIBTNCCS, test x$tnc_tnccs = xtrue)
AM_CONDITIONAL(USE_FILE_CONFIG, test x$stroke = xtrue)
@@ -1172,6 +1200,7 @@ AC_OUTPUT(
src/libhydra/plugins/kernel_pfkey/Makefile
src/libhydra/plugins/kernel_pfroute/Makefile
src/libhydra/plugins/resolve/Makefile
src/libipsec/Makefile
src/libsimaka/Makefile
src/libtls/Makefile
src/libradius/Makefile
@@ -1234,6 +1263,7 @@ AC_OUTPUT(
src/libcharon/plugins/coupling/Makefile
src/libcharon/plugins/radattr/Makefile
src/libcharon/plugins/android/Makefile
src/libcharon/plugins/android_log/Makefile
src/libcharon/plugins/maemo/Makefile
src/libcharon/plugins/stroke/Makefile
src/libcharon/plugins/updown/Makefile
+2 -1
View File
@@ -1051,7 +1051,8 @@ A comma separated list containing type/level-pairs may
be specified, e.g:
.B dmn 3, ike 1, net -1.
Acceptable values for types are
.B dmn, mgr, ike, chd, job, cfg, knl, net, asn, enc, lib, tls, tnc, imc, imv, pts
.B dmn, mgr, ike, chd, job, cfg, knl, net, asn, enc, lib, esp, tls,
.B tnc, imc, imv, pts
and the level is one of
.B -1, 0, 1, 2, 3, 4
(for silent, audit, control, controlmore, raw, private). By default, the level
+16 -1
View File
@@ -210,6 +210,15 @@ Enable multiple authentication exchanges (RFC 4739)
.BR charon.nbns2
WINS servers assigned to peer via configuration payload (CP)
.TP
.BR charon.port " [500]"
UDP port used locally. If set to 0 a random port will be allocated.
.TP
.BR charon.port_nat_t " [4500]"
UDP port used locally in case of NAT-T. If set to 0 a random port will be
allocated. Has to be different from
.BR charon.port ,
otherwise a random port will be allocated.
.TP
.BR charon.process_route " [yes]"
Process RTM_NEWROUTE and RTM_DELROUTE events
.TP
@@ -272,7 +281,7 @@ Section to define syslog loggers, see LOGGER CONFIGURATION
Number of worker threads in charon
.SS charon.plugins subsection
.TP
.BR charon.plugins.android.loglevel " [1]"
.BR charon.plugins.android_log.loglevel " [1]"
Loglevel for logging to Android specific logger
.TP
.BR charon.plugins.attr
@@ -486,6 +495,9 @@ is appended to this prefix to make it unique. The result has to be a valid
interface name according to the rules defined by resolvconf. Also, it should
have a high priority according to the order defined in interface-order(5).
.TP
.BR charon.plugins.socket-default.set_source " [yes]"
Set source address on outbound packets, if possible.
.TP
.BR charon.plugins.sql.database
Database URI for charons SQL plugin
.TP
@@ -922,6 +934,9 @@ Packet encoding/decoding encryption/decryption operations
.B tls
libtls library messages
.TP
.B esp
libipsec library messages
.TP
.B lib
libstrongwan library messages
.TP
+4
View File
@@ -8,6 +8,10 @@ if USE_LIBHYDRA
SUBDIRS += libhydra
endif
if USE_LIBIPSEC
SUBDIRS += libipsec
endif
if USE_SIMAKA
SUBDIRS += libsimaka
endif
+2 -1
View File
@@ -497,7 +497,8 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
/**
* Set up configurations
*/
ike_cfg = ike_cfg_create(TRUE, encap, "0.0.0.0", FALSE, IKEV2_UDP_PORT,
ike_cfg = ike_cfg_create(TRUE, encap, "0.0.0.0", FALSE,
charon->socket->get_port(charon->socket, FALSE),
(char*)address, FALSE, IKEV2_UDP_PORT);
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
peer_cfg = peer_cfg_create(priv->name, IKEV2, ike_cfg,
+2 -1
View File
@@ -387,7 +387,7 @@ static void usage(const char *msg)
" [--version]\n"
" [--use-syslog]\n"
" [--debug-<type> <level>]\n"
" <type>: log context type (dmn|mgr|ike|chd|job|cfg|knl|net|asn|enc|tnc|imc|imv|pts|tls|lib)\n"
" <type>: log context type (dmn|mgr|ike|chd|job|cfg|knl|net|asn|enc|tnc|imc|imv|pts|tls|esp|lib)\n"
" <level>: log verbosity (-1 = silent, 0 = audit, 1 = control,\n"
" 2 = controlmore, 3 = raw, 4 = private)\n"
"\n"
@@ -466,6 +466,7 @@ int main(int argc, char *argv[])
{ "debug-imv", required_argument, &group, DBG_IMV },
{ "debug-pts", required_argument, &group, DBG_PTS },
{ "debug-tls", required_argument, &group, DBG_TLS },
{ "debug-esp", required_argument, &group, DBG_ESP },
{ "debug-lib", required_argument, &group, DBG_LIB },
{ 0,0,0,0 }
};
+5
View File
@@ -40,6 +40,11 @@ if !MONOLITHIC
endif
endif
if USE_LIBIPSEC
deps += $(top_builddir)/src/libipsec/libipsec.la
libs += $(DESTDIR)$(ipseclibdir)/libipsec.so
endif
if USE_TLS
deps += $(top_builddir)/src/libtls/libtls.la
libs += $(DESTDIR)$(ipseclibdir)/libtls.so
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>
+4
View File
@@ -0,0 +1,4 @@
bin/
gen/
libs/
obj/
+29
View File
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.strongswan.android"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="14" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".strongSwanActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".CharonVpnService" android:permission="android.permission.BIND_VPN_SERVICE">
<intent-filter>
<action android:name="android.net.VpnService"/>
</intent-filter>
</service>
</application>
</manifest>
+22
View File
@@ -0,0 +1,22 @@
To build this within the NDK several things have to be added in the jni
folder:
- strongswan: The strongSwan sources. This can either be an extracted tarball,
or a symlink to the Git repository. To build from the repository the sources
have to be prepared first (see HACKING for a list of required tools):
./autogen.sh && ./configure && make && make distclean
- openssl: The OpenSSL sources. Since the sources need to be changed to be
built on Android (and especially in the NDK), we provide a modified mirror
of the official Android OpenSSL version on git.strongswan.org.
- vstr: The Vstr string library. Since cross-compiling this library is not
that easy with the configure script and Makefiles included in the tarball,
the easiest way to build it is using either droid-gcc (as described on
wiki.strongswan.org) or a standalone toolchain built with the NDK.
The build script provided on the wiki builds the library with droid-gcc
and copies the required header files to the configured installation
directory. Please note that the Android.mk provided on the wiki (vstr.mk)
does not work in the NDK. A replacement is already in place in jni/vstr.
+4
View File
@@ -0,0 +1,4 @@
openssl
strongswan
vstr/libvstr.a
vstr/include
+65
View File
@@ -0,0 +1,65 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
strongswan_CHARON_PLUGINS := android-log openssl fips-prf random nonce pubkey \
pkcs1 pem xcbc hmac socket-default \
eap-identity eap-mschapv2 eap-md5
strongswan_PLUGINS := $(strongswan_CHARON_PLUGINS)
include $(LOCAL_PATH)/strongswan/Android.common.mk
# includes
strongswan_PATH := $(LOCAL_PATH)/strongswan
libvstr_PATH := $(LOCAL_PATH)/vstr/include
openssl_PATH := $(LOCAL_PATH)/openssl/include
# CFLAGS (partially from a configure run using droid-gcc)
strongswan_CFLAGS := \
-Wno-format \
-Wno-pointer-sign \
-Wno-pointer-arith \
-Wno-sign-compare \
-Wno-strict-aliasing \
-DHAVE___BOOL \
-DHAVE_STDBOOL_H \
-DHAVE_ALLOCA_H \
-DHAVE_ALLOCA \
-DHAVE_CLOCK_GETTIME \
-DHAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC \
-DHAVE_PRCTL \
-DHAVE_LINUX_UDP_H \
-DHAVE_STRUCT_SADB_X_POLICY_SADB_X_POLICY_PRIORITY \
-DHAVE_IPSEC_MODE_BEET \
-DHAVE_IPSEC_DIR_FWD \
-DOPENSSL_NO_EC \
-DOPENSSL_NO_ECDSA \
-DOPENSSL_NO_ECDH \
-DOPENSSL_NO_ENGINE \
-DCONFIG_H_INCLUDED \
-DCAPABILITIES \
-DCAPABILITIES_NATIVE \
-DMONOLITHIC \
-DUSE_IKEV1 \
-DUSE_IKEV2 \
-DUSE_VSTR \
-DDEBUG \
-DCHARON_UDP_PORT=0 \
-DCHARON_NATT_PORT=0 \
-DVERSION=\"$(strongswan_VERSION)\" \
-DDEV_RANDOM=\"/dev/random\" \
-DDEV_URANDOM=\"/dev/urandom\"
# only for Android 2.0+
strongswan_CFLAGS += \
-DHAVE_IN6ADDR_ANY
include $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk, \
vstr \
openssl \
libandroidbridge \
strongswan/src/libipsec \
strongswan/src/libcharon \
strongswan/src/libhydra \
strongswan/src/libstrongswan \
))
@@ -0,0 +1,34 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# copy-n-paste from Makefile.am
LOCAL_SRC_FILES := \
charonservice.c
# build libandroidbridge -------------------------------------------------------
LOCAL_C_INCLUDES += \
$(libvstr_PATH) \
$(strongswan_PATH)/src/libipsec \
$(strongswan_PATH)/src/libhydra \
$(strongswan_PATH)/src/libcharon \
$(strongswan_PATH)/src/libstrongswan
LOCAL_CFLAGS := $(strongswan_CFLAGS) \
-DPLUGINS='"$(strongswan_CHARON_PLUGINS)"'
LOCAL_MODULE := libandroidbridge
LOCAL_MODULE_TAGS := optional
LOCAL_ARM_MODE := arm
LOCAL_PRELINK_MODULE := false
LOCAL_LDLIBS := -llog
LOCAL_SHARED_LIBRARIES := libstrongswan libhydra libipsec libcharon
include $(BUILD_SHARED_LIBRARY)
@@ -0,0 +1,124 @@
/*
* Copyright (C) 2012 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include <string.h>
#include <android/log.h>
#include <jni.h>
#include <hydra.h>
#include <ipsec.h>
#include <daemon.h>
#include <library.h>
#define JNI_PACKAGE org_strongswan_android
#define JNI_METHOD_PP(pack, klass, name, ret, ...) \
ret Java_##pack##_##klass##_##name(JNIEnv *env, jobject this, ##__VA_ARGS__)
#define JNI_METHOD_P(pack, klass, name, ret, ...) \
JNI_METHOD_PP(pack, klass, name, ret, ##__VA_ARGS__)
#define JNI_METHOD(klass, name, ret, ...) \
JNI_METHOD_P(JNI_PACKAGE, klass, name, ret, ##__VA_ARGS__)
/**
* hook in library for debugging messages
*/
extern void (*dbg) (debug_t group, level_t level, char *fmt, ...);
/**
* Logging hook for library logs, using android specific logging
*/
static void dbg_android(debug_t group, level_t level, char *fmt, ...)
{
va_list args;
if (level <= 4)
{
char sgroup[16], buffer[8192];
char *current = buffer, *next;
snprintf(sgroup, sizeof(sgroup), "%N", debug_names, group);
va_start(args, fmt);
vsnprintf(buffer, sizeof(buffer), fmt, args);
va_end(args);
while (current)
{ /* log each line separately */
next = strchr(current, '\n');
if (next)
{
*(next++) = '\0';
}
__android_log_print(ANDROID_LOG_INFO, "charon", "00[%s] %s\n",
sgroup, current);
current = next;
}
}
}
/**
* Initialize charon and the libraries via JNI
*/
JNI_METHOD(CharonVpnService, initializeCharon, void)
{
/* logging for library during initialization, as we have no bus yet */
dbg = dbg_android;
/* initialize library */
if (!library_init(NULL))
{
library_deinit();
return;
}
if (!libhydra_init("charon"))
{
libhydra_deinit();
library_deinit();
return;
}
if (!libipsec_init())
{
libipsec_deinit();
libhydra_deinit();
library_deinit();
return;
}
if (!libcharon_init("charon") ||
!charon->initialize(charon, PLUGINS))
{
libcharon_deinit();
libipsec_deinit();
libhydra_deinit();
library_deinit();
return;
}
/* start daemon (i.e. the threads in the thread-pool) */
charon->start(charon);
}
/**
* Initialize charon and the libraries via JNI
*/
JNI_METHOD(CharonVpnService, deinitializeCharon, void)
{
libcharon_deinit();
libipsec_deinit();
libhydra_deinit();
library_deinit();
}
+11
View File
@@ -0,0 +1,11 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := libvstr.a
LOCAL_MODULE := libvstr
LOCAL_PRELINK_MODULE := false
include $(PREBUILT_STATIC_LIBRARY)
+40
View File
@@ -0,0 +1,40 @@
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
+11
View File
@@ -0,0 +1,11 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "ant.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=android-14
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

+12
View File
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
</LinearLayout>
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, strongSwanActivity!</string>
<string name="app_name">strongSwan</string>
</resources>
@@ -0,0 +1,57 @@
package org.strongswan.android;
import android.content.Intent;
import android.net.VpnService;
public class CharonVpnService extends VpnService
{
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
// called whenever the service is started with startService
// create our own thread because we are running in the calling processes
// main thread
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onCreate()
{
// onCreate is only called once
initializeCharon();
super.onCreate();
}
@Override
public void onDestroy()
{
// called once the service is to be destroyed
deinitializeCharon();
super.onDestroy();
}
/**
* Initialization of charon, provided by libandroidbridge.so
*/
public native void initializeCharon();
/**
* Deinitialize charon, provided by libandroidbridge.so
*/
public native void deinitializeCharon();
/*
* The libraries are extracted to /data/data/org.strongswan.android/...
* during installation.
*/
static
{
System.loadLibrary("crypto");
System.loadLibrary("strongswan");
System.loadLibrary("hydra");
System.loadLibrary("charon");
System.loadLibrary("ipsec");
System.loadLibrary("androidbridge");
}
}
@@ -0,0 +1,40 @@
package org.strongswan.android;
import android.app.Activity;
import android.content.Intent;
import android.net.VpnService;
import android.os.Bundle;
public class strongSwanActivity extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startVpnService();
}
private void startVpnService()
{
Intent intent = VpnService.prepare(this);
if (intent != null)
{
startActivityForResult(intent, 0);
}
else
{
onActivityResult(0, RESULT_OK, null);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (resultCode == RESULT_OK)
{
Intent intent = new Intent(this, CharonVpnService.class);
startService(intent);
}
}
}
+5
View File
@@ -130,6 +130,11 @@ LOCAL_C_INCLUDES += frameworks/base/cmds/keystore
LOCAL_SHARED_LIBRARIES += libcutils
endif
LOCAL_SRC_FILES += $(call add_plugin, android-log)
ifneq ($(call plugin_enabled, android-log),)
LOCAL_LDLIBS += -llog
endif
LOCAL_SRC_FILES += $(call add_plugin, attr)
LOCAL_SRC_FILES += $(call add_plugin, eap-aka)
+7
View File
@@ -456,6 +456,13 @@ if MONOLITHIC
endif
endif
if USE_ANDROID_LOG
SUBDIRS += plugins/android_log
if MONOLITHIC
libcharon_la_LIBADD += plugins/android_log/libstrongswan-android-log.la
endif
endif
if USE_MAEMO
SUBDIRS += plugins/maemo
if MONOLITHIC
+17 -2
View File
@@ -178,15 +178,30 @@ typedef struct daemon_t daemon_t;
#define DEFAULT_THREADS 16
/**
* UDP Port on which the daemon will listen for incoming traffic.
* Primary UDP port used by IKE.
*/
#define IKEV2_UDP_PORT 500
/**
* UDP Port to which the daemon will float to if NAT is detected.
* UDP port defined for use in case a NAT is detected.
*/
#define IKEV2_NATT_PORT 4500
/**
* UDP port on which the daemon will listen for incoming traffic (also used as
* source port for outgoing traffic).
*/
#ifndef CHARON_UDP_PORT
#define CHARON_UDP_PORT IKEV2_UDP_PORT
#endif
/**
* UDP port used by the daemon in case a NAT is detected.
*/
#ifndef CHARON_NATT_PORT
#define CHARON_NATT_PORT IKEV2_NATT_PORT
#endif
/**
* Main class of daemon, contains some globals.
*/
+16 -3
View File
@@ -1,4 +1,5 @@
/*
* Copyright (C) 2012 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -42,6 +43,11 @@ struct private_packet_t {
* message data
*/
chunk_t data;
/**
* actual chunk returned from get_data, adjusted when skip_bytes is called
*/
chunk_t adjusted_data;
};
METHOD(packet_t, set_source, void,
@@ -73,14 +79,20 @@ METHOD(packet_t, get_destination, host_t*,
METHOD(packet_t, get_data, chunk_t,
private_packet_t *this)
{
return this->data;
return this->adjusted_data;
}
METHOD(packet_t, set_data, void,
private_packet_t *this, chunk_t data)
{
free(this->data.ptr);
this->data = data;
this->adjusted_data = this->data = data;
}
METHOD(packet_t, skip_bytes, void,
private_packet_t *this, size_t bytes)
{
this->adjusted_data = chunk_skip(this->adjusted_data, bytes);
}
METHOD(packet_t, destroy, void,
@@ -108,7 +120,7 @@ METHOD(packet_t, clone_, packet_t*,
}
if (this->data.ptr != NULL)
{
other->set_data(other, chunk_clone(this->data));
other->set_data(other, chunk_clone(this->adjusted_data));
}
return other;
}
@@ -128,6 +140,7 @@ packet_t *packet_create(void)
.get_source = _get_source,
.set_destination = _set_destination,
.get_destination = _get_destination,
.skip_bytes = _skip_bytes,
.clone = _clone_,
.destroy = _destroy,
},
+10
View File
@@ -1,4 +1,5 @@
/*
* Copyright (C) 2012 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -92,6 +93,15 @@ struct packet_t {
*/
void (*set_data) (packet_t *packet, chunk_t data);
/**
* Increase the offset where the actual packet data starts.
*
* @note The offset is reset to 0 when set_data() is called.
*
* @param bytes the number of additional bytes to skip
*/
void (*skip_bytes) (packet_t *packet, size_t bytes);
/**
* Clones a packet_t object.
*
+82 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2008 Tobias Brunner
* Copyright (C) 2008-2012 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -27,6 +27,7 @@
#include <processing/jobs/process_message_job.h>
#include <processing/jobs/callback_job.h>
#include <crypto/hashers/hasher.h>
#include <threading/mutex.h>
/** lifetime of a cookie, in seconds */
#define COOKIE_LIFETIME 10
@@ -54,6 +55,19 @@ struct private_receiver_t {
*/
receiver_t public;
/**
* Registered callback for ESP packets
*/
struct {
receiver_esp_cb_t cb;
void *data;
} esp_cb;
/**
* Mutex for ESP callback
*/
mutex_t *esp_cb_mutex;
/**
* current secret to use for cookie calculation
*/
@@ -400,8 +414,10 @@ static job_requeue_t receive_packets(private_receiver_t *this)
ike_sa_id_t *id;
packet_t *packet;
message_t *message;
host_t *src, *dst;
status_t status;
bool supported = TRUE;
chunk_t data, marker = chunk_from_chars(0x00, 0x00, 0x00, 0x00);
/* read in a packet */
status = charon->socket->receive(charon->socket, &packet);
@@ -415,6 +431,46 @@ static job_requeue_t receive_packets(private_receiver_t *this)
return JOB_REQUEUE_FAIR;
}
data = packet->get_data(packet);
if (data.len == 1 && data.ptr[0] == 0xFF)
{ /* silently drop NAT-T keepalives */
packet->destroy(packet);
return JOB_REQUEUE_DIRECT;
}
else if (data.len < marker.len)
{ /* drop packets that are too small */
DBG3(DBG_NET, "received packet is too short (%d bytes)", data.len);
packet->destroy(packet);
return JOB_REQUEUE_DIRECT;
}
/* if neither source nor destination port is 500 we assume an IKE packet
* with Non-ESP marker or an ESP packet */
dst = packet->get_destination(packet);
src = packet->get_source(packet);
if (dst->get_port(dst) != IKEV2_UDP_PORT &&
src->get_port(src) != IKEV2_UDP_PORT)
{
if (memeq(data.ptr, marker.ptr, marker.len))
{ /* remove Non-ESP marker */
packet->skip_bytes(packet, marker.len);
}
else
{ /* this seems to be an ESP packet */
this->esp_cb_mutex->lock(this->esp_cb_mutex);
if (this->esp_cb.cb)
{
this->esp_cb.cb(this->esp_cb.data, packet);
}
else
{
packet->destroy(packet);
}
this->esp_cb_mutex->unlock(this->esp_cb_mutex);
return JOB_REQUEUE_DIRECT;
}
}
/* parse message header */
message = message_create_from_packet(packet);
if (message->parse_header(message) != SUCCESS)
@@ -513,11 +569,33 @@ static job_requeue_t receive_packets(private_receiver_t *this)
return JOB_REQUEUE_DIRECT;
}
METHOD(receiver_t, add_esp_cb, void,
private_receiver_t *this, receiver_esp_cb_t callback, void *data)
{
this->esp_cb_mutex->lock(this->esp_cb_mutex);
this->esp_cb.cb = callback;
this->esp_cb.data = data;
this->esp_cb_mutex->unlock(this->esp_cb_mutex);
}
METHOD(receiver_t, del_esp_cb, void,
private_receiver_t *this, receiver_esp_cb_t callback)
{
this->esp_cb_mutex->lock(this->esp_cb_mutex);
if (this->esp_cb.cb == callback)
{
this->esp_cb.cb = NULL;
this->esp_cb.data = NULL;
}
this->esp_cb_mutex->unlock(this->esp_cb_mutex);
}
METHOD(receiver_t, destroy, void,
private_receiver_t *this)
{
this->rng->destroy(this->rng);
this->hasher->destroy(this->hasher);
this->esp_cb_mutex->destroy(this->esp_cb_mutex);
free(this);
}
@@ -531,8 +609,11 @@ receiver_t *receiver_create()
INIT(this,
.public = {
.add_esp_cb = _add_esp_cb,
.del_esp_cb = _del_esp_cb,
.destroy = _destroy,
},
.esp_cb_mutex = mutex_create(MUTEX_TYPE_DEFAULT),
.secret_switch = now,
.secret_offset = random() % now,
);
+37 -5
View File
@@ -1,4 +1,5 @@
/*
* Copyright (C) 2012 Tobias Brunner
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -25,15 +26,28 @@
typedef struct receiver_t receiver_t;
#include <library.h>
#include <network/packet.h>
#include <utils/host.h>
/**
* Callback called for any received UDP encapsulated ESP packet.
*
* Implementation should be quick as the receiver doesn't receive any packets
* while calling this function.
*
* @param data data supplied during registration of the callback
* @param packet decapsulated ESP packet
*/
typedef void (*receiver_esp_cb_t)(void *data, packet_t *packet);
/**
* Receives packets from the socket and adds them to the job queue.
*
* The receiver starts a thread, which reads on the blocking socket. A received
* packet is preparsed and a process_message_job is queued in the job queue.
* The receiver uses a callback job, which reads on the blocking socket.
* A received packet is preparsed and a process_message_job is queued in the
* job queue.
*
* To endure DoS attacks, cookies are enabled when to many IKE_SAs are half
* To endure DoS attacks, cookies are enabled when too many IKE_SAs are half
* open. The calculation of cookies is slightly different from the proposed
* method in RFC4306. We do not include a nonce, because we think the advantage
* we gain does not justify the overhead to parse the whole message.
@@ -47,14 +61,32 @@ typedef struct receiver_t receiver_t;
* secret is stored to allow a clean migration between secret changes.
*
* Further, the number of half-initiated IKE_SAs is limited per peer. This
* mades it impossible for a peer to flood the server with its real IP address.
* makes it impossible for a peer to flood the server with its real IP address.
*/
struct receiver_t {
/**
* Register a callback which is called for any incoming ESP packets.
*
* @note Only the last callback registered will receive any packets.
*
* @param callback callback to register
* @param data data provided to callback
*/
void (*add_esp_cb)(receiver_t *this, receiver_esp_cb_t callback,
void *data);
/**
* Unregister a previously registered callback for ESP packets.
*
* @param callback previously registered callback
*/
void (*del_esp_cb)(receiver_t *this, receiver_esp_cb_t callback);
/**
* Destroys a receiver_t object.
*/
void (*destroy) (receiver_t *receiver);
void (*destroy)(receiver_t *this);
};
/**
+24 -2
View File
@@ -1,4 +1,5 @@
/*
* Copyright (C) 2012 Tobias Brunner
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -79,7 +80,7 @@ struct private_sender_t {
bool send_delay_response;
};
METHOD(sender_t, send_, void,
METHOD(sender_t, send_no_marker, void,
private_sender_t *this, packet_t *packet)
{
host_t *src, *dst;
@@ -115,10 +116,30 @@ METHOD(sender_t, send_, void,
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);
if (dst->get_port(dst) != IKEV2_UDP_PORT &&
src->get_port(src) != IKEV2_UDP_PORT)
{
chunk_t data, marker = chunk_from_chars(0x00, 0x00, 0x00, 0x00);
data = chunk_cat("cc", marker, packet->get_data(packet));
packet->set_data(packet, data);
}
send_no_marker(this, packet);
}
/**
* Job callback function to send packets
*/
static job_requeue_t send_packets(private_sender_t * this)
static job_requeue_t send_packets(private_sender_t *this)
{
packet_t *packet;
bool oldstate;
@@ -176,6 +197,7 @@ sender_t * sender_create()
INIT(this,
.public = {
.send = _send_,
.send_no_marker = _send_no_marker,
.flush = _flush,
.destroy = _destroy,
},
+9 -1
View File
@@ -1,4 +1,5 @@
/*
* Copyright (C) 2012 Tobias Brunner
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
@@ -28,7 +29,7 @@ typedef struct sender_t sender_t;
#include <network/packet.h>
/**
* Thread responsible for sending packets over the socket.
* Callback job responsible for sending IKE packets over the socket.
*/
struct sender_t {
@@ -43,6 +44,13 @@ struct sender_t {
*/
void (*send) (sender_t *this, packet_t *packet);
/**
* The same as send() but does not add Non-ESP markers automatically.
*
* @param packet packet to send
*/
void (*send_no_marker) (sender_t *this, packet_t *packet);
/**
* Enforce a flush of the send queue.
*
+9 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2006-2010 Tobias Brunner
* Copyright (C) 2006-2012 Tobias Brunner
* Copyright (C) 2005-2010 Martin Willi
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005 Jan Hutter
@@ -67,6 +67,14 @@ struct socket_t {
*/
status_t (*send) (socket_t *this, packet_t *packet);
/**
* Get the port this socket is listening on.
*
* @param nat_t TRUE to get the port used to float in case of NAT-T
* @return the port
*/
u_int16_t (*get_port) (socket_t *this, bool nat_t);
/**
* Destroy a socket implementation.
*/
+15 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2010 Tobias Brunner
* Copyright (C) 2010-2012 Tobias Brunner
* Hochschule fuer Technik Rapperswil
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
@@ -89,6 +89,19 @@ METHOD(socket_manager_t, sender, status_t,
return status;
}
METHOD(socket_manager_t, get_port, u_int16_t,
private_socket_manager_t *this, bool nat_t)
{
u_int16_t port = 0;
this->lock->read_lock(this->lock);
if (this->socket)
{
port = this->socket->get_port(this->socket, nat_t);
}
this->lock->unlock(this->lock);
return port;
}
static void create_socket(private_socket_manager_t *this)
{
socket_constructor_t create;
@@ -153,6 +166,7 @@ socket_manager_t *socket_manager_create()
.public = {
.send = _sender,
.receive = _receiver,
.get_port = _get_port,
.add_socket = _add_socket,
.remove_socket = _remove_socket,
.destroy = _destroy,
+9 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2010 Tobias Brunner
* Copyright (C) 2010-2012 Tobias Brunner
* Hochschule fuer Technik Rapperswil
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
@@ -52,6 +52,14 @@ struct socket_manager_t {
*/
status_t (*send) (socket_manager_t *this, packet_t *packet);
/**
* Get the port the registered socket is listening on.
*
* @param nat_t TRUE to get the port used to float in case of NAT-T
* @return the port, or 0, if no socket is registered
*/
u_int16_t (*get_port) (socket_manager_t *this, bool nat_t);
/**
* Register a socket constructor.
*
@@ -14,7 +14,6 @@ libstrongswan_android_la_SOURCES = \
android_plugin.c android_plugin.h \
android_service.c android_service.h \
android_handler.c android_handler.h \
android_logger.c android_logger.h \
android_creds.c android_creds.h
libstrongswan_android_la_LDFLAGS = -module -avoid-version
@@ -15,7 +15,6 @@
*/
#include "android_plugin.h"
#include "android_logger.h"
#include "android_handler.h"
#include "android_creds.h"
#include "android_service.h"
@@ -35,11 +34,6 @@ struct private_android_plugin_t {
*/
android_plugin_t public;
/**
* Android specific logger
*/
android_logger_t *logger;
/**
* Android specific DNS handler
*/
@@ -68,10 +62,8 @@ METHOD(plugin_t, destroy, void,
hydra->attributes->remove_handler(hydra->attributes,
&this->handler->handler);
lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
charon->bus->remove_logger(charon->bus, &this->logger->logger);
this->creds->destroy(this->creds);
this->handler->destroy(this->handler);
this->logger->destroy(this->logger);
DESTROY_IF(this->service);
free(this);
}
@@ -91,14 +83,12 @@ plugin_t *android_plugin_create()
.destroy = _destroy,
},
},
.logger = android_logger_create(),
.creds = android_creds_create(),
);
this->service = android_service_create(this->creds);
this->handler = android_handler_create(this->service != NULL);
charon->bus->add_logger(charon->bus, &this->logger->logger);
lib->credmgr->add_set(lib->credmgr, &this->creds->set);
hydra->attributes->add_handler(hydra->attributes, &this->handler->handler);
@@ -264,7 +264,8 @@ static job_requeue_t initiate(private_android_service_t *this)
this->creds->set_username_password(this->creds, user, password);
}
ike_cfg = ike_cfg_create(TRUE, FALSE, "0.0.0.0", FALSE, IKEV2_UDP_PORT,
ike_cfg = ike_cfg_create(TRUE, FALSE, "0.0.0.0", FALSE,
charon->socket->get_port(charon->socket, FALSE),
hostname, FALSE, IKEV2_UDP_PORT);
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
@@ -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-android-log.la
else
plugin_LTLIBRARIES = libstrongswan-android-log.la
endif
libstrongswan_android_log_la_SOURCES = \
android_log_plugin.c android_log_plugin.h \
android_log_logger.c android_log_logger.h
libstrongswan_android_log_la_LDFLAGS = -module -avoid-version
@@ -16,23 +16,23 @@
#include <string.h>
#include <android/log.h>
#include "android_logger.h"
#include "android_log_logger.h"
#include <library.h>
#include <daemon.h>
#include <threading/mutex.h>
typedef struct private_android_logger_t private_android_logger_t;
typedef struct private_android_log_logger_t private_android_log_logger_t;
/**
* Private data of an android_logger_t object
* Private data of an android_log_logger_t object
*/
struct private_android_logger_t {
struct private_android_log_logger_t {
/**
* Public interface
*/
android_logger_t public;
android_log_logger_t public;
/**
* logging level
@@ -46,7 +46,7 @@ struct private_android_logger_t {
};
METHOD(logger_t, log_, void,
private_android_logger_t *this, debug_t group, level_t level,
private_android_log_logger_t *this, debug_t group, level_t level,
int thread, ike_sa_t* ike_sa, const char *message)
{
int prio = level > 1 ? ANDROID_LOG_DEBUG : ANDROID_LOG_INFO;
@@ -71,13 +71,13 @@ METHOD(logger_t, log_, void,
}
METHOD(logger_t, get_level, level_t,
private_android_logger_t *this, debug_t group)
private_android_log_logger_t *this, debug_t group)
{
return this->level;
}
METHOD(android_logger_t, destroy, void,
private_android_logger_t *this)
METHOD(android_log_logger_t, destroy, void,
private_android_log_logger_t *this)
{
this->mutex->destroy(this->mutex);
free(this);
@@ -86,9 +86,9 @@ METHOD(android_logger_t, destroy, void,
/**
* Described in header.
*/
android_logger_t *android_logger_create()
android_log_logger_t *android_log_logger_create()
{
private_android_logger_t *this;
private_android_log_logger_t *this;
INIT(this,
.public = {
@@ -100,7 +100,7 @@ android_logger_t *android_logger_create()
},
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
.level = lib->settings->get_int(lib->settings,
"%s.plugins.android.loglevel", 1, charon->name),
"%s.plugins.android_log.loglevel", 1, charon->name),
);
return &this->public;
@@ -14,21 +14,21 @@
*/
/**
* @defgroup android_logger android_logger
* @{ @ingroup android
* @defgroup android_log_logger android_log_logger
* @{ @ingroup android_log
*/
#ifndef ANDROID_LOGGER_H_
#define ANDROID_LOGGER_H_
#ifndef ANDROID_LOG_LOGGER_H_
#define ANDROID_LOG_LOGGER_H_
#include <bus/bus.h>
typedef struct android_logger_t android_logger_t;
typedef struct android_log_logger_t android_log_logger_t;
/**
* Android specific logger.
*/
struct android_logger_t {
struct android_log_logger_t {
/**
* Implements logger_t interface
@@ -38,7 +38,7 @@ struct android_logger_t {
/**
* Destroy the logger.
*/
void (*destroy)(android_logger_t *this);
void (*destroy)(android_log_logger_t *this);
};
@@ -47,6 +47,6 @@ struct android_logger_t {
*
* @return logger instance
*/
android_logger_t *android_logger_create();
android_log_logger_t *android_log_logger_create();
#endif /** ANDROID_LOGGER_H_ @}*/
#endif /** ANDROID_LOG_LOGGER_H_ @}*/
@@ -0,0 +1,76 @@
/*
* Copyright (C) 2012 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "android_log_plugin.h"
#include "android_log_logger.h"
#include <daemon.h>
typedef struct private_android_log_plugin_t private_android_log_plugin_t;
/**
* Private data of an android_log_plugin_t object.
*/
struct private_android_log_plugin_t {
/**
* Public android_log_plugin_t interface.
*/
android_log_plugin_t public;
/**
* Android specific logger
*/
android_log_logger_t *logger;
};
METHOD(plugin_t, get_name, char*,
private_android_log_plugin_t *this)
{
return "android-log";
}
METHOD(plugin_t, destroy, void,
private_android_log_plugin_t *this)
{
charon->bus->remove_logger(charon->bus, &this->logger->logger);
this->logger->destroy(this->logger);
free(this);
}
/**
* See header
*/
plugin_t *android_log_plugin_create()
{
private_android_log_plugin_t *this;
INIT(this,
.public = {
.plugin = {
.get_name = _get_name,
.reload = (void*)return_false,
.destroy = _destroy,
},
},
.logger = android_log_logger_create(),
);
charon->bus->add_logger(charon->bus, &this->logger->logger);
return &this->public.plugin;
}
@@ -0,0 +1,42 @@
/*
* Copyright (C) 2012 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 android_log android_log
* @ingroup cplugins
*
* @defgroup android_log_plugin android_log_plugin
* @{ @ingroup android_log
*/
#ifndef ANDROID_LOG_PLUGIN_H_
#define ANDROID_LOG_PLUGIN_H_
#include <plugins/plugin.h>
typedef struct android_log_plugin_t android_log_plugin_t;
/**
* Plugin providing an Android specific logger implementation.
*/
struct android_log_plugin_t {
/**
* Implements plugin interface.
*/
plugin_t plugin;
};
#endif /** ANDROID_LOG_PLUGIN_H_ @}*/
+2 -1
View File
@@ -203,7 +203,8 @@ static void setup_tunnel(private_ha_tunnel_t *this,
lib->credmgr->add_set(lib->credmgr, &this->creds.public);
/* create config and backend */
ike_cfg = ike_cfg_create(FALSE, FALSE, local, FALSE, IKEV2_UDP_PORT,
ike_cfg = ike_cfg_create(FALSE, FALSE, local, FALSE,
charon->socket->get_port(charon->socket, FALSE),
remote, FALSE, IKEV2_UDP_PORT);
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
peer_cfg = peer_cfg_create("ha", IKEV2, ike_cfg, CERT_NEVER_SEND,
@@ -257,7 +257,7 @@ static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num)
else
{
ike_cfg = ike_cfg_create(FALSE, FALSE,
this->local, FALSE, IKEV2_UDP_PORT,
this->local, FALSE, charon->socket->get_port(charon->socket, FALSE),
this->remote, FALSE, IKEV2_UDP_PORT);
}
ike_cfg->add_proposal(ike_cfg, this->proposal->clone(this->proposal));
@@ -108,12 +108,6 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
return SUCCESS;
}
METHOD(kernel_ipsec_t, bypass_socket, bool,
private_load_tester_ipsec_t *this, int fd, int family)
{
return TRUE;
}
METHOD(kernel_ipsec_t, destroy, void,
private_load_tester_ipsec_t *this)
{
@@ -141,7 +135,8 @@ load_tester_ipsec_t *load_tester_ipsec_create()
.query_policy = _query_policy,
.del_policy = _del_policy,
.flush_policies = (void*)return_failed,
.bypass_socket = _bypass_socket,
.bypass_socket = (void*)return_true,
.enable_udp_decap = (void*)return_true,
.destroy = _destroy,
},
},
+2 -1
View File
@@ -323,7 +323,8 @@ static gboolean initiate_connection(private_maemo_service_t *this,
NULL);
}
ike_cfg = ike_cfg_create(TRUE, FALSE, "0.0.0.0", FALSE, IKEV2_UDP_PORT,
ike_cfg = ike_cfg_create(TRUE, FALSE, "0.0.0.0", FALSE,
charon->socket->get_port(charon->socket, FALSE),
hostname, FALSE, IKEV2_UDP_PORT);
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
+2 -2
View File
@@ -119,7 +119,7 @@ METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
return NULL;
}
ike_cfg = ike_cfg_create(FALSE, FALSE,
"0.0.0.0", FALSE, IKEV2_UDP_PORT,
"0.0.0.0", FALSE, charon->socket->get_port(charon->socket, FALSE),
address, FALSE, IKEV2_UDP_PORT);
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
med_cfg = peer_cfg_create(
@@ -396,7 +396,7 @@ medcli_config_t *medcli_config_create(database_t *db)
.rekey = lib->settings->get_time(lib->settings, "medcli.rekey", 1200),
.dpd = lib->settings->get_time(lib->settings, "medcli.dpd", 300),
.ike = ike_cfg_create(FALSE, FALSE,
"0.0.0.0", FALSE, IKEV2_UDP_PORT,
"0.0.0.0", FALSE, charon->socket->get_port(charon->socket, FALSE),
"0.0.0.0", FALSE, IKEV2_UDP_PORT),
);
this->ike->add_proposal(this->ike, proposal_create_default(PROTO_IKE));
+1 -1
View File
@@ -141,7 +141,7 @@ medsrv_config_t *medsrv_config_create(database_t *db)
.rekey = lib->settings->get_time(lib->settings, "medsrv.rekey", 1200),
.dpd = lib->settings->get_time(lib->settings, "medsrv.dpd", 300),
.ike = ike_cfg_create(FALSE, FALSE,
"0.0.0.0", FALSE, IKEV2_UDP_PORT,
"0.0.0.0", FALSE, charon->socket->get_port(charon->socket, FALSE),
"0.0.0.0", FALSE, IKEV2_UDP_PORT),
);
this->ike->add_proposal(this->ike, proposal_create_default(PROTO_IKE));
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2006-2010 Tobias Brunner
* Copyright (C) 2006-2012 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2010 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -40,9 +40,6 @@
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <net/if.h>
#ifdef __APPLE__
#include <sys/sysctl.h>
#endif
#include <hydra.h>
#include <daemon.h>
@@ -51,18 +48,6 @@
/* Maximum size of a packet */
#define MAX_PACKET 10000
/* length of non-esp marker */
#define MARKER_LEN sizeof(u_int32_t)
/* from linux/udp.h */
#ifndef UDP_ENCAP
#define UDP_ENCAP 100
#endif /*UDP_ENCAP*/
#ifndef UDP_ENCAP_ESPINUDP
#define UDP_ENCAP_ESPINUDP 2
#endif /*UDP_ENCAP_ESPINUDP*/
/* these are not defined on some platforms */
#ifndef SOL_IP
#define SOL_IP IPPROTO_IP
@@ -70,9 +55,6 @@
#ifndef SOL_IPV6
#define SOL_IPV6 IPPROTO_IPV6
#endif
#ifndef SOL_UDP
#define SOL_UDP IPPROTO_UDP
#endif
/* IPV6_RECVPKTINFO is defined in RFC 3542 which obsoletes RFC 2292 that
* previously defined IPV6_PKTINFO */
@@ -101,22 +83,32 @@ struct private_socket_default_socket_t {
socket_default_socket_t public;
/**
* IPv4 socket (500)
* Configured port (or random, if initially 0)
*/
u_int16_t port;
/**
* Configured port for NAT-T (or random, if initially 0)
*/
u_int16_t natt;
/**
* IPv4 socket (500 or port)
*/
int ipv4;
/**
* IPv4 socket for NATT (4500)
* IPv4 socket for NAT-T (4500 or natt)
*/
int ipv4_natt;
/**
* IPv6 socket (500)
* IPv6 socket (500 or port)
*/
int ipv6;
/**
* IPv6 socket for NATT (4500)
* IPv6 socket for NAT-T (4500 or natt)
*/
int ipv6_natt;
@@ -124,6 +116,11 @@ struct private_socket_default_socket_t {
* Maximum packet size to receive
*/
int max_packet;
/**
* TRUE if the source address should be set on outbound packets
*/
bool set_source;
};
METHOD(socket_t, receiver, status_t,
@@ -133,7 +130,7 @@ METHOD(socket_t, receiver, status_t,
chunk_t data;
packet_t *pkt;
host_t *source = NULL, *dest = NULL;
int bytes_read = 0, data_offset;
int bytes_read = 0;
bool oldstate;
fd_set rfds;
@@ -171,22 +168,22 @@ METHOD(socket_t, receiver, status_t,
if (FD_ISSET(this->ipv4, &rfds))
{
port = IKEV2_UDP_PORT;
port = this->port;
selected = this->ipv4;
}
if (FD_ISSET(this->ipv4_natt, &rfds))
{
port = IKEV2_NATT_PORT;
port = this->natt;
selected = this->ipv4_natt;
}
if (FD_ISSET(this->ipv6, &rfds))
{
port = IKEV2_UDP_PORT;
port = this->port;
selected = this->ipv6;
}
if (FD_ISSET(this->ipv6_natt, &rfds))
{
port = IKEV2_NATT_PORT;
port = this->natt;
selected = this->ipv6_natt;
}
if (selected)
@@ -222,13 +219,6 @@ METHOD(socket_t, receiver, status_t,
}
DBG3(DBG_NET, "received packet %b", buffer, bytes_read);
if (bytes_read < MARKER_LEN)
{
DBG3(DBG_NET, "received packet too short (%d bytes)",
bytes_read);
return FAILED;
}
/* read ancillary data to get destination address */
for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
@@ -297,17 +287,8 @@ METHOD(socket_t, receiver, status_t,
pkt->set_source(pkt, source);
pkt->set_destination(pkt, dest);
DBG2(DBG_NET, "received packet: from %#H to %#H", source, dest);
data_offset = 0;
/* remove non esp marker */
if (dest->get_port(dest) == IKEV2_NATT_PORT)
{
data_offset += MARKER_LEN;
}
/* fill in packet */
data.len = bytes_read - data_offset;
data.ptr = malloc(data.len);
memcpy(data.ptr, buffer + data_offset, data.len);
pkt->set_data(pkt, data);
data = chunk_create(buffer, bytes_read);
pkt->set_data(pkt, chunk_clone(data));
}
else
{
@@ -324,7 +305,7 @@ METHOD(socket_t, sender, status_t,
{
int sport, skt, family;
ssize_t bytes_sent;
chunk_t data, marked;
chunk_t data;
host_t *src, *dst;
struct msghdr msg;
struct cmsghdr *cmsg;
@@ -339,7 +320,7 @@ METHOD(socket_t, sender, status_t,
/* send data */
sport = src->get_port(src);
family = dst->get_family(dst);
if (sport == IKEV2_UDP_PORT)
if (sport == 0 || sport == this->port)
{
if (family == AF_INET)
{
@@ -350,7 +331,7 @@ METHOD(socket_t, sender, status_t,
skt = this->ipv6;
}
}
else if (sport == IKEV2_NATT_PORT)
else if (sport == this->natt)
{
if (family == AF_INET)
{
@@ -360,17 +341,6 @@ METHOD(socket_t, sender, status_t,
{
skt = this->ipv6_natt;
}
/* NAT keepalives without marker */
if (data.len != 1 || data.ptr[0] != 0xFF)
{
/* add non esp marker to packet */
marked = chunk_alloc(data.len + MARKER_LEN);
memset(marked.ptr, 0, MARKER_LEN);
memcpy(marked.ptr + MARKER_LEN, data.ptr, data.len);
/* let the packet do the clean up for us */
packet->set_data(packet, marked);
data = marked;
}
}
else
{
@@ -387,7 +357,7 @@ METHOD(socket_t, sender, status_t,
msg.msg_iovlen = 1;
msg.msg_flags = 0;
if (!src->is_anyaddr(src))
if (this->set_source && !src->is_anyaddr(src))
{
if (family == AF_INET)
{
@@ -450,11 +420,17 @@ METHOD(socket_t, sender, status_t,
return SUCCESS;
}
METHOD(socket_t, get_port, u_int16_t,
private_socket_default_socket_t *this, bool nat_t)
{
return nat_t ? this->natt : this->port;
}
/**
* open a socket to send and receive packets
*/
static int open_socket(private_socket_default_socket_t *this,
int family, u_int16_t port)
int family, u_int16_t *port)
{
int on = TRUE;
struct sockaddr_storage addr;
@@ -471,7 +447,7 @@ static int open_socket(private_socket_default_socket_t *this,
{
struct sockaddr_in *sin = (struct sockaddr_in *)&addr;
htoun32(&sin->sin_addr.s_addr, INADDR_ANY);
htoun16(&sin->sin_port, port);
htoun16(&sin->sin_port, *port);
addrlen = sizeof(struct sockaddr_in);
sol = SOL_IP;
#ifdef IP_PKTINFO
@@ -485,7 +461,7 @@ static int open_socket(private_socket_default_socket_t *this,
{
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr;
memcpy(&sin6->sin6_addr, &in6addr_any, sizeof(in6addr_any));
htoun16(&sin6->sin6_port, port);
htoun16(&sin6->sin6_port, *port);
addrlen = sizeof(struct sockaddr_in6);
sol = SOL_IPV6;
pktinfo = IPV6_RECVPKTINFO;
@@ -516,6 +492,32 @@ static int open_socket(private_socket_default_socket_t *this,
return 0;
}
/* retrieve randomly allocated port if needed */
if (*port == 0)
{
if (getsockname(skt, (struct sockaddr *)&addr, &addrlen) < 0)
{
DBG1(DBG_NET, "unable to determine port: %s", strerror(errno));
close(skt);
return 0;
}
switch (family)
{
case AF_INET:
{
struct sockaddr_in *sin = (struct sockaddr_in *)&addr;
*port = untoh16(&sin->sin_port);
break;
}
case AF_INET6:
{
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr;
*port = untoh16(&sin6->sin6_port);
break;
}
}
}
/* get additional packet info on receive */
if (pktinfo > 0)
{
@@ -532,18 +534,6 @@ static int open_socket(private_socket_default_socket_t *this,
{
DBG1(DBG_NET, "installing IKE bypass policy failed");
}
#ifndef __APPLE__
{
/* enable UDP decapsulation globally, only for one socket needed */
int type = UDP_ENCAP_ESPINUDP;
if (family == AF_INET && port == IKEV2_NATT_PORT &&
setsockopt(skt, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0)
{
DBG1(DBG_NET, "unable to set UDP_ENCAP: %s", strerror(errno));
}
}
#endif
return skt;
}
@@ -581,59 +571,72 @@ socket_default_socket_t *socket_default_socket_create()
.socket = {
.send = _sender,
.receive = _receiver,
.get_port = _get_port,
.destroy = _destroy,
},
},
.port = lib->settings->get_int(lib->settings,
"%s.port", CHARON_UDP_PORT, charon->name),
.natt = lib->settings->get_int(lib->settings,
"%s.port_nat_t", CHARON_NATT_PORT, charon->name),
.max_packet = lib->settings->get_int(lib->settings,
"%s.max_packet", MAX_PACKET, charon->name),
"%s.max_packet", MAX_PACKET, charon->name),
.set_source = lib->settings->get_bool(lib->settings,
"%s.plugins.socket-default.set_source", TRUE,
charon->name),
);
#ifdef __APPLE__
if (this->port && this->port == this->natt)
{
int natt_port = IKEV2_NATT_PORT;
if (sysctlbyname("net.inet.ipsec.esp_port", NULL, NULL, &natt_port,
sizeof(natt_port)) != 0)
{
DBG1(DBG_NET, "could not set net.inet.ipsec.esp_port to %d: %s",
natt_port, strerror(errno));
}
}
#endif
this->ipv4 = open_socket(this, AF_INET, IKEV2_UDP_PORT);
if (this->ipv4 == 0)
{
DBG1(DBG_NET, "could not open IPv4 socket, IPv4 disabled");
}
else
{
this->ipv4_natt = open_socket(this, AF_INET, IKEV2_NATT_PORT);
if (this->ipv4_natt == 0)
{
DBG1(DBG_NET, "could not open IPv4 NAT-T socket");
}
DBG1(DBG_NET, "IKE ports can't be equal, will allocate NAT-T "
"port randomly");
this->natt = 0;
}
this->ipv6 = open_socket(this, AF_INET6, IKEV2_UDP_PORT);
/* we allocate IPv6 sockets first as that will reserve randomly allocated
* ports also for IPv4 */
this->ipv6 = open_socket(this, AF_INET6, &this->port);
if (this->ipv6 == 0)
{
DBG1(DBG_NET, "could not open IPv6 socket, IPv6 disabled");
}
else
{
this->ipv6_natt = open_socket(this, AF_INET6, IKEV2_NATT_PORT);
this->ipv6_natt = open_socket(this, AF_INET6, &this->natt);
if (this->ipv6_natt == 0)
{
DBG1(DBG_NET, "could not open IPv6 NAT-T socket");
}
}
this->ipv4 = open_socket(this, AF_INET, &this->port);
if (this->ipv4 == 0)
{
DBG1(DBG_NET, "could not open IPv4 socket, IPv4 disabled");
}
else
{
this->ipv4_natt = open_socket(this, AF_INET, &this->natt);
if (this->ipv4_natt == 0)
{
DBG1(DBG_NET, "could not open IPv4 NAT-T socket");
}
}
if (!this->ipv4 && !this->ipv6)
{
DBG1(DBG_NET, "could not create any sockets");
destroy(this);
return NULL;
}
/* enable UDP decapsulation globally, only for one socket needed */
if (!hydra->kernel_interface->enable_udp_decap(hydra->kernel_interface,
this->ipv6_natt ?: this->ipv4_natt,
this->ipv6_natt ? AF_INET6 : AF_INET, this->natt))
{
DBG1(DBG_NET, "enabling UDP decapsulation failed");
}
return &this->public;
}
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2006-2010 Tobias Brunner
* Copyright (C) 2006-2012 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2010 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -45,18 +45,6 @@
/* Maximum size of a packet */
#define MAX_PACKET 10000
/* length of non-esp marker */
#define MARKER_LEN sizeof(u_int32_t)
/* from linux/udp.h */
#ifndef UDP_ENCAP
#define UDP_ENCAP 100
#endif /*UDP_ENCAP*/
#ifndef UDP_ENCAP_ESPINUDP
#define UDP_ENCAP_ESPINUDP 2
#endif /*UDP_ENCAP_ESPINUDP*/
/* these are not defined on some platforms */
#ifndef SOL_IP
#define SOL_IP IPPROTO_IP
@@ -64,9 +52,6 @@
#ifndef SOL_IPV6
#define SOL_IPV6 IPPROTO_IPV6
#endif
#ifndef SOL_UDP
#define SOL_UDP IPPROTO_UDP
#endif
/* IPV6_RECVPKTINFO is defined in RFC 3542 which obsoletes RFC 2292 that
* previously defined IPV6_PKTINFO */
@@ -237,12 +222,6 @@ static packet_t *receive_packet(private_socket_dynamic_socket_t *this,
}
DBG3(DBG_NET, "received packet %b", buffer, (u_int)len);
if (len < MARKER_LEN)
{
DBG3(DBG_NET, "received packet too short (%d bytes)", len);
return NULL;
}
/* read ancillary data to get destination address */
for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
@@ -297,12 +276,6 @@ static packet_t *receive_packet(private_socket_dynamic_socket_t *this,
packet = packet_create();
packet->set_source(packet, source);
packet->set_destination(packet, dest);
/* we assume a non-ESP marker if none of the ports is on 500 */
if (dest->get_port(dest) != IKEV2_UDP_PORT &&
source->get_port(source) != IKEV2_UDP_PORT)
{
data = chunk_skip(data, MARKER_LEN);
}
packet->set_data(packet, chunk_clone(data));
return packet;
}
@@ -358,7 +331,7 @@ METHOD(socket_t, receiver, status_t,
static int open_socket(private_socket_dynamic_socket_t *this,
int family, u_int16_t port)
{
int on = TRUE, type = UDP_ENCAP_ESPINUDP;
int on = TRUE;
struct sockaddr_storage addr;
socklen_t addrlen;
u_int sol, pktinfo = 0;
@@ -430,10 +403,12 @@ static int open_socket(private_socket_dynamic_socket_t *this,
}
/* enable UDP decapsulation on each socket */
if (setsockopt(fd, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0)
if (!hydra->kernel_interface->enable_udp_decap(hydra->kernel_interface,
fd, family, port))
{
DBG1(DBG_NET, "unable to set UDP_ENCAP: %s", strerror(errno));
DBG1(DBG_NET, "enabling UDP decapsulation failed");
}
return fd;
}
@@ -483,7 +458,7 @@ METHOD(socket_t, sender, status_t,
host_t *src, *dst;
int port, family;
ssize_t len;
chunk_t data, marked;
chunk_t data;
struct msghdr msg;
struct cmsghdr *cmsg;
struct iovec iov;
@@ -492,6 +467,7 @@ METHOD(socket_t, sender, status_t,
dst = packet->get_destination(packet);
family = src->get_family(src);
port = src->get_port(src);
port = port ?: CHARON_UDP_PORT;
skt = find_socket(this, family, port);
if (!skt)
{
@@ -501,19 +477,6 @@ METHOD(socket_t, sender, status_t,
data = packet->get_data(packet);
DBG2(DBG_NET, "sending packet: from %#H to %#H", src, dst);
/* use non-ESP marker if none of the ports is 500, not for keep alives */
if (port != IKEV2_UDP_PORT && dst->get_port(dst) != IKEV2_UDP_PORT &&
!(data.len == 1 && data.ptr[0] == 0xFF))
{
/* add non esp marker to packet */
marked = chunk_alloc(data.len + MARKER_LEN);
memset(marked.ptr, 0, MARKER_LEN);
memcpy(marked.ptr + MARKER_LEN, data.ptr, data.len);
/* let the packet do the clean up for us */
packet->set_data(packet, marked);
data = marked;
}
memset(&msg, 0, sizeof(struct msghdr));
msg.msg_name = dst->get_sockaddr(dst);;
msg.msg_namelen = *dst->get_sockaddr_len(dst);
@@ -572,6 +535,14 @@ METHOD(socket_t, sender, status_t,
return SUCCESS;
}
METHOD(socket_t, get_port, u_int16_t,
private_socket_dynamic_socket_t *this, bool nat_t)
{
/* we return 0 here for users that have no explicit port configured, the
* sender will default to the default port in this case */
return 0;
}
METHOD(socket_t, destroy, void,
private_socket_dynamic_socket_t *this)
{
@@ -605,6 +576,7 @@ socket_dynamic_socket_t *socket_dynamic_socket_create()
.socket = {
.send = _sender,
.receive = _receiver,
.get_port = _get_port,
.destroy = _destroy,
},
},
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2006-2010 Tobias Brunner
* Copyright (C) 2006-2012 Tobias Brunner
* Copyright (C) 2005-2010 Martin Willi
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005 Jan Hutter
@@ -55,15 +55,6 @@
#define IKE_VERSION_OFFSET 17
#define IKE_LENGTH_OFFSET 24
/* from linux/udp.h */
#ifndef UDP_ENCAP
#define UDP_ENCAP 100
#endif /*UDP_ENCAP*/
#ifndef UDP_ENCAP_ESPINUDP
#define UDP_ENCAP_ESPINUDP 2
#endif /*UDP_ENCAP_ESPINUDP*/
/* needed for older kernel headers */
#ifndef IPV6_2292PKTINFO
#define IPV6_2292PKTINFO 2
@@ -181,7 +172,7 @@ METHOD(socket_t, receiver, status_t,
DBG3(DBG_NET, "received IPv4 packet %b", buffer, bytes_read);
/* read source/dest from raw IP/UDP header */
if (bytes_read < IP_LEN + UDP_LEN + MARKER_LEN)
if (bytes_read < IP_LEN + UDP_LEN)
{
DBG1(DBG_NET, "received IPv4 packet too short (%d bytes)",
bytes_read);
@@ -203,16 +194,9 @@ METHOD(socket_t, receiver, status_t,
pkt->set_destination(pkt, dest);
DBG2(DBG_NET, "received packet: from %#H to %#H", source, dest);
data_offset = IP_LEN + UDP_LEN;
/* remove non esp marker */
if (dest->get_port(dest) == IKEV2_NATT_PORT)
{
data_offset += MARKER_LEN;
}
/* fill in packet */
data.len = bytes_read - data_offset;
data.ptr = malloc(data.len);
memcpy(data.ptr, buffer + data_offset, data.len);
pkt->set_data(pkt, data);
data.ptr = buffer + data_offset;
pkt->set_data(pkt, chunk_clone(data));
}
else if (this->recv6 && FD_ISSET(this->recv6, &rfds))
{
@@ -242,7 +226,7 @@ METHOD(socket_t, receiver, status_t,
}
DBG3(DBG_NET, "received IPv6 packet %b", buffer, bytes_read);
if (bytes_read < IP_LEN + UDP_LEN + MARKER_LEN)
if (bytes_read < IP_LEN + UDP_LEN)
{
DBG3(DBG_NET, "received IPv6 packet too short (%d bytes)",
bytes_read);
@@ -290,16 +274,9 @@ METHOD(socket_t, receiver, status_t,
pkt->set_destination(pkt, dest);
DBG2(DBG_NET, "received packet: from %#H to %#H", source, dest);
data_offset = UDP_LEN;
/* remove non esp marker */
if (dest->get_port(dest) == IKEV2_NATT_PORT)
{
data_offset += MARKER_LEN;
}
/* fill in packet */
data.len = bytes_read - data_offset;
data.ptr = malloc(data.len);
memcpy(data.ptr, buffer + data_offset, data.len);
pkt->set_data(pkt, data);
data.ptr = buffer + data_offset;
pkt->set_data(pkt, chunk_clone(data));
}
else
{
@@ -317,7 +294,7 @@ METHOD(socket_t, sender, status_t,
{
int sport, skt, family;
ssize_t bytes_sent;
chunk_t data, marked;
chunk_t data;
host_t *src, *dst;
struct msghdr msg;
struct cmsghdr *cmsg;
@@ -332,7 +309,7 @@ METHOD(socket_t, sender, status_t,
/* send data */
sport = src->get_port(src);
family = dst->get_family(dst);
if (sport == IKEV2_UDP_PORT)
if (sport == 0 || sport == CHARON_UDP_PORT)
{
if (family == AF_INET)
{
@@ -343,7 +320,7 @@ METHOD(socket_t, sender, status_t,
skt = this->send6;
}
}
else if (sport == IKEV2_NATT_PORT)
else if (sport == CHARON_NATT_PORT)
{
if (family == AF_INET)
{
@@ -353,17 +330,6 @@ METHOD(socket_t, sender, status_t,
{
skt = this->send6_natt;
}
/* NAT keepalives without marker */
if (data.len != 1 || data.ptr[0] != 0xFF)
{
/* add non esp marker to packet */
marked = chunk_alloc(data.len + MARKER_LEN);
memset(marked.ptr, 0, MARKER_LEN);
memcpy(marked.ptr + MARKER_LEN, data.ptr, data.len);
/* let the packet do the clean up for us */
packet->set_data(packet, marked);
data = marked;
}
}
else
{
@@ -437,7 +403,6 @@ static int open_send_socket(private_socket_raw_socket_t *this,
int family, u_int16_t port)
{
int on = TRUE;
int type = UDP_ENCAP_ESPINUDP;
struct sockaddr_storage addr;
int skt;
@@ -488,25 +453,29 @@ static int open_send_socket(private_socket_raw_socket_t *this,
return 0;
}
if (family == AF_INET)
{
/* enable UDP decapsulation globally, only for one socket needed */
if (setsockopt(skt, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0)
{
DBG1(DBG_NET, "unable to set UDP_ENCAP: %s; NAT-T may fail",
strerror(errno));
}
}
if (!hydra->kernel_interface->bypass_socket(hydra->kernel_interface,
skt, family))
{
DBG1(DBG_NET, "installing bypass policy on send socket failed");
}
/* enable UDP decapsulation globally, only for one socket needed */
if (family == AF_INET && port == CHARON_NATT_PORT &&
!hydra->kernel_interface->enable_udp_decap(hydra->kernel_interface,
skt, family, port))
{
DBG1(DBG_NET, "enabling UDP decapsulation failed");
}
return skt;
}
METHOD(socket_t, get_port, u_int16_t,
private_socket_raw_socket_t *this, bool nat_t)
{
return nat_t ? CHARON_NATT_PORT : CHARON_UDP_PORT;
}
/**
* open a socket to receive packets
*/
@@ -541,8 +510,8 @@ static int open_recv_socket(private_socket_raw_socket_t *this, int family)
{
/* Destination Port must be either port or natt_port */
BPF_STMT(BPF_LD+BPF_H+BPF_ABS, udp_header + 2),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IKEV2_UDP_PORT, 1, 0),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IKEV2_NATT_PORT, 6, 14),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, CHARON_UDP_PORT, 1, 0),
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, CHARON_NATT_PORT, 6, 14),
/* port */
/* IKE version must be 2.x */
BPF_STMT(BPF_LD+BPF_B+BPF_ABS, ike_header + IKE_VERSION_OFFSET),
@@ -653,6 +622,7 @@ socket_raw_socket_t *socket_raw_socket_create()
.socket = {
.send = _sender,
.receive = _receiver,
.get_port = _get_port,
.destroy = _destroy,
},
},
@@ -667,7 +637,7 @@ socket_raw_socket_t *socket_raw_socket_create()
}
else
{
this->send4 = open_send_socket(this, AF_INET, IKEV2_UDP_PORT);
this->send4 = open_send_socket(this, AF_INET, CHARON_UDP_PORT);
if (this->send4 == 0)
{
DBG1(DBG_NET, "could not open IPv4 send socket, IPv4 disabled");
@@ -675,7 +645,7 @@ socket_raw_socket_t *socket_raw_socket_create()
}
else
{
this->send4_natt = open_send_socket(this, AF_INET, IKEV2_NATT_PORT);
this->send4_natt = open_send_socket(this, AF_INET, CHARON_NATT_PORT);
if (this->send4_natt == 0)
{
DBG1(DBG_NET, "could not open IPv4 NAT-T send socket");
@@ -690,7 +660,7 @@ socket_raw_socket_t *socket_raw_socket_create()
}
else
{
this->send6 = open_send_socket(this, AF_INET6, IKEV2_UDP_PORT);
this->send6 = open_send_socket(this, AF_INET6, CHARON_UDP_PORT);
if (this->send6 == 0)
{
DBG1(DBG_NET, "could not open IPv6 send socket, IPv6 disabled");
@@ -698,7 +668,7 @@ socket_raw_socket_t *socket_raw_socket_create()
}
else
{
this->send6_natt = open_send_socket(this, AF_INET6, IKEV2_NATT_PORT);
this->send6_natt = open_send_socket(this, AF_INET6, CHARON_NATT_PORT);
if (this->send6_natt == 0)
{
DBG1(DBG_NET, "could not open IPv6 NAT-T send socket");
+1 -1
View File
@@ -259,7 +259,7 @@ static ike_cfg_t *build_ike_cfg(private_sql_config_t *this, enumerator_t *e,
ike_cfg_t *ike_cfg;
ike_cfg = ike_cfg_create(certreq, force_encap,
local, FALSE, IKEV2_UDP_PORT,
local, FALSE, charon->socket->get_port(charon->socket, FALSE),
remote, FALSE, IKEV2_UDP_PORT);
add_ike_proposals(this, ike_cfg, id);
return ike_cfg;
+5 -1
View File
@@ -188,6 +188,7 @@ static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg
ike_cfg_t *ike_cfg;
char *interface;
host_t *host;
u_int16_t ikeport;
host = host_create_from_dns(msg->add_conn.other.address, 0, 0);
if (host)
@@ -224,11 +225,14 @@ static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg
}
}
}
ikeport = msg->add_conn.me.ikeport;
ikeport = (ikeport == IKEV2_UDP_PORT) ?
charon->socket->get_port(charon->socket, FALSE) : ikeport;
ike_cfg = ike_cfg_create(msg->add_conn.other.sendcert != CERT_NEVER_SEND,
msg->add_conn.force_encap,
msg->add_conn.me.address,
msg->add_conn.me.allow_any,
msg->add_conn.me.ikeport,
ikeport,
msg->add_conn.other.address,
msg->add_conn.other.allow_any,
msg->add_conn.other.ikeport);
+2 -2
View File
@@ -169,7 +169,7 @@ METHOD(enumerator_t, peer_enumerator_enumerate, bool,
{
DESTROY_IF(this->peer_cfg);
ike_cfg = ike_cfg_create(FALSE, FALSE,
local_addr, FALSE, IKEV2_UDP_PORT,
local_addr, FALSE, charon->socket->get_port(charon->socket, FALSE),
remote_addr, FALSE, IKEV2_UDP_PORT);
ike_cfg->add_proposal(ike_cfg, create_proposal(ike_proposal, PROTO_IKE));
this->peer_cfg = peer_cfg_create(
@@ -267,7 +267,7 @@ METHOD(enumerator_t, ike_enumerator_enumerate, bool,
{
DESTROY_IF(this->ike_cfg);
this->ike_cfg = ike_cfg_create(FALSE, FALSE,
local_addr, FALSE, IKEV2_UDP_PORT,
local_addr, FALSE, charon->socket->get_port(charon->socket, FALSE),
remote_addr, FALSE, IKEV2_UDP_PORT);
this->ike_cfg->add_proposal(this->ike_cfg,
create_proposal(ike_proposal, PROTO_IKE));
+1 -1
View File
@@ -97,7 +97,7 @@ METHOD(job_t, execute, job_requeue_t,
ike_sa->set_kmaddress(ike_sa, this->local, this->remote);
host = this->local->clone(this->local);
host->set_port(host, IKEV2_UDP_PORT);
host->set_port(host, charon->socket->get_port(charon->socket, FALSE));
ike_sa->set_my_host(ike_sa, host);
host = this->remote->clone(this->remote);
+8 -5
View File
@@ -489,7 +489,7 @@ METHOD(ike_sa_t, send_keepalive, void,
data.len = 1;
packet->set_data(packet, data);
DBG1(DBG_IKE, "sending keep alive");
charon->sender->send(charon->sender, packet);
charon->sender->send_no_marker(charon->sender, packet);
diff = 0;
}
job = send_keepalive_job_create(this->ike_sa_id);
@@ -845,9 +845,11 @@ METHOD(ike_sa_t, float_ports, void,
private_ike_sa_t *this)
{
/* do not switch if we have a custom port from MOBIKE/NAT */
if (this->my_host->get_port(this->my_host) == IKEV2_UDP_PORT)
if (this->my_host->get_port(this->my_host) ==
charon->socket->get_port(charon->socket, FALSE))
{
this->my_host->set_port(this->my_host, IKEV2_NATT_PORT);
this->my_host->set_port(this->my_host,
charon->socket->get_port(charon->socket, TRUE));
}
if (this->other_host->get_port(this->other_host) == IKEV2_UDP_PORT)
{
@@ -1054,7 +1056,7 @@ static void resolve_hosts(private_ike_sa_t *this)
if (this->local_host)
{
host = this->local_host->clone(this->local_host);
host->set_port(host, IKEV2_UDP_PORT);
host->set_port(host, charon->socket->get_port(charon->socket, FALSE));
}
else
{
@@ -2239,7 +2241,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
}
this->task_manager = task_manager_create(&this->public);
this->my_host->set_port(this->my_host, IKEV2_UDP_PORT);
this->my_host->set_port(this->my_host,
charon->socket->get_port(charon->socket, FALSE));
if (!this->task_manager || !this->keymat)
{
+2 -1
View File
@@ -116,7 +116,8 @@ METHOD(task_t, process_r, status_t,
notify_type_names, type, redirect);
/* Cisco boxes reject the first message from 4500 */
me = this->ike_sa->get_my_host(this->ike_sa);
me->set_port(me, IKEV2_UDP_PORT);
me->set_port(me, charon->socket->get_port(
charon->socket, FALSE));
this->ike_sa->set_other_host(this->ike_sa, redirect);
this->ike_sa->reauth(this->ike_sa);
enumerator->destroy(enumerator);
+8 -4
View File
@@ -271,13 +271,17 @@ static void update_children(private_ike_mobike_t *this)
/**
* Apply the port of the old host, if its ip equals the new, use port otherwise.
*/
static void apply_port(host_t *host, host_t *old, u_int16_t port)
static void apply_port(host_t *host, host_t *old, u_int16_t port, bool local)
{
if (host->ip_equals(host, old))
{
port = old->get_port(old);
}
else if (port == IKEV2_UDP_PORT)
else if (local && port == charon->socket->get_port(charon->socket, FALSE))
{
port = charon->socket->get_port(charon->socket, TRUE);
}
else if (!local && port == IKEV2_UDP_PORT)
{
port = IKEV2_NATT_PORT;
}
@@ -314,9 +318,9 @@ METHOD(ike_mobike_t, transmit, void,
continue;
}
/* reuse port for an active address, 4500 otherwise */
apply_port(me, me_old, ike_cfg->get_my_port(ike_cfg));
apply_port(me, me_old, ike_cfg->get_my_port(ike_cfg), TRUE);
other = other->clone(other);
apply_port(other, other_old, ike_cfg->get_other_port(ike_cfg));
apply_port(other, other_old, ike_cfg->get_other_port(ike_cfg), FALSE);
DBG1(DBG_IKE, "checking path %#H - %#H", me, other);
copy = packet->clone(packet);
copy->set_source(copy, me);
+12 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2008-2011 Tobias Brunner
* Copyright (C) 2008-2012 Tobias Brunner
* Hochschule fuer Technik Rapperswil
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
@@ -294,6 +294,16 @@ METHOD(kernel_interface_t, bypass_socket, bool,
return this->ipsec->bypass_socket(this->ipsec, fd, family);
}
METHOD(kernel_interface_t, enable_udp_decap, bool,
private_kernel_interface_t *this, int fd, int family, u_int16_t port)
{
if (!this->ipsec)
{
return FALSE;
}
return this->ipsec->enable_udp_decap(this->ipsec, fd, family, port);
}
METHOD(kernel_interface_t, get_address_by_ts, status_t,
private_kernel_interface_t *this, traffic_selector_t *ts, host_t **ip)
{
@@ -539,6 +549,7 @@ kernel_interface_t *kernel_interface_create()
.add_route = _add_route,
.del_route = _del_route,
.bypass_socket = _bypass_socket,
.enable_udp_decap = _enable_udp_decap,
.get_address_by_ts = _get_address_by_ts,
.add_ipsec_interface = _add_ipsec_interface,
+14 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2006-2011 Tobias Brunner
* Copyright (C) 2006-2012 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -361,10 +361,22 @@ struct kernel_interface_t {
*
* @param fd socket file descriptor to setup policy for
* @param family protocol family of the socket
* @return TRUE of policy set up successfully
* @return TRUE if policy set up successfully
*/
bool (*bypass_socket)(kernel_interface_t *this, int fd, int family);
/**
* Enable decapsulation of ESP-in-UDP packets for the given port/socket.
*
* @param fd socket file descriptor
* @param family protocol family of the socket
* @param port the UDP port
* @return TRUE if UDP decapsulation was enabled successfully
*/
bool (*enable_udp_decap)(kernel_interface_t *this, int fd, int family,
u_int16_t port);
/**
* manager methods
*/
+12 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2006-2011 Tobias Brunner
* Copyright (C) 2006-2012 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -402,6 +402,17 @@ struct kernel_ipsec_t {
*/
bool (*bypass_socket)(kernel_ipsec_t *this, int fd, int family);
/**
* Enable decapsulation of ESP-in-UDP packets for the given port/socket.
*
* @param fd socket file descriptor
* @param family protocol family of the socket
* @param port the UDP port
* @return TRUE if UDP decapsulation was enabled successfully
*/
bool (*enable_udp_decap)(kernel_ipsec_t *this, int fd, int family,
u_int16_t port);
/**
* Destroy the implementation.
*/
@@ -2537,13 +2537,6 @@ static status_t register_pfkey_socket(private_kernel_klips_ipsec_t *this, u_int8
return SUCCESS;
}
METHOD(kernel_ipsec_t, bypass_socket, bool,
private_kernel_klips_ipsec_t *this, int fd, int family)
{
/* KLIPS does not need a bypass policy for IKE */
return TRUE;
}
METHOD(kernel_ipsec_t, destroy, void,
private_kernel_klips_ipsec_t *this)
{
@@ -2585,7 +2578,10 @@ kernel_klips_ipsec_t *kernel_klips_ipsec_create()
.query_policy = _query_policy,
.del_policy = _del_policy,
.flush_policies = (void*)return_failed,
.bypass_socket = _bypass_socket,
/* KLIPS does not need a bypass policy for IKE */
.bypass_socket = (void*)return_true,
/* KLIPS does not need enabling UDP decap explicitly */
.enable_udp_decap = (void*)return_true,
.destroy = _destroy,
},
},
@@ -58,6 +58,20 @@
#define IPV6_XFRM_POLICY 34
#endif /*IPV6_XFRM_POLICY*/
/* from linux/udp.h */
#ifndef UDP_ENCAP
#define UDP_ENCAP 100
#endif
#ifndef UDP_ENCAP_ESPINUDP
#define UDP_ENCAP_ESPINUDP 2
#endif
/* this is not defined on some platforms */
#ifndef SOL_UDP
#define SOL_UDP IPPROTO_UDP
#endif
/** Default priority of installed policies */
#define PRIO_BASE 512
@@ -2607,6 +2621,19 @@ METHOD(kernel_ipsec_t, bypass_socket, bool,
return TRUE;
}
METHOD(kernel_ipsec_t, enable_udp_decap, bool,
private_kernel_netlink_ipsec_t *this, int fd, int family, u_int16_t port)
{
int type = UDP_ENCAP_ESPINUDP;
if (setsockopt(fd, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0)
{
DBG1(DBG_KNL, "unable to set UDP_ENCAP: %s", strerror(errno));
return FALSE;
}
return TRUE;
}
METHOD(kernel_ipsec_t, destroy, void,
private_kernel_netlink_ipsec_t *this)
{
@@ -2654,6 +2681,7 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create()
.del_policy = _del_policy,
.flush_policies = _flush_policies,
.bypass_socket = _bypass_socket,
.enable_udp_decap = _enable_udp_decap,
.destroy = _destroy,
},
},
@@ -51,6 +51,9 @@
#include <unistd.h>
#include <time.h>
#include <errno.h>
#ifdef __APPLE__
#include <sys/sysctl.h>
#endif
#include "kernel_pfkey_ipsec.h"
@@ -99,6 +102,20 @@
#define IPV6_IPSEC_POLICY 34
#endif
/* from linux/udp.h */
#ifndef UDP_ENCAP
#define UDP_ENCAP 100
#endif
#ifndef UDP_ENCAP_ESPINUDP
#define UDP_ENCAP_ESPINUDP 2
#endif
/* this is not defined on some platforms */
#ifndef SOL_UDP
#define SOL_UDP IPPROTO_UDP
#endif
/** default priority of installed policies */
#define PRIO_BASE 512
@@ -2488,6 +2505,30 @@ METHOD(kernel_ipsec_t, bypass_socket, bool,
return TRUE;
}
METHOD(kernel_ipsec_t, enable_udp_decap, bool,
private_kernel_pfkey_ipsec_t *this, int fd, int family, u_int16_t port)
{
#ifndef __APPLE__
int type = UDP_ENCAP_ESPINUDP;
if (setsockopt(fd, SOL_UDP, UDP_ENCAP, &type, sizeof(type)) < 0)
{
DBG1(DBG_KNL, "unable to set UDP_ENCAP: %s", strerror(errno));
return FALSE;
}
#else /* __APPLE__ */
if (sysctlbyname("net.inet.ipsec.esp_port", NULL, NULL, &port,
sizeof(port)) != 0)
{
DBG1(DBG_KNL, "could not set net.inet.ipsec.esp_port to %d: %s",
port, strerror(errno));
return FALSE;
}
#endif /* __APPLE__ */
return TRUE;
}
METHOD(kernel_ipsec_t, destroy, void,
private_kernel_pfkey_ipsec_t *this)
{
@@ -2532,6 +2573,7 @@ kernel_pfkey_ipsec_t *kernel_pfkey_ipsec_create()
.del_policy = _del_policy,
.flush_policies = _flush_policies,
.bypass_socket = _bypass_socket,
.enable_udp_decap = _enable_udp_decap,
.destroy = _destroy,
},
},
+29
View File
@@ -0,0 +1,29 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# copy-n-paste from Makefile.am
LOCAL_SRC_FILES := \
ipsec.c ipsec.h
# build libipsec ---------------------------------------------------------------
LOCAL_C_INCLUDES += \
$(libvstr_PATH) \
$(strongswan_PATH)/src/include \
$(strongswan_PATH)/src/libhydra \
$(strongswan_PATH)/src/libstrongswan
LOCAL_CFLAGS := $(strongswan_CFLAGS)
LOCAL_MODULE := libipsec
LOCAL_MODULE_TAGS := optional
LOCAL_ARM_MODE := arm
LOCAL_PRELINK_MODULE := false
LOCAL_SHARED_LIBRARIES += libstrongswan libhydra
include $(BUILD_SHARED_LIBRARY)
+20
View File
@@ -0,0 +1,20 @@
ipseclib_LTLIBRARIES = libipsec.la
libipsec_la_SOURCES = \
ipsec.c ipsec.h
libipsec_la_LIBADD =
INCLUDES = -I$(top_srcdir)/src/libstrongswan
EXTRA_DIST = Android.mk
# build optional plugins
########################
if MONOLITHIC
SUBDIRS =
else
SUBDIRS = .
endif
+69
View File
@@ -0,0 +1,69 @@
/*
* Copyright (C) 2012 Tobias Brunner
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
#include "ipsec.h"
#include <debug.h>
typedef struct private_ipsec_t private_ipsec_t;
/**
* Private additions to ipsec_t.
*/
struct private_ipsec_t {
/**
* Public members of ipsec_t.
*/
ipsec_t public;
};
/**
* Single instance of ipsec_t.
*/
ipsec_t *ipsec;
/**
* Described in header.
*/
void libipsec_deinit()
{
private_ipsec_t *this = (private_ipsec_t*)ipsec;
free(this);
ipsec = NULL;
}
/**
* Described in header.
*/
bool libipsec_init()
{
private_ipsec_t *this;
INIT(this,
.public = {
},
);
ipsec = &this->public;
if (lib->integrity &&
!lib->integrity->check(lib->integrity, "libipsec", libipsec_init))
{
DBG1(DBG_LIB, "integrity check of libipsec failed");
return FALSE;
}
return TRUE;
}
+56
View File
@@ -0,0 +1,56 @@
/*
* Copyright (C) 2012 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 libipsec libipsec
*
* @addtogroup libipsec
* @{
*/
#ifndef IPSEC_H_
#define IPSEC_H_
typedef struct ipsec_t ipsec_t;
#include <library.h>
/**
* User space IPsec implementation.
*/
struct ipsec_t {
};
/**
* The single instance of ipsec_t.
*
* Set between calls to libipsec_init() and libipsec_deinit() calls.
*/
extern ipsec_t *ipsec;
/**
* Initialize libipsec.
*
* @return FALSE if integrity check failed
*/
bool libipsec_init();
/**
* Deinitialize libipsec.
*/
void libipsec_deinit();
#endif /** IPSEC_H_ @}*/
+1 -1
View File
@@ -58,7 +58,7 @@ LOCAL_SRC_FILES += $(call add_plugin, nonce)
LOCAL_SRC_FILES += $(call add_plugin, openssl)
ifneq ($(call plugin_enabled, openssl),)
LOCAL_C_INCLUDES += external/openssl/include
LOCAL_C_INCLUDES += $(openssl_PATH)
LOCAL_SHARED_LIBRARIES += libcrypto
endif
+2
View File
@@ -34,6 +34,7 @@ ENUM(debug_names, DBG_DMN, DBG_LIB,
"PTS",
"TLS",
"APP",
"ESP",
"LIB",
);
@@ -54,6 +55,7 @@ ENUM(debug_lower_names, DBG_DMN, DBG_LIB,
"pts",
"tls",
"app",
"esp",
"lib",
);
+2
View File
@@ -64,6 +64,8 @@ enum debug_t {
DBG_TLS,
/** applications other than daemons */
DBG_APP,
/** libipsec */
DBG_ESP,
/** libstrongswan */
DBG_LIB,
/** number of groups */
+15 -6
View File
@@ -250,8 +250,11 @@ static bool load_plugin(private_plugin_loader_t *this, char *name, char *file,
this->plugins->insert_last(this->plugins, entry);
return TRUE;
case NOT_FOUND:
/* try to load the plugin from a file */
break;
if (file)
{ /* try to load the plugin from a file */
break;
}
/* fall-through */
default:
return FALSE;
}
@@ -651,16 +654,18 @@ METHOD(plugin_loader_t, load_plugins, bool,
char *token;
bool critical_failed = FALSE;
#ifdef PLUGINDIR
if (path == NULL)
{
path = PLUGINDIR;
}
#endif /* PLUGINDIR */
enumerator = enumerator_create_token(list, " ", " ");
while (!critical_failed && enumerator->enumerate(enumerator, &token))
{
bool critical = FALSE;
char file[PATH_MAX];
char buf[PATH_MAX], *file = NULL;
int len;
token = strdup(token);
@@ -675,10 +680,14 @@ METHOD(plugin_loader_t, load_plugins, bool,
free(token);
continue;
}
if (snprintf(file, sizeof(file), "%s/libstrongswan-%s.so",
path, token) >= sizeof(file))
if (path)
{
return FALSE;
if (snprintf(buf, sizeof(buf), "%s/libstrongswan-%s.so",
path, token) >= sizeof(buf))
{
return FALSE;
}
file = buf;
}
if (!load_plugin(this, token, file, critical) && critical)
{
+9 -2
View File
@@ -1117,14 +1117,21 @@ static bool load_files_internal(private_settings_t *this, section_t *parent,
char *pattern, bool merge)
{
char *text;
linked_list_t *contents = linked_list_create();
section_t *section = section_create(NULL);
linked_list_t *contents;
section_t *section;
if (pattern == NULL)
{
#ifdef STRONGSWAN_CONF
pattern = STRONGSWAN_CONF;
#else
return FALSE;
#endif
}
contents = linked_list_create();
section = section_create(NULL);
if (!parse_files(contents, NULL, 0, pattern, section))
{
contents->destroy_function(contents, (void*)free);
+1 -1
View File
@@ -407,7 +407,7 @@ static void exit_usage(char *error)
printf(" where: START and optional END define the clients source IP\n");
printf(" Set loglevel for a logging type:\n");
printf(" stroke loglevel TYPE LEVEL\n");
printf(" where: TYPE is any|dmn|mgr|ike|chd|job|cfg|knl|net|asn|enc|tnc|imc|imv|pts|tls|lib\n");
printf(" where: TYPE is any|dmn|mgr|ike|chd|job|cfg|knl|net|asn|enc|tnc|imc|imv|pts|tls|esp|lib\n");
printf(" LEVEL is -1|0|1|2|3|4\n");
printf(" Show connection status:\n");
printf(" stroke status\n");