summaryrefslogtreecommitdiff
path: root/src/libcharon/plugins/eap_radius
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/plugins/eap_radius')
-rw-r--r--src/libcharon/plugins/eap_radius/Makefile.in243
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius.c126
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_accounting.c2
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_xauth.c182
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_xauth.h4
5 files changed, 442 insertions, 115 deletions
diff --git a/src/libcharon/plugins/eap_radius/Makefile.in b/src/libcharon/plugins/eap_radius/Makefile.in
index 24818d4fb..3064ceadb 100644
--- a/src/libcharon/plugins/eap_radius/Makefile.in
+++ b/src/libcharon/plugins/eap_radius/Makefile.in
@@ -1,9 +1,8 @@
-# Makefile.in generated by automake 1.11.6 from Makefile.am.
+# Makefile.in generated by automake 1.13.3 from Makefile.am.
# @configure_input@
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
-# Foundation, Inc.
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -16,23 +15,51 @@
@SET_MAKE@
VPATH = @srcdir@
-am__make_dryrun = \
- { \
- am__dry=no; \
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
- echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
- | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
- *) \
- for am__flg in $$MAKEFLAGS; do \
- case $$am__flg in \
- *=*|--*) ;; \
- *n*) am__dry=yes; break;; \
- esac; \
- done;; \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
- test $$am__dry = yes; \
- }
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -52,13 +79,15 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = src/libcharon/plugins/eap_radius
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/depcomp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
$(top_srcdir)/m4/config/ltoptions.m4 \
$(top_srcdir)/m4/config/ltsugar.m4 \
$(top_srcdir)/m4/config/ltversion.m4 \
$(top_srcdir)/m4/config/lt~obsolete.m4 \
+ $(top_srcdir)/m4/macros/split-package-version.m4 \
$(top_srcdir)/m4/macros/with.m4 \
$(top_srcdir)/m4/macros/enable-disable.m4 \
$(top_srcdir)/m4/macros/add-plugin.m4 \
@@ -108,6 +137,7 @@ libstrongswan_eap_radius_la_OBJECTS = \
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
+am__v_lt_1 =
libstrongswan_eap_radius_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
$(AM_CFLAGS) $(CFLAGS) $(libstrongswan_eap_radius_la_LDFLAGS) \
@@ -115,6 +145,18 @@ libstrongswan_eap_radius_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
@MONOLITHIC_FALSE@am_libstrongswan_eap_radius_la_rpath = -rpath \
@MONOLITHIC_FALSE@ $(plugindir)
@MONOLITHIC_TRUE@am_libstrongswan_eap_radius_la_rpath =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@@ -127,20 +169,16 @@ LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
-am__v_CC_0 = @echo " CC " $@;
-AM_V_at = $(am__v_at_@AM_V@)
-am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
-am__v_at_0 = @
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
-am__v_CCLD_0 = @echo " CCLD " $@;
-AM_V_GEN = $(am__v_GEN_@AM_V@)
-am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
-am__v_GEN_0 = @echo " GEN " $@;
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
SOURCES = $(libstrongswan_eap_radius_la_SOURCES)
DIST_SOURCES = $(libstrongswan_eap_radius_la_SOURCES)
am__can_run_installinfo = \
@@ -148,6 +186,23 @@ am__can_run_installinfo = \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -224,6 +279,10 @@ PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
+PACKAGE_VERSION_BUILD = @PACKAGE_VERSION_BUILD@
+PACKAGE_VERSION_MAJOR = @PACKAGE_VERSION_MAJOR@
+PACKAGE_VERSION_MINOR = @PACKAGE_VERSION_MINOR@
+PACKAGE_VERSION_REVIEW = @PACKAGE_VERSION_REVIEW@
PATH_SEPARATOR = @PATH_SEPARATOR@
PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
@@ -340,6 +399,7 @@ starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
+t_plugins = @t_plugins@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
@@ -406,12 +466,15 @@ $(am__aclocal_m4_deps):
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
- @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
- dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
- test "$$dir" != "$$p" || dir=.; \
- echo "rm -f \"$${dir}/so_locations\""; \
- rm -f "$${dir}/so_locations"; \
- done
+ @list='$(noinst_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES)
@$(NORMAL_INSTALL)
@list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \
@@ -438,12 +501,15 @@ uninstall-pluginLTLIBRARIES:
clean-pluginLTLIBRARIES:
-test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
- @list='$(plugin_LTLIBRARIES)'; for p in $$list; do \
- dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
- test "$$dir" != "$$p" || dir=.; \
- echo "rm -f \"$${dir}/so_locations\""; \
- rm -f "$${dir}/so_locations"; \
- done
+ @list='$(plugin_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
libstrongswan-eap-radius.la: $(libstrongswan_eap_radius_la_OBJECTS) $(libstrongswan_eap_radius_la_DEPENDENCIES) $(EXTRA_libstrongswan_eap_radius_la_DEPENDENCIES)
$(AM_V_CCLD)$(libstrongswan_eap_radius_la_LINK) $(am_libstrongswan_eap_radius_la_rpath) $(libstrongswan_eap_radius_la_OBJECTS) $(libstrongswan_eap_radius_la_LIBADD) $(LIBS)
@@ -462,22 +528,25 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eap_radius_xauth.Plo@am__quote@
.c.o:
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
.c.obj:
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.c.lo:
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
+@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
@@ -488,26 +557,15 @@ mostlyclean-libtool:
clean-libtool:
-rm -rf .libs _libs
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- mkid -fID $$unique
-tags: TAGS
-
-TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
+ $(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
@@ -519,15 +577,11 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$$unique; \
fi; \
fi
-ctags: CTAGS
-CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
@@ -536,6 +590,21 @@ GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
@@ -680,20 +749,20 @@ uninstall-am: uninstall-pluginLTLIBRARIES
.MAKE: install-am install-strip
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLTLIBRARIES clean-pluginLTLIBRARIES \
- ctags distclean distclean-compile distclean-generic \
- distclean-libtool distclean-tags distdir dvi dvi-am html \
- html-am info info-am install install-am install-data \
- install-data-am install-dvi install-dvi-am install-exec \
- install-exec-am install-html install-html-am install-info \
- install-info-am install-man install-pdf install-pdf-am \
- install-pluginLTLIBRARIES install-ps install-ps-am \
- install-strip installcheck installcheck-am installdirs \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
- pdf pdf-am ps ps-am tags uninstall uninstall-am \
- uninstall-pluginLTLIBRARIES
+ cscopelist-am ctags ctags-am distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-pluginLTLIBRARIES install-ps \
+ install-ps-am install-strip installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
+ uninstall-am uninstall-pluginLTLIBRARIES
# Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/src/libcharon/plugins/eap_radius/eap_radius.c b/src/libcharon/plugins/eap_radius/eap_radius.c
index b06b6c392..6087a528f 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius.c
@@ -21,6 +21,7 @@
#include <radius_message.h>
#include <radius_client.h>
+#include <bio/bio_writer.h>
#include <daemon.h>
@@ -392,6 +393,85 @@ static void process_timeout(radius_message_t *msg)
}
/**
+ * Add a Cisco Unity configuration attribute
+ */
+static void add_unity_attribute(eap_radius_provider_t *provider, u_int32_t id,
+ int type, chunk_t data)
+{
+ switch (type)
+ {
+ case 15: /* CVPN3000-IPSec-Banner1 */
+ case 36: /* CVPN3000-IPSec-Banner2 */
+ provider->add_attribute(provider, id, UNITY_BANNER, data);
+ break;
+ case 28: /* CVPN3000-IPSec-Default-Domain */
+ provider->add_attribute(provider, id, UNITY_DEF_DOMAIN, data);
+ break;
+ case 29: /* CVPN3000-IPSec-Split-DNS-Names */
+ provider->add_attribute(provider, id, UNITY_SPLITDNS_NAME, data);
+ break;
+ }
+}
+
+/**
+ * Add a UNITY_LOCAL_LAN or UNITY_SPLIT_INCLUDE attribute
+ */
+static void add_unity_split_attribute(eap_radius_provider_t *provider,
+ u_int32_t id, configuration_attribute_type_t type,
+ chunk_t data)
+{
+ enumerator_t *enumerator;
+ bio_writer_t *writer;
+ char buffer[256], *token, *slash;
+
+ if (snprintf(buffer, sizeof(buffer), "%.*s", (int)data.len,
+ data.ptr) >= sizeof(buffer))
+ {
+ return;
+ }
+ writer = bio_writer_create(16); /* two IPv4 addresses and 6 bytes padding */
+ enumerator = enumerator_create_token(buffer, ",", " ");
+ while (enumerator->enumerate(enumerator, &token))
+ {
+ host_t *net, *mask = NULL;
+ chunk_t padding;
+
+ slash = strchr(token, '/');
+ if (slash)
+ {
+ *slash++ = '\0';
+ mask = host_create_from_string(slash, 0);
+ }
+ if (!mask)
+ { /* default to /32 */
+ mask = host_create_from_string("255.255.255.255", 0);
+ }
+ net = host_create_from_string(token, 0);
+ if (!net || net->get_family(net) != AF_INET ||
+ mask->get_family(mask) != AF_INET)
+ {
+ mask->destroy(mask);
+ DESTROY_IF(net);
+ continue;
+ }
+ writer->write_data(writer, net->get_address(net));
+ writer->write_data(writer, mask->get_address(mask));
+ padding = writer->skip(writer, 6); /* 6 bytes pdding */
+ memset(padding.ptr, 0, padding.len);
+ mask->destroy(mask);
+ net->destroy(net);
+ }
+ enumerator->destroy(enumerator);
+
+ data = writer->get_buf(writer);
+ if (data.len)
+ {
+ provider->add_attribute(provider, id, type, data);
+ }
+ writer->destroy(writer);
+}
+
+/**
* Handle Framed-IP-Address and other IKE configuration attributes
*/
static void process_cfg_attributes(radius_message_t *msg)
@@ -401,6 +481,7 @@ static void process_cfg_attributes(radius_message_t *msg)
ike_sa_t *ike_sa;
host_t *host;
chunk_t data;
+ configuration_attribute_type_t split_type = 0;
int type, vendor;
ike_sa = charon->bus->get_sa(charon->bus);
@@ -419,6 +500,11 @@ static void process_cfg_attributes(radius_message_t *msg)
ike_sa->get_unique_id(ike_sa), host);
}
}
+ else if (type == RAT_FRAMED_IP_NETMASK && data.len == 4)
+ {
+ provider->add_attribute(provider, ike_sa->get_unique_id(ike_sa),
+ INTERNAL_IP4_NETMASK, data);
+ }
}
enumerator->destroy(enumerator);
@@ -430,12 +516,30 @@ static void process_cfg_attributes(radius_message_t *msg)
switch (type)
{
case 15: /* CVPN3000-IPSec-Banner1 */
+ case 28: /* CVPN3000-IPSec-Default-Domain */
+ case 29: /* CVPN3000-IPSec-Split-DNS-Names */
case 36: /* CVPN3000-IPSec-Banner2 */
if (ike_sa->supports_extension(ike_sa, EXT_CISCO_UNITY))
{
- provider->add_attribute(provider,
- ike_sa->get_unique_id(ike_sa),
- UNITY_BANNER, data);
+ add_unity_attribute(provider,
+ ike_sa->get_unique_id(ike_sa), type, data);
+ }
+ break;
+ case 55: /* CVPN3000-IPSec-Split-Tunneling-Policy */
+ if (data.len)
+ {
+ switch (data.ptr[data.len - 1])
+ {
+ case 0: /* tunnelall */
+ default:
+ break;
+ case 1: /* tunnelspecified */
+ split_type = UNITY_SPLIT_INCLUDE;
+ break;
+ case 2: /* excludespecified */
+ split_type = UNITY_LOCAL_LAN;
+ break;
+ }
}
break;
default:
@@ -444,6 +548,22 @@ static void process_cfg_attributes(radius_message_t *msg)
}
}
enumerator->destroy(enumerator);
+
+ if (split_type != 0 &&
+ ike_sa->supports_extension(ike_sa, EXT_CISCO_UNITY))
+ {
+ enumerator = msg->create_vendor_enumerator(msg);
+ while (enumerator->enumerate(enumerator, &vendor, &type, &data))
+ {
+ if (vendor == PEN_ALTIGA /* aka Cisco VPN3000 */ &&
+ type == 27 /* CVPN3000-IPSec-Split-Tunnel-List */)
+ {
+ add_unity_split_attribute(provider,
+ ike_sa->get_unique_id(ike_sa), split_type, data);
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
}
}
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_accounting.c b/src/libcharon/plugins/eap_radius/eap_radius_accounting.c
index e004589da..afb661e19 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_accounting.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius_accounting.c
@@ -210,7 +210,7 @@ static void add_ike_sa_parameters(private_eap_radius_accounting_t *this,
{
enumerator_t *enumerator;
host_t *vip, *host;
- char buf[64];
+ char buf[128];
chunk_t data;
u_int32_t value;
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_xauth.c b/src/libcharon/plugins/eap_radius/eap_radius_xauth.c
index bd960d2bc..e66bbf38f 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_xauth.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius_xauth.c
@@ -20,9 +20,21 @@
#include <daemon.h>
#include <radius_client.h>
+#include <collections/array.h>
typedef struct private_eap_radius_xauth_t private_eap_radius_xauth_t;
+typedef struct xauth_round_t xauth_round_t;
+
+/**
+ * Configuration for an XAuth authentication exchange
+ */
+struct xauth_round_t {
+ /** XAuth message type to send */
+ configuration_attribute_type_t type;
+ /** Message to present to user */
+ char *message;
+};
/**
* Private data of an eap_radius_xauth_t object.
@@ -48,33 +60,74 @@ struct private_eap_radius_xauth_t {
* RADIUS connection
*/
radius_client_t *client;
+
+ /**
+ * XAuth authentication rounds, as xauth_round_t
+ */
+ array_t *rounds;
+
+ /**
+ * XAuth round currently in progress
+ */
+ xauth_round_t round;
+
+ /**
+ * Concatentated password of all rounds
+ */
+ chunk_t pass;
};
+/**
+ * Fetch next XAuth round, add attributes to CP payload
+ */
+static bool build_round(private_eap_radius_xauth_t *this, cp_payload_t *cp)
+{
+ if (!array_remove(this->rounds, ARRAY_HEAD, &this->round))
+ {
+ return FALSE;
+ }
+ cp->add_attribute(cp, configuration_attribute_create_chunk(
+ CONFIGURATION_ATTRIBUTE_V1, this->round.type, chunk_empty));
+
+ if (this->round.message && strlen(this->round.message))
+ {
+ cp->add_attribute(cp, configuration_attribute_create_chunk(
+ CONFIGURATION_ATTRIBUTE_V1, XAUTH_MESSAGE,
+ chunk_from_str(this->round.message)));
+ }
+ return TRUE;
+}
+
METHOD(xauth_method_t, initiate, status_t,
private_eap_radius_xauth_t *this, cp_payload_t **out)
{
cp_payload_t *cp;
cp = cp_payload_create_type(CONFIGURATION_V1, CFG_REQUEST);
+ /* first message always comes with username */
cp->add_attribute(cp, configuration_attribute_create_chunk(
CONFIGURATION_ATTRIBUTE_V1, XAUTH_USER_NAME, chunk_empty));
- cp->add_attribute(cp, configuration_attribute_create_chunk(
- CONFIGURATION_ATTRIBUTE_V1, XAUTH_USER_PASSWORD, chunk_empty));
- *out = cp;
- return NEED_MORE;
+
+ if (build_round(this, cp))
+ {
+ *out = cp;
+ return NEED_MORE;
+ }
+ cp->destroy(cp);
+ return FAILED;
}
/**
* Verify a password using RADIUS User-Name/User-Password attributes
*/
-static status_t verify_radius(private_eap_radius_xauth_t *this, chunk_t pass)
+static status_t verify_radius(private_eap_radius_xauth_t *this)
{
radius_message_t *request, *response;
status_t status = FAILED;
request = radius_message_create(RMC_ACCESS_REQUEST);
request->add(request, RAT_USER_NAME, this->peer->get_encoding(this->peer));
- request->add(request, RAT_USER_PASSWORD, pass);
+ request->add(request, RAT_USER_PASSWORD, this->pass);
eap_radius_build_attributes(request);
eap_radius_forward_from_ike(request);
@@ -114,34 +167,34 @@ METHOD(xauth_method_t, process, status_t,
configuration_attribute_t *attr;
enumerator_t *enumerator;
identification_t *id;
+ cp_payload_t *cp;
chunk_t user = chunk_empty, pass = chunk_empty;
enumerator = in->create_attribute_enumerator(in);
while (enumerator->enumerate(enumerator, &attr))
{
- switch (attr->get_type(attr))
+ if (attr->get_type(attr) == XAUTH_USER_NAME)
{
- case XAUTH_USER_NAME:
- user = attr->get_chunk(attr);
- break;
- case XAUTH_USER_PASSWORD:
- pass = attr->get_chunk(attr);
- /* trim password to any null termination. As User-Password
- * uses null padding, we can't have any null in it, and some
- * clients actually send null terminated strings (Android). */
- pass.len = strnlen(pass.ptr, pass.len);
- break;
- default:
- break;
+ user = attr->get_chunk(attr);
+ }
+ else if (attr->get_type(attr) == this->round.type)
+ {
+ pass = attr->get_chunk(attr);
+ /* trim password to any null termination. As User-Password
+ * uses null padding, we can't have any null in it, and some
+ * clients actually send null terminated strings (Android). */
+ pass.len = strnlen(pass.ptr, pass.len);
}
}
enumerator->destroy(enumerator);
- if (!user.ptr || !pass.ptr)
+ if (!pass.ptr)
{
- DBG1(DBG_IKE, "peer did not respond to our XAuth request");
+ DBG1(DBG_IKE, "peer did not respond to our XAuth %N request",
+ configuration_attribute_type_names, this->round.type);
return FAILED;
}
+ this->pass = chunk_cat("mc", this->pass, pass);
if (user.len)
{
id = identification_create_from_data(user);
@@ -153,7 +206,19 @@ METHOD(xauth_method_t, process, status_t,
this->peer->destroy(this->peer);
this->peer = id;
}
- return verify_radius(this, pass);
+
+ if (array_count(this->rounds) == 0)
+ {
+ return verify_radius(this);
+ }
+ cp = cp_payload_create_type(CONFIGURATION_V1, CFG_REQUEST);
+ if (build_round(this, cp))
+ {
+ *out = cp;
+ return NEED_MORE;
+ }
+ cp->destroy(cp);
+ return FAILED;
}
METHOD(xauth_method_t, get_identity, identification_t*,
@@ -162,10 +227,74 @@ METHOD(xauth_method_t, get_identity, identification_t*,
return this->peer;
}
+/**
+ * Parse XAuth round configuration
+ */
+static bool parse_rounds(private_eap_radius_xauth_t *this, char *profile)
+{
+ struct {
+ char *str;
+ configuration_attribute_type_t type;
+ } map[] = {
+ { "password", XAUTH_USER_PASSWORD, },
+ { "passcode", XAUTH_PASSCODE, },
+ { "nextpin", XAUTH_NEXT_PIN, },
+ { "answer", XAUTH_ANSWER, },
+ };
+ enumerator_t *enumerator;
+ char *type, *message;
+ xauth_round_t round;
+ int i;
+
+ if (!profile || strlen(profile) == 0)
+ {
+ /* no config, fallback to password */
+ round.type = XAUTH_USER_PASSWORD;
+ round.message = NULL;
+ array_insert(this->rounds, ARRAY_TAIL, &round);
+ return TRUE;
+ }
+
+ enumerator = lib->settings->create_key_value_enumerator(lib->settings,
+ "%s.plugins.eap-radius.xauth.%s", charon->name, profile);
+ while (enumerator->enumerate(enumerator, &type, &message))
+ {
+ bool invalid = TRUE;
+
+ for (i = 0; i < countof(map); i++)
+ {
+ if (strcaseeq(map[i].str, type))
+ {
+ round.type = map[i].type;
+ round.message = message;
+ array_insert(this->rounds, ARRAY_TAIL, &round);
+ invalid = FALSE;
+ break;
+ }
+ }
+ if (invalid)
+ {
+ DBG1(DBG_CFG, "invalid XAuth round type: '%s'", type);
+ enumerator->destroy(enumerator);
+ return FALSE;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (array_count(this->rounds) == 0)
+ {
+ DBG1(DBG_CFG, "XAuth configuration profile '%s' invalid", profile);
+ return FALSE;
+ }
+ return TRUE;
+}
+
METHOD(xauth_method_t, destroy, void,
private_eap_radius_xauth_t *this)
{
DESTROY_IF(this->client);
+ chunk_clear(&this->pass);
+ array_destroy(this->rounds);
this->server->destroy(this->server);
this->peer->destroy(this->peer);
free(this);
@@ -175,7 +304,8 @@ METHOD(xauth_method_t, destroy, void,
* Described in header.
*/
eap_radius_xauth_t *eap_radius_xauth_create_server(identification_t *server,
- identification_t *peer)
+ identification_t *peer,
+ char *profile)
{
private_eap_radius_xauth_t *this;
@@ -191,8 +321,14 @@ eap_radius_xauth_t *eap_radius_xauth_create_server(identification_t *server,
.server = server->clone(server),
.peer = peer->clone(peer),
.client = eap_radius_create_client(),
+ .rounds = array_create(sizeof(xauth_round_t), 0),
);
+ if (!parse_rounds(this, profile))
+ {
+ destroy(this);
+ return NULL;
+ }
if (!this->client)
{
destroy(this);
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_xauth.h b/src/libcharon/plugins/eap_radius/eap_radius_xauth.h
index 8571bbc9f..5baacfbe8 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_xauth.h
+++ b/src/libcharon/plugins/eap_radius/eap_radius_xauth.h
@@ -41,9 +41,11 @@ struct eap_radius_xauth_t {
*
* @param server ID of the XAuth server
* @param peer ID of the XAuth client
+ * @param profile configuration string
* @return xauth_generic_t object
*/
eap_radius_xauth_t *eap_radius_xauth_create_server(identification_t *server,
- identification_t *peer);
+ identification_t *peer,
+ char *profile);
#endif /** EAP_RADIUS_XAUTH_H_ @}*/