diff options
Diffstat (limited to 'src/tcsd')
-rw-r--r-- | src/tcsd/Makefile.am | 13 | ||||
-rw-r--r-- | src/tcsd/Makefile.in | 589 | ||||
-rw-r--r-- | src/tcsd/platform.c | 134 | ||||
-rw-r--r-- | src/tcsd/svrside.c | 355 | ||||
-rw-r--r-- | src/tcsd/tcsd_conf.c | 852 | ||||
-rw-r--r-- | src/tcsd/tcsd_threads.c | 457 |
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 |