From: Arran Cudbard-Bell Date: Sat, 9 Mar 2013 03:56:32 +0000 (-0500) Subject: Rewrite eap-tnc to work with tnch@fhh libraries X-Git-Tag: release_3_0_0_beta1~777 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=529b3fed6964969820b83f4e1501520231af7b3f;p=thirdparty%2Ffreeradius-server.git Rewrite eap-tnc to work with tnch@fhh libraries Original patch by Avesh Agarwal --- diff --git a/src/modules/rlm_eap/types/rlm_eap_tnc/all.mk.in b/src/modules/rlm_eap/types/rlm_eap_tnc/all.mk.in index ab93608b5bd..9ba45133b7f 100644 --- a/src/modules/rlm_eap/types/rlm_eap_tnc/all.mk.in +++ b/src/modules/rlm_eap/types/rlm_eap_tnc/all.mk.in @@ -4,11 +4,10 @@ ifneq "$(TARGETNAME)" "" TARGET := $(TARGETNAME).a endif -SOURCES := $(TARGETNAME).c eap_tnc.c tncs_connect.c +SOURCES := $(TARGETNAME).c SRC_CFLAGS := @eap_tnc_cflags@ TGT_LDLIBS := @eap_tnc_ldflags@ -TGT_LDLIBS += $(OPENSSL_LIBS) SRC_INCDIRS := ../../ ../../libeap/ TGT_PREREQS := libfreeradius-eap.a diff --git a/src/modules/rlm_eap/types/rlm_eap_tnc/configure b/src/modules/rlm_eap/types/rlm_eap_tnc/configure index 7d4fcf1e1eb..f141f100647 100755 --- a/src/modules/rlm_eap/types/rlm_eap_tnc/configure +++ b/src/modules/rlm_eap/types/rlm_eap_tnc/configure @@ -1839,18 +1839,6 @@ if test "${with_eap_tnc_dir+set}" = set; then : fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenSSL support" >&5 -$as_echo_n "checking for OpenSSL support... " >&6; } - if test "x$OPENSSL_LIBS" != "x"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fail="OpenSSL" - fi - smart_try_dir="$eap_tnc_include_dir" ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -2644,20 +2632,20 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu -ac_safe=`echo "libtnc.h" | sed 'y%./+-%__pm%'` +ac_safe=`echo "naaeap/naaeap.h" | sed 'y%./+-%__pm%'` old_CFLAGS="$CFLAGS" smart_include= smart_include_dir= if test "x$smart_try_dir" != "x"; then for try in $smart_try_dir; do - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libtnc.h in $try" >&5 -$as_echo_n "checking for libtnc.h in $try... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for naaeap/naaeap.h in $try" >&5 +$as_echo_n "checking for naaeap/naaeap.h in $try... " >&6; } CFLAGS="$old_CFLAGS -I$try" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - #include + #include int main () { @@ -2686,12 +2674,12 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x$smart_include" = "x"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libtnc.h" >&5 -$as_echo_n "checking for libtnc.h... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for naaeap/naaeap.h" >&5 +$as_echo_n "checking for naaeap/naaeap.h... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - #include + #include int main () { @@ -2722,7 +2710,7 @@ if test "x$smart_include" = "x"; then if test "x$LOCATE" != "x"; then DIRS= - file=libtnc.h + file=naaeap/naaeap.h for x in `${LOCATE} $file 2>/dev/null`; do base=`echo $x | sed "s%/${file}%%"` @@ -2746,13 +2734,13 @@ fi eval "smart_include_dir=\"\$smart_include_dir $DIRS\"" for try in $smart_include_dir /usr/local/include /opt/include; do - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libtnc.h in $try" >&5 -$as_echo_n "checking for libtnc.h in $try... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for naaeap/naaeap.h in $try" >&5 +$as_echo_n "checking for naaeap/naaeap.h in $try... " >&6; } CFLAGS="$old_CFLAGS -I$try" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - #include + #include int main () { @@ -2786,17 +2774,16 @@ if test "x$smart_include" != "x"; then SMART_CFLAGS="$SMART_CFLAGS $smart_include" fi - if test "x$ac_cv_header_libtnc_h" != "xyes"; then - fail="$fail libtnc.h" + if test "x$ac_cv_header_naaeap_naaeap_h" != "xyes"; then + fail="$fail naaeap.h" fi - LIBS="${OPENSSL_LIBS}" smart_try_dir="$eap_tnc_lib_dir" -sm_lib_safe=`echo "tnc" | sed 'y%./+-%__p_%'` -sm_func_safe=`echo "exchangeTNCCSMessages" | sed 'y%./+-%__p_%'` +sm_lib_safe=`echo "naaeap" | sed 'y%./+-%__p_%'` +sm_func_safe=`echo "processEAPTNCData" | sed 'y%./+-%__p_%'` old_LIBS="$LIBS" smart_lib= @@ -2804,23 +2791,23 @@ smart_lib_dir= if test "x$smart_try_dir" != "x"; then for try in $smart_try_dir; do - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for exchangeTNCCSMessages in -ltnc in $try" >&5 -$as_echo_n "checking for exchangeTNCCSMessages in -ltnc in $try... " >&6; } - LIBS="-L$try -ltnc $old_LIBS -Wl,-rpath,$try" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for processEAPTNCData in -lnaaeap in $try" >&5 +$as_echo_n "checking for processEAPTNCData in -lnaaeap in $try... " >&6; } + LIBS="-L$try -lnaaeap $old_LIBS -Wl,-rpath,$try" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -extern char exchangeTNCCSMessages(); +extern char processEAPTNCData(); int main () { -exchangeTNCCSMessages() +processEAPTNCData() ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - smart_lib="-L$try -ltnc -Wl,-rpath,$try" + smart_lib="-L$try -lnaaeap -Wl,-rpath,$try" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } break @@ -2836,23 +2823,23 @@ rm -f core conftest.err conftest.$ac_objext \ fi if test "x$smart_lib" = "x"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for exchangeTNCCSMessages in -ltnc" >&5 -$as_echo_n "checking for exchangeTNCCSMessages in -ltnc... " >&6; } - LIBS="-ltnc $old_LIBS" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for processEAPTNCData in -lnaaeap" >&5 +$as_echo_n "checking for processEAPTNCData in -lnaaeap... " >&6; } + LIBS="-lnaaeap $old_LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -extern char exchangeTNCCSMessages(); +extern char processEAPTNCData(); int main () { -exchangeTNCCSMessages() +processEAPTNCData() ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - smart_lib="-ltnc" + smart_lib="-lnaaeap" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } @@ -2870,7 +2857,7 @@ if test "x$smart_lib" = "x"; then if test "x$LOCATE" != "x"; then DIRS= - file=libtnc${libltdl_cv_shlibext} + file=libnaaeap${libltdl_cv_shlibext} for x in `${LOCATE} $file 2>/dev/null`; do base=`echo $x | sed "s%/${file}%%"` @@ -2897,7 +2884,7 @@ eval "smart_lib_dir=\"\$smart_lib_dir $DIRS\"" if test "x$LOCATE" != "x"; then DIRS= - file=libtnc.a + file=libnaaeap.a for x in `${LOCATE} $file 2>/dev/null`; do base=`echo $x | sed "s%/${file}%%"` @@ -2922,23 +2909,23 @@ eval "smart_lib_dir=\"\$smart_lib_dir $DIRS\"" for try in $smart_lib_dir /usr/local/lib /opt/lib; do - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for exchangeTNCCSMessages in -ltnc in $try" >&5 -$as_echo_n "checking for exchangeTNCCSMessages in -ltnc in $try... " >&6; } - LIBS="-L$try -rpath$try -ltnc $old_LIBS -Wl,-rpath,$try" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for processEAPTNCData in -lnaaeap in $try" >&5 +$as_echo_n "checking for processEAPTNCData in -lnaaeap in $try... " >&6; } + LIBS="-L$try -rpath$try -lnaaeap $old_LIBS -Wl,-rpath,$try" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -extern char exchangeTNCCSMessages(); +extern char processEAPTNCData(); int main () { -exchangeTNCCSMessages() +processEAPTNCData() ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - smart_lib="-L$try -ltnc -Wl,-rpath,$try" + smart_lib="-L$try -lnaaeap -Wl,-rpath,$try" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } break @@ -2959,8 +2946,8 @@ if test "x$smart_lib" != "x"; then SMART_LIBS="$smart_lib $SMART_LIBS" fi - if test "x$ac_cv_lib_tnc_exchangetnccsmessages" != "xyes"; then - fail="$fail libtnc" + if test "x$ac_cv_lib_naaeap_processEAPTNCData" != "xyes"; then + fail="$fail libnaaeap" fi targetname=rlm_eap_tnc # keep this! Don't change! @@ -2977,6 +2964,8 @@ if test x"$fail" != x""; then $as_echo "$as_me: WARNING: silently not building rlm_eap_tnc." >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: FAILURE: rlm_eap_tnc requires: $fail." >&5 $as_echo "$as_me: WARNING: FAILURE: rlm_eap_tnc requires: $fail." >&2;}; + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Required libraries are available from https://github.com/trustatfhh/tnc-fhh" >&5 +$as_echo "$as_me: WARNING: Required libraries are available from https://github.com/trustatfhh/tnc-fhh" >&2;}; targetname="" fi fi diff --git a/src/modules/rlm_eap/types/rlm_eap_tnc/configure.in b/src/modules/rlm_eap/types/rlm_eap_tnc/configure.in index 17f234e47de..14feca33710 100644 --- a/src/modules/rlm_eap/types/rlm_eap_tnc/configure.in +++ b/src/modules/rlm_eap/types/rlm_eap_tnc/configure.in @@ -50,37 +50,24 @@ if test x$with_[]modname != xno; then eap_tnc_include_dir="$withval/include" ;; esac]) - - dnl ############################################################ - dnl # Check for OpenSSL support - dnl ############################################################ - - AC_MSG_CHECKING(for OpenSSL support) - if test "x$OPENSSL_LIBS" != "x"; then - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - fail="OpenSSL" - fi dnl ############################################################ dnl # Check for eap-tnc includes dnl ############################################################ smart_try_dir="$eap_tnc_include_dir" - FR_SMART_CHECK_INCLUDE([libtnc.h]) - if test "x$ac_cv_header_libtnc_h" != "xyes"; then - fail="$fail libtnc.h" + FR_SMART_CHECK_INCLUDE([naaeap/naaeap.h]) + if test "x$ac_cv_header_naaeap_naaeap_h" != "xyes"; then + fail="$fail naaeap.h" fi dnl ############################################################ dnl # Check for eap-tnc library dnl ############################################################ - LIBS="${OPENSSL_LIBS}" smart_try_dir="$eap_tnc_lib_dir" - FR_SMART_CHECK_LIB([tnc],[exchangeTNCCSMessages]) - if test "x$ac_cv_lib_tnc_exchangetnccsmessages" != "xyes"; then - fail="$fail libtnc" + FR_SMART_CHECK_LIB([naaeap],[processEAPTNCData]) + if test "x$ac_cv_lib_naaeap_processEAPTNCData" != "xyes"; then + fail="$fail libnaaeap" fi targetname=modname # keep this! Don't change! @@ -95,7 +82,8 @@ if test x"$fail" != x""; then AC_MSG_ERROR([set --without-]modname[ to disable it explicitly.]) else AC_MSG_WARN([silently not building ]modname[.]) - AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]); + AC_MSG_WARN([FAILURE: ]modname[ requires: $fail.]); + AC_MSG_WARN([Required libraries are available from https://github.com/trustatfhh/tnc-fhh]); targetname="" fi fi diff --git a/src/modules/rlm_eap/types/rlm_eap_tnc/eap_tnc.c b/src/modules/rlm_eap/types/rlm_eap_tnc/eap_tnc.c deleted file mode 100644 index 213ede51c46..00000000000 --- a/src/modules/rlm_eap/types/rlm_eap_tnc/eap_tnc.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * eap_tnc.c EAP TNC functionality. - * - * This software is Copyright (C) 2006,2007 FH Hannover - * - * Portions of this code unrelated to FreeRADIUS are available - * separately under a commercial license. If you require an - * implementation of EAP-TNC that is not under the GPLv2, please - * contact tnc@inform.fh-hannover.de for details. - * - * 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. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - * - */ -#include -RCSID("$Id$") - - -/* - * - * MD5 Packet Format in EAP Type-Data - * --- ------ ------ -- --- --------- - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Value-Size | Value ... - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Name ... - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * - * EAP-TNC Packet Format in EAP Type-Data - * - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Flags |Ver | Data Length ... - * |L M S R R|=1 | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * |... | Data ... - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - * - */ - -#include -#include -#include "eap.h" - -#include "eap_tnc.h" - - /* - * WTF is wrong with htonl ? - */ -static uint32_t ByteSwap2 (uint32_t nLongNumber) -{ - return (((nLongNumber&0x000000FF)<<24)+((nLongNumber&0x0000FF00)<<8)+ - ((nLongNumber&0x00FF0000)>>8)+((nLongNumber&0xFF000000)>>24)); -} - -/* - * Allocate a new TNC_PACKET - */ -TNC_PACKET *eaptnc_alloc(void) -{ - TNC_PACKET *rp; - - if ((rp = malloc(sizeof(TNC_PACKET))) == NULL) { - radlog(L_ERR, "rlm_eap_tnc: out of memory"); - return NULL; - } - memset(rp, 0, sizeof(TNC_PACKET)); - return rp; -} - -/* - * Free TNC_PACKET - */ -void eaptnc_free(TNC_PACKET **tnc_packet_ptr) -{ - TNC_PACKET *tnc_packet; - - if (!tnc_packet_ptr) return; - tnc_packet = *tnc_packet_ptr; - if (tnc_packet == NULL) return; - - if (tnc_packet->data) free(tnc_packet->data); - - free(tnc_packet); - - *tnc_packet_ptr = NULL; -} - -/* - * We expect only RESPONSE for which REQUEST, SUCCESS or FAILURE is sent back - */ -TNC_PACKET *eaptnc_extract(EAP_DS *eap_ds) -{ - tnc_packet_t *data; - TNC_PACKET *packet; - /* - * We need a response, of type EAP-TNC - */ - if (!eap_ds || - !eap_ds->response || - (eap_ds->response->code != PW_TNC_RESPONSE) || - eap_ds->response->type.type != PW_EAP_TNC || - !eap_ds->response->type.data || - (eap_ds->response->length <= TNC_HEADER_LEN) || - (eap_ds->response->type.data[0] <= 0)) { - radlog(L_ERR, "rlm_eap_tnc: corrupted data"); - return NULL; - } - packet = eaptnc_alloc(); - if (!packet) return NULL; - - - packet->code = eap_ds->response->code; - packet->id = eap_ds->response->id; - packet->length = eap_ds->response->length; - - data = (tnc_packet_t *)eap_ds->response->type.data; - /* - * Already checked the size above. - */ - packet->flags_ver = data->flags_ver; - unsigned char *ptr = (unsigned char*)data; - - - DEBUG2("Flags/Ver: %x\n", packet->flags_ver); - int thisDataLength; - int dataStart; - if(TNC_LENGTH_INCLUDED(packet->flags_ver)){ - DEBUG2("data_length included\n"); -// memcpy(&packet->flags_ver[1], &data->flags_ver[1], 4); - //packet->data_length = data->data_length; - memcpy(&packet->data_length, &ptr[1], TNC_DATA_LENGTH_LENGTH); - DEBUG2("data_length: %x\n", packet->data_length); - DEBUG2("data_length: %d\n", packet->data_length); - DEBUG2("data_length: %x\n", ByteSwap2(packet->data_length)); - DEBUG2("data_length: %d\n", ByteSwap2(packet->data_length)); - packet->data_length = ByteSwap2(packet->data_length); - thisDataLength = packet->length-TNC_PACKET_LENGTH; //1: we need space for flags_ver - dataStart = TNC_DATA_LENGTH_LENGTH+TNC_FLAGS_VERSION_LENGTH; - }else{ - DEBUG2("no data_length included\n"); - thisDataLength = packet->length-TNC_PACKET_LENGTH_WITHOUT_DATA_LENGTH; - packet->data_length = 0; - dataStart = TNC_FLAGS_VERSION_LENGTH; - - } - /* - * Allocate room for the data, and copy over the data. - */ - packet->data = malloc(thisDataLength); - if (packet->data == NULL) { - radlog(L_ERR, "rlm_eap_tnc: out of memory"); - eaptnc_free(&packet); - return NULL; - } - - memcpy(packet->data, &(eap_ds->response->type.data[dataStart]), thisDataLength); - - return packet; -} - - -/* - * Compose the portions of the reply packet specific to the - * EAP-TNC protocol, in the EAP reply typedata - */ -int eaptnc_compose(EAP_DS *eap_ds, TNC_PACKET *reply) -{ - uint8_t *ptr; - - - if (reply->code < 3) { - //fill: EAP-Type (0x888e) - eap_ds->request->type.type = PW_EAP_TNC; - DEBUG2("TYPE: EAP-TNC set\n"); - rad_assert(reply->length > 0); - - //alloc enough space for whole TNC-Packet (from Code on) - eap_ds->request->type.data = calloc(reply->length, sizeof(unsigned char*)); - DEBUG2("Malloc %d bytes for packet\n", reply->length); - if (eap_ds->request->type.data == NULL) { - radlog(L_ERR, "rlm_eap_tnc: out of memory"); - return 0; - } - //put pointer at position where data starts (behind Type) - ptr = eap_ds->request->type.data; - //*ptr = (uint8_t)(reply->data_length & 0xFF); - - //ptr++; - *ptr = reply->flags_ver; - DEBUG2("Set Flags/Version: %d\n", *ptr); - if(reply->data_length!=0){ - DEBUG2("Set data-length: %d\n", reply->data_length); - ptr++; //move to start-position of "data_length" - DEBUG2("Set data-length: %x\n", reply->data_length); - DEBUG2("Set data-length (swapped): %x\n", ByteSwap2(reply->data_length)); - unsigned long swappedDataLength = ByteSwap2(reply->data_length); - //DEBUG2("DATA-length: %d", reply->data_ - memcpy(ptr, &swappedDataLength, 4); - //*ptr = swappedDataLength; - } - uint16_t thisDataLength=0; - if(reply->data!=NULL){ - DEBUG2("Adding TNCCS-Data "); - int offset; - //if data_length-Field present - if(reply->data_length !=0){ - DEBUG2("with Fragmentation\n"); - offset = TNC_DATA_LENGTH_LENGTH; //length of data_length-field: 4 - thisDataLength = reply->length-TNC_PACKET_LENGTH; - }else{ //data_length-Field not present - DEBUG2("without Fragmentation\n"); - offset = 1; - thisDataLength = reply->length-TNC_PACKET_LENGTH_WITHOUT_DATA_LENGTH; - } - DEBUG2("TNCCS-Datalength: %d\n", thisDataLength); - ptr=ptr+offset; //move to start-position of "data" - memcpy(ptr,reply->data, thisDataLength); - }else{ - DEBUG2("No TNCCS-Data present"); - } - - //the length of the TNC-packet (behind Type) - if(reply->data_length!=0){ - eap_ds->request->type.length = TNC_DATA_LENGTH_LENGTH+TNC_FLAGS_VERSION_LENGTH+thisDataLength; //4:data_length, 1: flags_ver - }else{ - eap_ds->request->type.length = TNC_FLAGS_VERSION_LENGTH+thisDataLength; //1: flags_ver - } - DEBUG2("Packet built\n"); - - } else { - eap_ds->request->type.length = 0; - } - eap_ds->request->code = reply->code; - - return 1; -} diff --git a/src/modules/rlm_eap/types/rlm_eap_tnc/eap_tnc.h b/src/modules/rlm_eap/types/rlm_eap_tnc/eap_tnc.h deleted file mode 100644 index 22f5325217d..00000000000 --- a/src/modules/rlm_eap/types/rlm_eap_tnc/eap_tnc.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * This software is Copyright (C) 2006,2007 FH Hannover - * - * Portions of this code unrelated to FreeRADIUS are available - * separately under a commercial license. If you require an - * implementation of EAP-TNC that is not under the GPLv2, please - * contact tnc@inform.fh-hannover.de for details. - * - * 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. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - * - */ - -#ifndef _EAP_TNC_H -#define _EAP_TNC_H - -#include "eap.h" - -#define PW_TNC_REQUEST 1 -#define PW_TNC_RESPONSE 2 -#define PW_TNC_SUCCESS 3 -#define PW_TNC_FAILURE 4 -#define PW_TNC_MAX_CODES 4 - -#define TNC_HEADER_LEN 4 -#define TNC_CHALLENGE_LEN 16 -#define TNC_START_LEN 8 - -#define TNC_PACKET_LENGTH_WITHOUT_DATA_LENGTH 6 -#define TNC_PACKET_LENGTH 10 -#define TNC_DATA_LENGTH_LENGTH 4 -#define TNC_FLAGS_VERSION_LENGTH 1 - -typedef unsigned int VlanAccessMode; - -#define VLAN_ISOLATE 97 -#define VLAN_ACCESS 2 -/* - **** - * EAP - MD5 doesnot specify code, id & length but chap specifies them, - * for generalization purpose, complete header should be sent - * and not just value_size, value and name. - * future implementation. - * - * Huh? What does that mean? - */ - -/* - * - * MD5 Packet Format in EAP Type-Data - * --- ------ ------ -- --- --------- - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Value-Size | Value ... - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Name ... - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * - * EAP-TNC Packet Format in EAP Type-Data - * - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Flags |Ver | Data Length ... - * |L M S R R|=1 | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * |... | Data ... - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - * - */ - -/* eap packet structure */ -typedef struct tnc_packet_t { -/* - uint8_t code; - uint8_t id; - uint16_t length; -*/ - uint8_t flags_ver; - uint32_t data_length; - uint8_t *data; -} tnc_packet_t; - -typedef struct tnc_packet { - uint8_t code; - uint8_t id; - uint16_t length; - uint8_t flags_ver; - uint32_t data_length; - uint8_t *data; -} TNC_PACKET; - -#define TNC_START(x) (((x) & 0x20) != 0) -#define TNC_MORE_FRAGMENTS(x) (((x) & 0x40) != 0) -#define TNC_LENGTH_INCLUDED(x) (((x) & 0x80) != 0) -#define TNC_RESERVED_EQ_NULL(x) (((x) & 0x10) == 0 && ((x) & 0x8) == 0) -#define TNC_VERSION_EQ_ONE(x) (((x) & 0x07) == 1) - -#define SET_START(x) ((x) | (0x20)) -#define SET_MORE_FRAGMENTS(x) ((x) | (0x40)) -#define SET_LENGTH_INCLUDED(x) ((x) | (0x80)) - - -/* function declarations here */ - -TNC_PACKET *eaptnc_alloc(void); -void eaptnc_free(TNC_PACKET **tnc_packet_ptr); - -int eaptnc_compose(EAP_DS *auth, TNC_PACKET *reply); -TNC_PACKET *eaptnc_extract(EAP_DS *auth); -int eaptnc_verify(TNC_PACKET *pkt, VALUE_PAIR* pwd, uint8_t *ch); - - - - - -#endif /*_EAP_TNC_H*/ diff --git a/src/modules/rlm_eap/types/rlm_eap_tnc/rlm_eap_tnc.c b/src/modules/rlm_eap/types/rlm_eap_tnc/rlm_eap_tnc.c index e3f2f6e824e..8c8e701aca6 100644 --- a/src/modules/rlm_eap/types/rlm_eap_tnc/rlm_eap_tnc.c +++ b/src/modules/rlm_eap/types/rlm_eap_tnc/rlm_eap_tnc.c @@ -1,12 +1,8 @@ /* - * rlm_eap_tnc.c Handles that are called from eap - * - * This software is Copyright (C) 2006,2007 FH Hannover - * * Portions of this code unrelated to FreeRADIUS are available * separately under a commercial license. If you require an * implementation of EAP-TNC that is not under the GPLv2, please - * contact tnc@inform.fh-hannover.de for details. + * contact trust@f4-i.fh-hannover.de for details. * * 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 @@ -22,98 +18,229 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * - * Modifications to integrate with FreeRADIUS configuration - * Copyright (C) 2007 Alan DeKok + */ + +/** + * $Id$ + * @file rlm_eap_tnc.c + * @brief Interfaces with the naeap library to provide EAP-TNC inner method. + * + * @copyright 2013 The FreeRADIUS project + * @copyright 2007 Alan DeKok + * @copyright 2006-2009 FH Hannover */ -#include -RCSID("$Id$") +/* + * EAP-TNC Packet with EAP Header, general structure + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Code | Identifier | Length | + * | | | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type | Flags | Ver | Data Length | + * | |L M S R R| =1 | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Data Length | Data ... + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ #include #include -#include "tncs_connect.h" -#include "eap_tnc.h" -#include "tncs.h" #include -typedef struct rlm_eap_tnc_t { - char *vlan_access; - char *vlan_isolate; - char *tnc_path; +#include "eap.h" +#include +#include + +#define VERSION "0.7.0" +#define SET_START(x) ((x) | (0x20)) + +typedef struct rlm_eap_tnc { + char *connection_string; } rlm_eap_tnc_t; -static int sessionCounter=0; +static CONF_PARSER module_config[] = { + { "connection_string", PW_TYPE_STRING_PTR, + offsetof(rlm_eap_tnc_t, connection_string), NULL, + "NAS Port: %{NAS-Port} NAS IP: %{NAS-IP-Address} NAS_PORT_TYPE: %{NAS-Port-Type}"}, + + { NULL, -1, 0, NULL, NULL } /* end the list */ +}; + +static int tnc_attach(CONF_SECTION *cs, void **instance) +{ + rlm_eap_tnc_t *inst; + TNC_Result result; + + *instance = inst = talloc_zero(cs, rlm_eap_tnc_t); + if (!inst) return -1; + + /* + * Parse the configuration attributes. + */ + if (cf_section_parse(cs, inst, module_config) < 0) { + return -1; + } + + result = initializeDefault(); + if (result != TNC_RESULT_SUCCESS) { + radlog(L_ERR, "rlm_eap_tnc: NAA-EAP initializeDefault returned an " + "error code"); + + return -1; + } + + return 0; +} + +static int tnc_detach(void *instance) +{ + TNC_Result result; + + talloc_free(instance); + + result = terminate(); + if (result != TNC_RESULT_SUCCESS) { + radlog(L_ERR, "rlm_eap_tnc: NAA-EAP terminate returned an " + "error code whilst detaching"); + return -1; + } + + return 0; +} + +static void tnc_free(void *conn_id) +{ + talloc_free(conn_id); +} /* - * Initiate the EAP-MD5 session by sending a challenge to the peer. - * Initiate the EAP-TNC session by sending a EAP Request witch Start Bit set - * and with no data + * This function is called when the first EAP_IDENTITY_RESPONSE message + * was received. + * + * Initiates the EPA_TNC session by sending the first EAP_TNC_RESPONSE + * to the peer. The packet has the Start-Bit set and contains no data. + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Code | Identifier | Length | + * | | | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Type | Flags | Ver | + * | |0 0 1 0 0|0 0 1| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * For this package, only 'Identifier' has to be set dynamically. Any + * other information is static. */ -static int tnc_initiate(void *type_data, EAP_HANDLER *handler) +static int tnc_initiate(void *instance, EAP_HANDLER *handler) { - uint8_t flags_ver = 1; //set version to 1 - rlm_eap_tnc_t *inst = type_data; - TNC_PACKET *reply; + rlm_eap_tnc_t *inst = instance; + REQUEST *request = NULL; + + char buff[71]; + size_t len = 0; + + TNC_Result result; + TNC_ConnectionID conn_id; + TNC_BufferReference eap_tnc_request; + TNC_BufferReference eap_tnc_user; + + VALUE_PAIR *username; + + /* + * Check if we run inside a secure EAP method. + * FIXME check concrete outer EAP method. + */ if (!handler->request || !handler->request->parent) { - DEBUG("rlm_eap_tnc: EAP-TNC can only be run inside of a TLS-based method."); + radlog(L_ERR, "rlm_eap_tnc: EAP_TNC must only be used as an " + "inner method within a protected tunneled EAP created " + "by an outer EAP method"); + return 0; } + + request = handler->request->parent; /* - * FIXME: Update this when the TTLS and PEAP methods can - * run EAP-TLC *after* the user has been authenticated. - * This likely means moving the phase2 handlers to a - * common code base. + * Build the connection string */ - if (1) { - DEBUG("rlm-eap_tnc: EAP-TNC can only be run after the user has been authenticated."); + len = radius_xlat(buff, sizeof(buff), inst->connection_string, request, + NULL, NULL); + if(len == 0){ + radlog(L_ERR, "rlm_eap_tnc: Connection string expansion failed"); + return 0; } - DEBUG("tnc_initiate: %ld", handler->timestamp); + RDEBUG("Getting connection from NAA-EAP"); + + /* + * Get connection (uses a function from the NAA-EAP-library) + */ + result = getConnection(buff, &conn_id); + if (result != TNC_RESULT_SUCCESS) { + radlog(L_ERR, "rlm_eap_tnc: NAA-EAP getConnection returned an " + "error code"); - if(connectToTncs(inst->tnc_path)==-1){ - DEBUG("Could not connect to TNCS"); + return 0; } /* - * Allocate an EAP-MD5 packet. + * Previous code manually parsed the EAP identity response + * this was wrong. rlm_eap will *always* create the Username + * from the EAP Identity response. + * + * Something has gone very wrong if the User-Name doesn't exist. + */ + username = pairfind(request->packet->vps, PW_USER_NAME, 0, TAG_ANY); + + RDEBUG("Username for TNC connection: %s", username->vp_strvalue); + + /* + * Stores the username associated with the connection + * + * What becomes of username? Who knows... but we don't free it + * so not safe to use talloc. */ - reply = eaptnc_alloc(); - if (reply == NULL) { - radlog(L_ERR, "rlm_eap_tnc: out of memory"); + MEM(eap_tnc_user = (TNC_BufferReference) strdup(username->vp_strvalue)); + + result = storeUsername(conn_id, eap_tnc_user, username->length); + if (result != TNC_RESULT_SUCCESS) { + radlog(L_ERR, "rlm_eap_tnc: NAA-EAP storeUsername returned an " + "error code"); + return 0; } /* - * Fill it with data. + * Set connection ID */ - reply->code = PW_TNC_REQUEST; - flags_ver = SET_START(flags_ver); //set start-flag - DEBUG("$$$$$$$$$$$$$$$$Flags: %d", flags_ver); - reply->flags_ver = flags_ver; - reply->length = 1+1; /* one byte of flags_ver */ - + handler->opaque = talloc(NULL, TNC_ConnectionID); + memcpy(handler->opaque, &conn_id, sizeof(TNC_ConnectionID)); + handler->free_opaque = tnc_free; /* - * Compose the EAP-TNC packet out of the data structure, - * and free it. + * Bild first EAP TNC request */ - eaptnc_compose(handler->eap_ds, reply); - eaptnc_free(&reply); - //put sessionAttribute to Handler and increase sessionCounter - handler->opaque = calloc(sizeof(TNC_ConnectionID), 1); - if (handler->opaque == NULL) { - radlog(L_ERR, "rlm_eap_tnc: out of memory"); - return 0; - } - handler->free_opaque = free; - memcpy(handler->opaque, &sessionCounter, sizeof(int)); - sessionCounter++; - + MEM(eap_tnc_request = malloc(1)); + *eap_tnc_request = SET_START(1); + + handler->eap_ds->request->code = PW_EAP_REQUEST; + handler->eap_ds->request->type.type = PW_EAP_TNC; + + handler->eap_ds->request->type.length = 1; + + free(handler->eap_ds->request->type.data); + handler->eap_ds->request->type.data = eap_tnc_request; + /* * We don't need to authorize the user at this point. * @@ -122,233 +249,137 @@ static int tnc_initiate(void *type_data, EAP_HANDLER *handler) * to us... */ handler->stage = AUTHENTICATE; - - return 1; -} -static void setVlanAttribute(rlm_eap_tnc_t *inst, EAP_HANDLER *handler, - VlanAccessMode mode){ - VALUE_PAIR *vp; - char *vlanNumber = NULL; - switch(mode){ - case VLAN_ISOLATE: - vlanNumber = inst->vlan_isolate; - vp = pairfind(handler->request->config_items, PW_TNC_VLAN_ISOLATE, - TAG_ANY); - if (vp) vlanNumber = vp->vp_strvalue; - break; - case VLAN_ACCESS: - vlanNumber = inst->vlan_access; - vp = pairfind(handler->request->config_items, PW_TNC_VLAN_ACCESS, - TAG_ANY); - if (vp) vlanNumber = vp->vp_strvalue; - break; - - default: - DEBUG2(" rlm_eap_tnc: Internal error. Not setting vlan number"); - return; - } - pairadd(&handler->request->reply->vps, - pairmake("Tunnel-Type", "VLAN", T_OP_SET)); - - pairadd(&handler->request->reply->vps, - pairmake("Tunnel-Medium-Type", "IEEE-802", T_OP_SET)); - - pairadd(&handler->request->reply->vps, - pairmake("Tunnel-Private-Group-ID", vlanNumber, T_OP_SET)); - + return 1; } -/* - * Authenticate a previously sent challenge. +/** + * This function is called when a EAP_TNC_RESPONSE was received. + * It basically forwards the EAP_TNC data to NAA-TNCS and forms + * and appropriate EAP_RESPONSE. Furthermore, it sets the VlanID + * based on the TNC_ConnectionState determined by NAA-TNCS. + * + * @param type_arg The configuration data + * @param handler The EAP_HANDLER + * @return True, if successfully, else false. */ -static int tnc_authenticate(void *type_arg, EAP_HANDLER *handler) +static int tnc_authenticate(UNUSED void *instance, EAP_HANDLER *handler) { - TNC_PACKET *packet; - TNC_PACKET *reply; - TNC_ConnectionID connId = *((TNC_ConnectionID *) (handler->opaque)); - TNC_ConnectionState state; - rlm_eap_tnc_t *inst = type_arg; - int isAcknowledgement = 0; - TNC_UInt32 tnccsMsgLength = 0; - int isLengthIncluded; - int moreFragments; - TNC_UInt32 overallLength; - TNC_BufferReference outMessage; - TNC_UInt32 outMessageLength = 2; - int outIsLengthIncluded=0; - int outMoreFragments=0; - TNC_UInt32 outOverallLength=0; - - DEBUG2("HANDLER_OPAQUE: %d", (int) *((TNC_ConnectionID *) (handler->opaque))); - DEBUG2("TNC-AUTHENTICATE is starting now for %d..........", (int) connId); + TNC_ConnectionID conn_id; + TNC_Result result; + + TNC_BufferReference data = NULL; + TNC_UInt32 datalen = 0; + + TNC_ConnectionState connection_state; + uint8_t code = 0; /* - * Get the User-Password for this user. - */ - rad_assert(handler->request != NULL); - rad_assert(handler->stage == AUTHENTICATE); - - /* - * Extract the EAP-TNC packet. - */ - if (!(packet = eaptnc_extract(handler->eap_ds))) + if (!handler->opaque){ + radlog(L_ERR, "rlm_eap_tnc: Invalid session data: handler->opaque was " + "NULL"); return 0; + } - /* - * Create a reply, and initialize it. - */ - reply = eaptnc_alloc(); - if (!reply) { - eaptnc_free(&packet); + if (!handler->eap_ds) { + radlog(L_ERR, "rlm_eap_tnc: Invalid session data: handler->eap_ds " + "was NULL"); + return 0; } - - reply->id = handler->eap_ds->request->id; - reply->length = 0; - if(packet->data_length==0){ - tnccsMsgLength = packet->length-TNC_PACKET_LENGTH_WITHOUT_DATA_LENGTH; - }else{ - tnccsMsgLength = packet->length-TNC_PACKET_LENGTH; - } - isLengthIncluded = TNC_LENGTH_INCLUDED(packet->flags_ver); - moreFragments = TNC_MORE_FRAGMENTS(packet->flags_ver); - overallLength = packet->data_length; - if(isLengthIncluded == 0 - && moreFragments == 0 - && overallLength == 0 - && tnccsMsgLength == 0 - && TNC_START(packet->flags_ver)==0){ - - isAcknowledgement = 1; - } - - DEBUG("Data received: (%d)", (int) tnccsMsgLength); -/* int i; - for(i=0;idata)[i]); - } - DEBUG2("\n"); - */ - state = exchangeTNCCSMessages(inst->tnc_path, - connId, - isAcknowledgement, - packet->data, - tnccsMsgLength, - isLengthIncluded, - moreFragments, - overallLength, - &outMessage, - &outMessageLength, - &outIsLengthIncluded, - &outMoreFragments, - &outOverallLength); - DEBUG("GOT State %08x from TNCS", (unsigned int) state); - if(state == TNC_CONNECTION_EAP_ACKNOWLEDGEMENT){ //send back acknoledgement - reply->code = PW_TNC_REQUEST; - reply->data = NULL; - reply->data_length = 0; - reply->flags_ver = 1; - reply->length =TNC_PACKET_LENGTH_WITHOUT_DATA_LENGTH; - }else{ //send back normal message - DEBUG("GOT Message from TNCS (length: %d)", (int) outMessageLength); - - /* for(i=0;icode = PW_TNC_REQUEST; - DEBUG2("Set Reply->Code to EAP-REQUEST\n"); - break; - case TNC_CONNECTION_STATE_ACCESS_ALLOWED: - reply->code = PW_TNC_SUCCESS; - setVlanAttribute(inst, handler,VLAN_ACCESS); - break; - case TNC_CONNECTION_STATE_ACCESS_NONE: - reply->code = PW_TNC_FAILURE; - //setVlanAttribute(inst, handler, VLAN_ISOLATE); - break; - case TNC_CONNECTION_STATE_ACCESS_ISOLATED: - reply->code = PW_TNC_SUCCESS; - setVlanAttribute(inst, handler, VLAN_ISOLATE); - break; - default: - reply->code= PW_TNC_FAILURE; - - } - if(outMessage!=NULL && outMessageLength!=0){ - reply->data = outMessage; - } - reply->flags_ver = 1; - if(outIsLengthIncluded){ - reply->flags_ver = SET_LENGTH_INCLUDED(reply->flags_ver); - reply->data_length = outOverallLength; - reply->length = TNC_PACKET_LENGTH + outMessageLength; - DEBUG("SET LENGTH: %d", reply->length); - DEBUG("SET DATALENGTH: %d", (int) outOverallLength); - }else{ - reply->data_length = 0; - reply->length = TNC_PACKET_LENGTH_WITHOUT_DATA_LENGTH + outMessageLength; - DEBUG("SET LENGTH: %d", reply->length); - } - if(outMoreFragments){ - reply->flags_ver = SET_MORE_FRAGMENTS(reply->flags_ver); - } - } - - /* - * Compose the EAP-MD5 packet out of the data structure, - * and free it. - */ - eaptnc_compose(handler->eap_ds, reply); - eaptnc_free(&reply); - handler->stage = AUTHENTICATE; - - eaptnc_free(&packet); - return 1; -} + if (!handler->eap_ds->request) { + radlog(L_ERR, "rlm_eap_tnc: Invalid session data: " + "handler->eap_ds->request was NULL"); + + return 0; + } + if (!handler->eap_ds->response) { + radlog(L_ERR, "rlm_eap_tnc: Invalid session data: " + "handler->eap_ds->response was NULL"); + + return 0; + } + */ + + if (handler->eap_ds->response->type.type != PW_EAP_TNC) { + radlog(L_ERR, "rlm_eap_tnc: Incorrect response type"); -static CONF_PARSER module_config[] = { - { "vlan_access", PW_TYPE_STRING_PTR, - offsetof(rlm_eap_tnc_t, vlan_access), NULL, NULL }, - { "vlan_isolate", PW_TYPE_STRING_PTR, - offsetof(rlm_eap_tnc_t, vlan_isolate), NULL, NULL }, - { "tnc_path", PW_TYPE_STRING_PTR, - offsetof(rlm_eap_tnc_t, tnc_path), NULL, - "/usr/local/lib/libTNCS.so"}, + return 0; + } - { NULL, -1, 0, NULL, NULL } /* end the list */ -}; + /* + * Retrieve connection ID + */ + conn_id = *((TNC_ConnectionID *) (handler->opaque)); -/* - * Attach the EAP-TNC module. - */ -static int tnc_attach(CONF_SECTION *cs, void **instance) -{ - rlm_eap_tnc_t *inst; + DEBUG2("rlm_eap_tnc: Starting authentication for connection ID %lX", + conn_id); - *instance = inst = talloc_zero(cs, rlm_eap_tnc_t); - if (!inst) return -1; + /* + * Pass EAP_TNC data to NAA-EAP and get answer data + */ + connection_state = TNC_CONNECTION_STATE_CREATE; - if (cf_section_parse(cs, inst, module_config) < 0) { - return -1; + /* + * Forwards the eap_tnc data to NAA-EAP and gets the response + */ + result = processEAPTNCData(conn_id, handler->eap_ds->response->type.data, + handler->eap_ds->response->type.length, + &data, &datalen, &connection_state); + if (result != TNC_RESULT_SUCCESS) { + radlog(L_ERR, "rlm_eap_tnc: NAA-EAP processEAPTNCData returned " + "an error code"); + + return 0; + } + /* + * Determine eap code for the response + */ + switch (connection_state) { + case TNC_CONNECTION_STATE_HANDSHAKE: + code = PW_EAP_REQUEST; + + break; + case TNC_CONNECTION_STATE_ACCESS_NONE: + code = PW_EAP_FAILURE; + pairadd(&handler->request->config_items, + pairmake("TNC-Status", "None", T_OP_SET)); + + break; + + case TNC_CONNECTION_STATE_ACCESS_ALLOWED: + code = PW_EAP_SUCCESS; + pairadd(&handler->request->config_items, + pairmake("TNC-Status", "Access", T_OP_SET)); + + break; + + case TNC_CONNECTION_STATE_ACCESS_ISOLATED: + code = PW_EAP_SUCCESS; + pairadd(&handler->request->config_items, + pairmake("TNC-Status", "Isolate", T_OP_SET)); + + break; + default: + radlog(L_ERR, "rlm_eap_tnc: Invalid connection state"); + + return 0; } + /* + * Build the TNC EAP request + */ + handler->eap_ds->request->code = code; + handler->eap_ds->request->type.type = PW_EAP_TNC; - if (!inst->vlan_access || !inst->vlan_isolate) { - radlog(L_ERR, "rlm_eap_tnc: Must set both vlan_access and vlan_isolate"); - return -1; - } + handler->eap_ds->request->type.length = datalen; + + free(handler->eap_ds->request->type.data); + handler->eap_ds->request->type.data = data; - return 0; + return 1; } /* @@ -356,10 +387,10 @@ static int tnc_attach(CONF_SECTION *cs, void **instance) * That is, everything else should be 'static'. */ EAP_TYPE rlm_eap_tnc = { - "eap_tnc", - tnc_attach, /* attach */ - tnc_initiate, /* Start the initial request */ - NULL, /* authorization */ - tnc_authenticate, /* authentication */ - NULL /* detach */ + "eap_tnc", + tnc_attach, /* attach */ + tnc_initiate, /* Start the initial request */ + NULL, /* authorization */ + tnc_authenticate, /* authentication */ + tnc_detach /* detach */ }; diff --git a/src/modules/rlm_eap/types/rlm_eap_tnc/tncs.h b/src/modules/rlm_eap/types/rlm_eap_tnc/tncs.h deleted file mode 100644 index 00ac56b23c0..00000000000 --- a/src/modules/rlm_eap/types/rlm_eap_tnc/tncs.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * This software is Copyright (C) 2006,2007 FH Hannover - * - * Portions of this code unrelated to FreeRADIUS are available - * separately under a commercial license. If you require an - * implementation of EAP-TNC that is not under the GPLv2, please - * contact tnc@inform.fh-hannover.de for details. - * - * 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. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - * - */ - -#ifndef _TNCS_H_ -#define _TNCS_H_ - - - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * copied from tncimv.h: - */ -typedef unsigned long TNC_UInt32; -typedef TNC_UInt32 TNC_ConnectionState; -typedef unsigned char *TNC_BufferReference; -typedef TNC_UInt32 TNC_ConnectionID; - -#define TNC_CONNECTION_STATE_CREATE 0 -#define TNC_CONNECTION_STATE_HANDSHAKE 1 -#define TNC_CONNECTION_STATE_ACCESS_ALLOWED 2 -#define TNC_CONNECTION_STATE_ACCESS_ISOLATED 3 -#define TNC_CONNECTION_STATE_ACCESS_NONE 4 -#define TNC_CONNECTION_STATE_DELETE 5 -#define TNC_CONNECTION_EAP_ACKNOWLEDGEMENT 6 - -/* - * Accesspoint (as function-pointer) to the TNCS for sending and receiving - * TNCCS-Messages. - * - * -connId: identifies the client which the passed message belongs to. - * -isAcknoledgement: 1 if acknoledgement received (then all following in-parameters unimportant - * -input: input-TNCCS-message received from the client with connId - * -inputLength: length of input-TNCCS-message - * -isFirst: 1 if first message in fragmentation else 0 - * -moreFragments: are there more Fragments to come (yes: 1, no: 0)? - * -overallLength: length of all fragments together (only set if fragmentation) - * -output: answer-TNCCS-message from the TNCS to the client - * -outputLength: length of answer-TNCCS-message - * -answerIsFirst: returned answer is first in row - * -moreFragmentsFollow: more fragments after this answer - * -overallLengthOut: length of all fragments together (only set if fragmentation) as answer - * - * return: state of connection as result of the exchange - */ -typedef TNC_ConnectionState (*ExchangeTNCCSMessagePointer)(/*in*/ TNC_ConnectionID connId, - /*in*/ int isAcknoledgement, - /*in*/ TNC_BufferReference input, - /*in*/ TNC_UInt32 inputLength, - /*in*/ int isFirst, - /*in*/ int moreFragments, - /*in*/ TNC_UInt32 overallLength, - /*out*/ TNC_BufferReference *output, - /*out*/ TNC_UInt32 *outputLength, - /*out*/ int *answerIsFirst, - /*out*/ int *moreFragmentsFollow, - /*out*/ TNC_UInt32 *overallLengthOut -); - -#ifdef __cplusplus -} -#endif -#endif //_TNCS_H_ diff --git a/src/modules/rlm_eap/types/rlm_eap_tnc/tncs_connect.c b/src/modules/rlm_eap/types/rlm_eap_tnc/tncs_connect.c deleted file mode 100644 index 6077f6d2bdc..00000000000 --- a/src/modules/rlm_eap/types/rlm_eap_tnc/tncs_connect.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * This software is Copyright (C) 2006,2007 FH Hannover - * - * Portions of this code unrelated to FreeRADIUS are available - * separately under a commercial license. If you require an - * implementation of EAP-TNC that is not under the GPLv2, please - * contact tnc@inform.fh-hannover.de for details. - * - * 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. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - * - */ -#include -RCSID("$Id$") - -#include "tncs_connect.h" -#include -#include -#include -#include - - /* - * FIXME: This linking should really be done at compile time. - */ -static lt_dlhandle handle = NULL; - -static ExchangeTNCCSMessagePointer callTNCS = NULL; - -/* - * returns the function-pointer to a function of a shared-object - * - * soHandle: handle to a shared-object - * name: name of the requested function - * - * return: the procAddress if found, else NULL - */ -static void *getProcAddress(lt_dlhandle soHandle, const char *name){ - void *proc = lt_dlsym(soHandle, name); - DEBUG("Searching for function %s", name); - if(proc == NULL){ - DEBUG("rlm_eap_tnc: Failed to resolve symbol %s: %s", - name, lt_dlerror()); - } - return proc; -} - - -/* - * establishs the connection to the TNCCS without calling functionality. - * That means that the TNCS-shared-object is loaded and the function-pointer - * to "exchangeTNCCSMessages" is explored. - * - * return: -1 if connect failed, 0 if connect was successful - */ -int connectToTncs(char *pathToSO){ - int state = -1; - if(handle==NULL){ - handle = lt_dlopen(pathToSO); - DEBUG("OPENED HANDLE!"); - } - - if(handle==NULL){ - DEBUG("HANDLE IS NULL"); - DEBUG("rlm_eap_tnc: Failed to link to library %s: %s", - pathToSO, lt_dlerror()); - }else{ - DEBUG("SO %s found!", pathToSO); - if(callTNCS==NULL){ - callTNCS = (ExchangeTNCCSMessagePointer) getProcAddress(handle, "exchangeTNCCSMessages"); - } - if(callTNCS!=NULL){ - DEBUG("TNCS is connected"); - state = 0; -// int ret = callTNCS2(2, "Bla", NULL); - // DEBUG("GOT %d from exchangeTNCCSMessages", ret); - }else{ - DEBUG("Could not find exchangeTNCCSMessages"); - } - - } - return state; -} - -/* - * Accesspoint to the TNCS for sending and receiving TNCCS-Messages. - * -pathToSO: Path to TNCCS-Shared Object - * -connId: identifies the client which the passed message belongs to. - * -isAcknoledgement: 1 if acknoledgement received (then all following in-parameters unimportant - * -input: input-TNCCS-message received from the client with connId - * -inputLength: length of input-TNCCS-message - * -isFirst: 1 if first message in fragmentation else 0 - * -moreFragments: are there more Fragments to come (yes: 1, no: 0)? - * -overallLength: length of all fragments together (only set if fragmentation) - * -output: answer-TNCCS-message from the TNCS to the client - * -outputLength: length of answer-TNCCS-message - * -answerIsFirst: returned answer is first in row - * -moreFragmentsFollow: more fragments after this answer - * -overallLengthOut: length of all fragments together (only set if fragmentation) as answer - * - * return: state of connection as result of the exchange - */ -TNC_ConnectionState exchangeTNCCSMessages(/*in*/ char *pathToSO, - /*in*/ TNC_ConnectionID connId, - /*in*/ int isAcknoledgement, - /*in*/ TNC_BufferReference input, - /*in*/ TNC_UInt32 inputLength, - /*in*/ int isFirst, - /*in*/ int moreFragments, - /*in*/ TNC_UInt32 overallLength, - /*out*/ TNC_BufferReference *output, - /*out*/ TNC_UInt32 *outputLength, - /*out*/ int *answerIsFirst, - /*out*/ int *moreFragmentsFollow, - /*out*/ TNC_UInt32 *overallLengthOut){ - TNC_ConnectionState state = TNC_CONNECTION_STATE_ACCESS_NONE; - int connectStatus = connectToTncs(pathToSO); - if(connectStatus!=-1){ - state = callTNCS(connId, - isAcknoledgement, - input, - inputLength, - isFirst, - moreFragments, - overallLength, - output, - outputLength, - answerIsFirst, - moreFragmentsFollow, - overallLengthOut); - DEBUG("GOT TNC_ConnectionState (juhuuu): %u", (unsigned int) state); - }else{ - DEBUG("CAN NOT CONNECT TO TNCS"); - } - return state; -} diff --git a/src/modules/rlm_eap/types/rlm_eap_tnc/tncs_connect.h b/src/modules/rlm_eap/types/rlm_eap_tnc/tncs_connect.h deleted file mode 100644 index 0dd2c25a1c1..00000000000 --- a/src/modules/rlm_eap/types/rlm_eap_tnc/tncs_connect.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This software is Copyright (C) 2006,2007 FH Hannover - * - * Portions of this code unrelated to FreeRADIUS are available - * separately under a commercial license. If you require an - * implementation of EAP-TNC that is not under the GPLv2, please - * contact tnc@inform.fh-hannover.de for details. - * - * 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. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - * - */ - -#ifndef _TNCS_CONNECT_H_ -#define _TNCS_CONNECT_H_ - -#include "tncs.h" - -/* - * establishs the connection to the TNCCS without calling functionality. - * That means that the TNCS-shared-object is loaded and the function-pointer - * to "exchangeTNCCSMessages" is explored. - * - * return: -1 if connect failed, 0 if connect was successful - */ -int connectToTncs(char *pathToSO); -/* - * Accesspoint to the TNCS for sending and receiving TNCCS-Messages. - * -pathToSO: Path to TNCCS-Shared Object - * -connId: identifies the client which the passed message belongs to. - * -isAcknoledgement: 1 if acknoledgement received (then all following in-parameters unimportant - * -input: input-TNCCS-message received from the client with connId - * -inputLength: length of input-TNCCS-message - * -isFirst: 1 if first message in fragmentation else 0 - * -moreFragments: are there more Fragments to come (yes: 1, no: 0)? - * -overallLength: length of all fragments together (only set if fragmentation) - * -output: answer-TNCCS-message from the TNCS to the client - * -outputLength: length of answer-TNCCS-message - * -answerIsFirst: returned answer is first in row - * -moreFragmentsFollow: more fragments after this answer - * -overallLengthOut: length of all fragments together (only set if fragmentation) as answer - * - * return: state of connection as result of the exchange - */ -TNC_ConnectionState exchangeTNCCSMessages(/*in*/ char *pathToSO, - /*in*/ TNC_ConnectionID connId, - /*in*/ int isAcknoledgement, - /*in*/ TNC_BufferReference input, - /*in*/ TNC_UInt32 inputLength, - /*in*/ int isFirst, - /*in*/ int moreFragments, - /*in*/ TNC_UInt32 overallLength, - /*out*/ TNC_BufferReference *output, - /*out*/ TNC_UInt32 *outputLength, - /*out*/ int *answerIsFirst, - /*out*/ int *moreFragmentsFollow, - /*out*/ TNC_UInt32 *overallLengthOut); - -#endif //_TNCS_CONNECT_H_