diff options
Diffstat (limited to 'src/libcharon/plugins/eap_radius')
-rw-r--r-- | src/libcharon/plugins/eap_radius/Makefile.in | 243 | ||||
-rw-r--r-- | src/libcharon/plugins/eap_radius/eap_radius.c | 126 | ||||
-rw-r--r-- | src/libcharon/plugins/eap_radius/eap_radius_accounting.c | 2 | ||||
-rw-r--r-- | src/libcharon/plugins/eap_radius/eap_radius_xauth.c | 182 | ||||
-rw-r--r-- | src/libcharon/plugins/eap_radius/eap_radius_xauth.h | 4 |
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_ @}*/ |