summaryrefslogtreecommitdiff
path: root/radsecproxy
diff options
context:
space:
mode:
Diffstat (limited to 'radsecproxy')
-rw-r--r--radsecproxy/Makefile.am23
-rw-r--r--radsecproxy/Makefile.in589
-rw-r--r--radsecproxy/debug.c213
-rw-r--r--radsecproxy/debug.h36
-rw-r--r--radsecproxy/gconfig.h32
-rw-r--r--radsecproxy/hash.c131
-rw-r--r--radsecproxy/hash.h51
-rw-r--r--radsecproxy/hostport_types.h6
-rw-r--r--radsecproxy/list.c122
-rw-r--r--radsecproxy/list.h54
-rw-r--r--radsecproxy/radmsg.h40
-rw-r--r--radsecproxy/radsecproxy.h216
-rw-r--r--radsecproxy/tlscommon.c455
-rw-r--r--radsecproxy/tlscommon.h42
-rw-r--r--radsecproxy/tlv11.h23
-rw-r--r--radsecproxy/util.c256
-rw-r--r--radsecproxy/util.h35
17 files changed, 2324 insertions, 0 deletions
diff --git a/radsecproxy/Makefile.am b/radsecproxy/Makefile.am
new file mode 100644
index 0000000..dc5ffc4
--- /dev/null
+++ b/radsecproxy/Makefile.am
@@ -0,0 +1,23 @@
+AUTOMAKE_OPTIONS = foreign
+ACLOCAL_AMFLAGS = -I m4
+
+AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)
+AM_CFLAGS = -Wall -Werror -g
+
+noinst_LTLIBRARIES = libradsec-radsecproxy.la
+
+libradsec_radsecproxy_la_SOURCES = \
+ debug.c debug.h \
+ gconfig.h \
+ hash.c hash.h \
+ hostport_types.h \
+ list.c list.h \
+ radmsg.h \
+ radsecproxy.h \
+ tlv11.h \
+ util.c util.h
+
+if RS_ENABLE_TLS
+libradsec_radsecproxy_la_SOURCES += \
+ tlscommon.c tlscommon.h
+endif
diff --git a/radsecproxy/Makefile.in b/radsecproxy/Makefile.in
new file mode 100644
index 0000000..f1b074b
--- /dev/null
+++ b/radsecproxy/Makefile.in
@@ -0,0 +1,589 @@
+# Makefile.in generated by automake 1.14 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@RS_ENABLE_TLS_TRUE@am__append_1 = \
+@RS_ENABLE_TLS_TRUE@ tlscommon.c tlscommon.h
+
+subdir = radsecproxy
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/build-aux/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libradsec_radsecproxy_la_LIBADD =
+am__libradsec_radsecproxy_la_SOURCES_DIST = debug.c debug.h gconfig.h \
+ hash.c hash.h hostport_types.h list.c list.h radmsg.h \
+ radsecproxy.h tlv11.h util.c util.h tlscommon.c tlscommon.h
+@RS_ENABLE_TLS_TRUE@am__objects_1 = tlscommon.lo
+am_libradsec_radsecproxy_la_OBJECTS = debug.lo hash.lo list.lo util.lo \
+ $(am__objects_1)
+libradsec_radsecproxy_la_OBJECTS = \
+ $(am_libradsec_radsecproxy_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(libradsec_radsecproxy_la_SOURCES)
+DIST_SOURCES = $(am__libradsec_radsecproxy_la_SOURCES_DIST)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AUTOMAKE_OPTIONS = foreign
+ACLOCAL_AMFLAGS = -I m4
+AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)
+AM_CFLAGS = -Wall -Werror -g
+noinst_LTLIBRARIES = libradsec-radsecproxy.la
+libradsec_radsecproxy_la_SOURCES = debug.c debug.h gconfig.h hash.c \
+ hash.h hostport_types.h list.c list.h radmsg.h radsecproxy.h \
+ tlv11.h util.c util.h $(am__append_1)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign radsecproxy/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign radsecproxy/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+libradsec-radsecproxy.la: $(libradsec_radsecproxy_la_OBJECTS) $(libradsec_radsecproxy_la_DEPENDENCIES) $(EXTRA_libradsec_radsecproxy_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) $(libradsec_radsecproxy_la_OBJECTS) $(libradsec_radsecproxy_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tlscommon.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/util.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \
+ ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/radsecproxy/debug.c b/radsecproxy/debug.c
new file mode 100644
index 0000000..8a4881d
--- /dev/null
+++ b/radsecproxy/debug.c
@@ -0,0 +1,213 @@
+/* Copyright (c) 2007-2009, UNINETT AS
+ * Copyright (c) 2010-2011, NORDUnet A/S */
+/* See LICENSE for licensing information. */
+
+#ifndef SYS_SOLARIS9
+#include <stdint.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <strings.h>
+#include <time.h>
+#include <sys/time.h>
+#include <syslog.h>
+#include <errno.h>
+#include <assert.h>
+#include "debug.h"
+#include "util.h"
+
+static char *debug_ident = NULL;
+static uint8_t debug_level = DBG_INFO;
+static char *debug_filepath = NULL;
+static FILE *debug_file = NULL;
+static int debug_syslogfacility = 0;
+static uint8_t debug_timestamp = 0;
+
+void debug_init(char *ident) {
+ debug_file = stderr;
+ setvbuf(debug_file, NULL, _IONBF, 0);
+ debug_ident = ident;
+}
+
+void debug_set_level(uint8_t level) {
+ switch (level) {
+ case 1:
+ debug_level = DBG_ERR;
+ return;
+ case 2:
+ debug_level = DBG_WARN;
+ return;
+ case 3:
+ debug_level = DBG_NOTICE;
+ return;
+ case 4:
+ debug_level = DBG_INFO;
+ return;
+ case 5:
+ debug_level = DBG_DBG;
+ return;
+ }
+}
+
+void debug_timestamp_on() {
+ debug_timestamp = 1;
+}
+
+uint8_t debug_get_level() {
+ return debug_level;
+}
+
+int debug_set_destination(char *dest) {
+ static const char *facstrings[] = { "LOG_DAEMON", "LOG_MAIL", "LOG_USER", "LOG_LOCAL0",
+ "LOG_LOCAL1", "LOG_LOCAL2", "LOG_LOCAL3", "LOG_LOCAL4",
+ "LOG_LOCAL5", "LOG_LOCAL6", "LOG_LOCAL7", NULL };
+ static const int facvals[] = { LOG_DAEMON, LOG_MAIL, LOG_USER, LOG_LOCAL0,
+ LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4,
+ LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7 };
+ extern int errno;
+ int i;
+
+ if (!strncasecmp(dest, "file:///", 8)) {
+ debug_filepath = stringcopy(dest + 7, 0);
+ debug_file = fopen(debug_filepath, "a");
+ if (!debug_file) {
+ debug_file = stderr;
+ debugx(1, DBG_ERR, "Failed to open logfile %s\n%s",
+ debug_filepath, strerror(errno));
+ }
+ setvbuf(debug_file, NULL, _IONBF, 0);
+ return 1;
+ }
+ if (!strncasecmp(dest, "x-syslog://", 11)) {
+ dest += 11;
+ if (*dest == '/')
+ dest++;
+ if (*dest) {
+ for (i = 0; facstrings[i]; i++)
+ if (!strcasecmp(dest, facstrings[i]))
+ break;
+ if (!facstrings[i])
+ debugx(1, DBG_ERR, "Unknown syslog facility %s", dest);
+ debug_syslogfacility = facvals[i];
+ } else
+ debug_syslogfacility = LOG_DAEMON;
+ openlog(debug_ident, LOG_PID, debug_syslogfacility);
+ return 1;
+ }
+ debug(DBG_ERR, "Unknown log destination, exiting %s", dest);
+ exit(1);
+}
+
+void debug_reopen_log() {
+ extern int errno;
+
+ /* not a file, noop, return success */
+ if (!debug_filepath) {
+ debug(DBG_ERR, "skipping reopen");
+ return;
+ }
+
+ if (debug_file != stderr)
+ fclose(debug_file);
+
+ debug_file = fopen(debug_filepath, "a");
+ if (debug_file)
+ debug(DBG_ERR, "Reopened logfile %s", debug_filepath);
+ else {
+ debug_file = stderr;
+ debug(DBG_ERR, "Failed to open logfile %s, using stderr\n%s",
+ debug_filepath, strerror(errno));
+ }
+ setvbuf(debug_file, NULL, _IONBF, 0);
+}
+
+void debug_logit(uint8_t level, const char *format, va_list ap) {
+ struct timeval now;
+ char *timebuf;
+ int priority;
+
+ if (debug_syslogfacility) {
+ switch (level) {
+ case DBG_DBG:
+ priority = LOG_DEBUG;
+ break;
+ case DBG_INFO:
+ priority = LOG_INFO;
+ break;
+ case DBG_NOTICE:
+ priority = LOG_NOTICE;
+ break;
+ case DBG_WARN:
+ priority = LOG_WARNING;
+ break;
+ case DBG_ERR:
+ priority = LOG_ERR;
+ break;
+ default:
+ priority = LOG_DEBUG;
+ }
+ vsyslog(priority, format, ap);
+ } else {
+ if (debug_timestamp && (timebuf = malloc(256))) {
+ gettimeofday(&now, NULL);
+ ctime_r(&now.tv_sec, timebuf);
+ timebuf[strlen(timebuf) - 1] = '\0';
+ fprintf(debug_file, "%s: ", timebuf + 4);
+ free(timebuf);
+ }
+ vfprintf(debug_file, format, ap);
+ fprintf(debug_file, "\n");
+ }
+}
+
+void debug(uint8_t level, char *format, ...) {
+ va_list ap;
+ if (level < debug_level)
+ return;
+ va_start(ap, format);
+ debug_logit(level, format, ap);
+ va_end(ap);
+}
+
+void debugx(int status, uint8_t level, char *format, ...) {
+ if (level >= debug_level) {
+ va_list ap;
+ va_start(ap, format);
+ debug_logit(level, format, ap);
+ va_end(ap);
+ }
+ exit(status);
+}
+
+void debugerrno(int err, uint8_t level, char *format, ...) {
+ if (level >= debug_level) {
+ va_list ap;
+ size_t len = strlen(format);
+ char *tmp = malloc(len + 1024 + 2);
+ assert(tmp);
+ strcpy(tmp, format);
+ tmp[len++] = ':';
+ tmp[len++] = ' ';
+ if (strerror_r(err, tmp + len, 1024))
+ tmp = format;
+ va_start(ap, format);
+ debug_logit(level, tmp, ap);
+ va_end(ap);
+ }
+}
+
+void debugerrnox(int err, uint8_t level, char *format, ...) {
+ if (level >= debug_level) {
+ va_list ap;
+ va_start(ap, format);
+ debugerrno(err, level, format, ap);
+ va_end(ap);
+ }
+ exit(err);
+}
+
+/* Local Variables: */
+/* c-file-style: "stroustrup" */
+/* End: */
diff --git a/radsecproxy/debug.h b/radsecproxy/debug.h
new file mode 100644
index 0000000..f9858ab
--- /dev/null
+++ b/radsecproxy/debug.h
@@ -0,0 +1,36 @@
+/* Copyright (c) 2007-2009, UNINETT AS
+ * Copyright (c) 2010-2011, NORDUnet A/S */
+/* See LICENSE for licensing information. */
+
+#ifndef SYS_SOLARIS9
+#include <stdint.h>
+#endif
+
+#define DBG_DBG 8
+#define DBG_INFO 16
+#define DBG_NOTICE 32
+#define DBG_WARN 64
+#define DBG_ERR 128
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+void debug_init(char *ident);
+void debug_set_level(uint8_t level);
+void debug_timestamp_on();
+uint8_t debug_get_level();
+void debug(uint8_t level, char *format, ...);
+void debugx(int status, uint8_t level, char *format, ...);
+void debugerrno(int err, uint8_t level, char *format, ...);
+void debugerrnox(int err, uint8_t level, char *format, ...);
+int debug_set_destination(char *dest);
+void debug_reopen_log();
+
+#if defined (__cplusplus)
+}
+#endif
+
+/* Local Variables: */
+/* c-file-style: "stroustrup" */
+/* End: */
diff --git a/radsecproxy/gconfig.h b/radsecproxy/gconfig.h
new file mode 100644
index 0000000..3cb34b3
--- /dev/null
+++ b/radsecproxy/gconfig.h
@@ -0,0 +1,32 @@
+/* Copyright (c) 2007-2008, UNINETT AS */
+/* See LICENSE for licensing information. */
+
+#define CONF_STR 1
+#define CONF_CBK 2
+#define CONF_MSTR 3
+#define CONF_BLN 4
+#define CONF_LINT 5
+
+#include <stdio.h>
+
+struct gconffile {
+ char *path;
+ FILE *file;
+ const char *data;
+ size_t datapos;
+};
+
+int getconfigline(struct gconffile **cf, char *block, char **opt, char **val, int *conftype);
+int getgenericconfig(struct gconffile **cf, char *block, ...);
+int pushgconfdata(struct gconffile **cf, const char *data);
+FILE *pushgconfpath(struct gconffile **cf, const char *path);
+FILE *pushgconffile(struct gconffile **cf, FILE *file, const char *description);
+FILE *pushgconfpaths(struct gconffile **cf, const char *path);
+int popgconf(struct gconffile **cf);
+void freegconfmstr(char **mstr);
+void freegconf(struct gconffile **cf);
+struct gconffile *openconfigfile(const char *file);
+
+/* Local Variables: */
+/* c-file-style: "stroustrup" */
+/* End: */
diff --git a/radsecproxy/hash.c b/radsecproxy/hash.c
new file mode 100644
index 0000000..ab17433
--- /dev/null
+++ b/radsecproxy/hash.c
@@ -0,0 +1,131 @@
+/* Copyright (c) 2008, UNINETT AS */
+/* See LICENSE for licensing information. */
+
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include "list.h"
+#include "hash.h"
+
+/* allocates and initialises hash structure; returns NULL if malloc fails */
+struct hash *hash_create() {
+ struct hash *h = malloc(sizeof(struct hash));
+ if (!h)
+ return NULL;
+ h->hashlist = list_create();
+ if (!h->hashlist) {
+ free(h);
+ return NULL;
+ }
+ pthread_mutex_init(&h->mutex, NULL);
+ return h;
+}
+
+/* frees all memory associated with the hash */
+void hash_destroy(struct hash *h) {
+ struct list_node *ln;
+
+ if (!h)
+ return;
+ for (ln = list_first(h->hashlist); ln; ln = list_next(ln)) {
+ free(((struct hash_entry *)ln->data)->key);
+ free(((struct hash_entry *)ln->data)->data);
+ }
+ list_destroy(h->hashlist);
+ pthread_mutex_destroy(&h->mutex);
+}
+
+/* insert entry in hash; returns 1 if ok, 0 if malloc fails */
+int hash_insert(struct hash *h, void *key, uint32_t keylen, void *data) {
+ struct hash_entry *e;
+
+ if (!h)
+ return 0;
+ e = malloc(sizeof(struct hash_entry));
+ if (!e)
+ return 0;
+ memset(e, 0, sizeof(struct hash_entry));
+ e->key = malloc(keylen);
+ if (!e->key) {
+ free(e);
+ return 0;
+ }
+ memcpy(e->key, key, keylen);
+ e->keylen = keylen;
+ e->data = data;
+ pthread_mutex_lock(&h->mutex);
+ if (!list_push(h->hashlist, e)) {
+ pthread_mutex_unlock(&h->mutex);
+ free(e->key);
+ free(e);
+ return 0;
+ }
+ pthread_mutex_unlock(&h->mutex);
+ return 1;
+}
+
+/* reads entry from hash */
+void *hash_read(struct hash *h, void *key, uint32_t keylen) {
+ struct list_node *ln;
+ struct hash_entry *e;
+
+ if (!h)
+ return 0;
+ pthread_mutex_lock(&h->mutex);
+ for (ln = list_first(h->hashlist); ln; ln = list_next(ln)) {
+ e = (struct hash_entry *)ln->data;
+ if (e->keylen == keylen && !memcmp(e->key, key, keylen)) {
+ pthread_mutex_unlock(&h->mutex);
+ return e->data;
+ }
+ }
+ pthread_mutex_unlock(&h->mutex);
+ return NULL;
+}
+
+/* extracts entry from hash */
+void *hash_extract(struct hash *h, void *key, uint32_t keylen) {
+ struct list_node *ln;
+ struct hash_entry *e;
+
+ if (!h)
+ return 0;
+ pthread_mutex_lock(&h->mutex);
+ for (ln = list_first(h->hashlist); ln; ln = list_next(ln)) {
+ e = (struct hash_entry *)ln->data;
+ if (e->keylen == keylen && !memcmp(e->key, key, keylen)) {
+ free(e->key);
+ list_removedata(h->hashlist, e);
+ free(e);
+ pthread_mutex_unlock(&h->mutex);
+ return e->data;
+ }
+ }
+ pthread_mutex_unlock(&h->mutex);
+ return NULL;
+}
+
+/* returns first entry */
+struct hash_entry *hash_first(struct hash *hash) {
+ struct list_node *ln;
+ struct hash_entry *e;
+ if (!hash || !((ln = list_first(hash->hashlist))))
+ return NULL;
+ e = (struct hash_entry *)ln->data;
+ e->next = ln->next;
+ return e;
+}
+
+/* returns the next node after the argument */
+struct hash_entry *hash_next(struct hash_entry *entry) {
+ struct hash_entry *e;
+ if (!entry || !entry->next)
+ return NULL;
+ e = (struct hash_entry *)entry->next->data;
+ e->next = (struct list_node *)entry->next->next;
+ return e;
+}
+
+/* Local Variables: */
+/* c-file-style: "stroustrup" */
+/* End: */
diff --git a/radsecproxy/hash.h b/radsecproxy/hash.h
new file mode 100644
index 0000000..90ba64b
--- /dev/null
+++ b/radsecproxy/hash.h
@@ -0,0 +1,51 @@
+/* Copyright (c) 2008, UNINETT AS */
+/* See LICENSE for licensing information. */
+
+#ifndef SYS_SOLARIS9
+#include <stdint.h>
+#endif
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+struct hash {
+ struct list *hashlist;
+ pthread_mutex_t mutex;
+};
+
+struct hash_entry {
+ void *key;
+ uint32_t keylen;
+ void *data;
+ struct list_node *next; /* used when walking through hash */
+};
+
+/* allocates and initialises hash structure; returns NULL if malloc fails */
+struct hash *hash_create();
+
+/* frees all memory associated with the hash */
+void hash_destroy(struct hash *hash);
+
+/* insert entry in hash; returns 1 if ok, 0 if malloc fails */
+int hash_insert(struct hash *hash, void *key, uint32_t keylen, void *data);
+
+/* reads entry from hash */
+void *hash_read(struct hash *hash, void *key, uint32_t keylen);
+
+/* extracts (read and remove) entry from hash */
+void *hash_extract(struct hash *hash, void *key, uint32_t keylen);
+
+/* returns first entry */
+struct hash_entry *hash_first(struct hash *hash);
+
+/* returns the next entry after the argument */
+struct hash_entry *hash_next(struct hash_entry *entry);
+
+#if defined (__cplusplus)
+}
+#endif
+
+/* Local Variables: */
+/* c-file-style: "stroustrup" */
+/* End: */
diff --git a/radsecproxy/hostport_types.h b/radsecproxy/hostport_types.h
new file mode 100644
index 0000000..01fb443
--- /dev/null
+++ b/radsecproxy/hostport_types.h
@@ -0,0 +1,6 @@
+struct hostportres {
+ char *host;
+ char *port;
+ uint8_t prefixlen;
+ struct addrinfo *addrinfo;
+};
diff --git a/radsecproxy/list.c b/radsecproxy/list.c
new file mode 100644
index 0000000..4cfd358
--- /dev/null
+++ b/radsecproxy/list.c
@@ -0,0 +1,122 @@
+/* Copyright (c) 2007-2009, UNINETT AS */
+/* See LICENSE for licensing information. */
+
+#if defined HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include "list.h"
+
+/* allocates and initialises list structure; returns NULL if malloc fails */
+struct list *list_create() {
+ struct list *list = malloc(sizeof(struct list));
+ if (list)
+ memset(list, 0, sizeof(struct list));
+ return list;
+}
+
+/* frees all memory associated with the list */
+void list_destroy(struct list *list) {
+ struct list_node *node, *next;
+
+ if (!list)
+ return;
+
+ for (node = list->first; node; node = next) {
+ free(node->data);
+ next = node->next;
+ free(node);
+ }
+ free(list);
+}
+
+/* appends entry to list; returns 1 if ok, 0 if malloc fails */
+int list_push(struct list *list, void *data) {
+ struct list_node *node;
+
+ node = malloc(sizeof(struct list_node));
+ if (!node)
+ return 0;
+
+ node->next = NULL;
+ node->data = data;
+
+ if (list->first)
+ list->last->next = node;
+ else
+ list->first = node;
+ list->last = node;
+
+ list->count++;
+ return 1;
+}
+
+/* removes first entry from list and returns data */
+void *list_shift(struct list *list) {
+ struct list_node *node;
+ void *data;
+
+ if (!list || !list->first)
+ return NULL;
+
+ node = list->first;
+ list->first = node->next;
+ if (!list->first)
+ list->last = NULL;
+ data = node->data;
+ free(node);
+ list->count--;
+ return data;
+}
+
+/* removes all entries with matching data pointer */
+void list_removedata(struct list *list, void *data) {
+ struct list_node *node, *t;
+
+ if (!list || !list->first)
+ return;
+
+ node = list->first;
+ while (node->data == data) {
+ list->first = node->next;
+ free(node);
+ list->count--;
+ node = list->first;
+ if (!node) {
+ list->last = NULL;
+ return;
+ }
+ }
+ for (; node->next; node = node->next)
+ if (node->next->data == data) {
+ t = node->next;
+ node->next = t->next;
+ free(t);
+ list->count--;
+ if (!node->next) { /* we removed the last one */
+ list->last = node;
+ return;
+ }
+ }
+}
+
+/* returns first node */
+struct list_node *list_first(struct list *list) {
+ return list ? list->first : NULL;
+}
+
+/* returns the next node after the argument */
+struct list_node *list_next(struct list_node *node) {
+ return node->next;
+}
+
+/* returns number of nodes */
+uint32_t list_count(struct list *list) {
+ return list->count;
+}
+
+/* Local Variables: */
+/* c-file-style: "stroustrup" */
+/* End: */
diff --git a/radsecproxy/list.h b/radsecproxy/list.h
new file mode 100644
index 0000000..4f4d1f9
--- /dev/null
+++ b/radsecproxy/list.h
@@ -0,0 +1,54 @@
+/* Copyright (c) 2007-2009, UNINETT AS */
+/* See LICENSE for licensing information. */
+
+#ifdef SYS_SOLARIS9
+#include <sys/inttypes.h>
+#else
+#include <stdint.h>
+#endif
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+struct list_node {
+ struct list_node *next;
+ void *data;
+};
+
+struct list {
+ struct list_node *first, *last;
+ uint32_t count;
+};
+
+/* allocates and initialises list structure; returns NULL if malloc fails */
+struct list *list_create();
+
+/* frees all memory associated with the list */
+void list_destroy(struct list *list);
+
+/* appends entry to list; returns 1 if ok, 0 if malloc fails */
+int list_push(struct list *list, void *data);
+
+/* removes first entry from list and returns data */
+void *list_shift(struct list *list);
+
+/* removes first entry with matching data pointer */
+void list_removedata(struct list *list, void *data);
+
+/* returns first node */
+struct list_node *list_first(struct list *list);
+
+/* returns the next node after the argument */
+struct list_node *list_next(struct list_node *node);
+
+/* returns number of nodes */
+uint32_t list_count(struct list *list);
+
+#if defined (__cplusplus)
+}
+#endif
+
+/* Local Variables: */
+/* c-file-style: "stroustrup" */
+/* End: */
diff --git a/radsecproxy/radmsg.h b/radsecproxy/radmsg.h
new file mode 100644
index 0000000..1bef59b
--- /dev/null
+++ b/radsecproxy/radmsg.h
@@ -0,0 +1,40 @@
+/* Copyright (c) 2007-2008, UNINETT AS */
+/* See LICENSE for licensing information. */
+
+#define RAD_Access_Request 1
+#define RAD_Access_Accept 2
+#define RAD_Access_Reject 3
+#define RAD_Accounting_Request 4
+#define RAD_Accounting_Response 5
+#define RAD_Access_Challenge 11
+#define RAD_Status_Server 12
+#define RAD_Status_Client 13
+
+#define RAD_Attr_User_Name 1
+#define RAD_Attr_User_Password 2
+#define RAD_Attr_Reply_Message 18
+#define RAD_Attr_Vendor_Specific 26
+#define RAD_Attr_Calling_Station_Id 31
+#define RAD_Attr_Tunnel_Password 69
+#define RAD_Attr_Message_Authenticator 80
+
+#define RAD_VS_ATTR_MS_MPPE_Send_Key 16
+#define RAD_VS_ATTR_MS_MPPE_Recv_Key 17
+
+struct radmsg {
+ uint8_t code;
+ uint8_t id;
+ uint8_t auth[20];
+ struct list *attrs;
+};
+
+void radmsg_free(struct radmsg *);
+struct radmsg *radmsg_init(uint8_t, uint8_t, uint8_t *);
+int radmsg_add(struct radmsg *, struct tlv *);
+struct tlv *radmsg_gettype(struct radmsg *, uint8_t);
+uint8_t *radmsg2buf(struct radmsg *msg, uint8_t *);
+struct radmsg *buf2radmsg(uint8_t *, uint8_t *, uint8_t *);
+
+/* Local Variables: */
+/* c-file-style: "stroustrup" */
+/* End: */
diff --git a/radsecproxy/radsecproxy.h b/radsecproxy/radsecproxy.h
new file mode 100644
index 0000000..7528f7f
--- /dev/null
+++ b/radsecproxy/radsecproxy.h
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2006-2009 Stig Venaas <venaas@uninett.no>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ */
+
+#include "tlv11.h"
+#include "radmsg.h"
+#include "gconfig.h"
+
+#define DEBUG_LEVEL 2
+
+#define CONFIG_MAIN "/etc/radsecproxy.conf"
+
+/* MAX_REQUESTS must be 256 due to Radius' 8 bit ID field */
+#define MAX_REQUESTS 256
+#define REQUEST_RETRY_INTERVAL 5
+#define REQUEST_RETRY_COUNT 2
+#define DUPLICATE_INTERVAL REQUEST_RETRY_INTERVAL * REQUEST_RETRY_COUNT
+#define MAX_CERT_DEPTH 5
+#define STATUS_SERVER_PERIOD 25
+#define IDLE_TIMEOUT 300
+
+/* 27262 is vendor DANTE Ltd. */
+#define DEFAULT_TTL_ATTR "27262:1"
+
+#define RAD_UDP 0
+#define RAD_TLS 1
+#define RAD_TCP 2
+#define RAD_DTLS 3
+#define RAD_PROTOCOUNT 4
+
+struct options {
+ char *logdestination;
+ char *ttlattr;
+ uint32_t ttlattrtype[2];
+ uint8_t addttl;
+ uint8_t loglevel;
+ uint8_t loopprevention;
+};
+
+struct commonprotoopts {
+ char **listenargs;
+ char *sourcearg;
+};
+
+struct request {
+ struct timeval created;
+ uint32_t refcount;
+ uint8_t *buf, *replybuf;
+ struct radmsg *msg;
+ struct client *from;
+ struct server *to;
+ char *origusername;
+ uint8_t rqid;
+ uint8_t rqauth[16];
+ uint8_t newid;
+ int udpsock; /* only for UDP */
+ uint16_t udpport; /* only for UDP */
+};
+
+/* requests that our client will send */
+struct rqout {
+ pthread_mutex_t *lock;
+ struct request *rq;
+ uint8_t tries;
+ struct timeval expiry;
+};
+
+struct gqueue {
+ struct list *entries;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+};
+
+struct clsrvconf {
+ char *name;
+ uint8_t type; /* RAD_UDP/RAD_TLS/RAD_TCP */
+ const struct protodefs *pdef;
+ char **hostsrc;
+ char *portsrc;
+ struct list *hostports;
+ char *secret;
+ char *tls;
+ char *matchcertattr;
+ regex_t *certcnregex;
+ regex_t *certuriregex;
+ char *confrewritein;
+ char *confrewriteout;
+ char *confrewriteusername;
+ struct modattr *rewriteusername;
+ char *dynamiclookupcommand;
+ uint8_t statusserver;
+ uint8_t retryinterval;
+ uint8_t retrycount;
+ uint8_t dupinterval;
+ uint8_t certnamecheck;
+ uint8_t addttl;
+ uint8_t loopprevention;
+ struct rewrite *rewritein;
+ struct rewrite *rewriteout;
+ pthread_mutex_t *lock; /* only used for updating clients so far */
+ struct tls *tlsconf;
+ struct list *clients;
+ struct server *servers;
+};
+
+#include "tlscommon.h"
+
+struct client {
+ struct clsrvconf *conf;
+ int sock;
+ SSL *ssl;
+ struct request *rqs[MAX_REQUESTS];
+ struct gqueue *replyq;
+ struct gqueue *rbios; /* for dtls */
+ struct sockaddr *addr;
+ time_t expiry; /* for udp */
+};
+
+struct server {
+ struct clsrvconf *conf;
+ int sock;
+ SSL *ssl;
+ pthread_mutex_t lock;
+ pthread_t clientth;
+ uint8_t clientrdgone;
+ struct timeval lastconnecttry;
+ struct timeval lastreply;
+ uint8_t connectionok;
+ uint8_t lostrqs;
+ uint8_t dynstartup;
+ char *dynamiclookuparg;
+ int nextid;
+ struct timeval lastrcv;
+ struct rqout *requests;
+ uint8_t newrq;
+ pthread_mutex_t newrq_mutex;
+ pthread_cond_t newrq_cond;
+ struct gqueue *rbios; /* for dtls */
+};
+
+struct realm {
+ char *name;
+ char *message;
+ uint8_t accresp;
+ regex_t regex;
+ uint32_t refcount;
+ pthread_mutex_t mutex;
+ struct realm *parent;
+ struct list *subrealms;
+ struct list *srvconfs;
+ struct list *accsrvconfs;
+};
+
+struct modattr {
+ uint8_t t;
+ char *replacement;
+ regex_t *regex;
+};
+
+struct rewrite {
+ uint8_t *removeattrs;
+ uint32_t *removevendorattrs;
+ struct list *addattrs;
+ struct list *modattrs;
+};
+
+struct protodefs {
+ char *name;
+ char *secretdefault;
+ int socktype;
+ char *portdefault;
+ uint8_t retrycountdefault;
+ uint8_t retrycountmax;
+ uint8_t retryintervaldefault;
+ uint8_t retryintervalmax;
+ uint8_t duplicateintervaldefault;
+ void (*setprotoopts)(struct commonprotoopts *);
+ char **(*getlistenerargs)();
+ void *(*listener)(void*);
+ int (*connecter)(struct server *, struct timeval *, int, char *);
+ void *(*clientconnreader)(void*);
+ int (*clientradput)(struct server *, unsigned char *);
+ void (*addclient)(struct client *);
+ void (*addserverextra)(struct clsrvconf *);
+ void (*setsrcres)();
+ void (*initextra)();
+};
+
+#define RADLEN(x) ntohs(((uint16_t *)(x))[1])
+
+#define ATTRTYPE(x) ((x)[0])
+#define ATTRLEN(x) ((x)[1])
+#define ATTRVAL(x) ((x) + 2)
+#define ATTRVALLEN(x) ((x)[1] - 2)
+
+struct clsrvconf *find_clconf(uint8_t type, struct sockaddr *addr, struct list_node **cur);
+struct clsrvconf *find_srvconf(uint8_t type, struct sockaddr *addr, struct list_node **cur);
+struct clsrvconf *find_clconf_type(uint8_t type, struct list_node **cur);
+struct client *addclient(struct clsrvconf *conf, uint8_t lock);
+void removelockedclient(struct client *client);
+void removeclient(struct client *client);
+struct gqueue *newqueue();
+void freebios(struct gqueue *q);
+struct request *newrequest();
+void freerq(struct request *rq);
+int radsrv(struct request *rq);
+void replyh(struct server *server, unsigned char *buf);
+struct addrinfo *resolve_hostport_addrinfo(uint8_t type, char *hostport);
+
+/* Local Variables: */
+/* c-file-style: "stroustrup" */
+/* End: */
diff --git a/radsecproxy/tlscommon.c b/radsecproxy/tlscommon.c
new file mode 100644
index 0000000..a31fa32
--- /dev/null
+++ b/radsecproxy/tlscommon.c
@@ -0,0 +1,455 @@
+/* Copyright (c) 2007-2009, UNINETT AS
+ * Copyright (c) 2010-2011, NORDUnet A/S */
+/* See LICENSE for licensing information. */
+
+#if defined HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <signal.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+#ifdef SYS_SOLARIS9
+#include <fcntl.h>
+#endif
+#include <sys/time.h>
+#include <sys/select.h>
+#include <ctype.h>
+#include <sys/wait.h>
+#include <arpa/inet.h>
+#include <regex.h>
+#include <libgen.h>
+#include <pthread.h>
+#include <openssl/ssl.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#include <openssl/md5.h>
+#include <openssl/x509v3.h>
+#include "debug.h"
+#include "list.h"
+#include "hash.h"
+#include "util.h"
+#include "hostport_types.h"
+#include "radsecproxy.h"
+
+static int pem_passwd_cb(char *buf, int size, int rwflag, void *userdata) {
+ int pwdlen = strlen(userdata);
+ if (rwflag != 0 || pwdlen > size) /* not for decryption or too large */
+ return 0;
+ memcpy(buf, userdata, pwdlen);
+ return pwdlen;
+}
+
+static int verify_cb(int ok, X509_STORE_CTX *ctx) {
+ char *buf = NULL;
+ X509 *err_cert;
+ int err, depth;
+
+ err_cert = X509_STORE_CTX_get_current_cert(ctx);
+ err = X509_STORE_CTX_get_error(ctx);
+ depth = X509_STORE_CTX_get_error_depth(ctx);
+
+ if (depth > MAX_CERT_DEPTH) {
+ ok = 0;
+ err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
+ X509_STORE_CTX_set_error(ctx, err);
+ }
+
+ if (!ok) {
+ if (err_cert)
+ buf = X509_NAME_oneline(X509_get_subject_name(err_cert), NULL, 0);
+ debug(DBG_WARN, "verify error: num=%d:%s:depth=%d:%s", err, X509_verify_cert_error_string(err), depth, buf ? buf : "");
+ free(buf);
+ buf = NULL;
+
+ switch (err) {
+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+ if (err_cert) {
+ buf = X509_NAME_oneline(X509_get_issuer_name(err_cert), NULL, 0);
+ if (buf) {
+ debug(DBG_WARN, "\tIssuer=%s", buf);
+ free(buf);
+ buf = NULL;
+ }
+ }
+ break;
+ case X509_V_ERR_CERT_NOT_YET_VALID:
+ case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+ debug(DBG_WARN, "\tCertificate not yet valid");
+ break;
+ case X509_V_ERR_CERT_HAS_EXPIRED:
+ debug(DBG_WARN, "Certificate has expired");
+ break;
+ case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+ debug(DBG_WARN, "Certificate no longer valid (after notAfter)");
+ break;
+ case X509_V_ERR_NO_EXPLICIT_POLICY:
+ debug(DBG_WARN, "No Explicit Certificate Policy");
+ break;
+ }
+ }
+ return ok;
+}
+
+#ifdef DEBUG
+static void ssl_info_callback(const SSL *ssl, int where, int ret) {
+ const char *s;
+ int w;
+
+ w = where & ~SSL_ST_MASK;
+
+ if (w & SSL_ST_CONNECT)
+ s = "SSL_connect";
+ else if (w & SSL_ST_ACCEPT)
+ s = "SSL_accept";
+ else
+ s = "undefined";
+
+ if (where & SSL_CB_LOOP)
+ debug(DBG_DBG, "%s:%s\n", s, SSL_state_string_long(ssl));
+ else if (where & SSL_CB_ALERT) {
+ s = (where & SSL_CB_READ) ? "read" : "write";
+ debug(DBG_DBG, "SSL3 alert %s:%s:%s\n", s, SSL_alert_type_string_long(ret), SSL_alert_desc_string_long(ret));
+ }
+ else if (where & SSL_CB_EXIT) {
+ if (ret == 0)
+ debug(DBG_DBG, "%s:failed in %s\n", s, SSL_state_string_long(ssl));
+ else if (ret < 0)
+ debug(DBG_DBG, "%s:error in %s\n", s, SSL_state_string_long(ssl));
+ }
+}
+#endif
+
+static X509_VERIFY_PARAM *createverifyparams(char **poids) {
+ X509_VERIFY_PARAM *pm;
+ ASN1_OBJECT *pobject;
+ int i;
+
+ pm = X509_VERIFY_PARAM_new();
+ if (!pm)
+ return NULL;
+
+ for (i = 0; poids[i]; i++) {
+ pobject = OBJ_txt2obj(poids[i], 0);
+ if (!pobject) {
+ X509_VERIFY_PARAM_free(pm);
+ return NULL;
+ }
+ X509_VERIFY_PARAM_add0_policy(pm, pobject);
+ }
+
+ X509_VERIFY_PARAM_set_flags(pm, X509_V_FLAG_POLICY_CHECK | X509_V_FLAG_EXPLICIT_POLICY);
+ return pm;
+}
+
+static int tlsaddcacrl(SSL_CTX *ctx, struct tls *conf) {
+ STACK_OF(X509_NAME) *calist;
+ X509_STORE *x509_s;
+ unsigned long error;
+
+ if (!SSL_CTX_load_verify_locations(ctx, conf->cacertfile, conf->cacertpath)) {
+ while ((error = ERR_get_error()))
+ debug(DBG_ERR, "SSL: %s", ERR_error_string(error, NULL));
+ debug(DBG_ERR, "tlsaddcacrl: Error updating TLS context %s", conf->name);
+ return 0;
+ }
+
+ calist = conf->cacertfile ? SSL_load_client_CA_file(conf->cacertfile) : NULL;
+
+ if (!conf->cacertfile || calist) {
+ if (conf->cacertpath) {
+ if (!calist)
+ calist = sk_X509_NAME_new_null();
+ if (!SSL_add_dir_cert_subjects_to_stack(calist, conf->cacertpath)) {
+ sk_X509_NAME_free(calist);
+ calist = NULL;
+ }
+ }
+ }
+ if (!calist) {
+ while ((error = ERR_get_error()))
+ debug(DBG_ERR, "SSL: %s", ERR_error_string(error, NULL));
+ debug(DBG_ERR, "tlsaddcacrl: Error adding CA subjects in TLS context %s", conf->name);
+ return 0;
+ }
+ ERR_clear_error(); /* add_dir_cert_subj returns errors on success */
+ SSL_CTX_set_client_CA_list(ctx, calist);
+
+ SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb);
+ SSL_CTX_set_verify_depth(ctx, MAX_CERT_DEPTH + 1);
+
+ if (conf->crlcheck || conf->vpm) {
+ x509_s = SSL_CTX_get_cert_store(ctx);
+ if (conf->crlcheck)
+ X509_STORE_set_flags(x509_s, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
+ if (conf->vpm)
+ X509_STORE_set1_param(x509_s, conf->vpm);
+ }
+
+ debug(DBG_DBG, "tlsaddcacrl: updated TLS context %s", conf->name);
+ return 1;
+}
+
+static SSL_CTX *tlscreatectx(uint8_t type, struct tls *conf) {
+ SSL_CTX *ctx = NULL;
+ unsigned long error;
+
+ switch (type) {
+#ifdef RADPROT_TLS
+ case RAD_TLS:
+ ctx = SSL_CTX_new(TLSv1_method());
+ break;
+#endif
+#ifdef RADPROT_DTLS
+ case RAD_DTLS:
+ ctx = SSL_CTX_new(DTLSv1_method());
+ SSL_CTX_set_read_ahead(ctx, 1);
+ break;
+#endif
+ }
+ if (!ctx) {
+ debug(DBG_ERR, "tlscreatectx: Error initialising SSL/TLS in TLS context %s", conf->name);
+ while ((error = ERR_get_error()))
+ debug(DBG_ERR, "SSL: %s", ERR_error_string(error, NULL));
+ return NULL;
+ }
+#ifdef DEBUG
+ SSL_CTX_set_info_callback(ctx, ssl_info_callback);
+#endif
+
+ if (conf->certkeypwd) {
+ SSL_CTX_set_default_passwd_cb_userdata(ctx, conf->certkeypwd);
+ SSL_CTX_set_default_passwd_cb(ctx, pem_passwd_cb);
+ }
+ if (conf->certfile || conf->certkeyfile) {
+ if (!SSL_CTX_use_certificate_chain_file(ctx, conf->certfile) ||
+ !SSL_CTX_use_PrivateKey_file(ctx, conf->certkeyfile, SSL_FILETYPE_PEM) ||
+ !SSL_CTX_check_private_key(ctx)) {
+ while ((error = ERR_get_error()))
+ debug(DBG_ERR, "SSL: %s", ERR_error_string(error, NULL));
+ debug(DBG_ERR, "tlscreatectx: Error initialising SSL/TLS (certfile issues) in TLS context %s", conf->name);
+ SSL_CTX_free(ctx);
+ return NULL;
+ }
+ }
+
+ if (conf->policyoids) {
+ if (!conf->vpm) {
+ conf->vpm = createverifyparams(conf->policyoids);
+ if (!conf->vpm) {
+ debug(DBG_ERR, "tlscreatectx: Failed to add policyOIDs in TLS context %s", conf->name);
+ SSL_CTX_free(ctx);
+ return NULL;
+ }
+ }
+ }
+
+ if (conf->cacertfile != NULL || conf->cacertpath != NULL)
+ if (!tlsaddcacrl(ctx, conf)) {
+ if (conf->vpm) {
+ X509_VERIFY_PARAM_free(conf->vpm);
+ conf->vpm = NULL;
+ }
+ SSL_CTX_free(ctx);
+ return NULL;
+ }
+
+ debug(DBG_DBG, "tlscreatectx: created TLS context %s", conf->name);
+ return ctx;
+}
+
+SSL_CTX *tlsgetctx(uint8_t type, struct tls *t) {
+ struct timeval now;
+
+ if (!t)
+ return NULL;
+ gettimeofday(&now, NULL);
+
+ switch (type) {
+#ifdef RADPROT_TLS
+ case RAD_TLS:
+ if (t->tlsexpiry && t->tlsctx) {
+ if (t->tlsexpiry < now.tv_sec) {
+ t->tlsexpiry = now.tv_sec + t->cacheexpiry;
+ tlsaddcacrl(t->tlsctx, t);
+ }
+ }
+ if (!t->tlsctx) {
+ t->tlsctx = tlscreatectx(RAD_TLS, t);
+ if (t->cacheexpiry)
+ t->tlsexpiry = now.tv_sec + t->cacheexpiry;
+ }
+ return t->tlsctx;
+#endif
+#ifdef RADPROT_DTLS
+ case RAD_DTLS:
+ if (t->dtlsexpiry && t->dtlsctx) {
+ if (t->dtlsexpiry < now.tv_sec) {
+ t->dtlsexpiry = now.tv_sec + t->cacheexpiry;
+ tlsaddcacrl(t->dtlsctx, t);
+ }
+ }
+ if (!t->dtlsctx) {
+ t->dtlsctx = tlscreatectx(RAD_DTLS, t);
+ if (t->cacheexpiry)
+ t->dtlsexpiry = now.tv_sec + t->cacheexpiry;
+ }
+ return t->dtlsctx;
+#endif
+ }
+ return NULL;
+}
+
+X509 *verifytlscert(SSL *ssl) {
+ X509 *cert;
+ unsigned long error;
+
+ if (SSL_get_verify_result(ssl) != X509_V_OK) {
+ debug(DBG_ERR, "verifytlscert: basic validation failed");
+ while ((error = ERR_get_error()))
+ debug(DBG_ERR, "verifytlscert: TLS: %s", ERR_error_string(error, NULL));
+ return NULL;
+ }
+
+ cert = SSL_get_peer_certificate(ssl);
+ if (!cert)
+ debug(DBG_ERR, "verifytlscert: failed to obtain certificate");
+ return cert;
+}
+
+int subjectaltnameaddr(X509 *cert, int family, const struct in6_addr *addr) {
+ int loc, i, l, n, r = 0;
+ char *v;
+ X509_EXTENSION *ex;
+ STACK_OF(GENERAL_NAME) *alt;
+ GENERAL_NAME *gn;
+
+ debug(DBG_DBG, "subjectaltnameaddr");
+
+ loc = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1);
+ if (loc < 0)
+ return r;
+
+ ex = X509_get_ext(cert, loc);
+ alt = X509V3_EXT_d2i(ex);
+ if (!alt)
+ return r;
+
+ n = sk_GENERAL_NAME_num(alt);
+ for (i = 0; i < n; i++) {
+ gn = sk_GENERAL_NAME_value(alt, i);
+ if (gn->type != GEN_IPADD)
+ continue;
+ r = -1;
+ v = (char *)ASN1_STRING_data(gn->d.ia5);
+ l = ASN1_STRING_length(gn->d.ia5);
+ if (((family == AF_INET && l == sizeof(struct in_addr)) || (family == AF_INET6 && l == sizeof(struct in6_addr)))
+ && !memcmp(v, &addr, l)) {
+ r = 1;
+ break;
+ }
+ }
+ GENERAL_NAMES_free(alt);
+ return r;
+}
+
+int subjectaltnameregexp(X509 *cert, int type, const char *exact, const regex_t *regex) {
+ int loc, i, l, n, r = 0;
+ char *s, *v;
+ X509_EXTENSION *ex;
+ STACK_OF(GENERAL_NAME) *alt;
+ GENERAL_NAME *gn;
+
+ debug(DBG_DBG, "subjectaltnameregexp");
+
+ loc = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1);
+ if (loc < 0)
+ return r;
+
+ ex = X509_get_ext(cert, loc);
+ alt = X509V3_EXT_d2i(ex);
+ if (!alt)
+ return r;
+
+ n = sk_GENERAL_NAME_num(alt);
+ for (i = 0; i < n; i++) {
+ gn = sk_GENERAL_NAME_value(alt, i);
+ if (gn->type != type)
+ continue;
+ r = -1;
+ v = (char *)ASN1_STRING_data(gn->d.ia5);
+ l = ASN1_STRING_length(gn->d.ia5);
+ if (l <= 0)
+ continue;
+#ifdef DEBUG
+ printfchars(NULL, gn->type == GEN_DNS ? "dns" : "uri", NULL, v, l);
+#endif
+ if (exact) {
+ if (memcmp(v, exact, l))
+ continue;
+ } else {
+ s = stringcopy((char *)v, l);
+ if (!s) {
+ debug(DBG_ERR, "malloc failed");
+ continue;
+ }
+ if (regexec(regex, s, 0, NULL, 0)) {
+ free(s);
+ continue;
+ }
+ free(s);
+ }
+ r = 1;
+ break;
+ }
+ GENERAL_NAMES_free(alt);
+ return r;
+}
+
+int cnregexp(X509 *cert, const char *exact, const regex_t *regex) {
+ int loc, l;
+ char *v, *s;
+ X509_NAME *nm;
+ X509_NAME_ENTRY *e;
+ ASN1_STRING *t;
+
+ nm = X509_get_subject_name(cert);
+ loc = -1;
+ for (;;) {
+ loc = X509_NAME_get_index_by_NID(nm, NID_commonName, loc);
+ if (loc == -1)
+ break;
+ e = X509_NAME_get_entry(nm, loc);
+ t = X509_NAME_ENTRY_get_data(e);
+ v = (char *) ASN1_STRING_data(t);
+ l = ASN1_STRING_length(t);
+ if (l < 0)
+ continue;
+ if (exact) {
+ if (l == strlen(exact) && !strncasecmp(exact, v, l))
+ return 1;
+ } else {
+ s = stringcopy((char *)v, l);
+ if (!s) {
+ debug(DBG_ERR, "malloc failed");
+ continue;
+ }
+ if (regexec(regex, s, 0, NULL, 0)) {
+ free(s);
+ continue;
+ }
+ free(s);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* Local Variables: */
+/* c-file-style: "stroustrup" */
+/* End: */
diff --git a/radsecproxy/tlscommon.h b/radsecproxy/tlscommon.h
new file mode 100644
index 0000000..5a6d262
--- /dev/null
+++ b/radsecproxy/tlscommon.h
@@ -0,0 +1,42 @@
+/* Copyright (c) 2007-2009, UNINETT AS */
+/* See LICENSE for licensing information. */
+
+#include <netinet/in.h>
+#include <openssl/ssl.h>
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+struct tls {
+ char *name;
+ char *cacertfile;
+ char *cacertpath;
+ char *certfile;
+ char *certkeyfile;
+ char *certkeypwd;
+ uint8_t crlcheck;
+ char **policyoids;
+ uint32_t cacheexpiry;
+ uint32_t tlsexpiry;
+ uint32_t dtlsexpiry;
+ X509_VERIFY_PARAM *vpm;
+ SSL_CTX *tlsctx;
+ SSL_CTX *dtlsctx;
+};
+
+#if defined(RADPROT_TLS) || defined(RADPROT_DTLS)
+SSL_CTX *tlsgetctx(uint8_t type, struct tls *t);
+X509 *verifytlscert(SSL *ssl);
+int subjectaltnameaddr(X509 *cert, int family, const struct in6_addr *addr);
+int subjectaltnameregexp(X509 *cert, int type, const char *exact, const regex_t *regex);
+int cnregexp(X509 *cert, const char *exact, const regex_t *regex);
+#endif
+
+#if defined (__cplusplus)
+}
+#endif
+
+/* Local Variables: */
+/* c-file-style: "stroustrup" */
+/* End: */
diff --git a/radsecproxy/tlv11.h b/radsecproxy/tlv11.h
new file mode 100644
index 0000000..87909c0
--- /dev/null
+++ b/radsecproxy/tlv11.h
@@ -0,0 +1,23 @@
+/* Copyright (c) 2008, UNINETT AS
+ * Copyright (c) 2010, NORDUnet A/S */
+/* See LICENSE for licensing information. */
+
+struct tlv {
+ uint8_t t;
+ uint8_t l;
+ uint8_t *v;
+};
+
+struct tlv *maketlv(uint8_t, uint8_t, void *);
+struct tlv *copytlv(struct tlv *);
+void freetlv(struct tlv *);
+int eqtlv(struct tlv *, struct tlv *);
+struct list *copytlvlist(struct list *);
+void freetlvlist(struct list *);
+void rmtlv(struct list *, uint8_t);
+uint8_t *tlv2str(struct tlv *tlv);
+uint8_t *tlv2buf(uint8_t *, const struct tlv *tlv);
+
+/* Local Variables: */
+/* c-file-style: "stroustrup" */
+/* End: */
diff --git a/radsecproxy/util.c b/radsecproxy/util.c
new file mode 100644
index 0000000..ad974ac
--- /dev/null
+++ b/radsecproxy/util.c
@@ -0,0 +1,256 @@
+/* Copyright (c) 2007-2009, UNINETT AS */
+/* See LICENSE for licensing information. */
+
+/* Code contributions from:
+ *
+ * Stefan Winter <stefan.winter@restena.lu>
+ */
+
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/select.h>
+#include <stdarg.h>
+#include "debug.h"
+#include "util.h"
+
+char *stringcopy(const char *s, int len) {
+ char *r;
+ if (!s)
+ return NULL;
+ if (!len)
+ len = strlen(s);
+ r = malloc(len + 1);
+ if (!r)
+ debug(DBG_ERR, "stringcopy: malloc failed");
+ memcpy(r, s, len);
+ r[len] = '\0';
+ return r;
+}
+
+void printfchars(char *prefixfmt, char *prefix, char *charfmt, char *chars, int len) {
+ int i;
+ unsigned char *s = (unsigned char *)chars;
+ if (prefix)
+ printf(prefixfmt ? prefixfmt : "%s: ", prefix);
+ for (i = 0; i < len; i++)
+ printf(charfmt ? charfmt : "%c", s[i]);
+ printf("\n");
+}
+
+void port_set(struct sockaddr *sa, uint16_t port) {
+ switch (sa->sa_family) {
+ case AF_INET:
+ ((struct sockaddr_in *)sa)->sin_port = htons(port);
+ break;
+ case AF_INET6:
+ ((struct sockaddr_in6 *)sa)->sin6_port = htons(port);
+ break;
+ }
+}
+
+struct sockaddr *addr_copy(struct sockaddr *in) {
+ struct sockaddr *out = NULL;
+
+ switch (in->sa_family) {
+ case AF_INET:
+ out = malloc(sizeof(struct sockaddr_in));
+ if (out) {
+ memset(out, 0, sizeof(struct sockaddr_in));
+ ((struct sockaddr_in *)out)->sin_addr = ((struct sockaddr_in *)in)->sin_addr;
+ }
+ break;
+ case AF_INET6:
+ out = malloc(sizeof(struct sockaddr_in6));
+ if (out) {
+ memset(out, 0, sizeof(struct sockaddr_in6));
+ ((struct sockaddr_in6 *)out)->sin6_addr = ((struct sockaddr_in6 *)in)->sin6_addr;
+ }
+ break;
+ }
+ out->sa_family = in->sa_family;
+#ifdef SIN6_LEN
+ out->sa_len = in->sa_len;
+#endif
+ return out;
+}
+
+char *addr2string(struct sockaddr *addr) {
+ union {
+ struct sockaddr *sa;
+ struct sockaddr_in *sa4;
+ struct sockaddr_in6 *sa6;
+ } u;
+ struct sockaddr_in sa4;
+ static char addr_buf[2][INET6_ADDRSTRLEN];
+ static int i = 0;
+ i = !i;
+ u.sa = addr;
+ if (u.sa->sa_family == AF_INET6) {
+ if (IN6_IS_ADDR_V4MAPPED(&u.sa6->sin6_addr)) {
+ memset(&sa4, 0, sizeof(sa4));
+ sa4.sin_family = AF_INET;
+ sa4.sin_port = u.sa6->sin6_port;
+ memcpy(&sa4.sin_addr, &u.sa6->sin6_addr.s6_addr[12], 4);
+ u.sa4 = &sa4;
+ }
+ }
+ if (getnameinfo(u.sa, SOCKADDRP_SIZE(u.sa), addr_buf[i], sizeof(addr_buf[i]),
+ NULL, 0, NI_NUMERICHOST)) {
+ debug(DBG_WARN, "getnameinfo failed");
+ return "getnameinfo_failed";
+ }
+ return addr_buf[i];
+}
+
+#if 0
+/* not in use */
+int connectport(int type, char *host, char *port) {
+ struct addrinfo hints, *res0, *res;
+ int s = -1;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_socktype = type;
+ hints.ai_family = AF_UNSPEC;
+
+ if (getaddrinfo(host, port, &hints, &res0) != 0) {
+ debug(DBG_ERR, "connectport: can't resolve host %s port %s", host, port);
+ return -1;
+ }
+
+ for (res = res0; res; res = res->ai_next) {
+ s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (s < 0) {
+ debug(DBG_WARN, "connectport: socket failed");
+ continue;
+ }
+ if (connect(s, res->ai_addr, res->ai_addrlen) == 0)
+ break;
+ debug(DBG_WARN, "connectport: connect failed");
+ close(s);
+ s = -1;
+ }
+ freeaddrinfo(res0);
+ return s;
+}
+#endif
+
+/* Disable the "Don't Fragment" bit for UDP sockets. It is set by default, which may cause an "oversized"
+ RADIUS packet to be discarded on first attempt (due to Path MTU discovery).
+*/
+
+void disable_DF_bit(int socket, struct addrinfo *res) {
+ if ((res->ai_family == AF_INET) && (res->ai_socktype == SOCK_DGRAM)) {
+#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
+ /*
+ * Turn off Path MTU discovery on IPv4/UDP sockets, Linux variant.
+ */
+ int r, action;
+ debug(DBG_INFO, "disable_DF_bit: disabling DF bit (Linux variant)");
+ action = IP_PMTUDISC_DONT;
+ r = setsockopt(socket, IPPROTO_IP, IP_MTU_DISCOVER, &action, sizeof(action));
+ if (r == -1)
+ debug(DBG_WARN, "Failed to set IP_MTU_DISCOVER");
+#else
+ debug(DBG_INFO, "Non-Linux platform, unable to unset DF bit for UDP. You should check with tcpdump whether radsecproxy will send its UDP packets with DF bit set!");
+#endif
+ }
+}
+
+int bindtoaddr(struct addrinfo *addrinfo, int family, int reuse, int v6only) {
+ int s, on = 1;
+ struct addrinfo *res;
+
+ for (res = addrinfo; res; res = res->ai_next) {
+ if (family != AF_UNSPEC && family != res->ai_family)
+ continue;
+ s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (s < 0) {
+ debug(DBG_WARN, "bindtoaddr: socket failed");
+ continue;
+ }
+
+ disable_DF_bit(s,res);
+
+ if (reuse)
+ setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
+#ifdef IPV6_V6ONLY
+ if (v6only)
+ setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
+#endif
+ if (!bind(s, res->ai_addr, res->ai_addrlen))
+ return s;
+ debug(DBG_WARN, "bindtoaddr: bind failed");
+ close(s);
+ }
+ return -1;
+}
+
+int connectnonblocking(int s, const struct sockaddr *addr, socklen_t addrlen, struct timeval *timeout) {
+ int origflags, error = 0, r = -1;
+ fd_set writefds;
+ socklen_t len;
+
+ origflags = fcntl(s, F_GETFL, 0);
+ fcntl(s, F_SETFL, origflags | O_NONBLOCK);
+ if (!connect(s, addr, addrlen)) {
+ r = 0;
+ goto exit;
+ }
+ if (errno != EINPROGRESS)
+ goto exit;
+
+ FD_ZERO(&writefds);
+ FD_SET(s, &writefds);
+ if (select(s + 1, NULL, &writefds, NULL, timeout) < 1)
+ goto exit;
+
+ len = sizeof(error);
+ if (!getsockopt(s, SOL_SOCKET, SO_ERROR, (char*)&error, &len) && !error)
+ r = 0;
+
+exit:
+ fcntl(s, F_SETFL, origflags);
+ return r;
+}
+
+int connecttcp(struct addrinfo *addrinfo, struct addrinfo *src, uint16_t timeout) {
+ int s;
+ struct addrinfo *res;
+ struct timeval to;
+
+ s = -1;
+ if (timeout) {
+ if (addrinfo && addrinfo->ai_next && timeout > 5)
+ timeout = 5;
+ to.tv_sec = timeout;
+ to.tv_usec = 0;
+ }
+
+ for (res = addrinfo; res; res = res->ai_next) {
+ s = bindtoaddr(src, res->ai_family, 1, 1);
+ if (s < 0) {
+ debug(DBG_WARN, "connecttoserver: socket failed");
+ continue;
+ }
+ if ((timeout
+ ? connectnonblocking(s, res->ai_addr, res->ai_addrlen, &to)
+ : connect(s, res->ai_addr, res->ai_addrlen)) == 0)
+ break;
+ debug(DBG_WARN, "connecttoserver: connect failed");
+ close(s);
+ s = -1;
+ }
+ return s;
+}
+
+/* Local Variables: */
+/* c-file-style: "stroustrup" */
+/* End: */
diff --git a/radsecproxy/util.h b/radsecproxy/util.h
new file mode 100644
index 0000000..cec4673
--- /dev/null
+++ b/radsecproxy/util.h
@@ -0,0 +1,35 @@
+/* Copyright (c) 2007-2009, UNINETT AS */
+/* See LICENSE for licensing information. */
+
+#include <sys/socket.h>
+#include <netdb.h>
+
+#define SOCKADDR_SIZE(addr) ((addr).ss_family == AF_INET ? \
+ sizeof(struct sockaddr_in) : \
+ sizeof(struct sockaddr_in6))
+
+#define SOCKADDRP_SIZE(addr) ((addr)->sa_family == AF_INET ? \
+ sizeof(struct sockaddr_in) : \
+ sizeof(struct sockaddr_in6))
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+char *stringcopy(const char *s, int len);
+char *addr2string(struct sockaddr *addr);
+struct sockaddr *addr_copy(struct sockaddr *in);
+void port_set(struct sockaddr *sa, uint16_t port);
+
+void printfchars(char *prefixfmt, char *prefix, char *charfmt, char *chars, int len);
+void disable_DF_bit(int socket, struct addrinfo *res);
+int bindtoaddr(struct addrinfo *addrinfo, int family, int reuse, int v6only);
+int connecttcp(struct addrinfo *addrinfo, struct addrinfo *src, uint16_t timeout);
+
+#if defined (__cplusplus)
+}
+#endif
+
+/* Local Variables: */
+/* c-file-style: "stroustrup" */
+/* End: */