summaryrefslogtreecommitdiff
path: root/src/tcsd
diff options
context:
space:
mode:
Diffstat (limited to 'src/tcsd')
-rw-r--r--src/tcsd/Makefile.am13
-rw-r--r--src/tcsd/Makefile.in589
-rw-r--r--src/tcsd/platform.c134
-rw-r--r--src/tcsd/svrside.c355
-rw-r--r--src/tcsd/tcsd_conf.c852
-rw-r--r--src/tcsd/tcsd_threads.c457
6 files changed, 2400 insertions, 0 deletions
diff --git a/src/tcsd/Makefile.am b/src/tcsd/Makefile.am
new file mode 100644
index 0000000..ff61a21
--- /dev/null
+++ b/src/tcsd/Makefile.am
@@ -0,0 +1,13 @@
+sbin_PROGRAMS=tcsd
+
+tcsd_CFLAGS=-DAPPID=\"TCSD\" -DVAR_PREFIX=\"@localstatedir@\" -DETC_PREFIX=\"@sysconfdir@\" -I${top_srcdir}/src/include
+tcsd_LDADD=${top_builddir}/src/tcs/libtcs.a ${top_builddir}/src/tddl/libtddl.a -lpthread @CRYPTOLIB@
+
+tcsd_SOURCES=svrside.c tcsd_conf.c tcsd_threads.c platform.c
+
+if TSS_BUILD_PS
+tcsd_CFLAGS+=-DTSS_BUILD_PS
+endif
+if TSS_BUILD_PCR_EVENTS
+tcsd_CFLAGS+=-DTSS_BUILD_PCR_EVENTS
+endif
diff --git a/src/tcsd/Makefile.in b/src/tcsd/Makefile.in
new file mode 100644
index 0000000..6ef1b00
--- /dev/null
+++ b/src/tcsd/Makefile.in
@@ -0,0 +1,589 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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@
+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@
+target_triplet = @target@
+sbin_PROGRAMS = tcsd$(EXEEXT)
+@TSS_BUILD_PS_TRUE@am__append_1 = -DTSS_BUILD_PS
+@TSS_BUILD_PCR_EVENTS_TRUE@am__append_2 = -DTSS_BUILD_PCR_EVENTS
+subdir = src/tcsd
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(sbindir)"
+PROGRAMS = $(sbin_PROGRAMS)
+am_tcsd_OBJECTS = tcsd-svrside.$(OBJEXT) tcsd-tcsd_conf.$(OBJEXT) \
+ tcsd-tcsd_threads.$(OBJEXT) tcsd-platform.$(OBJEXT)
+tcsd_OBJECTS = $(am_tcsd_OBJECTS)
+tcsd_DEPENDENCIES = ${top_builddir}/src/tcs/libtcs.a \
+ ${top_builddir}/src/tddl/libtddl.a
+tcsd_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(tcsd_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(tcsd_SOURCES)
+DIST_SOURCES = $(tcsd_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTOLIB = @CRYPTOLIB@
+CRYPTO_PACKAGE = @CRYPTO_PACKAGE@
+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@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+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@
+OPENSSL_LIB_DIR = @OPENSSL_LIB_DIR@
+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@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+RANLIB = @RANLIB@
+RPC = @RPC@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TCSD_DEFAULT_PORT = @TCSD_DEFAULT_PORT@
+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 = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+tcsd_CFLAGS = -DAPPID=\"TCSD\" -DVAR_PREFIX=\"@localstatedir@\" \
+ -DETC_PREFIX=\"@sysconfdir@\" -I${top_srcdir}/src/include \
+ $(am__append_1) $(am__append_2)
+tcsd_LDADD = ${top_builddir}/src/tcs/libtcs.a ${top_builddir}/src/tddl/libtddl.a -lpthread @CRYPTOLIB@
+tcsd_SOURCES = svrside.c tcsd_conf.c tcsd_threads.c platform.c
+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 src/tcsd/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign src/tcsd/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):
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)"
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p || test -f $$p1; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(sbindir)" && rm -f $$files
+
+clean-sbinPROGRAMS:
+ @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+tcsd$(EXEEXT): $(tcsd_OBJECTS) $(tcsd_DEPENDENCIES)
+ @rm -f tcsd$(EXEEXT)
+ $(tcsd_LINK) $(tcsd_OBJECTS) $(tcsd_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcsd-platform.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcsd-svrside.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcsd-tcsd_conf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcsd-tcsd_threads.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+tcsd-svrside.o: svrside.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcsd_CFLAGS) $(CFLAGS) -MT tcsd-svrside.o -MD -MP -MF $(DEPDIR)/tcsd-svrside.Tpo -c -o tcsd-svrside.o `test -f 'svrside.c' || echo '$(srcdir)/'`svrside.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcsd-svrside.Tpo $(DEPDIR)/tcsd-svrside.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='svrside.c' object='tcsd-svrside.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcsd_CFLAGS) $(CFLAGS) -c -o tcsd-svrside.o `test -f 'svrside.c' || echo '$(srcdir)/'`svrside.c
+
+tcsd-svrside.obj: svrside.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcsd_CFLAGS) $(CFLAGS) -MT tcsd-svrside.obj -MD -MP -MF $(DEPDIR)/tcsd-svrside.Tpo -c -o tcsd-svrside.obj `if test -f 'svrside.c'; then $(CYGPATH_W) 'svrside.c'; else $(CYGPATH_W) '$(srcdir)/svrside.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcsd-svrside.Tpo $(DEPDIR)/tcsd-svrside.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='svrside.c' object='tcsd-svrside.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcsd_CFLAGS) $(CFLAGS) -c -o tcsd-svrside.obj `if test -f 'svrside.c'; then $(CYGPATH_W) 'svrside.c'; else $(CYGPATH_W) '$(srcdir)/svrside.c'; fi`
+
+tcsd-tcsd_conf.o: tcsd_conf.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcsd_CFLAGS) $(CFLAGS) -MT tcsd-tcsd_conf.o -MD -MP -MF $(DEPDIR)/tcsd-tcsd_conf.Tpo -c -o tcsd-tcsd_conf.o `test -f 'tcsd_conf.c' || echo '$(srcdir)/'`tcsd_conf.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcsd-tcsd_conf.Tpo $(DEPDIR)/tcsd-tcsd_conf.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tcsd_conf.c' object='tcsd-tcsd_conf.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcsd_CFLAGS) $(CFLAGS) -c -o tcsd-tcsd_conf.o `test -f 'tcsd_conf.c' || echo '$(srcdir)/'`tcsd_conf.c
+
+tcsd-tcsd_conf.obj: tcsd_conf.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcsd_CFLAGS) $(CFLAGS) -MT tcsd-tcsd_conf.obj -MD -MP -MF $(DEPDIR)/tcsd-tcsd_conf.Tpo -c -o tcsd-tcsd_conf.obj `if test -f 'tcsd_conf.c'; then $(CYGPATH_W) 'tcsd_conf.c'; else $(CYGPATH_W) '$(srcdir)/tcsd_conf.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcsd-tcsd_conf.Tpo $(DEPDIR)/tcsd-tcsd_conf.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tcsd_conf.c' object='tcsd-tcsd_conf.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcsd_CFLAGS) $(CFLAGS) -c -o tcsd-tcsd_conf.obj `if test -f 'tcsd_conf.c'; then $(CYGPATH_W) 'tcsd_conf.c'; else $(CYGPATH_W) '$(srcdir)/tcsd_conf.c'; fi`
+
+tcsd-tcsd_threads.o: tcsd_threads.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcsd_CFLAGS) $(CFLAGS) -MT tcsd-tcsd_threads.o -MD -MP -MF $(DEPDIR)/tcsd-tcsd_threads.Tpo -c -o tcsd-tcsd_threads.o `test -f 'tcsd_threads.c' || echo '$(srcdir)/'`tcsd_threads.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcsd-tcsd_threads.Tpo $(DEPDIR)/tcsd-tcsd_threads.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tcsd_threads.c' object='tcsd-tcsd_threads.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcsd_CFLAGS) $(CFLAGS) -c -o tcsd-tcsd_threads.o `test -f 'tcsd_threads.c' || echo '$(srcdir)/'`tcsd_threads.c
+
+tcsd-tcsd_threads.obj: tcsd_threads.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcsd_CFLAGS) $(CFLAGS) -MT tcsd-tcsd_threads.obj -MD -MP -MF $(DEPDIR)/tcsd-tcsd_threads.Tpo -c -o tcsd-tcsd_threads.obj `if test -f 'tcsd_threads.c'; then $(CYGPATH_W) 'tcsd_threads.c'; else $(CYGPATH_W) '$(srcdir)/tcsd_threads.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcsd-tcsd_threads.Tpo $(DEPDIR)/tcsd-tcsd_threads.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='tcsd_threads.c' object='tcsd-tcsd_threads.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcsd_CFLAGS) $(CFLAGS) -c -o tcsd-tcsd_threads.obj `if test -f 'tcsd_threads.c'; then $(CYGPATH_W) 'tcsd_threads.c'; else $(CYGPATH_W) '$(srcdir)/tcsd_threads.c'; fi`
+
+tcsd-platform.o: platform.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcsd_CFLAGS) $(CFLAGS) -MT tcsd-platform.o -MD -MP -MF $(DEPDIR)/tcsd-platform.Tpo -c -o tcsd-platform.o `test -f 'platform.c' || echo '$(srcdir)/'`platform.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcsd-platform.Tpo $(DEPDIR)/tcsd-platform.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='platform.c' object='tcsd-platform.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcsd_CFLAGS) $(CFLAGS) -c -o tcsd-platform.o `test -f 'platform.c' || echo '$(srcdir)/'`platform.c
+
+tcsd-platform.obj: platform.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcsd_CFLAGS) $(CFLAGS) -MT tcsd-platform.obj -MD -MP -MF $(DEPDIR)/tcsd-platform.Tpo -c -o tcsd-platform.obj `if test -f 'platform.c'; then $(CYGPATH_W) 'platform.c'; else $(CYGPATH_W) '$(srcdir)/platform.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tcsd-platform.Tpo $(DEPDIR)/tcsd-platform.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='platform.c' object='tcsd-platform.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcsd_CFLAGS) $(CFLAGS) -c -o tcsd-platform.obj `if test -f 'platform.c'; then $(CYGPATH_W) 'platform.c'; else $(CYGPATH_W) '$(srcdir)/platform.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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"
+
+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 $(PROGRAMS)
+installdirs:
+ for dir in "$(DESTDIR)$(sbindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+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:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+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-sbinPROGRAMS \
+ 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-sbinPROGRAMS
+
+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: uninstall-sbinPROGRAMS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-sbinPROGRAMS ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-sbinPROGRAMS install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-sbinPROGRAMS
+
+
+# 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/src/tcsd/platform.c b/src/tcsd/platform.c
new file mode 100644
index 0000000..c7a1c80
--- /dev/null
+++ b/src/tcsd/platform.c
@@ -0,0 +1,134 @@
+
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2004, 2005
+ *
+ */
+
+
+#if (defined (__FreeBSD__) || defined (__OpenBSD__))
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <err.h>
+#elif (defined (__linux) || defined (linux) || defined(__GLIBC__))
+#include <utmp.h>
+#elif (defined (SOLARIS))
+#include <utmpx.h>
+#endif
+
+#include <sys/time.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "trousers/tss.h"
+#include "trousers_types.h"
+#include "tcs_tsp.h"
+#include "tcs_int_literals.h"
+#include "capabilities.h"
+#include "tcsps.h"
+#include "tcslog.h"
+
+
+#if (defined (__linux) || defined (linux) || defined(__GLIBC__))
+MUTEX_DECLARE_INIT(utmp_lock);
+
+char
+platform_get_runlevel()
+{
+ char runlevel;
+ struct utmp ut, save, *next = NULL;
+ struct timeval tv;
+ int flag = 0, counter = 0;
+
+ MUTEX_LOCK(utmp_lock);
+
+ memset(&ut, 0, sizeof(struct utmp));
+ memset(&save, 0, sizeof(struct utmp));
+ memset(&tv, 0, sizeof(struct timeval));
+
+ ut.ut_type = RUN_LVL;
+
+ next = getutid(&ut);
+
+ while (next != NULL) {
+ if (next->ut_tv.tv_sec > tv.tv_sec) {
+ memcpy(&save, next, sizeof(*next));
+ flag = 1;
+ } else if (next->ut_tv.tv_sec == tv.tv_sec) {
+ if (next->ut_tv.tv_usec > tv.tv_usec) {
+ memcpy(&save, next, sizeof(*next));
+ flag = 1;
+ }
+ }
+
+ counter++;
+ next = getutid(&ut);
+ }
+
+ if (flag) {
+ //printf("prev_runlevel=%c, runlevel=%c\n", save.ut_pid / 256, save.ut_pid % 256);
+ runlevel = save.ut_pid % 256;
+ } else {
+ //printf("unknown\n");
+ runlevel = 'u';
+ }
+
+ MUTEX_UNLOCK(utmp_lock);
+
+ return runlevel;
+}
+#elif (defined (__FreeBSD__) || defined (__OpenBSD__))
+
+char
+platform_get_runlevel()
+{
+ int mib[2], rlevel = -1;
+ size_t len;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_SECURELVL;
+
+ len = sizeof(rlevel);
+ if (sysctl(mib,2,&rlevel,&len, NULL,0) == -1) {
+ err(1,"Could not get runlevel");
+ return 'u';
+ }
+#if defined (__OpenBSD__)
+ if (rlevel == 0)
+#else
+ if (rlevel == -1)
+#endif
+ return 's';
+
+ return rlevel + '0';
+}
+#elif (defined (SOLARIS))
+
+MUTEX_DECLARE_INIT(utmp_lock);
+char
+platform_get_runlevel()
+{
+ char runlevel;
+ struct utmpx ut, *utp = NULL;
+
+ MUTEX_LOCK(utmp_lock);
+
+ memset(&ut, 0, sizeof(ut));
+ ut.ut_type = RUN_LVL;
+
+ setutxent();
+ utp = getutxid(&ut);
+ if (utp->ut_type == RUN_LVL &&
+ sscanf(utp->ut_line, "run-level %c", &runlevel) != 1)
+ runlevel = 'u';
+ endutxent();
+
+ MUTEX_UNLOCK(utmp_lock);
+
+ return runlevel;
+}
+#endif
diff --git a/src/tcsd/svrside.c b/src/tcsd/svrside.c
new file mode 100644
index 0000000..08ca1c8
--- /dev/null
+++ b/src/tcsd/svrside.c
@@ -0,0 +1,355 @@
+
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2004
+ *
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <pwd.h>
+#if (defined (__OpenBSD__) || defined (__FreeBSD__))
+#include <netinet/in.h>
+#endif
+#include <arpa/inet.h>
+#include <errno.h>
+#include <getopt.h>
+#include "trousers/tss.h"
+#include "trousers_types.h"
+#include "tcs_tsp.h"
+#include "tcs_utils.h"
+#include "tcs_int_literals.h"
+#include "capabilities.h"
+#include "tcslog.h"
+#include "tcsd_wrap.h"
+#include "tcsps.h"
+#include "tcsd.h"
+#include "req_mgr.h"
+
+struct tcsd_config tcsd_options;
+struct tpm_properties tpm_metrics;
+static volatile int hup = 0, term = 0;
+extern char *optarg;
+int sd;
+char *tcsd_config_file = NULL;
+
+static void
+tcsd_shutdown(void)
+{
+ /* order is important here:
+ * allow all threads to complete their current request */
+ tcsd_threads_final();
+ PS_close_disk_cache();
+ auth_mgr_final();
+ (void)req_mgr_final();
+ conf_file_final(&tcsd_options);
+ EVENT_LOG_final();
+}
+
+static void
+tcsd_signal_term(int signal)
+{
+ term = 1;
+ close(sd);
+}
+
+void
+tcsd_signal_hup(int signal)
+{
+ hup = 1;
+}
+
+static TSS_RESULT
+signals_init(void)
+{
+ int rc;
+ sigset_t sigmask;
+ struct sigaction sa;
+
+ sigemptyset(&sigmask);
+ if ((rc = sigaddset(&sigmask, SIGTERM))) {
+ LogError("sigaddset: %s", strerror(errno));
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ }
+ if ((rc = sigaddset(&sigmask, SIGHUP))) {
+ LogError("sigaddset: %s", strerror(errno));
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ }
+
+ if ((rc = THREAD_SET_SIGNAL_MASK(SIG_UNBLOCK, &sigmask, NULL))) {
+ LogError("Setting thread signal mask: %s", strerror(rc));
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ }
+
+ sa.sa_flags = 0;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_handler = tcsd_signal_term;
+ if ((rc = sigaction(SIGTERM, &sa, NULL))) {
+ LogError("signal SIGTERM not registered: %s", strerror(errno));
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ }
+
+ sa.sa_handler = tcsd_signal_hup;
+ if ((rc = sigaction(SIGHUP, &sa, NULL))) {
+ LogError("signal SIGHUP not registered: %s", strerror(errno));
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ }
+
+ return TSS_SUCCESS;
+}
+
+static TSS_RESULT
+tcsd_startup(void)
+{
+ TSS_RESULT result;
+
+#ifdef TSS_DEBUG
+ /* Set stdout to be unbuffered to match stderr and interleave output correctly */
+ setvbuf(stdout, (char *)NULL, _IONBF, 0);
+#endif
+
+ if ((result = signals_init()))
+ return result;
+
+ if ((result = conf_file_init(&tcsd_options)))
+ return result;
+
+ if ((result = tcsd_threads_init())) {
+ conf_file_final(&tcsd_options);
+ return result;
+ }
+
+ if ((result = req_mgr_init())) {
+ conf_file_final(&tcsd_options);
+ return result;
+ }
+
+ if ((result = ps_dirs_init())) {
+ conf_file_final(&tcsd_options);
+ (void)req_mgr_final();
+ return result;
+ }
+
+ result = PS_init_disk_cache();
+ if (result != TSS_SUCCESS) {
+ conf_file_final(&tcsd_options);
+ (void)req_mgr_final();
+ return result;
+ }
+
+ if ((result = get_tpm_metrics(&tpm_metrics))) {
+ conf_file_final(&tcsd_options);
+ PS_close_disk_cache();
+ (void)req_mgr_final();
+ return result;
+ }
+
+ /* must happen after get_tpm_metrics() */
+ if ((result = auth_mgr_init())) {
+ conf_file_final(&tcsd_options);
+ PS_close_disk_cache();
+ (void)req_mgr_final();
+ return result;
+ }
+
+ result = EVENT_LOG_init();
+ if (result != TSS_SUCCESS) {
+ auth_mgr_final();
+ conf_file_final(&tcsd_options);
+ PS_close_disk_cache();
+ (void)req_mgr_final();
+ return result;
+ }
+
+ result = owner_evict_init();
+ if (result != TSS_SUCCESS) {
+ auth_mgr_final();
+ conf_file_final(&tcsd_options);
+ PS_close_disk_cache();
+ (void)req_mgr_final();
+ return result;
+ }
+
+ return TSS_SUCCESS;
+}
+
+
+void
+usage(void)
+{
+ fprintf(stderr, "\tusage: tcsd [-f] [-e] [-c <config file> [-h]\n\n");
+ fprintf(stderr, "\t-f|--foreground\trun in the foreground. Logging goes to stderr "
+ "instead of syslog.\n");
+ fprintf(stderr, "\t-e| attempts to connect to software TPMs over TCP\n");
+ fprintf(stderr, "\t-c|--config\tpath to configuration file\n");
+ fprintf(stderr, "\t-h|--help\tdisplay this help message\n");
+ fprintf(stderr, "\n");
+}
+
+static TSS_RESULT
+reload_config(void)
+{
+ TSS_RESULT result;
+ hup = 0;
+
+ // FIXME: reload the config - work in progress
+ result = TSS_SUCCESS;
+
+ return result;
+}
+
+
+int
+main(int argc, char **argv)
+{
+ struct sockaddr_in serv_addr, client_addr;
+ TSS_RESULT result;
+ int newsd, c, option_index = 0;
+ unsigned client_len;
+ char *hostname = NULL;
+ struct passwd *pwd;
+ struct hostent *client_hostent = NULL;
+ struct option long_options[] = {
+ {"help", 0, NULL, 'h'},
+ {"foreground", 0, NULL, 'f'},
+ {"config", 1, NULL, 'c'},
+ {0, 0, 0, 0}
+ };
+
+ unsetenv("TCSD_USE_TCP_DEVICE");
+ while ((c = getopt_long(argc, argv, "fhec:", long_options, &option_index)) != -1) {
+ switch (c) {
+ case 'f':
+ setenv("TCSD_FOREGROUND", "1", 1);
+ break;
+ case 'c':
+ tcsd_config_file = optarg;
+ break;
+ case 'e':
+ setenv("TCSD_USE_TCP_DEVICE", "1", 1);
+ break;
+ case 'h':
+ /* fall through */
+ default:
+ usage();
+ return -1;
+ break;
+ }
+ }
+
+ if (!tcsd_config_file)
+ tcsd_config_file = TCSD_DEFAULT_CONFIG_FILE;
+
+ if ((result = tcsd_startup()))
+ return (int)result;
+
+ sd = socket(AF_INET, SOCK_STREAM, 0);
+ if (sd < 0) {
+ LogError("Failed socket: %s", strerror(errno));
+ return -1;
+ }
+
+ memset(&serv_addr, 0, sizeof (serv_addr));
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_port = htons(tcsd_options.port);
+
+ /* If no remote_ops are defined, restrict connections to localhost
+ * only at the socket. */
+ if (tcsd_options.remote_ops[0] == 0)
+ serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ else
+ serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ c = 1;
+ setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &c, sizeof(c));
+ if (bind(sd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0) {
+ LogError("Failed bind: %s", strerror(errno));
+ return -1;
+ }
+#ifndef SOLARIS
+ pwd = getpwnam(TSS_USER_NAME);
+ if (pwd == NULL) {
+ if (errno == 0) {
+ LogError("User \"%s\" not found, please add this user"
+ " manually.", TSS_USER_NAME);
+ } else {
+ LogError("getpwnam(%s): %s", TSS_USER_NAME, strerror(errno));
+ }
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ }
+ setuid(pwd->pw_uid);
+#endif
+ if (listen(sd, TCSD_MAX_SOCKETS_QUEUED) < 0) {
+ LogError("Failed listen: %s", strerror(errno));
+ return -1;
+ }
+ client_len = (unsigned)sizeof(client_addr);
+
+ if (getenv("TCSD_FOREGROUND") == NULL) {
+ if (daemon(0, 0) == -1) {
+ perror("daemon");
+ tcsd_shutdown();
+ return -1;
+ }
+ }
+
+ LogInfo("%s: TCSD up and running.", PACKAGE_STRING);
+ do {
+ newsd = accept(sd, (struct sockaddr *) &client_addr, &client_len);
+ if (newsd < 0) {
+ if (errno == EINTR) {
+ if (term)
+ break;
+ else if (hup) {
+ if (reload_config() != TSS_SUCCESS)
+ LogError("Failed reloading config");
+ }
+ continue;
+ } else {
+ LogError("Failed accept: %s", strerror(errno));
+ continue;
+ }
+ }
+ LogDebug("accepted socket %i", newsd);
+
+ if ((client_hostent = gethostbyaddr((char *) &client_addr.sin_addr,
+ sizeof(client_addr.sin_addr),
+ AF_INET)) == NULL) {
+ char buf[16];
+ uint32_t addr = htonl(client_addr.sin_addr.s_addr);
+
+ snprintf(buf, 16, "%d.%d.%d.%d", (addr & 0xff000000) >> 24,
+ (addr & 0x00ff0000) >> 16, (addr & 0x0000ff00) >> 8,
+ addr & 0x000000ff);
+
+ LogWarn("Host name for connecting IP %s could not be resolved", buf);
+ hostname = strdup(buf);
+ } else {
+ hostname = strdup(client_hostent->h_name);
+ }
+
+ tcsd_thread_create(newsd, hostname);
+ hostname = NULL;
+ if (hup) {
+ if (reload_config() != TSS_SUCCESS)
+ LogError("Failed reloading config");
+ }
+ } while (term ==0);
+
+ /* To close correctly, we must receive a SIGTERM */
+ tcsd_shutdown();
+ return 0;
+}
diff --git a/src/tcsd/tcsd_conf.c b/src/tcsd/tcsd_conf.c
new file mode 100644
index 0000000..afc1dcb
--- /dev/null
+++ b/src/tcsd/tcsd_conf.c
@@ -0,0 +1,852 @@
+
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2004
+ *
+ */
+
+
+#include <stdio.h>
+#include <pwd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <string.h>
+#include <strings.h>
+#include <errno.h>
+#include <grp.h>
+#include <stdlib.h>
+
+#ifdef SOLARIS
+#include <libscf.h>
+#endif
+
+#include "trousers/tss.h"
+#include "trousers_types.h"
+#include "tcs_tsp.h"
+#include "tcs_utils.h"
+#include "tcsps.h"
+#include "tcslog.h"
+#include "tcsd_wrap.h"
+#include "tcsd.h"
+#include "tcsd_ops.h"
+
+
+struct tcsd_config_options options_list[] = {
+ {"port", opt_port},
+ {"num_threads", opt_max_threads},
+ {"system_ps_file", opt_system_ps_file},
+ {"firmware_log_file", opt_firmware_log},
+ {"firmware_pcrs", opt_firmware_pcrs},
+ {"kernel_log_file", opt_kernel_log},
+ {"kernel_pcrs", opt_kernel_pcrs},
+ {"platform_cred", opt_platform_cred},
+ {"conformance_cred", opt_conformance_cred},
+ {"endorsement_cred", opt_endorsement_cred},
+ {"remote_ops", opt_remote_ops},
+ {"enforce_exclusive_transport", opt_exclusive_transport},
+ {"host_platform_class", opt_host_platform_class},
+ {"all_platform_classes", opt_all_platform_classes},
+ {NULL, 0}
+};
+
+struct tcg_platform_spec tcg_platform_specs[] = {
+ {"PC_11", TPM_PS_PC_11, TPM_PS_PC_11_URI},
+ {"PC_12", TPM_PS_PC_12, TPM_PS_PC_12_URI},
+ {"PDA_12", TPM_PS_PDA_12, TPM_PS_PDA_12_URI},
+ {"SERVER_12", TPM_PS_Server_12, TPM_PS_Server_12_URI},
+ {"MOBILE_12", TPM_PS_Mobile_12, TPM_PS_Mobile_12_URI},
+ {NULL, 0, 0}
+};
+
+
+void
+init_tcsd_config(struct tcsd_config *conf)
+{
+ conf->port = -1;
+ conf->num_threads = -1;
+ conf->system_ps_file = NULL;
+ conf->system_ps_dir = NULL;
+ conf->firmware_log_file = NULL;
+ conf->firmware_pcrs = 0;
+ conf->kernel_log_file = NULL;
+ conf->kernel_pcrs = 0;
+ conf->platform_cred = NULL;
+ conf->conformance_cred = NULL;
+ conf->endorsement_cred = NULL;
+ memset(conf->remote_ops, 0, sizeof(conf->remote_ops));
+ conf->unset = 0xffffffff;
+ conf->exclusive_transport = 0;
+ conf->host_platform_class = NULL;
+ conf->all_platform_classes = NULL;
+}
+
+TSS_RESULT
+platform_class_list_append(struct tcsd_config *conf, char *specName, TSS_BOOL is_main)
+{
+ int i;
+ struct platform_class *tmp, *new_class;
+
+ LogDebugFn("platform_class_list_append start:");
+ for (i = 0; tcg_platform_specs[i].name; i++) {
+ if (!strncasecmp(specName, tcg_platform_specs[i].name,
+ strlen(tcg_platform_specs[i].name))) {
+ /* Allocate the new structure */
+ new_class = malloc(sizeof(struct platform_class));
+ if (new_class == NULL) {
+ LogError("malloc of %zd bytes failed",
+ sizeof(struct platform_class));
+ return TCSERR(TSS_E_OUTOFMEMORY);
+ }
+ new_class->simpleID = tcg_platform_specs[i].specNo;
+ new_class->classURISize = strlen(tcg_platform_specs[i].specURI) + 1;
+ new_class->classURI = malloc(new_class->classURISize);
+ if (new_class->classURI == NULL) {
+ LogError("malloc of %u bytes failed", new_class->classURISize);
+ return TCSERR(TSS_E_OUTOFMEMORY);
+ }
+ memcpy(new_class->classURI, tcg_platform_specs[i].specURI,
+ new_class->classURISize);
+
+ /* Append to the start of the list */
+ if (is_main) {
+ tmp = conf->host_platform_class;
+ conf->host_platform_class = new_class;
+ } else {
+ tmp = conf->all_platform_classes;
+ conf->all_platform_classes = new_class;
+ }
+ new_class->next = tmp;
+
+ LogDebugFn("Platform Class Added.");
+ return TSS_SUCCESS;
+ }
+ }
+
+ LogError("TCG Specification not supported: \"%s\"", specName);
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+}
+
+void
+config_set_defaults(struct tcsd_config *conf)
+{
+ /* give all unset options their default values */
+ if (conf->unset & TCSD_OPTION_PORT)
+ conf->port = TCSD_DEFAULT_PORT;
+
+ if (conf->unset & TCSD_OPTION_MAX_THREADS)
+ conf->num_threads = TCSD_DEFAULT_MAX_THREADS;
+
+ if (conf->unset & TCSD_OPTION_FIRMWARE_PCRS)
+ conf->firmware_pcrs = TCSD_DEFAULT_FIRMWARE_PCRS;
+
+ if (conf->unset & TCSD_OPTION_KERNEL_PCRS)
+ conf->kernel_pcrs = TCSD_DEFAULT_KERNEL_PCRS;
+
+ /* these are strdup'd so we know we can free them at shutdown time */
+ if (conf->unset & TCSD_OPTION_SYSTEM_PSFILE) {
+ conf->system_ps_file = strdup(TCSD_DEFAULT_SYSTEM_PS_FILE);
+ conf->system_ps_dir = strdup(TCSD_DEFAULT_SYSTEM_PS_DIR);
+ }
+
+ if (conf->unset & TCSD_OPTION_FIRMWARE_LOGFILE)
+ conf->firmware_log_file = strdup(TCSD_DEFAULT_FIRMWARE_LOG_FILE);
+
+ if (conf->unset & TCSD_OPTION_KERNEL_LOGFILE)
+ conf->kernel_log_file = strdup(TCSD_DEFAULT_KERNEL_LOG_FILE);
+
+ if (conf->unset & TCSD_OPTION_HOST_PLATFORM_CLASS)
+ platform_class_list_append(conf, "PC_12", TRUE);
+}
+
+int
+get_config_option(char *ptr, char **arg)
+{
+ int i;
+
+ for (i = 0; options_list[i].name; i++) {
+ if (!strncasecmp(ptr, options_list[i].name, strlen(options_list[i].name))) {
+ /* move ptr past our recognized token */
+ ptr += strlen(options_list[i].name);
+
+ /* try to move ptr to the start of the option's argument */
+ while (*ptr == '=' || *ptr == ' ' || *ptr == '\t')
+ ptr++;
+
+ *arg = ptr;
+ return options_list[i].option;
+ }
+ }
+ /* on error we'll print the whole line to the log */
+ *arg = ptr;
+ return 0;
+}
+
+/* copy a file path from a string into a newly malloc'd string */
+int
+get_file_path(char *ptr, char **dest)
+{
+ char tmp_buf[1024];
+ int i = 0;
+
+ while (isalpha(*ptr) || isdigit(*ptr) ||
+ *ptr == '/' || *ptr == '.' || *ptr == '#' || *ptr == '_' || *ptr == '-')
+ {
+ tmp_buf[i] = *ptr;
+ ptr++;
+ i++;
+ }
+
+ /* move through whitespace after the path */
+ while (*ptr == ' ' || *ptr == '\t')
+ ptr++;
+
+ /* if we're not at a comment or EOL, there's junk */
+ if (*ptr != '#' && *ptr != '\n') {
+ *dest = ptr;
+ return 1;
+ }
+
+ /* too short a path */
+ if (i == 0)
+ return -1;
+
+ tmp_buf[i] = '\0';
+ *dest = strdup(tmp_buf);
+ if (*dest == NULL) {
+ LogError("malloc of %zd bytes failed", strlen(tmp_buf));
+ }
+
+ return 0;
+}
+
+/* add an op ordinal, checking for duplicates along the way */
+void
+tcsd_add_op(int *remote_ops, int *op)
+{
+ int i = 0, j;
+
+ while (op[i] != 0) {
+ j = 0;
+ while (remote_ops[j] != 0) {
+ if (remote_ops[j] == op[i]) {
+ break;
+ }
+ j++;
+ }
+ remote_ops[j] = op[i];
+ i++;
+ }
+}
+
+int
+tcsd_set_remote_op(struct tcsd_config *conf, char *op_name)
+{
+ int i = 0;
+
+ while(tcsd_ops[i]) {
+ if (!strcasecmp(tcsd_ops[i]->name, op_name)) {
+ /* match found */
+ tcsd_add_op(conf->remote_ops, tcsd_ops[i]->op);
+ return 0;
+ }
+ i++;
+ }
+
+ /* fail, op not found */
+ return 1;
+}
+
+TSS_RESULT
+read_conf_line(char *buf, int line_num, struct tcsd_config *conf)
+{
+ char *ptr = buf, *tmp_ptr = NULL, *arg, *comma;
+ int option, tmp_int;
+ TSS_RESULT result;
+
+ if (ptr == NULL || *ptr == '\0' || *ptr == '#' || *ptr == '\n')
+ return TSS_SUCCESS;
+
+ /* read through whitespace */
+ while (*ptr == ' ' || *ptr == '\t')
+ ptr++;
+
+ /* ignore comments */
+ if (*ptr == '#')
+ return TSS_SUCCESS;
+
+ option = get_config_option(ptr, &arg);
+
+ switch (option) {
+ case opt_port:
+ tmp_int = atoi(arg);
+ if (tmp_int < 0 || tmp_int > 65535) {
+ LogError("Config option \"port\" out of range. %s:%d: \"%d\"",
+ tcsd_config_file, line_num, tmp_int);
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ } else {
+ conf->port = tmp_int;
+ conf->unset &= ~TCSD_OPTION_PORT;
+ }
+ break;
+ case opt_max_threads:
+ tmp_int = atoi(arg);
+ if (tmp_int <= 0) {
+ LogError("Config option \"num_threads\" out of range. %s:%d: \"%d\"",
+ tcsd_config_file, line_num, tmp_int);
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ } else {
+ conf->num_threads = tmp_int;
+ conf->unset &= ~TCSD_OPTION_MAX_THREADS;
+ }
+ break;
+ case opt_firmware_pcrs:
+ conf->unset &= ~TCSD_OPTION_FIRMWARE_PCRS;
+ while (1) {
+ comma = rindex(arg, ',');
+
+ if (comma == NULL) {
+ if (!isdigit(*arg))
+ break;
+
+ comma = arg;
+ tmp_int = atoi(comma);
+ if (tmp_int >= 0 && tmp_int < TCSD_MAX_PCRS)
+ conf->firmware_pcrs |= (1 << tmp_int);
+ else
+ LogError("Config option \"firmware_pcrs\" is out of range."
+ "%s:%d: \"%d\"", tcsd_config_file, line_num,
+ tmp_int);
+ break;
+ }
+
+ *comma++ = '\0';
+ tmp_int = atoi(comma);
+ if (tmp_int >= 0 && tmp_int < TCSD_MAX_PCRS)
+ conf->firmware_pcrs |= (1 << tmp_int);
+ else
+ LogError("Config option \"firmware_pcrs\" is out of range. "
+ "%s:%d: \"%d\"", tcsd_config_file, line_num, tmp_int);
+ }
+ break;
+ case opt_kernel_pcrs:
+ conf->unset &= ~TCSD_OPTION_KERNEL_PCRS;
+ while (1) {
+ comma = rindex(arg, ',');
+
+ if (comma == NULL) {
+ if (!isdigit(*arg))
+ break;
+
+ comma = arg;
+ tmp_int = atoi(comma);
+ if (tmp_int >= 0 && tmp_int < TCSD_MAX_PCRS)
+ conf->kernel_pcrs |= (1 << tmp_int);
+ else
+ LogError("Config option \"kernel_pcrs\" is out of range. "
+ "%s:%d: \"%d\"", tcsd_config_file, line_num,
+ tmp_int);
+ break;
+ }
+
+ *comma++ = '\0';
+ tmp_int = atoi(comma);
+ if (tmp_int >= 0 && tmp_int < TCSD_MAX_PCRS)
+ conf->kernel_pcrs |= (1 << tmp_int);
+ else
+ LogError("Config option \"kernel_pcrs\" is out of range. "
+ "%s:%d: \"%d\"", tcsd_config_file, line_num, tmp_int);
+ }
+ break;
+ case opt_system_ps_file:
+ if (*arg != '/') {
+ LogError("Config option \"system_ps_dir\" must be an absolute path name. "
+ "%s:%d: \"%s\"", tcsd_config_file, line_num, arg);
+ } else {
+ char *dir_ptr;
+ int rc;
+
+ if ((rc = get_file_path(arg, &tmp_ptr)) < 0) {
+ LogError("Config option \"system_ps_file\" is invalid."
+ " %s:%d: \"%s\"", tcsd_config_file, line_num, arg);
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ } else if (rc > 0) {
+ LogError("Config option \"system_ps_file\" is invalid. %s:%d:"
+ " \"%s\"", tcsd_config_file, line_num, tmp_ptr);
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ }
+ if (tmp_ptr == NULL)
+ return TCSERR(TSS_E_OUTOFMEMORY);
+
+ if (conf->system_ps_file)
+ free(conf->system_ps_file);
+ if (conf->system_ps_dir)
+ free(conf->system_ps_dir);
+
+ /* break out the system ps directory from the file path */
+ dir_ptr = rindex(tmp_ptr, '/');
+ *dir_ptr = '\0';
+ if (strlen(tmp_ptr) == 0)
+ conf->system_ps_dir = strdup("/");
+ else
+ conf->system_ps_dir = strdup(tmp_ptr);
+
+ if (conf->system_ps_dir == NULL) {
+ LogError("malloc failed.");
+ free(tmp_ptr);
+ return TCSERR(TSS_E_OUTOFMEMORY);
+ }
+ *dir_ptr = '/';
+ conf->system_ps_file = tmp_ptr;
+ conf->unset &= ~TCSD_OPTION_SYSTEM_PSFILE;
+ }
+ break;
+ case opt_kernel_log:
+ if (*arg != '/') {
+ LogError("Config option \"kernel_log\" must be an absolute path name."
+ " %s:%d: \"%s\"", tcsd_config_file, line_num, arg);
+ } else {
+ int rc;
+
+ if ((rc = get_file_path(arg, &tmp_ptr)) < 0) {
+ LogError("Config option \"kernel_log\" is invalid. %s:%d: \"%s\"",
+ tcsd_config_file, line_num, arg);
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ } else if (rc > 0) {
+ LogError("Config option \"kernel_log\" is invalid. %s:%d: \"%s\"",
+ tcsd_config_file, line_num, tmp_ptr);
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ }
+ if (tmp_ptr == NULL)
+ return TCSERR(TSS_E_OUTOFMEMORY);
+
+ if (conf->kernel_log_file)
+ free(conf->kernel_log_file);
+
+ conf->kernel_log_file = tmp_ptr;
+ conf->unset &= ~TCSD_OPTION_KERNEL_LOGFILE;
+ }
+ break;
+ case opt_firmware_log:
+ if (*arg != '/') {
+ LogError("Config option \"firmware_log\" must be an absolute path name."
+ " %s:%d: \"%s\"", tcsd_config_file, line_num, arg);
+ } else {
+ int rc;
+
+ if ((rc = get_file_path(arg, &tmp_ptr)) < 0) {
+ LogError("Config option \"firmware_log\" is invalid. %s:%d: \"%s\"",
+ tcsd_config_file, line_num, arg);
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ } else if (rc > 0) {
+ LogError("Config option \"firmware_log\" is invalid. %s:%d: \"%s\"",
+ tcsd_config_file, line_num, tmp_ptr);
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ }
+ if (tmp_ptr == NULL)
+ return TCSERR(TSS_E_OUTOFMEMORY);
+
+ if (conf->firmware_log_file)
+ free(conf->firmware_log_file);
+
+ conf->firmware_log_file = tmp_ptr;
+ conf->unset &= ~TCSD_OPTION_FIRMWARE_LOGFILE;
+ }
+ break;
+ case opt_platform_cred:
+ if (*arg != '/') {
+ LogError("Config option \"platform_cred\" must be an absolute path name. "
+ "%s:%d: \"%s\"", tcsd_config_file, line_num, arg);
+ } else {
+ int rc;
+
+ if ((rc = get_file_path(arg, &tmp_ptr)) < 0) {
+ LogError("Config option \"platform_cred\" is invalid. %s:%d: "
+ "\"%s\"", tcsd_config_file, line_num, arg);
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ } else if (rc > 0) {
+ LogError("Config option \"platform_cred\" is invalid. %s:%d: "
+ "\"%s\"", tcsd_config_file, line_num, tmp_ptr);
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ }
+ if (tmp_ptr == NULL)
+ return TCSERR(TSS_E_OUTOFMEMORY);
+
+ if (conf->platform_cred)
+ free(conf->platform_cred);
+
+ conf->platform_cred = tmp_ptr;
+ conf->unset &= ~TCSD_OPTION_PLATFORM_CRED;
+ }
+ break;
+ case opt_conformance_cred:
+ if (*arg != '/') {
+ LogError("Config option \"conformance_cred\" must be an absolute path name."
+ " %s:%d: \"%s\"", tcsd_config_file, line_num, arg);
+ } else {
+ int rc;
+
+ if ((rc = get_file_path(arg, &tmp_ptr)) < 0) {
+ LogError("Config option \"conformance_cred\" is invalid. %s:%d: "
+ "\"%s\"", tcsd_config_file, line_num, arg);
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ } else if (rc > 0) {
+ LogError("Config option \"conformance_cred\" is invalid. %s:%d: "
+ "\"%s\"", tcsd_config_file, line_num, tmp_ptr);
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ }
+ if (tmp_ptr == NULL)
+ return TCSERR(TSS_E_OUTOFMEMORY);
+
+ if (conf->conformance_cred)
+ free(conf->conformance_cred);
+
+ conf->conformance_cred = tmp_ptr;
+ conf->unset &= ~TCSD_OPTION_CONFORMANCE_CRED;
+ }
+ break;
+ case opt_endorsement_cred:
+ if (*arg != '/') {
+ LogError("Config option \"endorsement_cred\" must be an absolute path name."
+ " %s:%d: \"%s\"", tcsd_config_file, line_num, arg);
+ } else {
+ int rc;
+
+ if ((rc = get_file_path(arg, &tmp_ptr)) < 0) {
+ LogError("Config option \"endorsement_cred\" is invalid. %s:%d: "
+ "\"%s\"", tcsd_config_file, line_num, arg);
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ } else if (rc > 0) {
+ LogError("Config option \"endorsement_cred\" is invalid. %s:%d: "
+ "\"%s\"", tcsd_config_file, line_num, tmp_ptr);
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ }
+ if (tmp_ptr == NULL)
+ return TCSERR(TSS_E_OUTOFMEMORY);
+
+ if (conf->endorsement_cred)
+ free(conf->endorsement_cred);
+
+ conf->endorsement_cred = tmp_ptr;
+ conf->unset &= ~TCSD_OPTION_ENDORSEMENT_CRED;
+ }
+ break;
+ case opt_remote_ops:
+ conf->unset &= ~TCSD_OPTION_REMOTE_OPS;
+ comma = rindex(arg, '\n');
+ *comma = '\0';
+ while (1) {
+ comma = rindex(arg, ',');
+
+ if (comma == NULL) {
+ comma = arg;
+
+ if (comma != NULL) {
+ if (tcsd_set_remote_op(conf, comma)) {
+ LogError("Config option \"remote_ops\" is invalid. "
+ "%s:%d: \"%s\"", tcsd_config_file,
+ line_num, comma);
+ }
+ }
+ break;
+ }
+
+ *comma++ = '\0';
+ if (tcsd_set_remote_op(conf, comma)) {
+ LogError("Config option \"remote_ops\" is invalid. "
+ "%s:%d: \"%s\"", tcsd_config_file, line_num, comma);
+ }
+ }
+ break;
+ case opt_exclusive_transport:
+ tmp_int = atoi(arg);
+ if (tmp_int < 0 || tmp_int > 1) {
+ LogError("Config option \"enforce_exclusive_transport\" out of range."
+ " %s:%d: \"%d\"", tcsd_config_file, line_num, tmp_int);
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ } else {
+ conf->exclusive_transport = tmp_int;
+ conf->unset &= ~TCSD_OPTION_EXCLUSIVE_TRANSPORT;
+ }
+ break;
+ case opt_host_platform_class:
+ /* append the host class on the list */
+ conf->unset &= ~TCSD_OPTION_HOST_PLATFORM_CLASS;
+ comma = rindex(arg,'\n');
+ *comma = '\0';
+
+ comma = rindex(arg,',');
+ /* At least one comma: error - more than one host class defined */
+ if (comma != NULL) {
+ LogError("Config option \"host_platform_class\" error: more than one "
+ "defined. %s:%d: \"%s\"", tcsd_config_file, line_num, comma);
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ } else {
+ comma = arg;
+ /* Add the platform class on the list */
+ if ((result = platform_class_list_append(conf, comma, TRUE))){
+ LogError("Config option \"host_platform_class\" invalid. "
+ "%s:%d: \"%s\"", tcsd_config_file, line_num, comma);
+ return result;
+ }
+ }
+ break;
+ case opt_all_platform_classes:
+ /* append each of the comma separated values on the list */
+ comma = rindex(arg, '\n');
+ *comma = '\0';
+ while (1) {
+ comma = rindex(arg, ',');
+
+ if (comma == NULL) {
+ comma = arg;
+
+ if (comma != NULL) {
+ /* Add the platform class on the list */
+ if ((result = platform_class_list_append(conf, comma,
+ FALSE))) {
+ LogError("Config option \"all_platform_class\" "
+ "invalid. %s:%d: \"%s\"", tcsd_config_file,
+ line_num, comma);
+ return result;
+ }
+ }
+ break;
+ }
+ *comma++ = '\0';
+ /* Add the platform class on the list */
+ if ((result = platform_class_list_append(conf, comma, FALSE))) {
+ LogError("Config option \"all_platform_class\" invalid. "
+ "%s:%d: \"%s\"", tcsd_config_file, line_num, comma);
+ return result;
+ }
+ }
+ break;
+ default:
+ /* bail out on any unknown option */
+ LogError("Unknown config option %s:%d \"%s\"!", tcsd_config_file, line_num, arg);
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ }
+
+ return TSS_SUCCESS;
+}
+
+TSS_RESULT
+read_conf_file(FILE *f, struct tcsd_config *conf)
+{
+ int line_num = 0;
+ char buf[1024];
+
+ while (fgets(buf, 1024, f)) {
+ line_num++;
+ if (read_conf_line(buf, line_num, conf))
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ }
+
+ return TSS_SUCCESS;
+}
+
+void
+free_platform_lists(struct platform_class *list)
+{
+ struct platform_class *tmp;
+
+ while (list != NULL){
+ if (list->classURISize > 0)
+ free(list->classURI);
+ tmp = list->next;
+ free(list);
+ list = tmp;
+ }
+}
+
+void
+conf_file_final(struct tcsd_config *conf)
+{
+ free(conf->system_ps_file);
+ free(conf->system_ps_dir);
+ free(conf->kernel_log_file);
+ free(conf->firmware_log_file);
+ free(conf->platform_cred);
+ free(conf->conformance_cred);
+ free(conf->endorsement_cred);
+ free_platform_lists(conf->host_platform_class);
+ free_platform_lists(conf->all_platform_classes);
+}
+
+#ifdef SOLARIS
+static int
+get_smf_prop(const char *var, boolean_t def_val)
+{
+ scf_simple_prop_t *prop;
+ uint8_t *val;
+ boolean_t res = def_val;
+ prop = scf_simple_prop_get(NULL, "svc:/application/security/tcsd:default",
+ "config", var);
+ if (prop) {
+ if ((val = scf_simple_prop_next_boolean(prop)) != NULL)
+ res = (*val == 0) ? B_FALSE : B_TRUE;
+ scf_simple_prop_free(prop);
+ }
+ if (prop == NULL || val == NULL) {
+ syslog(LOG_ALERT, "no value for config/%s (%s). "
+ "Using default \"%s\"", var, scf_strerror(scf_error()),
+ def_val ? "true" : "false");
+ }
+ return (res);
+}
+#endif
+
+TSS_RESULT
+conf_file_init(struct tcsd_config *conf)
+{
+ FILE *f = NULL;
+ struct stat stat_buf;
+#ifndef SOLARIS
+ struct group *grp;
+ struct passwd *pw;
+ mode_t mode = (S_IRUSR|S_IWUSR);
+#endif /* SOLARIS */
+ TSS_RESULT result;
+
+ init_tcsd_config(conf);
+
+#ifdef SOLARIS
+ /*
+ * Solaris runs as Rajiv Andrade <srajiv@linux.vnet.:sys but with reduced privileges
+ * so we don't need to create a new user/group and also so
+ * we can have auditing support. The permissions on
+ * the tcsd configuration file are not checked on Solaris.
+ */
+#endif
+ /* look for a config file, create if it doesn't exist */
+ if (stat(tcsd_config_file, &stat_buf) == -1) {
+ if (errno == ENOENT) {
+ /* no config file? use defaults */
+ config_set_defaults(conf);
+ LogInfo("Config file %s not found, using defaults.", tcsd_config_file);
+ return TSS_SUCCESS;
+ } else {
+ LogError("stat(%s): %s", tcsd_config_file, strerror(errno));
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ }
+ }
+
+#ifndef SOLARIS
+ /* find the gid that owns the conf file */
+ errno = 0;
+ grp = getgrnam(TSS_GROUP_NAME);
+ if (grp == NULL) {
+ if (errno == 0) {
+ LogError("Group \"%s\" not found, please add this group"
+ " manually.", TSS_GROUP_NAME);
+ } else {
+ LogError("getgrnam(%s): %s", TSS_GROUP_NAME, strerror(errno));
+ }
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ }
+
+ errno = 0;
+ pw = getpwnam(TSS_USER_NAME);
+ if (pw == NULL) {
+ if (errno == 0) {
+ LogError("User \"%s\" not found, please add this user"
+ " manually.", TSS_USER_NAME);
+ } else {
+ LogError("getpwnam(%s): %s", TSS_USER_NAME, strerror(errno));
+ }
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ }
+
+ /* make sure user/group TSS owns the conf file */
+ if (pw->pw_uid != stat_buf.st_uid || grp->gr_gid != stat_buf.st_gid) {
+ LogError("TCSD config file (%s) must be user/group %s/%s", tcsd_config_file,
+ TSS_USER_NAME, TSS_GROUP_NAME);
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ }
+
+ /* make sure only the tss user can manipulate the config file */
+ if (((stat_buf.st_mode & 0777) ^ mode) != 0) {
+ LogError("TCSD config file (%s) must be mode 0600", tcsd_config_file);
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ }
+#endif /* SOLARIS */
+
+ if ((f = fopen(tcsd_config_file, "r")) == NULL) {
+ LogError("fopen(%s): %s", tcsd_config_file, strerror(errno));
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ }
+
+ result = read_conf_file(f, conf);
+ fclose(f);
+
+ /* fill out any uninitialized options */
+ config_set_defaults(conf);
+
+#ifdef SOLARIS
+ /*
+ * The SMF value for "local_only" overrides the config file and
+ * disables all remote operations.
+ */
+if (get_smf_prop("local_only", B_TRUE)) {
+ (void) memset(conf->remote_ops, 0, sizeof(conf->remote_ops));
+ conf->unset |= TCSD_OPTION_REMOTE_OPS;
+
+ }
+#endif
+ return result;
+}
+
+TSS_RESULT
+ps_dirs_init()
+{
+ struct stat stat_buf;
+ mode_t mode = S_IRWXU; /* 0700 */
+
+ /* query the key storage directory to make sure it exists and is of the right mode */
+ if (stat(tcsd_options.system_ps_dir, &stat_buf) == -1) {
+ if (errno == ENOENT) {
+ /* The dir DNE, create it with mode drwxrwxrwt */
+ if (mkdir(tcsd_options.system_ps_dir, mode) == -1) {
+ LogError("mkdir(%s) failed: %s. If you'd like to use %s to "
+ "store your system persistent data, please"
+ " create it. Otherwise, change the location"
+ " in your tcsd config file.",
+ tcsd_options.system_ps_dir, strerror(errno),
+ tcsd_options.system_ps_dir);
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ }
+ } else {
+ LogError("stat failed: %s", strerror(errno));
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ }
+ }
+
+ /* stat should not fail now */
+ if (stat(tcsd_options.system_ps_dir, &stat_buf) == -1) {
+ LogError("stat %s failed: %s", tcsd_options.system_ps_dir, strerror(errno));
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ }
+
+ /* tcsd_options.system_ps_dir should be a directory with mode equal to mode */
+ if (!S_ISDIR(stat_buf.st_mode)) {
+ LogError("PS dir %s is not a directory! Exiting.", tcsd_options.system_ps_dir);
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ } else if (((stat_buf.st_mode & 0777) ^ mode) != 0) {
+ /* This path is likely to be hit since open &'s mode with ~umask */
+ LogInfo("resetting mode of %s from %o to: %o", tcsd_options.system_ps_dir,
+ (unsigned int) stat_buf.st_mode, (unsigned int) mode);
+ if (chmod(tcsd_options.system_ps_dir, mode) == -1) {
+ LogError("chmod(%s) failed: %s", tcsd_options.system_ps_dir,
+ strerror(errno));
+ return TCSERR(TSS_E_INTERNAL_ERROR);
+ }
+ }
+
+ return TSS_SUCCESS;
+}
+
diff --git a/src/tcsd/tcsd_threads.c b/src/tcsd/tcsd_threads.c
new file mode 100644
index 0000000..66a1ac7
--- /dev/null
+++ b/src/tcsd/tcsd_threads.c
@@ -0,0 +1,457 @@
+
+/*
+ * Licensed Materials - Property of IBM
+ *
+ * trousers - An open source TCG Software Stack
+ *
+ * (C) Copyright International Business Machines Corp. 2004-2006
+ *
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <syslog.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include "trousers/tss.h"
+#include "trousers_types.h"
+#include "tcs_int_literals.h"
+#include "tcs_tsp.h"
+#include "tcs_utils.h"
+#include "tcsd_wrap.h"
+#include "tcsd.h"
+#include "tcslog.h"
+#include "rpc_tcstp_tcs.h"
+
+struct tcsd_thread_mgr *tm = NULL;
+
+TSS_RESULT
+tcsd_threads_final()
+{
+ int rc;
+ UINT32 i;
+
+ MUTEX_LOCK(tm->lock);
+
+ tm->shutdown = 1;
+
+ MUTEX_UNLOCK(tm->lock);
+
+ /* wait for all currently running threads to exit */
+ for (i = 0; i < tm->max_threads; i++) {
+ if (tm->thread_data[i].thread_id != THREAD_NULL) {
+ if ((rc = THREAD_JOIN(*(tm->thread_data[i].thread_id), NULL))) {
+ LogError("Thread join failed: error: %d", rc);
+ }
+ }
+ }
+
+ free(tm->thread_data);
+ free(tm);
+
+ return TSS_SUCCESS;
+}
+
+TSS_RESULT
+tcsd_threads_init(void)
+{
+ /* allocate the thread mgmt structure */
+ tm = calloc(1, sizeof(struct tcsd_thread_mgr));
+ if (tm == NULL) {
+ LogError("malloc of %zd bytes failed.", sizeof(struct tcsd_thread_mgr));
+ return TCSERR(TSS_E_OUTOFMEMORY);
+ }
+ /* initialize mutex */
+ MUTEX_INIT(tm->lock);
+
+ /* set the max threads variable from config */
+ tm->max_threads = tcsd_options.num_threads;
+
+ /* allocate each thread's data structure */
+ tm->thread_data = calloc(tcsd_options.num_threads, sizeof(struct tcsd_thread_data));
+ if (tm->thread_data == NULL) {
+ LogError("malloc of %zu bytes failed.",
+ tcsd_options.num_threads * sizeof(struct tcsd_thread_data));
+ free(tm);
+ return TCSERR(TSS_E_OUTOFMEMORY);
+ }
+
+ return TSS_SUCCESS;
+}
+
+
+TSS_RESULT
+tcsd_thread_create(int socket, char *hostname)
+{
+ UINT32 thread_num = -1;
+ int rc = TCS_SUCCESS;
+#ifndef TCSD_SINGLE_THREAD_DEBUG
+ THREAD_ATTR_DECLARE(tcsd_thread_attr);
+
+ /* init the thread attribute */
+ if ((rc = THREAD_ATTR_INIT(tcsd_thread_attr))) {
+ LogError("Initializing thread attribute failed: error=%d: %s", rc, strerror(rc));
+ rc = TCSERR(TSS_E_INTERNAL_ERROR);
+ goto out;
+ }
+ /* make all threads joinable */
+ if ((rc = THREAD_ATTR_SETJOINABLE(tcsd_thread_attr))) {
+ LogError("Making thread attribute joinable failed: error=%d: %s", rc, strerror(rc));
+ rc = TCSERR(TSS_E_INTERNAL_ERROR);
+ goto out;
+ }
+
+ MUTEX_LOCK(tm->lock);
+#endif
+ if (tm->num_active_threads == tm->max_threads) {
+ if (hostname != NULL) {
+ LogError("max number of connections reached (%d), new connection"
+ " from %s refused.", tm->max_threads, hostname);
+ } else {
+ LogError("max number of connections reached (%d), new connection"
+ " refused.", tm->max_threads);
+ }
+ rc = TCSERR(TSS_E_CONNECTION_FAILED);
+#ifndef TCSD_SINGLE_THREAD_DEBUG
+ goto out_unlock;
+#else
+ goto out;
+#endif
+ }
+
+ /* search for an open slot to store the thread data in */
+ for (thread_num = 0; thread_num < tm->max_threads; thread_num++) {
+ if (tm->thread_data[thread_num].thread_id == THREAD_NULL)
+ break;
+ }
+
+ DBG_ASSERT(thread_num != tm->max_threads);
+
+ tm->thread_data[thread_num].sock = socket;
+ tm->thread_data[thread_num].context = NULL_TCS_HANDLE;
+ if (hostname != NULL)
+ tm->thread_data[thread_num].hostname = hostname;
+
+#ifdef TCSD_SINGLE_THREAD_DEBUG
+ (void)tcsd_thread_run((void *)(&(tm->thread_data[thread_num])));
+#else
+ tm->thread_data[thread_num].thread_id = calloc(1, sizeof(THREAD_TYPE));
+ if (tm->thread_data[thread_num].thread_id == NULL) {
+ rc = TCSERR(TSS_E_OUTOFMEMORY);
+ LogError("malloc of %zd bytes failed.", sizeof(THREAD_TYPE));
+ goto out_unlock;
+ }
+
+ if ((rc = THREAD_CREATE(tm->thread_data[thread_num].thread_id,
+ &tcsd_thread_attr,
+ tcsd_thread_run,
+ (void *)(&(tm->thread_data[thread_num]))))) {
+ LogError("Thread create failed: %d", rc);
+ rc = TCSERR(TSS_E_INTERNAL_ERROR);
+ goto out_unlock;
+ }
+
+ tm->num_active_threads++;
+
+out_unlock:
+ MUTEX_UNLOCK(tm->lock);
+#endif
+out:
+ /* cleanup in case of error */
+ if (rc != TCS_SUCCESS) {
+ if (hostname != NULL) {
+ tm->thread_data[thread_num].hostname = NULL;
+ free(hostname);
+ }
+ close(socket);
+ }
+ return rc;
+}
+
+/* Since we don't want any of the worker threads to catch any signals, we must mask off any
+ * potential signals here after creating the threads. If any of the created threads catch a signal,
+ * they'd eventually call join on themselves, causing a deadlock.
+ */
+void
+thread_signal_init()
+{
+ sigset_t thread_sigmask;
+ int rc;
+
+ if ((rc = sigfillset(&thread_sigmask))) {
+ LogError("sigfillset failed: error=%d: %s", rc, strerror(rc));
+ LogError("worker thread %ld is exiting prematurely", THREAD_ID);
+ THREAD_EXIT(NULL);
+ }
+
+ if ((rc = THREAD_SET_SIGNAL_MASK(SIG_BLOCK, &thread_sigmask, NULL))) {
+ LogError("Setting thread sigmask failed: error=%d: %s", rc, strerror(rc));
+ LogError("worker thread %ld is exiting prematurely", THREAD_ID);
+ THREAD_EXIT(NULL);
+ }
+}
+#if 0
+void *
+tcsd_thread_run(void *v)
+{
+ struct tcsd_thread_data *data = (struct tcsd_thread_data *)v;
+ BYTE buffer[TCSD_TXBUF_SIZE];
+ struct tcsd_packet_hdr *ret_buf = NULL;
+ TSS_RESULT result;
+ int sizeToSend, sent_total, sent;
+ UINT64 offset;
+#ifndef TCSD_SINGLE_THREAD_DEBUG
+ int rc;
+
+ thread_signal_init();
+#endif
+
+ if ((data->buf_size = recv(data->sock, buffer, TCSD_TXBUF_SIZE, 0)) < 0) {
+ LogError("Failed Receive: %s", strerror(errno));
+ goto done;
+ }
+ LogDebug("Rx'd packet");
+
+ data->buf = buffer;
+
+ while (1) {
+ sent_total = 0;
+ if (data->buf_size > TCSD_TXBUF_SIZE) {
+ LogError("Packet received from socket %d was too large (%u bytes)",
+ data->sock, data->buf_size);
+ goto done;
+ } else if (data->buf_size < (int)((2 * sizeof(UINT32)) + sizeof(UINT16))) {
+ LogError("Packet received from socket %d was too small (%u bytes)",
+ data->sock, data->buf_size);
+ goto done;
+ }
+
+ if ((result = getTCSDPacket(data, &ret_buf)) != TSS_SUCCESS) {
+ /* something internal to the TCSD went wrong in preparing the packet
+ * to return to the TSP. Use our already allocated buffer to return a
+ * TSS_E_INTERNAL_ERROR return code to the TSP. In the non-error path,
+ * these LoadBlob's are done in getTCSDPacket().
+ */
+ offset = 0;
+ /* load result */
+ LoadBlob_UINT32(&offset, result, buffer);
+ /* load packet size */
+ LoadBlob_UINT32(&offset, sizeof(struct tcsd_packet_hdr), buffer);
+ /* load num parms */
+ LoadBlob_UINT16(&offset, 0, buffer);
+
+ sizeToSend = sizeof(struct tcsd_packet_hdr);
+ LogDebug("Sending 0x%X bytes back", sizeToSend);
+
+ while (sent_total < sizeToSend) {
+ if ((sent = send(data->sock,
+ &data->buf[sent_total],
+ sizeToSend - sent_total, 0)) < 0) {
+ LogError("Packet send to TSP failed: send: %s. Thread exiting.",
+ strerror(errno));
+ goto done;
+ }
+ sent_total += sent;
+ }
+ } else {
+ sizeToSend = Decode_UINT32((BYTE *)&(ret_buf->packet_size));
+
+ LogDebug("Sending 0x%X bytes back", sizeToSend);
+
+ while (sent_total < sizeToSend) {
+ if ((sent = send(data->sock,
+ &(((BYTE *)ret_buf)[sent_total]),
+ sizeToSend - sent_total, 0)) < 0) {
+ LogError("response to TSP failed: send: %s. Thread exiting.",
+ strerror(errno));
+ free(ret_buf);
+ ret_buf = NULL;
+ goto done;
+ }
+ sent_total += sent;
+ }
+ free(ret_buf);
+ ret_buf = NULL;
+ }
+
+ if (tm->shutdown) {
+ LogDebug("Thread %zd exiting via shutdown signal!", THREAD_ID);
+ break;
+ }
+
+ /* receive the next packet */
+ if ((data->buf_size = recv(data->sock, buffer, TCSD_TXBUF_SIZE, 0)) < 0) {
+ LogError("TSP has closed its connection: %s. Thread exiting.",
+ strerror(errno));
+ break;
+ } else if (data->buf_size == 0) {
+ LogDebug("The TSP has closed the socket's connection. Thread exiting.");
+ break;
+ }
+ }
+
+done:
+ /* Closing connection to TSP */
+ close(data->sock);
+ data->sock = -1;
+ data->buf = NULL;
+ data->buf_size = -1;
+ /* If the connection was not shut down cleanly, free TCS resources here */
+ if (data->context != NULL_TCS_HANDLE) {
+ TCS_CloseContext_Internal(data->context);
+ data->context = NULL_TCS_HANDLE;
+ }
+
+#ifndef TCSD_SINGLE_THREAD_DEBUG
+ MUTEX_LOCK(tm->lock);
+ tm->num_active_threads--;
+ /* if we're not in shutdown mode, then nobody is waiting to join this thread, so
+ * detach it so that its resources are free at THREAD_EXIT() time. */
+ if (!tm->shutdown) {
+ if ((rc = THREAD_DETACH(*(data->thread_id)))) {
+ LogError("Thread detach failed (errno %d)."
+ " Resources may not be properly released.", rc);
+ }
+ }
+ free(data->hostname);
+ data->hostname = NULL;
+ data->thread_id = THREAD_NULL;
+ MUTEX_UNLOCK(tm->lock);
+ THREAD_EXIT(NULL);
+#else
+ return NULL;
+#endif
+}
+#else
+void *
+tcsd_thread_run(void *v)
+{
+ struct tcsd_thread_data *data = (struct tcsd_thread_data *)v;
+ BYTE *buffer;
+ int recv_size, send_size;
+ TSS_RESULT result;
+ UINT64 offset;
+#ifndef TCSD_SINGLE_THREAD_DEBUG
+ int rc;
+
+ thread_signal_init();
+#endif
+
+ data->comm.buf_size = TCSD_INIT_TXBUF_SIZE;
+ data->comm.buf = calloc(1, data->comm.buf_size);
+ while (data->comm.buf) {
+ /* get the packet header to get the size of the incoming packet */
+ buffer = data->comm.buf;
+ recv_size = sizeof(struct tcsd_packet_hdr);
+ if ((recv_size = recv_from_socket(data->sock, buffer, recv_size)) < 0)
+ break;
+ buffer += sizeof(struct tcsd_packet_hdr); /* increment the buffer pointer */
+
+ /* check the packet size */
+ recv_size = Decode_UINT32(data->comm.buf);
+ if (recv_size < (int)sizeof(struct tcsd_packet_hdr)) {
+ LogError("Packet to receive from socket %d is too small (%d bytes)",
+ data->sock, recv_size);
+ break;
+ }
+
+ if (recv_size > (int) data->comm.buf_size ) {
+ BYTE *new_buffer;
+
+ LogDebug("Increasing communication buffer to %d bytes.", recv_size);
+ new_buffer = realloc(data->comm.buf, recv_size);
+ if (new_buffer == NULL) {
+ LogError("realloc of %d bytes failed.", recv_size);
+ break;
+ }
+ buffer = new_buffer + sizeof(struct tcsd_packet_hdr);
+ data->comm.buf_size = recv_size;
+ data->comm.buf = new_buffer;
+ }
+
+ /* get the rest of the packet */
+ recv_size -= sizeof(struct tcsd_packet_hdr); /* already received the header */
+ if ((recv_size = recv_from_socket(data->sock, buffer, recv_size)) < 0)
+ break;
+ LogDebug("Rx'd packet");
+
+ /* create a platform version of the tcsd header */
+ offset = 0;
+ UnloadBlob_UINT32(&offset, &data->comm.hdr.packet_size, data->comm.buf);
+ UnloadBlob_UINT32(&offset, &data->comm.hdr.u.result, data->comm.buf);
+ UnloadBlob_UINT32(&offset, &data->comm.hdr.num_parms, data->comm.buf);
+ UnloadBlob_UINT32(&offset, &data->comm.hdr.type_size, data->comm.buf);
+ UnloadBlob_UINT32(&offset, &data->comm.hdr.type_offset, data->comm.buf);
+ UnloadBlob_UINT32(&offset, &data->comm.hdr.parm_size, data->comm.buf);
+ UnloadBlob_UINT32(&offset, &data->comm.hdr.parm_offset, data->comm.buf);
+
+ if ((result = getTCSDPacket(data)) != TSS_SUCCESS) {
+ /* something internal to the TCSD went wrong in preparing the packet
+ * to return to the TSP. Use our already allocated buffer to return a
+ * TSS_E_INTERNAL_ERROR return code to the TSP. In the non-error path,
+ * these LoadBlob's are done in getTCSDPacket().
+ */
+ /* set everything to zero, fill in what is non-zero */
+ memset(data->comm.buf, 0, data->comm.buf_size);
+ offset = 0;
+ /* load packet size */
+ LoadBlob_UINT32(&offset, sizeof(struct tcsd_packet_hdr), data->comm.buf);
+ /* load result */
+ LoadBlob_UINT32(&offset, result, data->comm.buf);
+ }
+ send_size = Decode_UINT32(data->comm.buf);
+ LogDebug("Sending 0x%X bytes back", send_size);
+ send_size = send_to_socket(data->sock, data->comm.buf, send_size);
+ if (send_size < 0)
+ break;
+
+ /* check for shutdown */
+ if (tm->shutdown) {
+ LogDebug("Thread %ld exiting via shutdown signal!", THREAD_ID);
+ break;
+ }
+ }
+
+ LogDebug("Thread exiting.");
+
+ /* Closing connection to TSP */
+ close(data->sock);
+ data->sock = -1;
+ free(data->comm.buf);
+ data->comm.buf = NULL;
+ data->comm.buf_size = -1;
+ /* If the connection was not shut down cleanly, free TCS resources here */
+ if (data->context != NULL_TCS_HANDLE) {
+ TCS_CloseContext_Internal(data->context);
+ data->context = NULL_TCS_HANDLE;
+ }
+ if(data->hostname != NULL) {
+ free(data->hostname);
+ data->hostname = NULL;
+ }
+
+#ifndef TCSD_SINGLE_THREAD_DEBUG
+ pthread_mutex_lock(&(tm->lock));
+ tm->num_active_threads--;
+ /* if we're not in shutdown mode, then nobody is waiting to join this thread, so
+ * detach it so that its resources are free at pthread_exit() time. */
+ if (!tm->shutdown) {
+ if ((rc = pthread_detach(*(data->thread_id)))) {
+ LogError("pthread_detach failed (errno %d)."
+ " Resources may not be properly released.", rc);
+ }
+ }
+ free(data->thread_id);
+ data->thread_id = THREAD_NULL;
+ pthread_mutex_unlock(&(tm->lock));
+ pthread_exit(NULL);
+#endif
+ return NULL;
+}
+
+#endif