From 568905f488e63e28778f87ac0e38d845f45bae79 Mon Sep 17 00:00:00 2001 From: René Mayrhofer Date: Sat, 5 Mar 2011 09:20:09 +0100 Subject: Imported Upstream version 4.5.1 --- src/libcharon/plugins/tnccs_11/Makefile.am | 16 +- src/libcharon/plugins/tnccs_11/Makefile.in | 92 +++- src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c | 323 +++++++++++++ src/libcharon/plugins/tnccs_11/batch/tnccs_batch.h | 100 ++++ .../plugins/tnccs_11/messages/imc_imv_msg.c | 242 ++++++++++ .../plugins/tnccs_11/messages/imc_imv_msg.h | 71 +++ .../plugins/tnccs_11/messages/tnccs_error_msg.c | 191 ++++++++ .../plugins/tnccs_11/messages/tnccs_error_msg.h | 80 ++++ .../plugins/tnccs_11/messages/tnccs_msg.c | 140 ++++++ .../plugins/tnccs_11/messages/tnccs_msg.h | 102 ++++ .../messages/tnccs_preferred_language_msg.c | 137 ++++++ .../messages/tnccs_preferred_language_msg.h | 64 +++ .../tnccs_11/messages/tnccs_reason_strings_msg.c | 149 ++++++ .../tnccs_11/messages/tnccs_reason_strings_msg.h | 64 +++ .../tnccs_11/messages/tnccs_recommendation_msg.c | 186 ++++++++ .../tnccs_11/messages/tnccs_recommendation_msg.h | 64 +++ .../messages/tnccs_tncs_contact_info_msg.c | 118 +++++ .../messages/tnccs_tncs_contact_info_msg.h | 54 +++ src/libcharon/plugins/tnccs_11/tnccs_11.c | 515 ++++++++++++++------- 19 files changed, 2521 insertions(+), 187 deletions(-) create mode 100644 src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c create mode 100644 src/libcharon/plugins/tnccs_11/batch/tnccs_batch.h create mode 100644 src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.c create mode 100644 src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.h create mode 100644 src/libcharon/plugins/tnccs_11/messages/tnccs_error_msg.c create mode 100644 src/libcharon/plugins/tnccs_11/messages/tnccs_error_msg.h create mode 100644 src/libcharon/plugins/tnccs_11/messages/tnccs_msg.c create mode 100644 src/libcharon/plugins/tnccs_11/messages/tnccs_msg.h create mode 100644 src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.c create mode 100644 src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.h create mode 100644 src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.c create mode 100644 src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.h create mode 100644 src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.c create mode 100644 src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.h create mode 100644 src/libcharon/plugins/tnccs_11/messages/tnccs_tncs_contact_info_msg.c create mode 100644 src/libcharon/plugins/tnccs_11/messages/tnccs_tncs_contact_info_msg.h (limited to 'src/libcharon/plugins/tnccs_11') diff --git a/src/libcharon/plugins/tnccs_11/Makefile.am b/src/libcharon/plugins/tnccs_11/Makefile.am index 7ccd0dfee..1042c3514 100644 --- a/src/libcharon/plugins/tnccs_11/Makefile.am +++ b/src/libcharon/plugins/tnccs_11/Makefile.am @@ -1,21 +1,27 @@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls \ - `xml2-config --cflags` + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls ${xml_CFLAGS} AM_CFLAGS = -rdynamic -libstrongswan_tnccs_11_la_LIBADD = -ltnc +libstrongswan_tnccs_11_la_LIBADD = ${xml_LIBS} if MONOLITHIC noinst_LTLIBRARIES = libstrongswan-tnccs-11.la else plugin_LTLIBRARIES = libstrongswan-tnccs-11.la -libstrongswan_tnccs_11_la_LIBADD += $(top_builddir)/src/libtls/libtls.la endif libstrongswan_tnccs_11_la_SOURCES = \ - tnccs_11_plugin.h tnccs_11_plugin.c tnccs_11.h tnccs_11.c + tnccs_11_plugin.h tnccs_11_plugin.c tnccs_11.h tnccs_11.c \ + batch/tnccs_batch.h batch/tnccs_batch.c \ + messages/tnccs_msg.h messages/tnccs_msg.c \ + messages/imc_imv_msg.h messages/imc_imv_msg.c \ + messages/tnccs_error_msg.h messages/tnccs_error_msg.c \ + messages/tnccs_preferred_language_msg.h messages/tnccs_preferred_language_msg.c \ + messages/tnccs_reason_strings_msg.h messages/tnccs_reason_strings_msg.c \ + messages/tnccs_recommendation_msg.h messages/tnccs_recommendation_msg.c \ + messages/tnccs_tncs_contact_info_msg.h messages/tnccs_tncs_contact_info_msg.c libstrongswan_tnccs_11_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/tnccs_11/Makefile.in b/src/libcharon/plugins/tnccs_11/Makefile.in index 200ff7a0a..5ab7ccbca 100644 --- a/src/libcharon/plugins/tnccs_11/Makefile.in +++ b/src/libcharon/plugins/tnccs_11/Makefile.in @@ -34,7 +34,6 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -@MONOLITHIC_FALSE@am__append_1 = $(top_builddir)/src/libtls/libtls.la subdir = src/libcharon/plugins/tnccs_11 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -75,8 +74,12 @@ am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) -libstrongswan_tnccs_11_la_DEPENDENCIES = $(am__append_1) -am_libstrongswan_tnccs_11_la_OBJECTS = tnccs_11_plugin.lo tnccs_11.lo +am__DEPENDENCIES_1 = +libstrongswan_tnccs_11_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am_libstrongswan_tnccs_11_la_OBJECTS = tnccs_11_plugin.lo tnccs_11.lo \ + tnccs_batch.lo tnccs_msg.lo imc_imv_msg.lo tnccs_error_msg.lo \ + tnccs_preferred_language_msg.lo tnccs_reason_strings_msg.lo \ + tnccs_recommendation_msg.lo tnccs_tncs_contact_info_msg.lo libstrongswan_tnccs_11_la_OBJECTS = \ $(am_libstrongswan_tnccs_11_la_OBJECTS) libstrongswan_tnccs_11_la_LINK = $(LIBTOOL) --tag=CC \ @@ -223,9 +226,7 @@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ ipsecdir = @ipsecdir@ -ipsecgid = @ipsecgid@ ipsecgroup = @ipsecgroup@ -ipsecuid = @ipsecuid@ ipsecuser = @ipsecuser@ libcharon_plugins = @libcharon_plugins@ libdir = @libdir@ @@ -264,6 +265,8 @@ sbindir = @sbindir@ scepclient_plugins = @scepclient_plugins@ scripts_plugins = @scripts_plugins@ sharedstatedir = @sharedstatedir@ +soup_CFLAGS = @soup_CFLAGS@ +soup_LIBS = @soup_LIBS@ srcdir = @srcdir@ strongswan_conf = @strongswan_conf@ sysconfdir = @sysconfdir@ @@ -275,15 +278,22 @@ urandom_device = @urandom_device@ xml_CFLAGS = @xml_CFLAGS@ xml_LIBS = @xml_LIBS@ INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \ - -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls \ - `xml2-config --cflags` + -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libtls ${xml_CFLAGS} AM_CFLAGS = -rdynamic -libstrongswan_tnccs_11_la_LIBADD = -ltnc $(am__append_1) +libstrongswan_tnccs_11_la_LIBADD = ${xml_LIBS} @MONOLITHIC_TRUE@noinst_LTLIBRARIES = libstrongswan-tnccs-11.la @MONOLITHIC_FALSE@plugin_LTLIBRARIES = libstrongswan-tnccs-11.la libstrongswan_tnccs_11_la_SOURCES = \ - tnccs_11_plugin.h tnccs_11_plugin.c tnccs_11.h tnccs_11.c + tnccs_11_plugin.h tnccs_11_plugin.c tnccs_11.h tnccs_11.c \ + batch/tnccs_batch.h batch/tnccs_batch.c \ + messages/tnccs_msg.h messages/tnccs_msg.c \ + messages/imc_imv_msg.h messages/imc_imv_msg.c \ + messages/tnccs_error_msg.h messages/tnccs_error_msg.c \ + messages/tnccs_preferred_language_msg.h messages/tnccs_preferred_language_msg.c \ + messages/tnccs_reason_strings_msg.h messages/tnccs_reason_strings_msg.c \ + messages/tnccs_recommendation_msg.h messages/tnccs_recommendation_msg.c \ + messages/tnccs_tncs_contact_info_msg.h messages/tnccs_tncs_contact_info_msg.c libstrongswan_tnccs_11_la_LDFLAGS = -module -avoid-version all: all-am @@ -369,8 +379,16 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/imc_imv_msg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_11.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_11_plugin.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_batch.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_error_msg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_msg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_preferred_language_msg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_reason_strings_msg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_recommendation_msg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnccs_tncs_contact_info_msg.Plo@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -393,6 +411,62 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< +tnccs_batch.lo: batch/tnccs_batch.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tnccs_batch.lo -MD -MP -MF $(DEPDIR)/tnccs_batch.Tpo -c -o tnccs_batch.lo `test -f 'batch/tnccs_batch.c' || echo '$(srcdir)/'`batch/tnccs_batch.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnccs_batch.Tpo $(DEPDIR)/tnccs_batch.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='batch/tnccs_batch.c' object='tnccs_batch.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tnccs_batch.lo `test -f 'batch/tnccs_batch.c' || echo '$(srcdir)/'`batch/tnccs_batch.c + +tnccs_msg.lo: messages/tnccs_msg.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tnccs_msg.lo -MD -MP -MF $(DEPDIR)/tnccs_msg.Tpo -c -o tnccs_msg.lo `test -f 'messages/tnccs_msg.c' || echo '$(srcdir)/'`messages/tnccs_msg.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnccs_msg.Tpo $(DEPDIR)/tnccs_msg.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='messages/tnccs_msg.c' object='tnccs_msg.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tnccs_msg.lo `test -f 'messages/tnccs_msg.c' || echo '$(srcdir)/'`messages/tnccs_msg.c + +imc_imv_msg.lo: messages/imc_imv_msg.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT imc_imv_msg.lo -MD -MP -MF $(DEPDIR)/imc_imv_msg.Tpo -c -o imc_imv_msg.lo `test -f 'messages/imc_imv_msg.c' || echo '$(srcdir)/'`messages/imc_imv_msg.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/imc_imv_msg.Tpo $(DEPDIR)/imc_imv_msg.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='messages/imc_imv_msg.c' object='imc_imv_msg.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o imc_imv_msg.lo `test -f 'messages/imc_imv_msg.c' || echo '$(srcdir)/'`messages/imc_imv_msg.c + +tnccs_error_msg.lo: messages/tnccs_error_msg.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tnccs_error_msg.lo -MD -MP -MF $(DEPDIR)/tnccs_error_msg.Tpo -c -o tnccs_error_msg.lo `test -f 'messages/tnccs_error_msg.c' || echo '$(srcdir)/'`messages/tnccs_error_msg.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnccs_error_msg.Tpo $(DEPDIR)/tnccs_error_msg.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='messages/tnccs_error_msg.c' object='tnccs_error_msg.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tnccs_error_msg.lo `test -f 'messages/tnccs_error_msg.c' || echo '$(srcdir)/'`messages/tnccs_error_msg.c + +tnccs_preferred_language_msg.lo: messages/tnccs_preferred_language_msg.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tnccs_preferred_language_msg.lo -MD -MP -MF $(DEPDIR)/tnccs_preferred_language_msg.Tpo -c -o tnccs_preferred_language_msg.lo `test -f 'messages/tnccs_preferred_language_msg.c' || echo '$(srcdir)/'`messages/tnccs_preferred_language_msg.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnccs_preferred_language_msg.Tpo $(DEPDIR)/tnccs_preferred_language_msg.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='messages/tnccs_preferred_language_msg.c' object='tnccs_preferred_language_msg.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tnccs_preferred_language_msg.lo `test -f 'messages/tnccs_preferred_language_msg.c' || echo '$(srcdir)/'`messages/tnccs_preferred_language_msg.c + +tnccs_reason_strings_msg.lo: messages/tnccs_reason_strings_msg.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tnccs_reason_strings_msg.lo -MD -MP -MF $(DEPDIR)/tnccs_reason_strings_msg.Tpo -c -o tnccs_reason_strings_msg.lo `test -f 'messages/tnccs_reason_strings_msg.c' || echo '$(srcdir)/'`messages/tnccs_reason_strings_msg.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnccs_reason_strings_msg.Tpo $(DEPDIR)/tnccs_reason_strings_msg.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='messages/tnccs_reason_strings_msg.c' object='tnccs_reason_strings_msg.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tnccs_reason_strings_msg.lo `test -f 'messages/tnccs_reason_strings_msg.c' || echo '$(srcdir)/'`messages/tnccs_reason_strings_msg.c + +tnccs_recommendation_msg.lo: messages/tnccs_recommendation_msg.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tnccs_recommendation_msg.lo -MD -MP -MF $(DEPDIR)/tnccs_recommendation_msg.Tpo -c -o tnccs_recommendation_msg.lo `test -f 'messages/tnccs_recommendation_msg.c' || echo '$(srcdir)/'`messages/tnccs_recommendation_msg.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnccs_recommendation_msg.Tpo $(DEPDIR)/tnccs_recommendation_msg.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='messages/tnccs_recommendation_msg.c' object='tnccs_recommendation_msg.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tnccs_recommendation_msg.lo `test -f 'messages/tnccs_recommendation_msg.c' || echo '$(srcdir)/'`messages/tnccs_recommendation_msg.c + +tnccs_tncs_contact_info_msg.lo: messages/tnccs_tncs_contact_info_msg.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tnccs_tncs_contact_info_msg.lo -MD -MP -MF $(DEPDIR)/tnccs_tncs_contact_info_msg.Tpo -c -o tnccs_tncs_contact_info_msg.lo `test -f 'messages/tnccs_tncs_contact_info_msg.c' || echo '$(srcdir)/'`messages/tnccs_tncs_contact_info_msg.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tnccs_tncs_contact_info_msg.Tpo $(DEPDIR)/tnccs_tncs_contact_info_msg.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='messages/tnccs_tncs_contact_info_msg.c' object='tnccs_tncs_contact_info_msg.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tnccs_tncs_contact_info_msg.lo `test -f 'messages/tnccs_tncs_contact_info_msg.c' || echo '$(srcdir)/'`messages/tnccs_tncs_contact_info_msg.c + mostlyclean-libtool: -rm -f *.lo diff --git a/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c b/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c new file mode 100644 index 000000000..0f6f3a675 --- /dev/null +++ b/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.c @@ -0,0 +1,323 @@ +/* + * Copyright (C) 2006 Mike McCauley (mikem@open.com.au) + * Copyright (C) 2010 Andreas Steffen, HSR 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 . + * + * 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 "tnccs_batch.h" +#include "messages/tnccs_error_msg.h" + +#include +#include +#include + +#include + +typedef struct private_tnccs_batch_t private_tnccs_batch_t; + +/** + * Private data of a tnccs_batch_t object. + * + */ +struct private_tnccs_batch_t { + /** + * Public tnccs_batch_t interface. + */ + tnccs_batch_t public; + + /** + * Batch ID + */ + int batch_id; + + /** + * TNCC if TRUE, TNCS if FALSE + */ + bool is_server; + + /** + * linked list of TNCCS messages + */ + linked_list_t *messages; + + /** + * linked list of TNCCS error messages + */ + linked_list_t *errors; + + /** + * XML document + */ + xmlDocPtr doc; + + /** + * Encoded message + */ + chunk_t encoding; +}; + +METHOD(tnccs_batch_t, get_encoding, chunk_t, + private_tnccs_batch_t *this) +{ + return this->encoding; +} + +METHOD(tnccs_batch_t, add_msg, void, + private_tnccs_batch_t *this, tnccs_msg_t* msg) +{ + xmlNodePtr root; + + DBG2(DBG_TNC, "adding %N message", tnccs_msg_type_names, + msg->get_type(msg)); + this->messages->insert_last(this->messages, msg); + root = xmlDocGetRootElement(this->doc); + xmlAddChild(root, msg->get_node(msg)); +} + +METHOD(tnccs_batch_t, build, void, + private_tnccs_batch_t *this) +{ + xmlChar *xmlbuf; + int buf_size; + + xmlDocDumpFormatMemory(this->doc, &xmlbuf, &buf_size, 1); + this->encoding = chunk_create((u_char*)xmlbuf, buf_size); + this->encoding = chunk_clone(this->encoding); + xmlFree(xmlbuf); +} + +METHOD(tnccs_batch_t, process, status_t, + private_tnccs_batch_t *this) +{ + tnccs_msg_t *tnccs_msg, *msg; + tnccs_error_type_t error_type = TNCCS_ERROR_OTHER; + char *error_msg, buf[BUF_LEN]; + xmlNodePtr cur; + xmlNsPtr ns; + xmlChar *batchid, *recipient; + int batch_id; + + this->doc = xmlParseMemory(this->encoding.ptr, this->encoding.len); + if (!this->doc) + { + error_type = TNCCS_ERROR_MALFORMED_BATCH; + error_msg = "failed to parse XML message"; + goto fatal; + } + + /* check out the XML document */ + cur = xmlDocGetRootElement(this->doc); + if (!cur) + { + error_type = TNCCS_ERROR_MALFORMED_BATCH; + error_msg = "empty XML document"; + goto fatal; + } + + /* check TNCCS namespace */ + ns = xmlSearchNsByHref(this->doc, cur, (const xmlChar*) + "http://www.trustedcomputinggroup.org/IWG/TNC/1_0/IF_TNCCS#"); + if (!ns) + { + error_type = TNCCS_ERROR_MALFORMED_BATCH; + error_msg = "TNCCS namespace not found"; + goto fatal; + } + + /* check XML document type */ + if (xmlStrcmp(cur->name, (const xmlChar*)"TNCCS-Batch")) + { + error_type = TNCCS_ERROR_MALFORMED_BATCH; + error_msg = buf; + snprintf(buf, BUF_LEN, "wrong XML document type '%s', expected TNCCS-Batch", + cur->name); + goto fatal; + } + + /* check presence of BatchID property */ + batchid = xmlGetProp(cur, (const xmlChar*)"BatchId"); + if (!batchid) + { + error_type = TNCCS_ERROR_INVALID_BATCH_ID; + error_msg = "BatchId is missing"; + goto fatal; + } + + /* check BatchID */ + batch_id = atoi((char*)batchid); + xmlFree(batchid); + if (batch_id != this->batch_id) + { + error_type = TNCCS_ERROR_INVALID_BATCH_ID; + error_msg = buf; + snprintf(buf, BUF_LEN, "BatchId %d expected, got %d", this->batch_id, + batch_id); + goto fatal; + } + + /* check presence of Recipient property */ + recipient = xmlGetProp(cur, (const xmlChar*)"Recipient"); + if (!recipient) + { + error_type = TNCCS_ERROR_INVALID_RECIPIENT_TYPE; + error_msg = "Recipient is missing"; + goto fatal; + } + + /* check recipient */ + if (!streq((char*)recipient, this->is_server ? "TNCS" : "TNCC")) + { + error_type = TNCCS_ERROR_INVALID_RECIPIENT_TYPE; + error_msg = buf; + snprintf(buf, BUF_LEN, "message recipient expected '%s', got '%s'", + this->is_server ? "TNCS" : "TNCC", (char*)recipient); + xmlFree(recipient); + goto fatal; + } + xmlFree(recipient); + + DBG2(DBG_TNC, "processing TNCCS Batch #%d", batch_id); + + /* Now walk the tree, handling message nodes as we go */ + for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) + { + /* ignore empty or blank nodes */ + if (xmlIsBlankNode(cur)) + { + continue; + } + + /* ignore nodes with wrong namespace */ + if (cur->ns != ns) + { + DBG1(DBG_TNC, "ignoring message node '%s' having wrong namespace", + (char*)cur->name); + continue; + } + + tnccs_msg = tnccs_msg_create_from_node(cur, this->errors); + + /* exit if a message parsing error occurred */ + if (this->errors->get_count(this->errors) > 0) + { + return FAILED; + } + + /* ignore unrecognized messages */ + if (!tnccs_msg) + { + continue; + } + + this->messages->insert_last(this->messages, tnccs_msg); + } + return SUCCESS; + +fatal: + msg = tnccs_error_msg_create(error_type, error_msg); + this->errors->insert_last(this->errors, msg); + return FAILED; +} + +METHOD(tnccs_batch_t, create_msg_enumerator, enumerator_t*, + private_tnccs_batch_t *this) +{ + return this->messages->create_enumerator(this->messages); +} + +METHOD(tnccs_batch_t, create_error_enumerator, enumerator_t*, + private_tnccs_batch_t *this) +{ + return this->errors->create_enumerator(this->errors); +} + +METHOD(tnccs_batch_t, destroy, void, + private_tnccs_batch_t *this) +{ + this->messages->destroy_offset(this->messages, + offsetof(tnccs_msg_t, destroy)); + this->errors->destroy_offset(this->errors, + offsetof(tnccs_msg_t, destroy)); + xmlFreeDoc(this->doc); + free(this->encoding.ptr); + free(this); +} + +/** + * See header + */ +tnccs_batch_t* tnccs_batch_create(bool is_server, int batch_id) +{ + private_tnccs_batch_t *this; + xmlNodePtr n; + char buf[12]; + const char *recipient; + + INIT(this, + .public = { + .get_encoding = _get_encoding, + .add_msg = _add_msg, + .build = _build, + .process = _process, + .create_msg_enumerator = _create_msg_enumerator, + .create_error_enumerator = _create_error_enumerator, + .destroy = _destroy, + }, + .is_server = is_server, + .messages = linked_list_create(), + .errors = linked_list_create(), + .batch_id = batch_id, + .doc = xmlNewDoc(BAD_CAST "1.0"), + ); + + DBG2(DBG_TNC, "creating TNCCS Batch #%d", this->batch_id); + n = xmlNewNode(NULL, BAD_CAST "TNCCS-Batch"); + snprintf(buf, sizeof(buf), "%d", batch_id); + recipient = this->is_server ? "TNCC" : "TNCS"; + xmlNewProp(n, BAD_CAST "BatchId", BAD_CAST buf); + xmlNewProp(n, BAD_CAST "Recipient", BAD_CAST recipient); + xmlNewProp(n, BAD_CAST "xmlns", BAD_CAST "http://www.trustedcomputinggroup.org/IWG/TNC/1_0/IF_TNCCS#"); + xmlNewProp(n, BAD_CAST "xmlns:xsi", BAD_CAST "http://www.w3.org/2001/XMLSchema-instance"); + xmlNewProp(n, BAD_CAST "xsi:schemaLocation", BAD_CAST "http://www.trustedcomputinggroup.org/IWG/TNC/1_0/IF_TNCCS# " + "https://www.trustedcomputinggroup.org/XML/SCHEMA/TNCCS_1.0.xsd"); + xmlDocSetRootElement(this->doc, n); + + return &this->public; +} + +/** + * See header + */ +tnccs_batch_t* tnccs_batch_create_from_data(bool is_server, int batch_id, chunk_t data) +{ + private_tnccs_batch_t *this; + + INIT(this, + .public = { + .get_encoding = _get_encoding, + .add_msg = _add_msg, + .build = _build, + .process = _process, + .create_msg_enumerator = _create_msg_enumerator, + .create_error_enumerator = _create_error_enumerator, + .destroy = _destroy, + }, + .is_server = is_server, + .batch_id = batch_id, + .messages = linked_list_create(), + .errors = linked_list_create(), + .encoding = chunk_clone(data), + ); + + return &this->public; +} + diff --git a/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.h b/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.h new file mode 100644 index 000000000..25301f763 --- /dev/null +++ b/src/libcharon/plugins/tnccs_11/batch/tnccs_batch.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2010 Andreas Steffen + * HSR 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 . + * + * 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 tnccs_batch tnccs_batch + * @{ @ingroup tnccs_11 + */ + +#ifndef TNCCS_BATCH_H_ +#define TNCCS_BATCH_H_ + +typedef enum tnccs_batch_type_t tnccs_batch_type_t; +typedef struct tnccs_batch_t tnccs_batch_t; + +#include "messages/tnccs_msg.h" + +#include + +/** + * Interface for a TNCCS 1.x Batch. + */ +struct tnccs_batch_t { + + /** + * Get the encoding of the TNCCS 1.x Batch + * + * @return encoded TNCCS 1.x batch + */ + chunk_t (*get_encoding)(tnccs_batch_t *this); + + /** + * Add TNCCS message + * + * @param msg TNCCS message to be addedd + */ + void (*add_msg)(tnccs_batch_t *this, tnccs_msg_t* msg); + + /** + * Build the TNCCS 1.x Batch + */ + void (*build)(tnccs_batch_t *this); + + /** + * Process the TNCCS 1.x Batch + * + * @return return processing status + */ + status_t (*process)(tnccs_batch_t *this); + + /** + * Enumerates over all TNCCS Messages + * + * @return return message enumerator + */ + enumerator_t* (*create_msg_enumerator)(tnccs_batch_t *this); + + /** + * Enumerates over all parsing errors + * + * @return return error enumerator + */ + enumerator_t* (*create_error_enumerator)(tnccs_batch_t *this); + + /** + * Destroys a tnccs_batch_t object. + */ + void (*destroy)(tnccs_batch_t *this); +}; + +/** + * Create an empty TNCCS 1.x Batch + * + * @param is_server TRUE if server, FALSE if client + * @param batch_id number of the batch to be sent + */ +tnccs_batch_t* tnccs_batch_create(bool is_server, int batch_id); + +/** + * Create an unprocessed TNCCS 1.x Batch from data + * + * @param is_server TRUE if server, FALSE if client + * @param batch_id current Batch ID + * @param data encoded PB-TNC batch + */ +tnccs_batch_t* tnccs_batch_create_from_data(bool is_server, int batch_id, + chunk_t data); + +#endif /** TNCCS_BATCH_H_ @}*/ diff --git a/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.c b/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.c new file mode 100644 index 000000000..f24c0dac9 --- /dev/null +++ b/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.c @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2006 Mike McCauley (mikem@open.com.au) + * Copyright (C) 2010 Andreas Steffen, HSR 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 . + * + * 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 "imc_imv_msg.h" + +#include +#include +#include + +typedef struct private_imc_imv_msg_t private_imc_imv_msg_t; + +#define BYTES_PER_LINE 57 + +/** + * Private data of a imc_imv_msg_t object. + * + */ +struct private_imc_imv_msg_t { + /** + * Public imc_imv_msg_t interface. + */ + imc_imv_msg_t public; + + /** + * TNCCS message type + */ + tnccs_msg_type_t type; + + /** + * XML-encoded message node + */ + xmlNodePtr node; + + /** + * IMC-IMV message type + */ + TNC_MessageType msg_type; + + /** + * IMC-IMV message body + */ + chunk_t msg_body; + +}; + +/** + * Encodes message data into multiple base64-encoded lines + */ +static chunk_t encode_base64(chunk_t data) +{ + chunk_t encoding; + u_char *pos; + size_t b64_chars, b64_lines; + + /* handle empty message data object */ + if (data.len == 0) + { + encoding = chunk_alloc(1); + *encoding.ptr = '\0'; + return encoding; + } + + /* compute and allocate maximum size of base64 object */ + b64_chars = 4 * ((data.len + 2) / 3); + b64_lines = (data.len + BYTES_PER_LINE - 1) / BYTES_PER_LINE; + encoding = chunk_alloc(b64_chars + b64_lines); + pos = encoding.ptr; + + /* encode lines */ + while (b64_lines--) + { + chunk_t data_line, b64_line; + + data_line = chunk_create(data.ptr, min(data.len, BYTES_PER_LINE)); + data.ptr += data_line.len; + data.len -= data_line.len; + b64_line = chunk_to_base64(data_line, pos); + pos += b64_line.len; + *pos = '\n'; + pos++; + } + /* terminate last line with NULL character instead of newline */ + *(pos-1) = '\0'; + + return encoding; +} + +/** + * Decodes message data from multiple base64-encoded lines + */ +static chunk_t decode_base64(chunk_t data) +{ + chunk_t decoding, data_line, b64_line; + u_char *pos; + + /* compute and allocate maximum size of decoded message data */ + decoding = chunk_alloc(3 * ((data.len + 3) / 4)); + pos = decoding.ptr; + decoding.len = 0; + + while (fetchline(&data, &b64_line)) + { + data_line = chunk_from_base64(b64_line, pos); + pos += data_line.len; + decoding.len += data_line.len; + } + + return decoding; +} + +METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t, + private_imc_imv_msg_t *this) +{ + return this->type; +} + +METHOD(tnccs_msg_t, get_node, xmlNodePtr, + private_imc_imv_msg_t *this) +{ + return this->node; +} + +METHOD(tnccs_msg_t, destroy, void, + private_imc_imv_msg_t *this) +{ + free(this->msg_body.ptr); + free(this); +} + +METHOD(imc_imv_msg_t, get_msg_type, TNC_MessageType, + private_imc_imv_msg_t *this) +{ + return this->msg_type; +} + +METHOD(imc_imv_msg_t, get_msg_body, chunk_t, + private_imc_imv_msg_t *this) +{ + return this->msg_body; +} + +/** + * See header + */ +tnccs_msg_t *imc_imv_msg_create_from_node(xmlNodePtr node, linked_list_t *errors) +{ + private_imc_imv_msg_t *this; + xmlNsPtr ns; + xmlNodePtr cur; + xmlChar *content; + chunk_t b64_body; + + INIT(this, + .public = { + .tnccs_msg_interface = { + .get_type = _get_type, + .get_node = _get_node, + .destroy = _destroy, + }, + .get_msg_type = _get_msg_type, + .get_msg_body = _get_msg_body, + }, + .type = IMC_IMV_MSG, + .node = node, + ); + + ns = node->ns; + cur = node->xmlChildrenNode; + while (cur) + { + if (streq((char*)cur->name, "Type") && cur->ns == ns) + { + content = xmlNodeGetContent(cur); + this->msg_type = strtoul((char*)content, NULL, 16); + xmlFree(content); + } + else if (streq((char*)cur->name, "Base64") && cur->ns == ns) + { + content = xmlNodeGetContent(cur); + b64_body = chunk_create((char*)content, strlen((char*)content)); + this->msg_body = decode_base64(b64_body); + xmlFree(content); + } + cur = cur->next; + } + + return &this->public.tnccs_msg_interface; +} + +/** + * See header + */ +tnccs_msg_t *imc_imv_msg_create(TNC_MessageType msg_type, chunk_t msg_body) +{ + private_imc_imv_msg_t *this; + chunk_t b64_body; + char buf[10]; /* big enough for hex-encoded message type */ + xmlNodePtr n; + + INIT(this, + .public = { + .tnccs_msg_interface = { + .get_type = _get_type, + .get_node = _get_node, + .destroy = _destroy, + }, + .get_msg_type = _get_msg_type, + .get_msg_body = _get_msg_body, + }, + .type = IMC_IMV_MSG, + .node = xmlNewNode(NULL, BAD_CAST "IMC-IMV-Message"), + .msg_type = msg_type, + .msg_body = chunk_clone(msg_body), + ); + + /* add the message type number in hex */ + n = xmlNewNode(NULL, BAD_CAST "Type"); + snprintf(buf, 10, "%08x", this->msg_type); + xmlNodeSetContent(n, BAD_CAST buf); + xmlAddChild(this->node, n); + + /* encode the message as a Base64 node */ + n = xmlNewNode(NULL, BAD_CAST "Base64"); + b64_body = encode_base64(this->msg_body); + xmlNodeSetContent(n, BAD_CAST b64_body.ptr); + xmlAddChild(this->node, n); + free(b64_body.ptr); + + return &this->public.tnccs_msg_interface; +} diff --git a/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.h b/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.h new file mode 100644 index 000000000..02f07199f --- /dev/null +++ b/src/libcharon/plugins/tnccs_11/messages/imc_imv_msg.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2010 Andreas Steffen + * HSR 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 . + * + * 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 imc_imv_msg imc_imv_msg + * @{ @ingroup tnccs_11 + */ + +#ifndef IMC_IMV_MSG_H_ +#define IMC_IMV_MSG_H_ + +typedef struct imc_imv_msg_t imc_imv_msg_t; + +#include "tnccs_msg.h" + +#include + +/** + * Classs representing the PB-PA message type. + */ +struct imc_imv_msg_t { + + /** + * TNCCS Message interface + */ + tnccs_msg_t tnccs_msg_interface; + + /** + * Get IMC-IMV message type + * + * @return IMC-IMV message type + */ + TNC_MessageType (*get_msg_type)(imc_imv_msg_t *this); + + /** + * Get IMC-IMV message body + * + * @return IMC-IMV message body + */ + chunk_t (*get_msg_body)(imc_imv_msg_t *this); +}; + +/** + * Create an IMC-IMV message from XML-encoded message node + * + * @param node XML-encoded message node + * @param errors linked list of TNCCS error messages +*/ +tnccs_msg_t *imc_imv_msg_create_from_node(xmlNodePtr node, linked_list_t *errors); + +/** + * Create an IMC-IMV message from parameters + * + * @param msg_type IMC-IMV message type + * @param msg_body IMC-IMV message body + */ +tnccs_msg_t *imc_imv_msg_create(TNC_MessageType msg_type, chunk_t msg_body); + +#endif /** IMC_IMV_MSG_H_ @}*/ diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_error_msg.c b/src/libcharon/plugins/tnccs_11/messages/tnccs_error_msg.c new file mode 100644 index 000000000..d0df4e7ca --- /dev/null +++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_error_msg.c @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2006 Mike McCauley (mikem@open.com.au) + * Copyright (C) 2010 Andreas Steffen, HSR 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 . + * + * 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 "tnccs_error_msg.h" + +#include + +ENUM(tnccs_error_type_names, TNCCS_ERROR_BATCH_TOO_LONG, TNCCS_ERROR_OTHER, + "batch-too-long", + "malformed-batch", + "invalid-batch-id", + "invalid-recipient-type", + "internal-error", + "other" +); + +typedef struct private_tnccs_error_msg_t private_tnccs_error_msg_t; + +/** + * Private data of a tnccs_error_msg_t object. + * + */ +struct private_tnccs_error_msg_t { + /** + * Public tnccs_error_msg_t interface. + */ + tnccs_error_msg_t public; + + /** + * TNCCS message type + */ + tnccs_msg_type_t type; + + /** + * XML-encoded message node + */ + xmlNodePtr node; + + /** + * Error type + */ + tnccs_error_type_t error_type; + + /** + * Error message + */ + char *error_msg; + + /** + * reference count + */ + refcount_t ref; +}; + +METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t, + private_tnccs_error_msg_t *this) +{ + return this->type; +} + +METHOD(tnccs_msg_t, get_node, xmlNodePtr, + private_tnccs_error_msg_t *this) +{ + return this->node; +} + +METHOD(tnccs_msg_t, get_ref, tnccs_msg_t*, + private_tnccs_error_msg_t *this) +{ + ref_get(&this->ref); + return &this->public.tnccs_msg_interface; +} + +METHOD(tnccs_msg_t, destroy, void, + private_tnccs_error_msg_t *this) +{ + if (ref_put(&this->ref)) + { + free(this->error_msg); + free(this); + } +} + +METHOD(tnccs_error_msg_t, get_message, char*, + private_tnccs_error_msg_t *this, tnccs_error_type_t *type) +{ + *type = this->error_type; + + return this->error_msg; +} + +/** + * See header + */ +tnccs_msg_t *tnccs_error_msg_create_from_node(xmlNodePtr node) +{ + private_tnccs_error_msg_t *this; + xmlChar *error_type_name, *error_msg; + + INIT(this, + .public = { + .tnccs_msg_interface = { + .get_type = _get_type, + .get_node = _get_node, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_message = _get_message, + }, + .type = TNCCS_MSG_ERROR, + .ref = 1, + .node = node, + .error_type = TNCCS_ERROR_OTHER, + ); + + error_type_name = xmlGetProp(node, (const xmlChar*)"type"); + if (error_type_name) + { + this->error_type = enum_from_name(tnccs_error_type_names, + (char*)error_type_name); + if (this->error_type == -1) + { + this->error_type = TNCCS_ERROR_OTHER; + } + xmlFree(error_type_name); + } + + error_msg = xmlNodeGetContent(node); + if (error_msg) + { + this->error_msg = strdup((char*)error_msg); + xmlFree(error_msg); + } + + return &this->public.tnccs_msg_interface; +} + +/** + * See header + */ +tnccs_msg_t *tnccs_error_msg_create(tnccs_error_type_t type, char *msg) +{ + private_tnccs_error_msg_t *this; + xmlNodePtr n, n2; + + INIT(this, + .public = { + .tnccs_msg_interface = { + .get_type = _get_type, + .get_node = _get_node, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .get_message = _get_message, + }, + .type = TNCCS_MSG_ERROR, + .ref = 1, + .node = xmlNewNode(NULL, BAD_CAST "TNCC-TNCS-Message"), + .error_type = type, + .error_msg = strdup(msg), + ); + + DBG1(DBG_TNC, "%s", msg); + + n = xmlNewNode(NULL, BAD_CAST "Type"); + xmlNodeSetContent(n, BAD_CAST "00000002"); + xmlAddChild(this->node, n); + + n = xmlNewNode(NULL, BAD_CAST "XML"); + xmlAddChild(this->node, n); + + n2 = xmlNewNode(NULL, BAD_CAST enum_to_name(tnccs_msg_type_names, this->type)); + xmlNewProp(n2, BAD_CAST "type", + BAD_CAST enum_to_name(tnccs_error_type_names, type)); + xmlNodeSetContent(n2, BAD_CAST msg); + xmlAddChild(n, n2); + + return &this->public.tnccs_msg_interface; +} diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_error_msg.h b/src/libcharon/plugins/tnccs_11/messages/tnccs_error_msg.h new file mode 100644 index 000000000..ce2ce9755 --- /dev/null +++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_error_msg.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2010 Andreas Steffen + * HSR 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 . + * + * 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 tnccs_error_msg tnccs_error_msg + * @{ @ingroup tnccs_11 + */ + +#ifndef TNCCS_ERROR_MSG_H_ +#define TNCCS_ERROR_MSG_H_ + +typedef enum tnccs_error_type_t tnccs_error_type_t; +typedef struct tnccs_error_msg_t tnccs_error_msg_t; + +#include "tnccs_msg.h" + +/** + * TNCCS error types as defined in section 8.1.4 of TCG TNC IF-TNCCS v1.2 + */ +enum tnccs_error_type_t { + TNCCS_ERROR_BATCH_TOO_LONG, + TNCCS_ERROR_MALFORMED_BATCH, + TNCCS_ERROR_INVALID_BATCH_ID, + TNCCS_ERROR_INVALID_RECIPIENT_TYPE, + TNCCS_ERROR_INTERNAL_ERROR, + TNCCS_ERROR_OTHER +}; + +/** + * enum name for tnccs_error_type_t. + */ +extern enum_name_t *tnccs_error_type_names; + +/** + * Class representing the TNCCS-Error message type + */ +struct tnccs_error_msg_t { + + /** + * TNCCS Message interface + */ + tnccs_msg_t tnccs_msg_interface; + + /** + * Get error message and type + * + * @param type TNCCS error type + * @return arbitrary error message + */ + char* (*get_message)(tnccs_error_msg_t *this, tnccs_error_type_t *type); +}; + +/** + * Create a TNCCS-Error message from XML-encoded message node + * + * @param node XML-encoded message node + */ +tnccs_msg_t *tnccs_error_msg_create_from_node(xmlNodePtr node); + +/** + * Create a TNCCS-Error message from parameters + * + * @param type TNCCS error type + * @param msg arbitrary error message + */ +tnccs_msg_t *tnccs_error_msg_create(tnccs_error_type_t type, char *msg); + +#endif /** TNCCS_ERROR_MSG_H_ @}*/ diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_msg.c b/src/libcharon/plugins/tnccs_11/messages/tnccs_msg.c new file mode 100644 index 000000000..5a050393a --- /dev/null +++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_msg.c @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2006 Mike McCauley (mikem@open.com.au) + * Copyright (C) 2010 Andreas Steffen, HSR 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 . + * + * 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 "tnccs_msg.h" +#include "imc_imv_msg.h" +#include "tnccs_error_msg.h" +#include "tnccs_preferred_language_msg.h" +#include "tnccs_reason_strings_msg.h" +#include "tnccs_recommendation_msg.h" +#include "tnccs_tncs_contact_info_msg.h" + +#include +#include + +ENUM(tnccs_msg_type_names, IMC_IMV_MSG, TNCCS_MSG_ROOF, + "IMC-IMV", + "TNCCS-Recommendation", + "TNCCS-Error", + "TNCCS-PreferredLanguage", + "TNCCS-ReasonStrings", + "TNCCS-TNCSContactInfo" +); + +/** + * See header + */ +tnccs_msg_t* tnccs_msg_create_from_node(xmlNodePtr node, linked_list_t *errors) +{ + char *error_msg, buf[BUF_LEN]; + tnccs_error_type_t error_type = TNCCS_ERROR_MALFORMED_BATCH; + tnccs_msg_t *msg; + tnccs_msg_type_t type = IMC_IMV_MSG; + + if (streq((char*)node->name, "IMC-IMV-Message")) + { + DBG2(DBG_TNC, "processing %N message", tnccs_msg_type_names, type); + return imc_imv_msg_create_from_node(node, errors); + } + else if (streq((char*)node->name, "TNCC-TNCS-Message")) + { + bool found = FALSE; + xmlNsPtr ns = node->ns; + xmlNodePtr cur = node->xmlChildrenNode; + xmlNodePtr xml_msg_node = NULL; + + while (cur) + { + if (streq((char*)cur->name, "Type") && cur->ns == ns) + { + xmlChar *content = xmlNodeGetContent(cur); + + type = strtol((char*)content, NULL, 16); + xmlFree(content); + found = TRUE; + } + else if (streq((char*)cur->name, "XML") && cur->ns == ns) + { + xml_msg_node = cur->xmlChildrenNode; + } + cur = cur->next; + } + if (!found) + { + error_msg = "Type is missing in TNCC-TNCS-Message"; + goto fatal; + } + if (!xml_msg_node) + { + error_msg = "XML node is missing in TNCC-TNCS-Message"; + goto fatal; + } + cur = xml_msg_node; + + /* skip empty and blank nodes */ + while (cur && xmlIsBlankNode(cur)) + { + cur = cur->next; + } + if (!cur) + { + error_msg = "XML node is empty"; + goto fatal; + } + + /* check if TNCCS message type and node name agree */ + if (type >= TNCCS_MSG_RECOMMENDATION && type <= TNCCS_MSG_ROOF) + { + DBG2(DBG_TNC, "processing %N message", tnccs_msg_type_names, type); + if (cur->ns != ns) + { + error_msg = "node is not in the TNCCS message namespace"; + goto fatal; + } + if (type != enum_from_name(tnccs_msg_type_names, (char*)cur->name)) + { + error_msg = buf; + snprintf(buf, BUF_LEN, "expected '%N' node but was '%s'", + tnccs_msg_type_names, type, (char*)cur->name); + goto fatal; + } + } + + switch (type) + { + case TNCCS_MSG_RECOMMENDATION: + return tnccs_recommendation_msg_create_from_node(cur, errors); + case TNCCS_MSG_ERROR: + return tnccs_error_msg_create_from_node(cur); + case TNCCS_MSG_PREFERRED_LANGUAGE: + return tnccs_preferred_language_msg_create_from_node(cur, errors); + case TNCCS_MSG_REASON_STRINGS: + return tnccs_reason_strings_msg_create_from_node(cur, errors); + case TNCCS_MSG_TNCS_CONTACT_INFO: + return tnccs_tncs_contact_info_msg_create_from_node(cur, errors); + default: + DBG1(DBG_TNC, "ignoring TNCC-TNCS-Message with type %d", type); + return NULL; + } + } + DBG1(DBG_TNC, "ignoring unknown message node '%s'", (char*)node->name); + return NULL; + +fatal: + msg = tnccs_error_msg_create(error_type, error_msg); + errors->insert_last(errors, msg); + return NULL; +} + diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_msg.h b/src/libcharon/plugins/tnccs_11/messages/tnccs_msg.h new file mode 100644 index 000000000..e0b54449a --- /dev/null +++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_msg.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2010 Andreas Steffen + * HSR 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 . + * + * 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 tnccs_msg tnccs_msg + * @{ @ingroup tnccs_11 + */ + +#ifndef TNCCS_MSG_H_ +#define TNCCS_MSG_H_ + +typedef enum tnccs_msg_type_t tnccs_msg_type_t; +typedef struct tnccs_msg_t tnccs_msg_t; + +#include +#include +#include + +/** + * TNCC-TNCS messages as defined in section 2.8.5 of TCG TNC IF-TNCCS v1.2 + */ +enum tnccs_msg_type_t { + IMC_IMV_MSG = 0, + TNCCS_MSG_RECOMMENDATION = 1, + TNCCS_MSG_ERROR = 2, + TNCCS_MSG_PREFERRED_LANGUAGE = 3, + TNCCS_MSG_REASON_STRINGS = 4, + TNCCS_MSG_TNCS_CONTACT_INFO = 5, + TNCCS_MSG_ROOF = 5 +}; + +/** + * enum name for tnccs_msg_type_t. + */ +extern enum_name_t *tnccs_msg_type_names; + +/** + * Generic interface for all TNCCS message types. + * + * To handle all messages in a generic way, this interface + * must be implemented by each message type. + */ +struct tnccs_msg_t { + + /** + * Get the TNCCS Message Type + * + * @return TNCCS Message Type + */ + tnccs_msg_type_t (*get_type)(tnccs_msg_t *this); + + /** + * Get the XML-encoded Message Node + * + * @return Message Node + */ + xmlNodePtr (*get_node)(tnccs_msg_t *this); + + /** + * Process the TNCCS Message + * + * @return return processing status + */ + status_t (*process)(tnccs_msg_t *this); + + /** + * Get a new reference to the message. + * + * @return this, with an increased refcount + */ + tnccs_msg_t* (*get_ref)(tnccs_msg_t *this); + + /** + * Destroys a tnccs_msg_t object. + */ + void (*destroy)(tnccs_msg_t *this); +}; + +/** + * Create a pre-processed TNCCS message + * + * Useful for the parser which wants a generic constructor for all + * tnccs_msg_t types. + * + * @param node TNCCS message node + * @param errors linked list of TNCCS error messages + */ +tnccs_msg_t* tnccs_msg_create_from_node(xmlNodePtr node, linked_list_t *errors); + +#endif /** TNCCS_MSG_H_ @}*/ diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.c b/src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.c new file mode 100644 index 000000000..fd85350b5 --- /dev/null +++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.c @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2006 Mike McCauley (mikem@open.com.au) + * Copyright (C) 2010 Andreas Steffen, HSR 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 . + * + * 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 "tnccs_preferred_language_msg.h" + +#include + +typedef struct private_tnccs_preferred_language_msg_t private_tnccs_preferred_language_msg_t; + +/** + * Private data of a tnccs_preferred_language_msg_t object. + * + */ +struct private_tnccs_preferred_language_msg_t { + /** + * Public tnccs_preferred_language_msg_t interface. + */ + tnccs_preferred_language_msg_t public; + + /** + * TNCCS message type + */ + tnccs_msg_type_t type; + + /** + * XML-encoded message node + */ + xmlNodePtr node; + + /** + * Preferred language + */ + char *preferred_language; +}; + +METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t, + private_tnccs_preferred_language_msg_t *this) +{ + return this->type; +} + +METHOD(tnccs_msg_t, get_node, xmlNodePtr, + private_tnccs_preferred_language_msg_t *this) +{ + return this->node; +} + +METHOD(tnccs_msg_t, destroy, void, + private_tnccs_preferred_language_msg_t *this) +{ + free(this->preferred_language); + free(this); +} + +METHOD(tnccs_preferred_language_msg_t, get_preferred_language, char*, + private_tnccs_preferred_language_msg_t *this) +{ + return this->preferred_language; +} + +/** + * See header + */ +tnccs_msg_t *tnccs_preferred_language_msg_create_from_node(xmlNodePtr node, + linked_list_t *errors) +{ + private_tnccs_preferred_language_msg_t *this; + xmlChar *language; + + INIT(this, + .public = { + .tnccs_msg_interface = { + .get_type = _get_type, + .get_node = _get_node, + .destroy = _destroy, + }, + .get_preferred_language = _get_preferred_language, + }, + .type = TNCCS_MSG_PREFERRED_LANGUAGE, + .node = node, + ); + + language = xmlNodeGetContent(node); + this->preferred_language = strdup((char*)language); + xmlFree(language); + + return &this->public.tnccs_msg_interface; +} + +/** + * See header + */ +tnccs_msg_t *tnccs_preferred_language_msg_create(char *language) +{ + private_tnccs_preferred_language_msg_t *this; + xmlNodePtr n, n2; + + INIT(this, + .public = { + .tnccs_msg_interface = { + .get_type = _get_type, + .get_node = _get_node, + .destroy = _destroy, + }, + .get_preferred_language = _get_preferred_language, + }, + .type = TNCCS_MSG_PREFERRED_LANGUAGE, + .node = xmlNewNode(NULL, BAD_CAST "TNCC-TNCS-Message"), + .preferred_language = strdup(language), + ); + + /* add the message type number in hex */ + n = xmlNewNode(NULL, BAD_CAST "Type"); + xmlNodeSetContent(n, BAD_CAST "00000003"); + xmlAddChild(this->node, n); + + n = xmlNewNode(NULL, BAD_CAST "XML"); + xmlAddChild(this->node, n); + + n2 = xmlNewNode(NULL, BAD_CAST enum_to_name(tnccs_msg_type_names, this->type)); + xmlNodeSetContent(n2, BAD_CAST language); + xmlAddChild(n, n2); + + return &this->public.tnccs_msg_interface; +} diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.h b/src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.h new file mode 100644 index 000000000..d301ab2bb --- /dev/null +++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_preferred_language_msg.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2010 Andreas Steffen + * HSR 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 . + * + * 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 tnccs_preferred_language_msg tnccs_preferred_language_msg + * @{ @ingroup tnccs_11 + */ + +#ifndef TNCCS_PREFERRED_LANGUAGE_MSG_H_ +#define TNCCS_PREFERRED_LANGUAGE_MSG_H_ + +typedef struct tnccs_preferred_language_msg_t tnccs_preferred_language_msg_t; + +#include "tnccs_msg.h" + +#include + +/** + * Class representing the TNCCS-PreferredLanguage message type + */ +struct tnccs_preferred_language_msg_t { + + /** + * TNCCS Message interface + */ + tnccs_msg_t tnccs_msg_interface; + + /** + * Get preferred language string + * + * @return preferred language string + */ + char* (*get_preferred_language)(tnccs_preferred_language_msg_t *this); +}; + +/** + * Create a TNCCS-PreferredLanguage message from XML-encoded message node + * + * @param node XML-encoded message node + * @param errors linked list of TNCCS error messages + */ +tnccs_msg_t *tnccs_preferred_language_msg_create_from_node(xmlNodePtr node, + linked_list_t *errors); + +/** + * Create a TNCCS-PreferredLanguage message from parameters + * + * @param language preferred language string + */ +tnccs_msg_t *tnccs_preferred_language_msg_create(char *language); + +#endif /** TNCCS_PREFERRED_LANGUAGE_MSG_H_ @}*/ diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.c b/src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.c new file mode 100644 index 000000000..d4b5d9bf9 --- /dev/null +++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.c @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2006 Mike McCauley (mikem@open.com.au) + * Copyright (C) 2010 Andreas Steffen, HSR 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 . + * + * 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 "tnccs_reason_strings_msg.h" + +#include + +typedef struct private_tnccs_reason_strings_msg_t private_tnccs_reason_strings_msg_t; + +/** + * Private data of a tnccs_reason_strings_msg_t object. + * + */ +struct private_tnccs_reason_strings_msg_t { + /** + * Public tnccs_reason_strings_msg_t interface. + */ + tnccs_reason_strings_msg_t public; + + /** + * TNCCS message type + */ + tnccs_msg_type_t type; + + /** + * XML-encoded message node + */ + xmlNodePtr node; + + /** + * Reason String + */ + chunk_t reason; + + /** + * Reason Language + */ + chunk_t language; +}; + +METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t, + private_tnccs_reason_strings_msg_t *this) +{ + return this->type; +} + +METHOD(tnccs_msg_t, get_node, xmlNodePtr, + private_tnccs_reason_strings_msg_t *this) +{ + return this->node; +} + +METHOD(tnccs_msg_t, destroy, void, + private_tnccs_reason_strings_msg_t *this) +{ + free(this->reason.ptr); + free(this->language.ptr); + free(this); +} + +METHOD(tnccs_reason_strings_msg_t, get_reason, chunk_t, + private_tnccs_reason_strings_msg_t *this, chunk_t *language) +{ + *language = this->language; + + return this->reason; +} + +/** + * See header + */ +tnccs_msg_t *tnccs_reason_strings_msg_create_from_node(xmlNodePtr node, + linked_list_t *errors) +{ + private_tnccs_reason_strings_msg_t *this; + + INIT(this, + .public = { + .tnccs_msg_interface = { + .get_type = _get_type, + .get_node = _get_node, + .destroy = _destroy, + }, + .get_reason = _get_reason, + }, + .type = TNCCS_MSG_REASON_STRINGS, + .node = node, + ); + + return &this->public.tnccs_msg_interface; +} + +/** + * See header + */ +tnccs_msg_t *tnccs_reason_strings_msg_create(chunk_t reason, chunk_t language) +{ + private_tnccs_reason_strings_msg_t *this; + xmlNodePtr n, n2, n3; + + INIT(this, + .public = { + .tnccs_msg_interface = { + .get_type = _get_type, + .get_node = _get_node, + .destroy = _destroy, + }, + .get_reason = _get_reason, + }, + .type = TNCCS_MSG_REASON_STRINGS, + .node = xmlNewNode(NULL, BAD_CAST "TNCC-TNCS-Message"), + .reason = chunk_create_clone(malloc(reason.len + 1), reason), + .language = chunk_create_clone(malloc(language.len + 1), language), + ); + + /* add NULL termination for XML string representation */ + this->reason.ptr[this->reason.len] = '\0'; + this->language.ptr[this->language.len] = '\0'; + + /* add the message type number in hex */ + n = xmlNewNode(NULL, BAD_CAST "Type"); + xmlNodeSetContent(n, BAD_CAST "00000004"); + xmlAddChild(this->node, n); + + n = xmlNewNode(NULL, BAD_CAST "XML"); + xmlAddChild(this->node, n); + + n2 = xmlNewNode(NULL, BAD_CAST enum_to_name(tnccs_msg_type_names, this->type)); + + /* could add multiple reasons here, if we had them */ + n3 = xmlNewNode(NULL, BAD_CAST "ReasonString"); + xmlNewProp(n3, BAD_CAST "xml:lang", BAD_CAST this->language.ptr); + xmlNodeSetContent(n3, BAD_CAST this->reason.ptr); + xmlAddChild(n2, n3); + + return &this->public.tnccs_msg_interface; +} diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.h b/src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.h new file mode 100644 index 000000000..0046a5789 --- /dev/null +++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_reason_strings_msg.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2010 Andreas Steffen + * HSR 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 . + * + * 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 tnccs_reason_strings_msg tnccs_reason_strings_msg + * @{ @ingroup tnccs_11 + */ + +#ifndef TNCCS_REASON_STRINGS_MSG_H_ +#define TNCCS_REASON_STRINGS_MSG_H_ + +typedef struct tnccs_reason_strings_msg_t tnccs_reason_strings_msg_t; + +#include "tnccs_msg.h" + +/** + * Class representing the TNCCS-ReasonStrings message type + */ +struct tnccs_reason_strings_msg_t { + + /** + * TNCCS Message interface + */ + tnccs_msg_t tnccs_msg_interface; + + /** + * Get reason string and language + * + * @param language reason language + * @return reason string + */ + chunk_t (*get_reason)(tnccs_reason_strings_msg_t *this, chunk_t *language); +}; + +/** + * Create a TNCCS-ReasonStrings message from XML-encoded message node + * + * @param node XML-encoded message node + * @param errors linked list of TNCCS error messages + */ +tnccs_msg_t *tnccs_reason_strings_msg_create_from_node(xmlNodePtr node, + linked_list_t *errors); + +/** + * Create a TNCCS-ReasonStrings message from parameters + * + * @param reason reason string + * @param language reason language + */ +tnccs_msg_t *tnccs_reason_strings_msg_create(chunk_t reason, chunk_t language); + +#endif /** TNCCS_REASON_STRINGS_MSG_H_ @}*/ diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.c b/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.c new file mode 100644 index 000000000..adc7b54b9 --- /dev/null +++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.c @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2006 Mike McCauley (mikem@open.com.au) + * Copyright (C) 2010 Andreas Steffen, HSR 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 . + * + * 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 "tnccs_recommendation_msg.h" +#include "tnccs_error_msg.h" + +#include + +typedef struct private_tnccs_recommendation_msg_t private_tnccs_recommendation_msg_t; + +/** + * Private data of a tnccs_recommendation_msg_t object. + * + */ +struct private_tnccs_recommendation_msg_t { + /** + * Public tnccs_recommendation_msg_t interface. + */ + tnccs_recommendation_msg_t public; + + /** + * TNCCS message type + */ + tnccs_msg_type_t type; + + /** + * XML-encoded message node + */ + xmlNodePtr node; + + /** + * Action Recommendation + */ + TNC_IMV_Action_Recommendation rec; +}; + +METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t, + private_tnccs_recommendation_msg_t *this) +{ + return this->type; +} + +METHOD(tnccs_msg_t, get_node, xmlNodePtr, + private_tnccs_recommendation_msg_t *this) +{ + return this->node; +} + +METHOD(tnccs_msg_t, destroy, void, + private_tnccs_recommendation_msg_t *this) +{ + free(this); +} + +METHOD(tnccs_recommendation_msg_t, get_recommendation, TNC_IMV_Action_Recommendation, + private_tnccs_recommendation_msg_t *this) +{ + return this->rec; +} + +/** + * See header + */ +tnccs_msg_t *tnccs_recommendation_msg_create_from_node(xmlNodePtr node, + linked_list_t *errors) +{ + private_tnccs_recommendation_msg_t *this; + xmlChar *rec_string; + char *error_msg, buf[BUF_LEN]; + tnccs_error_type_t error_type = TNCCS_ERROR_MALFORMED_BATCH; + tnccs_msg_t *msg; + + INIT(this, + .public = { + .tnccs_msg_interface = { + .get_type = _get_type, + .get_node = _get_node, + .destroy = _destroy, + }, + .get_recommendation = _get_recommendation, + }, + .type = TNCCS_MSG_RECOMMENDATION, + .node = node, + ); + + rec_string = xmlGetProp(node, (const xmlChar*)"type"); + if (!rec_string) + { + error_msg = "type property in TNCCS-Recommendation is missing"; + goto fatal; + } + else if (streq((char*)rec_string, "allow")) + { + this->rec = TNC_IMV_ACTION_RECOMMENDATION_ALLOW; + } + else if (streq((char*)rec_string, "isolate")) + { + this->rec = TNC_IMV_ACTION_RECOMMENDATION_ISOLATE; + } + else if (streq((char*)rec_string, "none")) + { + this->rec = TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS; + } + else + { + error_msg = buf; + snprintf(buf, BUF_LEN, "unsupported type property value '%s' " + "in TNCCS-Recommendation", rec_string); + xmlFree(rec_string); + goto fatal; + } + xmlFree(rec_string); + + return &this->public.tnccs_msg_interface; + +fatal: + msg = tnccs_error_msg_create(error_type, error_msg); + errors->insert_last(errors, msg); + _destroy(this); + return NULL; +} + +/** + * See header + */ +tnccs_msg_t *tnccs_recommendation_msg_create(TNC_IMV_Action_Recommendation rec) +{ + private_tnccs_recommendation_msg_t *this; + xmlNodePtr n, n2; + char *rec_string; + + INIT(this, + .public = { + .tnccs_msg_interface = { + .get_type = _get_type, + .get_node = _get_node, + .destroy = _destroy, + }, + .get_recommendation = _get_recommendation, + }, + .type = TNCCS_MSG_RECOMMENDATION, + .node = xmlNewNode(NULL, BAD_CAST "TNCC-TNCS-Message"), + .rec = rec, + ); + + /* add the message type number in hex */ + n = xmlNewNode(NULL, BAD_CAST "Type"); + xmlNodeSetContent(n, BAD_CAST "00000001"); + xmlAddChild(this->node, n); + + n = xmlNewNode(NULL, BAD_CAST "XML"); + xmlAddChild(this->node, n); + + switch (rec) + { + case TNC_IMV_ACTION_RECOMMENDATION_ALLOW: + rec_string = "allow"; + break; + case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE: + rec_string = "isolate"; + break; + case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS: + case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION: + default: + rec_string = "none"; + } + + n2 = xmlNewNode(NULL, BAD_CAST enum_to_name(tnccs_msg_type_names, this->type)); + xmlNewProp(n2, BAD_CAST "type", BAD_CAST rec_string); + xmlNodeSetContent(n2, ""); + xmlAddChild(n, n2); + + return &this->public.tnccs_msg_interface; +} diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.h b/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.h new file mode 100644 index 000000000..685049e95 --- /dev/null +++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_recommendation_msg.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2010 Andreas Steffen + * HSR 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 . + * + * 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 tnccs_recommendation_msg tnccs_recommendation_msg + * @{ @ingroup tnccs_11 + */ + +#ifndef TNCCS_RECOMMENDATION_MSG_H_ +#define TNCCS_RECOMMENDATION_MSG_H_ + +typedef struct tnccs_recommendation_msg_t tnccs_recommendation_msg_t; + +#include "tnccs_msg.h" + +#include + +/** + * Class representing the TNCCS-Recommendation message type + */ +struct tnccs_recommendation_msg_t { + + /** + * TNCCS Message interface + */ + tnccs_msg_t tnccs_msg_interface; + + /** + * Get Action Recommendation + * + * @return Action Recommendation + */ + TNC_IMV_Action_Recommendation (*get_recommendation)(tnccs_recommendation_msg_t *this); +}; + +/** + * Create a TNCCS-Recommendation message from XML-encoded message node + * + * @param node XML-encoded message node + * @param errors linked list of TNCCS error messages + */ +tnccs_msg_t *tnccs_recommendation_msg_create_from_node(xmlNodePtr node, + linked_list_t *errors); + +/** + * Create a TNCCS-Recommendation message from parameters + * + * @param rec Action Recommendation + */ +tnccs_msg_t *tnccs_recommendation_msg_create(TNC_IMV_Action_Recommendation rec); + +#endif /** TNCCS_RECOMMENDATION_MSG_H_ @}*/ diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_tncs_contact_info_msg.c b/src/libcharon/plugins/tnccs_11/messages/tnccs_tncs_contact_info_msg.c new file mode 100644 index 000000000..b8aac30fa --- /dev/null +++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_tncs_contact_info_msg.c @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2010 Andreas Steffen, HSR 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 . + * + * 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 "tnccs_tncs_contact_info_msg.h" + +#include + +typedef struct private_tnccs_tncs_contact_info_msg_t private_tnccs_tncs_contact_info_msg_t; + +/** + * Private data of a tnccs_tncs_contact_info_msg_t object. + * + */ +struct private_tnccs_tncs_contact_info_msg_t { + /** + * Public tnccs_tncs_contact_info_msg_t interface. + */ + tnccs_tncs_contact_info_msg_t public; + + /** + * TNCCS message type + */ + tnccs_msg_type_t type; + + /** + * XML-encoded message node + */ + xmlNodePtr node; +}; + +METHOD(tnccs_msg_t, get_type, tnccs_msg_type_t, + private_tnccs_tncs_contact_info_msg_t *this) +{ + return this->type; +} + +METHOD(tnccs_msg_t, get_node, xmlNodePtr, + private_tnccs_tncs_contact_info_msg_t *this) +{ + return this->node; +} + +METHOD(tnccs_msg_t, destroy, void, + private_tnccs_tncs_contact_info_msg_t *this) +{ + free(this); +} + +/** + * See header + */ +tnccs_msg_t *tnccs_tncs_contact_info_msg_create_from_node(xmlNodePtr node, + linked_list_t *errors) +{ + private_tnccs_tncs_contact_info_msg_t *this; + + INIT(this, + .public = { + .tnccs_msg_interface = { + .get_type = _get_type, + .get_node = _get_node, + .destroy = _destroy, + }, + }, + .type = TNCCS_MSG_TNCS_CONTACT_INFO, + .node = node, + ); + + return &this->public.tnccs_msg_interface; +} + +/** + * See header + */ +tnccs_msg_t *tnccs_tncs_contact_info_msg_create(void) +{ + private_tnccs_tncs_contact_info_msg_t *this; + xmlNodePtr n /*, n2 */; + + INIT(this, + .public = { + .tnccs_msg_interface = { + .get_type = _get_type, + .get_node = _get_node, + .destroy = _destroy, + }, + }, + .type = TNCCS_MSG_TNCS_CONTACT_INFO, + .node = xmlNewNode(NULL, BAD_CAST "TNCC-TNCS-Message"), + ); + + /* add the message type number in hex */ + n = xmlNewNode(NULL, BAD_CAST "Type"); + xmlNodeSetContent(n, BAD_CAST "00000005"); + xmlAddChild(this->node, n); + + n = xmlNewNode(NULL, BAD_CAST "XML"); + xmlAddChild(this->node, n); + +/* TODO + n2 = xmlNewNode(NULL, BAD_CAST enum_to_name(tnccs_msg_type_names, this->type)); + xmlNodeSetContent(n2, BAD_CAST language); + xmlAddChild(n, n2); +*/ + + return &this->public.tnccs_msg_interface; +} diff --git a/src/libcharon/plugins/tnccs_11/messages/tnccs_tncs_contact_info_msg.h b/src/libcharon/plugins/tnccs_11/messages/tnccs_tncs_contact_info_msg.h new file mode 100644 index 000000000..8ed210a57 --- /dev/null +++ b/src/libcharon/plugins/tnccs_11/messages/tnccs_tncs_contact_info_msg.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2010 Andreas Steffen + * HSR 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 . + * + * 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 tnccs_tncs_contact_info_msg tnccs_tncs_contact_info_msg + * @{ @ingroup tnccs_11 + */ + +#ifndef TNCCS_TNCS_CONTACT_INFO_MSG_H_ +#define TNCCS_TNCS_CONTACT_INFO_MSG_H_ + +typedef struct tnccs_tncs_contact_info_msg_t tnccs_tncs_contact_info_msg_t; + +#include "tnccs_msg.h" + +/** + * Class representing the TNCCS-TNCSContactInfo message type + */ +struct tnccs_tncs_contact_info_msg_t { + + /** + * TNCCS Message interface + */ + tnccs_msg_t tnccs_msg_interface; +}; + +/** + * Create a TNCCS-TNCSContactInfo message from XML-encoded message node + * + * @param node XML-encoded message node + * @param errors linked list of TNCCS error messages + */ +tnccs_msg_t *tnccs_tncs_contact_info_msg_create_from_node(xmlNodePtr node, + linked_list_t *errors); + +/** + * Create a TNCCS-TNCSContactInfo message from parameters + * + */ +tnccs_msg_t *tnccs_tncs_contact_info_msg_create(void); + +#endif /** TNCCS_TNCS_CONTACT_INFO_MSG_H_ @}*/ diff --git a/src/libcharon/plugins/tnccs_11/tnccs_11.c b/src/libcharon/plugins/tnccs_11/tnccs_11.c index 704bf64ed..2104bf401 100644 --- a/src/libcharon/plugins/tnccs_11/tnccs_11.c +++ b/src/libcharon/plugins/tnccs_11/tnccs_11.c @@ -14,81 +14,20 @@ */ #include "tnccs_11.h" - -#include -#include +#include "batch/tnccs_batch.h" +#include "messages/tnccs_msg.h" +#include "messages/imc_imv_msg.h" +#include "messages/tnccs_error_msg.h" +#include "messages/tnccs_preferred_language_msg.h" +#include "messages/tnccs_reason_strings_msg.h" +#include "messages/tnccs_recommendation_msg.h" #include #include - -#define TNC_SEND_BUFFER_SIZE 32 - -static chunk_t tnc_send_buffer[TNC_SEND_BUFFER_SIZE]; - -/** - * Buffers TNCCS batch to be sent (TODO make the buffer scalable) - */ -static TNC_Result buffer_batch(u_int32_t id, const char *data, size_t len) -{ - if (id >= TNC_SEND_BUFFER_SIZE) - { - DBG1(DBG_TNC, "TNCCS Batch for Connection ID %u cannot be stored in " - "send buffer with size %d", id, TNC_SEND_BUFFER_SIZE); - return TNC_RESULT_FATAL; - } - if (tnc_send_buffer[id].ptr) - { - DBG1(DBG_TNC, "send buffer slot for Connection ID %u is already " - "occupied", id); - return TNC_RESULT_FATAL; - } - tnc_send_buffer[id] = chunk_alloc(len); - memcpy(tnc_send_buffer[id].ptr, data, len); - - return TNC_RESULT_SUCCESS; -} - -/** - * Retrieves TNCCS batch to be sent - */ -static bool retrieve_batch(u_int32_t id, chunk_t *batch) -{ - if (id >= TNC_SEND_BUFFER_SIZE) - { - DBG1(DBG_TNC, "TNCCS Batch for Connection ID %u cannot be retrieved from " - "send buffer with size %d", id, TNC_SEND_BUFFER_SIZE); - return FALSE; - } - - *batch = tnc_send_buffer[id]; - return TRUE; -} - -/** - * Frees TNCCS batch that was sent - */ -static void free_batch(u_int32_t id) -{ - if (id < TNC_SEND_BUFFER_SIZE) - { - chunk_free(&tnc_send_buffer[id]); - } -} - -/** - * Define callback functions called by the libtnc library - */ -TNC_Result TNC_TNCC_SendBatch(libtnc_tncc_connection* conn, - const char* messageBuffer, size_t messageLength) -{ - return buffer_batch(conn->connectionID, messageBuffer, messageLength); -} - -TNC_Result TNC_TNCS_SendBatch(libtnc_tncs_connection* conn, - const char* messageBuffer, size_t messageLength) -{ - return buffer_batch(conn->connectionID, messageBuffer, messageLength); -} +#include +#include +#include +#include typedef struct private_tnccs_11_t private_tnccs_11_t; @@ -108,116 +47,372 @@ struct private_tnccs_11_t { bool is_server; /** - * TNCC Connection to IMCs + * Connection ID assigned to this TNCCS connection + */ + TNC_ConnectionID connection_id; + + /** + * Last TNCCS batch ID + */ + int batch_id; + + /** + * TNCCS batch being constructed + */ + tnccs_batch_t *batch; + + /** + * Mutex locking the batch in construction */ - libtnc_tncc_connection* tncc_connection; + mutex_t *mutex; /** - * TNCS Connection to IMVs + * Flag set while processing */ - libtnc_tncs_connection* tncs_connection; + bool fatal_error; + + /** + * Flag set by TNCCS-Recommendation message + */ + bool delete_state; + + /** + * Flag set by IMC/IMV RequestHandshakeRetry() function + */ + bool request_handshake_retry; + + /** + * Set of IMV recommendations (TNC Server only) + */ + recommendations_t *recs; }; -METHOD(tls_t, process, status_t, - private_tnccs_11_t *this, void *buf, size_t buflen) +METHOD(tnccs_t, send_msg, void, + private_tnccs_11_t* this, TNC_IMCID imc_id, TNC_IMVID imv_id, + TNC_BufferReference msg, + TNC_UInt32 msg_len, + TNC_MessageType msg_type) { - u_int32_t conn_id; + tnccs_msg_t *tnccs_msg; - if (this->is_server && !this->tncs_connection) + tnccs_msg = imc_imv_msg_create(msg_type, chunk_create(msg, msg_len)); + + /* adding an IMC-IMV Message to TNCCS batch */ + this->mutex->lock(this->mutex); + if (!this->batch) { - this->tncs_connection = libtnc_tncs_CreateConnection(NULL); - if (!this->tncs_connection) + this->batch = tnccs_batch_create(this->is_server, ++this->batch_id); + } + this->batch->add_msg(this->batch, tnccs_msg); + this->mutex->unlock(this->mutex); +} + +/** + * Handle a single TNCCS message according to its type + */ +static void handle_message(private_tnccs_11_t *this, tnccs_msg_t *msg) +{ + switch (msg->get_type(msg)) + { + case IMC_IMV_MSG: { - DBG1(DBG_TNC, "TNCS CreateConnection failed"); - return FAILED; + imc_imv_msg_t *imc_imv_msg; + TNC_MessageType msg_type; + chunk_t msg_body; + + imc_imv_msg = (imc_imv_msg_t*)msg; + msg_type = imc_imv_msg->get_msg_type(imc_imv_msg); + msg_body = imc_imv_msg->get_msg_body(imc_imv_msg); + + DBG2(DBG_TNC, "handling IMC_IMV message type 0x%08x", msg_type); + + if (this->is_server) + { + charon->imvs->receive_message(charon->imvs, + this->connection_id, msg_body.ptr, msg_body.len, msg_type); + } + else + { + charon->imcs->receive_message(charon->imcs, + this->connection_id, msg_body.ptr, msg_body.len,msg_type); + } + break; + } + case TNCCS_MSG_RECOMMENDATION: + { + tnccs_recommendation_msg_t *rec_msg; + TNC_IMV_Action_Recommendation rec; + TNC_ConnectionState state = TNC_CONNECTION_STATE_ACCESS_NONE; + + rec_msg = (tnccs_recommendation_msg_t*)msg; + rec = rec_msg->get_recommendation(rec_msg); + if (this->is_server) + { + DBG1(DBG_TNC, "ignoring NCCS-Recommendation message from " + " TNC client"); + break; + } + DBG1(DBG_TNC, "TNC recommendation is '%N'", + TNC_IMV_Action_Recommendation_names, rec); + switch (rec) + { + case TNC_IMV_ACTION_RECOMMENDATION_ALLOW: + state = TNC_CONNECTION_STATE_ACCESS_ALLOWED; + break; + case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE: + state = TNC_CONNECTION_STATE_ACCESS_ISOLATED; + break; + case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS: + default: + state = TNC_CONNECTION_STATE_ACCESS_NONE; + } + charon->imcs->notify_connection_change(charon->imcs, + this->connection_id, state); + this->delete_state = TRUE; + break; + } + case TNCCS_MSG_ERROR: + { + tnccs_error_msg_t *err_msg; + tnccs_error_type_t error_type; + char *error_msg; + + err_msg = (tnccs_error_msg_t*)msg; + error_msg = err_msg->get_message(err_msg, &error_type); + DBG1(DBG_TNC, "received '%N' TNCCS-Error: %s", + tnccs_error_type_names, error_type, error_msg); + + /* we assume that all errors are fatal */ + this->fatal_error = TRUE; + break; } - DBG1(DBG_TNC, "assigned TNCS Connection ID %u", - this->tncs_connection->connectionID); - if (libtnc_tncs_BeginSession(this->tncs_connection) != TNC_RESULT_SUCCESS) + case TNCCS_MSG_PREFERRED_LANGUAGE: + { + tnccs_preferred_language_msg_t *lang_msg; + char *lang; + + lang_msg = (tnccs_preferred_language_msg_t*)msg; + lang = lang_msg->get_preferred_language(lang_msg); + + DBG2(DBG_TNC, "setting preferred language to '%s'", lang); + this->recs->set_preferred_language(this->recs, + chunk_create(lang, strlen(lang))); + break; + } + case TNCCS_MSG_REASON_STRINGS: + { + tnccs_reason_strings_msg_t *reason_msg; + chunk_t reason_string, reason_lang; + + reason_msg = (tnccs_reason_strings_msg_t*)msg; + reason_string = reason_msg->get_reason(reason_msg, &reason_lang); + DBG2(DBG_TNC, "reason string is '%.*s", reason_string.len, + reason_string.ptr); + DBG2(DBG_TNC, "reason language is '%.*s", reason_lang.len, + reason_lang.ptr); + break; + } + default: + break; + } +} + +METHOD(tls_t, process, status_t, + private_tnccs_11_t *this, void *buf, size_t buflen) +{ + chunk_t data; + tnccs_batch_t *batch; + tnccs_msg_t *msg; + enumerator_t *enumerator; + status_t status; + + if (this->is_server && !this->connection_id) + { + this->connection_id = charon->tnccs->create_connection(charon->tnccs, + (tnccs_t*)this, _send_msg, + &this->request_handshake_retry, &this->recs); + if (!this->connection_id) { - DBG1(DBG_TNC, "TNCS BeginSession failed"); return FAILED; } + charon->imvs->notify_connection_change(charon->imvs, + this->connection_id, TNC_CONNECTION_STATE_CREATE); } - conn_id = this->is_server ? this->tncs_connection->connectionID - : this->tncc_connection->connectionID; + data = chunk_create(buf, buflen); DBG1(DBG_TNC, "received TNCCS Batch (%u bytes) for Connection ID %u", - buflen, conn_id); - DBG3(DBG_TNC, "%.*s", buflen, buf); + data.len, this->connection_id); + DBG3(DBG_TNC, "%.*s", data.len, data.ptr); + batch = tnccs_batch_create_from_data(this->is_server, ++this->batch_id, data); + status = batch->process(batch); - if (this->is_server) + if (status == FAILED) { - if (libtnc_tncs_ReceiveBatch(this->tncs_connection, buf, buflen) != - TNC_RESULT_SUCCESS) + this->fatal_error = TRUE; + this->mutex->lock(this->mutex); + if (this->batch) { - DBG1(DBG_TNC, "TNCS ReceiveBatch failed"); - return FAILED; + DBG1(DBG_TNC, "cancelling TNCCS batch"); + this->batch->destroy(this->batch); + this->batch_id--; + } + this->batch = tnccs_batch_create(this->is_server, ++this->batch_id); + + /* add error messages to outbound batch */ + enumerator = batch->create_error_enumerator(batch); + while (enumerator->enumerate(enumerator, &msg)) + { + this->batch->add_msg(this->batch, msg->get_ref(msg)); } + enumerator->destroy(enumerator); + this->mutex->unlock(this->mutex); } else { - if (libtnc_tncc_ReceiveBatch(this->tncc_connection, buf, buflen) != - TNC_RESULT_SUCCESS) + enumerator = batch->create_msg_enumerator(batch); + while (enumerator->enumerate(enumerator, &msg)) { - DBG1(DBG_TNC, "TNCC ReceiveBatch failed"); + handle_message(this, msg); + } + enumerator->destroy(enumerator); + + /* received any TNCCS-Error messages */ + if (this->fatal_error) + { + DBG1(DBG_TNC, "a fatal TNCCS-Error occurred, terminating connection"); + batch->destroy(batch); return FAILED; } + + if (this->is_server) + { + charon->imvs->batch_ending(charon->imvs, this->connection_id); + } + else + { + charon->imcs->batch_ending(charon->imcs, this->connection_id); + } } + batch->destroy(batch); + return NEED_MORE; } -METHOD(tls_t, build, status_t, - private_tnccs_11_t *this, void *buf, size_t *buflen, size_t *msglen) +/** + * Add a recommendation message if a final recommendation is available + */ +static void check_and_build_recommendation(private_tnccs_11_t *this) { - chunk_t batch; - u_int32_t conn_id; - size_t len; + TNC_IMV_Action_Recommendation rec; + TNC_IMV_Evaluation_Result eval; + TNC_IMVID id; + chunk_t reason, language; + enumerator_t *enumerator; + tnccs_msg_t *msg; - if (!this->is_server && !this->tncc_connection) + if (!this->recs->have_recommendation(this->recs, &rec, &eval)) + { + charon->imvs->solicit_recommendation(charon->imvs, this->connection_id); + } + if (this->recs->have_recommendation(this->recs, &rec, &eval)) { - this->tncc_connection = libtnc_tncc_CreateConnection(NULL); - if (!this->tncc_connection) + if (!this->batch) { - DBG1(DBG_TNC, "TNCC CreateConnection failed"); - return FAILED; + this->batch = tnccs_batch_create(this->is_server, ++this->batch_id); } - DBG1(DBG_TNC, "assigned TNCC Connection ID %u", - this->tncc_connection->connectionID); - if (libtnc_tncc_BeginSession(this->tncc_connection) != TNC_RESULT_SUCCESS) + + msg = tnccs_recommendation_msg_create(rec); + this->batch->add_msg(this->batch, msg); + + /* currently we just send the first Reason String */ + enumerator = this->recs->create_reason_enumerator(this->recs); + if (enumerator->enumerate(enumerator, &id, &reason, &language)) { - DBG1(DBG_TNC, "TNCC BeginSession failed"); - return FAILED; + msg = tnccs_reason_strings_msg_create(reason, language); + this->batch->add_msg(this->batch, msg); } + enumerator->destroy(enumerator); + + /* we have reache the final state */ + this->delete_state = TRUE; } - conn_id = this->is_server ? this->tncs_connection->connectionID - : this->tncc_connection->connectionID; - - if (!retrieve_batch(conn_id, &batch)) +} + +METHOD(tls_t, build, status_t, + private_tnccs_11_t *this, void *buf, size_t *buflen, size_t *msglen) +{ + status_t status; + + /* Initialize the connection */ + if (!this->is_server && !this->connection_id) { - return FAILED; + tnccs_msg_t *msg; + char *pref_lang; + + this->connection_id = charon->tnccs->create_connection(charon->tnccs, + (tnccs_t*)this, _send_msg, + &this->request_handshake_retry, NULL); + if (!this->connection_id) + { + return FAILED; + } + + /* Create TNCCS-PreferredLanguage message */ + pref_lang = charon->imcs->get_preferred_language(charon->imcs); + msg = tnccs_preferred_language_msg_create(pref_lang); + this->mutex->lock(this->mutex); + this->batch = tnccs_batch_create(this->is_server, ++this->batch_id); + this->batch->add_msg(this->batch, msg); + this->mutex->unlock(this->mutex); + + charon->imcs->notify_connection_change(charon->imcs, + this->connection_id, TNC_CONNECTION_STATE_CREATE); + charon->imcs->notify_connection_change(charon->imcs, + this->connection_id, TNC_CONNECTION_STATE_HANDSHAKE); + charon->imcs->begin_handshake(charon->imcs, this->connection_id); } - len = *buflen; - len = min(len, batch.len); - *buflen = len; - if (msglen) + + /* Do not allow any asynchronous IMCs or IMVs to add additional messages */ + this->mutex->lock(this->mutex); + + if (this->is_server && !this->delete_state && + (!this->batch || this->fatal_error)) { - *msglen = batch.len; + check_and_build_recommendation(this); } - if (batch.len) + if (this->batch) { + chunk_t data; + + this->batch->build(this->batch); + data = this->batch->get_encoding(this->batch); DBG1(DBG_TNC, "sending TNCCS Batch (%d bytes) for Connection ID %u", - batch.len, conn_id); - DBG3(DBG_TNC, "%.*s", batch.len, batch.ptr); - memcpy(buf, batch.ptr, len); - free_batch(conn_id); - return ALREADY_DONE; + data.len, this->connection_id); + DBG3(DBG_TNC, "%.*s", data.len, data.ptr); + *msglen = data.len; + + if (data.len > *buflen) + { + DBG1(DBG_TNC, "fragmentation of TNCCS batch not supported yet"); + } + else + { + *buflen = data.len; + } + memcpy(buf, data.ptr, *buflen); + this->batch->destroy(this->batch); + this->batch = NULL; + status = ALREADY_DONE; } else { - return INVALID_STATE; + DBG1(DBG_TNC, "no TNCCS Batch to send"); + status = INVALID_STATE; } + this->mutex->unlock(this->mutex); + + return status; } METHOD(tls_t, is_server, bool, @@ -237,39 +432,14 @@ METHOD(tls_t, is_complete, bool, { TNC_IMV_Action_Recommendation rec; TNC_IMV_Evaluation_Result eval; - char *group; - identification_t *id; - ike_sa_t *ike_sa; - auth_cfg_t *auth; - - if (libtnc_tncs_HaveRecommendation(this->tncs_connection, &rec, &eval) == - TNC_RESULT_SUCCESS) + + if (this->recs && this->recs->have_recommendation(this->recs, &rec, &eval)) { - switch (rec) - { - case TNC_IMV_ACTION_RECOMMENDATION_ALLOW: - DBG1(DBG_TNC, "TNC recommendation is allow"); - group = "allow"; - break; - case TNC_IMV_ACTION_RECOMMENDATION_ISOLATE: - DBG1(DBG_TNC, "TNC recommendation is isolate"); - group = "isolate"; - break; - case TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS: - case TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION: - default: - DBG1(DBG_TNC, "TNC recommendation is none"); - return FALSE; - } - ike_sa = charon->bus->get_sa(charon->bus); - if (ike_sa) - { - auth = ike_sa->get_auth_cfg(ike_sa, FALSE); - id = identification_create_from_string(group); - auth->add(auth, AUTH_RULE_GROUP, id); - DBG1(DBG_TNC, "added group membership '%s' based on TNC recommendation", group); - } - return TRUE; + DBG2(DBG_TNC, "Final recommendation is '%N' and evaluation is '%N'", + TNC_IMV_Action_Recommendation_names, rec, + TNC_IMV_Evaluation_Result_names, eval); + + return charon->imvs->enforce_recommendation(charon->imvs, rec); } else { @@ -288,19 +458,17 @@ METHOD(tls_t, destroy, void, { if (this->is_server) { - if (this->tncs_connection) - { - libtnc_tncs_DeleteConnection(this->tncs_connection); - } + charon->imvs->notify_connection_change(charon->imvs, + this->connection_id, TNC_CONNECTION_STATE_DELETE); } else { - if (this->tncc_connection) - { - libtnc_tncc_DeleteConnection(this->tncc_connection); - } - libtnc_tncc_Terminate(); + charon->imcs->notify_connection_change(charon->imcs, + this->connection_id, TNC_CONNECTION_STATE_DELETE); } + charon->tnccs->remove_connection(charon->tnccs, this->connection_id); + this->mutex->destroy(this->mutex); + DESTROY_IF(this->batch); free(this); } @@ -322,6 +490,7 @@ tls_t *tnccs_11_create(bool is_server) .destroy = _destroy, }, .is_server = is_server, + .mutex = mutex_create(MUTEX_TYPE_DEFAULT), ); return &this->public; -- cgit v1.2.3