diff options
author | Dave Brolley <brolley@redhat.com> | 2008-12-24 13:18:50 -0500 |
---|---|---|
committer | Dave Brolley <brolley@redhat.com> | 2008-12-24 13:18:50 -0500 |
commit | 1cecb3c506475a0e0b0ee4180a91e1a9433d346b (patch) | |
tree | fc093dc7c74968a86a20ddbe2d9e11564e070339 | |
parent | e5976ba0af9b828dcc76b3937b5a98fe9c0f6cb8 (diff) | |
download | systemtap-steved-1cecb3c506475a0e0b0ee4180a91e1a9433d346b.tar.gz systemtap-steved-1cecb3c506475a0e0b0ee4180a91e1a9433d346b.tar.xz systemtap-steved-1cecb3c506475a0e0b0ee4180a91e1a9433d346b.zip |
Systemtap compile server phase 2 (ssl) -- first cut.
-rw-r--r-- | ChangeLog | 49 | ||||
-rw-r--r-- | Makefile.am | 33 | ||||
-rw-r--r-- | Makefile.in | 115 | ||||
-rw-r--r-- | aclocal.m4 | 38 | ||||
-rw-r--r-- | doc/ChangeLog | 5 | ||||
-rw-r--r-- | doc/Makefile.in | 17 | ||||
-rw-r--r-- | doc/SystemTap_Tapset_Reference/Makefile.in | 19 | ||||
-rwxr-xr-x | stap-client | 194 | ||||
-rw-r--r-- | stap-client-connect.c | 449 | ||||
-rwxr-xr-x | stap-find-or-start-server | 2 | ||||
-rwxr-xr-x | stap-gen-server-cert | 74 | ||||
-rwxr-xr-x | stap-server | 118 | ||||
-rw-r--r-- | stap-server-connect.c | 756 | ||||
-rwxr-xr-x | stap-serverd | 67 | ||||
-rwxr-xr-x | stap-start-server | 2 | ||||
-rw-r--r-- | systemtap.spec | 5 | ||||
-rw-r--r-- | testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | testsuite/lib/systemtap.exp | 33 |
18 files changed, 1672 insertions, 310 deletions
@@ -1,3 +1,52 @@ +2008-12-24 Dave Brolley <brolley@redhat.com> + + * stap-client (netcat): Removed. + (initialization): Initialize ssl_db. + (parse_options): Handle the --ssl option. + (process_ssl): New function. + (send_request): Removed. + (receive_response): Removed. + (unpack_response): Use signtool to verify the contents of the + server's response against a local copy of the server's + certificate. + (find_and_connect_to_server): Make sure the server is referred to + as localhost if it is running on the local host. Call send_receive + in order to contact the server and perform the transaction. + (connect_to_server): Removed. + (disconnect_from_server): Removed. + (send_receive): New function. + (process_response): Work in $tmpdir_server. + (terminate, interrupt): Kill any running stap-client-connect. + * stap-find-or-start-server: Pass arguments to stap-start-server. + * stap-start-server: Pass arguments to stap-serverd. + * stap-server (port): Removed. + (netcat): Removed. + (receive_request): Removed. + (unpack_request): Use unzip. + (package_response): Use signtool to sign the response into a .jar + archive. + (send_response): Removed. + * stap-serverd (netcat): Removed. + (port1): Removed. + (initialize): Don't call recursively. Use a loop to select a port. + (listen): Call stap-server-connect. + (process_request): Removed. + (terminate): Kill any running stap-server-connect job. + * systemtap.spec: client and server sub packages require nss and nss-tools, + and no longer require nc or net-tools. + * Makefile.am (bin_PROGRAMS): Add stap-client-connect and + stap-server-connect. + (bin_SCRIPTS): Add stap-gen-server-cert. + (stap_client_connect_LDFLAGS, stap_server_connect_LDFLAGS): New. + (stamp-ssl): New target. + (ssl/server/stap-server.cert): New target. + (stap_client_connect_*): New. + (stap_server_connect_*): New. + (install-data-local): Install /etc/systemtap/ssl. + (uninstall-local): Remove /etc/systemtap. + * Makefile.in: Regenerated. + * aclocal.m4: Regenerated. + 2008-12-22 Masami Hiramatsu <mhiramat@redhat.com> PR7090 diff --git a/Makefile.am b/Makefile.am index db77456c..9b93d91e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -13,8 +13,9 @@ AM_CXXFLAGS = -Wall -Werror man_MANS = stap.1 stapprobes.5 stapfuncs.5 stapvars.5 stapex.5 staprun.8 stap-server.8 man/stapprobes.iosched.5 man/stapprobes.netdev.5 man/stapprobes.nfs.5 man/stapprobes.nfsd.5 man/stapprobes.pagefault.5 man/stapprobes.process.5 man/stapprobes.rpc.5 man/stapprobes.scsi.5 man/stapprobes.signal.5 man/stapprobes.socket.5 man/stapprobes.tcp.5 man/stapprobes.udp.5 # see also configure.ac -bin_PROGRAMS = stap staprun -bin_SCRIPTS = stap-client stap-server stap-serverd stap-find-servers stap-start-server stap-find-or-start-server stap-stop-server stap-report +bin_PROGRAMS = stap staprun stap-client-connect stap-server-connect +bin_SCRIPTS = stap-client stap-serverd stap-server stap-find-servers stap-start-server stap-find-or-start-server stap-stop-server \ + stap-gen-server-cert stap-report stap_SOURCES = main.cxx \ parse.cxx staptree.cxx elaborate.cxx translate.cxx \ tapsets.cxx buildrun.cxx loc2c.c hash.cxx mdfour.c \ @@ -23,6 +24,7 @@ stap_LDADD = @stap_LIBS@ @sqlite3_LIBS@ BUILT_SOURCES = CLEANFILES = +stap_DEPENDENCIES = # Arrange for git_version.h to be regenerated at every "make". # Code fragment is based upon RadeonHD.am. @@ -67,6 +69,8 @@ stap_LDFLAGS = $(AM_LDFLAGS) @PIELDFLAGS@ staprun_LDFLAGS = $(AM_LDFLAGS) @PIELDFLAGS@ stapio_CPPFLAGS = $(AM_CPPFLAGS) stapio_LDFLAGS = $(AM_LDFLAGS) @PIELDFLAGS@ +stap_client_connect_LDFLAGS = $(AM_LDFLAGS) +stap_server_connect_LDFLAGS = $(AM_LDFLAGS) PHONIES = @@ -84,7 +88,7 @@ stamp-elfutils: config.status $(MAKE) $(AM_MAKEFLAGS) -C build-elfutils/$$dir bin_PROGRAMS= install; \ done touch $@ -stap_DEPENDENCIES = lib-elfutils/libdw.so +stap_DEPENDENCIES += lib-elfutils/libdw.so lib-elfutils/libdw.so: stamp-elfutils ; pkglib_LIBRARIES = libsduprobes.a @@ -101,6 +105,14 @@ install-elfutils: install-exec-local: install-elfutils endif +BUILT_SOURCES += stamp-ssl +CLEANFILES += stamp-ssl +stamp-ssl: config.status + $(srcdir)/stap-gen-server-cert ssl + touch $@ +stap_DEPENDENCIES += ssl/server/stap-server.cert +ssl/server/stap-server.cert: stamp-ssl ; + staprun_SOURCES = runtime/staprun/staprun.c runtime/staprun/staprun_funcs.c\ runtime/staprun/ctl.c runtime/staprun/common.c @@ -115,6 +127,14 @@ stapio_SOURCES = runtime/staprun/stapio.c \ stapio_CFLAGS = @PROCFLAGS@ $(AM_CFLAGS) -fno-strict-aliasing stapio_LDADD = @PROCFLAGS@ -lpthread +stap_client_connect_SOURCES = stap-client-connect.c +stap_client_connect_CFLAGS = -Wall -Werror -I /usr/include/nss3 -I /usr/include/nspr4 +stap_client_connect_LDADD = -lssl3 + +stap_server_connect_SOURCES = stap-server-connect.c +stap_server_connect_CFLAGS = -Wall -Werror -I /usr/include/nss3 -I /usr/include/nspr4 +stap_server_connect_LDADD = -lssl3 + install-exec-hook: if [ `id -u` -eq 0 ]; then chmod 04111 "$(DESTDIR)$(bindir)/staprun"; fi @@ -178,6 +198,12 @@ install-data-local: i_cmd="$(INSTALL_PROGRAM)"; else \ i_cmd="$(INSTALL_DATA)"; fi; \ $$i_cmd -D $$f $(DESTDIR)$(docdir)/examples/$$f; done) + (cd $(builddir)/ssl/server; for f in pw; \ + do $(INSTALL) -m 600 -D $$f /etc/systemtap/ssl/server/$$f; done) + (cd $(builddir)/ssl/server; for f in *.db; \ + do $(INSTALL) -m 664 -D $$f /etc/systemtap/ssl/server/$$f; done) + (cd $(builddir)/ssl/client; for f in *.db; \ + do $(INSTALL) -m 664 -D $$f /etc/systemtap/ssl/client/$$f; done) TEST_COV_DIR = coverage @@ -217,6 +243,7 @@ uninstall-local: echo " rm -f '$(SAMPLE_INSTALL_DIR)/$$p'"; \ rm -f "$(SAMPLE_INSTALL_DIR)/$$p"; \ done + rm -rf /etc/systemtap # XXX: leaves behind man pages SUBDIRS = testsuite doc diff --git a/Makefile.in b/Makefile.in index de6d48e1..b922ff6e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10.1 from Makefile.am. +# Makefile.in generated by automake 1.10 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006 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. @@ -34,15 +34,16 @@ POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : -bin_PROGRAMS = stap$(EXEEXT) staprun$(EXEEXT) +bin_PROGRAMS = stap$(EXEEXT) staprun$(EXEEXT) \ + stap-client-connect$(EXEEXT) stap-server-connect$(EXEEXT) @BUILD_ELFUTILS_TRUE@am__append_1 = -Iinclude-elfutils @BUILD_ELFUTILS_TRUE@am__append_2 = -Llib-elfutils -Wl,-rpath-link,lib-elfutils \ @BUILD_ELFUTILS_TRUE@ -Wl,--enable-new-dtags,-rpath,$(pkglibdir) @BUILD_ELFUTILS_TRUE@am__append_3 = stamp-elfutils @BUILD_ELFUTILS_TRUE@am__append_4 = stamp-elfutils -@BUILD_ELFUTILS_FALSE@stap_DEPENDENCIES = -@BUILD_ELFUTILS_TRUE@am__append_5 = install-elfutils +@BUILD_ELFUTILS_TRUE@am__append_5 = lib-elfutils/libdw.so +@BUILD_ELFUTILS_TRUE@am__append_6 = install-elfutils pkglibexec_PROGRAMS = stapio$(EXEEXT) noinst_PROGRAMS = loc2c-test$(EXEEXT) subdir = . @@ -64,7 +65,8 @@ DIST_COMMON = INSTALL NEWS README AUTHORS ChangeLog \ $(top_srcdir)/man/stapprobes.signal.5.in \ $(top_srcdir)/man/stapprobes.socket.5.in \ $(top_srcdir)/man/stapprobes.tcp.5.in \ - $(top_srcdir)/man/stapprobes.udp.5.in depcomp + $(top_srcdir)/man/stapprobes.udp.5.in $(srcdir)/run-stap.in \ + depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ @@ -80,7 +82,7 @@ CONFIG_CLEAN_FILES = stap.1 stapprobes.5 stapfuncs.5 stapvars.5 \ man/stapprobes.process.5 man/stapprobes.rpc.5 \ man/stapprobes.scsi.5 man/stapprobes.signal.5 \ man/stapprobes.socket.5 man/stapprobes.tcp.5 \ - man/stapprobes.udp.5 + man/stapprobes.udp.5 run-stap am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -119,6 +121,18 @@ am_stap_OBJECTS = stap-main.$(OBJEXT) stap-parse.$(OBJEXT) \ stap_OBJECTS = $(am_stap_OBJECTS) stap_LINK = $(CXXLD) $(stap_CXXFLAGS) $(CXXFLAGS) $(stap_LDFLAGS) \ $(LDFLAGS) -o $@ +am_stap_client_connect_OBJECTS = \ + stap_client_connect-stap-client-connect.$(OBJEXT) +stap_client_connect_OBJECTS = $(am_stap_client_connect_OBJECTS) +stap_client_connect_DEPENDENCIES = +stap_client_connect_LINK = $(CCLD) $(stap_client_connect_CFLAGS) \ + $(CFLAGS) $(stap_client_connect_LDFLAGS) $(LDFLAGS) -o $@ +am_stap_server_connect_OBJECTS = \ + stap_server_connect-stap-server-connect.$(OBJEXT) +stap_server_connect_OBJECTS = $(am_stap_server_connect_OBJECTS) +stap_server_connect_DEPENDENCIES = +stap_server_connect_LINK = $(CCLD) $(stap_server_connect_CFLAGS) \ + $(CFLAGS) $(stap_server_connect_LDFLAGS) $(LDFLAGS) -o $@ am_stapio_OBJECTS = stapio-stapio.$(OBJEXT) stapio-mainloop.$(OBJEXT) \ stapio-common.$(OBJEXT) stapio-ctl.$(OBJEXT) \ stapio-relay.$(OBJEXT) stapio-relay_old.$(OBJEXT) @@ -148,7 +162,9 @@ CXXLD = $(CXX) CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ -o $@ SOURCES = $(libsduprobes_a_SOURCES) $(loc2c_test_SOURCES) \ - $(stap_SOURCES) $(stapio_SOURCES) $(staprun_SOURCES) + $(stap_SOURCES) $(stap_client_connect_SOURCES) \ + $(stap_server_connect_SOURCES) $(stapio_SOURCES) \ + $(staprun_SOURCES) RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ @@ -277,7 +293,9 @@ AM_CPPFLAGS = -DBINDIR='"$(bindir)"' -DPKGDATADIR='"${pkgdatadir}"' -DPKGLIBDIR= AM_CFLAGS = -D_GNU_SOURCE -fexceptions -Wall -Werror -Wunused -Wformat=2 -W AM_CXXFLAGS = -Wall -Werror man_MANS = stap.1 stapprobes.5 stapfuncs.5 stapvars.5 stapex.5 staprun.8 stap-server.8 man/stapprobes.iosched.5 man/stapprobes.netdev.5 man/stapprobes.nfs.5 man/stapprobes.nfsd.5 man/stapprobes.pagefault.5 man/stapprobes.process.5 man/stapprobes.rpc.5 man/stapprobes.scsi.5 man/stapprobes.signal.5 man/stapprobes.socket.5 man/stapprobes.tcp.5 man/stapprobes.udp.5 -bin_SCRIPTS = stap-client stap-server stap-serverd stap-find-servers stap-start-server stap-find-or-start-server stap-stop-server stap-report +bin_SCRIPTS = stap-client stap-serverd stap-server stap-find-servers stap-start-server stap-find-or-start-server stap-stop-server \ + stap-gen-server-cert stap-report + stap_SOURCES = main.cxx \ parse.cxx staptree.cxx elaborate.cxx translate.cxx \ tapsets.cxx buildrun.cxx loc2c.c hash.cxx mdfour.c \ @@ -293,8 +311,10 @@ stap_LDADD = @stap_LIBS@ @sqlite3_LIBS@ # of foo-bar.c if it is newer than the foo-bar.o file. Using noinst_foo_SOURCES # instead of foo_SOURCES prevents shipping git_version.h in dist tarballs, # which may cause false GIT_FOO readings. -BUILT_SOURCES = git_version.stamp $(am__append_3) -CLEANFILES = git_version.h $(am__append_4) $(pkglibexec_PROGRAMS) +BUILT_SOURCES = git_version.stamp $(am__append_3) stamp-ssl +CLEANFILES = git_version.h $(am__append_4) stamp-ssl \ + $(pkglibexec_PROGRAMS) +stap_DEPENDENCIES = $(am__append_5) ssl/server/stap-server.cert GIT_VERSION_CMD = $(SHELL) $(top_srcdir)/git_version.sh stap_CXXFLAGS = $(AM_CXXFLAGS) stap_CPPFLAGS = $(AM_CPPFLAGS) $(am__append_1) @@ -302,8 +322,9 @@ stap_LDFLAGS = $(AM_LDFLAGS) @PIELDFLAGS@ $(am__append_2) staprun_LDFLAGS = $(AM_LDFLAGS) @PIELDFLAGS@ stapio_CPPFLAGS = $(AM_CPPFLAGS) stapio_LDFLAGS = $(AM_LDFLAGS) @PIELDFLAGS@ -PHONIES = $(am__append_5) dist-gzip -@BUILD_ELFUTILS_TRUE@stap_DEPENDENCIES = lib-elfutils/libdw.so +stap_client_connect_LDFLAGS = $(AM_LDFLAGS) +stap_server_connect_LDFLAGS = $(AM_LDFLAGS) +PHONIES = $(am__append_6) dist-gzip @BUILD_ELFUTILS_TRUE@pkglib_LIBRARIES = libsduprobes.a @BUILD_ELFUTILS_TRUE@libsduprobes_a_SOURCES = runtime/sduprobes.c staprun_SOURCES = runtime/staprun/staprun.c runtime/staprun/staprun_funcs.c\ @@ -319,6 +340,12 @@ stapio_SOURCES = runtime/staprun/stapio.c \ stapio_CFLAGS = @PROCFLAGS@ $(AM_CFLAGS) -fno-strict-aliasing stapio_LDADD = @PROCFLAGS@ -lpthread +stap_client_connect_SOURCES = stap-client-connect.c +stap_client_connect_CFLAGS = -Wall -Werror -I /usr/include/nss3 -I /usr/include/nspr4 +stap_client_connect_LDADD = -lssl3 +stap_server_connect_SOURCES = stap-server-connect.c +stap_server_connect_CFLAGS = -Wall -Werror -I /usr/include/nss3 -I /usr/include/nspr4 +stap_server_connect_LDADD = -lssl3 loc2c_test_SOURCES = loc2c-test.c loc2c.c loc2c_test_CPPFLAGS = $(stap_CPPFLAGS) loc2c_test_LDFLAGS = $(stap_LDFLAGS) @@ -432,6 +459,8 @@ man/stapprobes.tcp.5: $(top_builddir)/config.status $(top_srcdir)/man/stapprobes cd $(top_builddir) && $(SHELL) ./config.status $@ man/stapprobes.udp.5: $(top_builddir)/config.status $(top_srcdir)/man/stapprobes.udp.5.in cd $(top_builddir) && $(SHELL) ./config.status $@ +run-stap: $(top_builddir)/config.status $(srcdir)/run-stap.in + cd $(top_builddir) && $(SHELL) ./config.status $@ install-pkglibLIBRARIES: $(pkglib_LIBRARIES) @$(NORMAL_INSTALL) test -z "$(pkglibdir)" || $(MKDIR_P) "$(DESTDIR)$(pkglibdir)" @@ -520,6 +549,12 @@ loc2c-test$(EXEEXT): $(loc2c_test_OBJECTS) $(loc2c_test_DEPENDENCIES) stap$(EXEEXT): $(stap_OBJECTS) $(stap_DEPENDENCIES) @rm -f stap$(EXEEXT) $(stap_LINK) $(stap_OBJECTS) $(stap_LDADD) $(LIBS) +stap-client-connect$(EXEEXT): $(stap_client_connect_OBJECTS) $(stap_client_connect_DEPENDENCIES) + @rm -f stap-client-connect$(EXEEXT) + $(stap_client_connect_LINK) $(stap_client_connect_OBJECTS) $(stap_client_connect_LDADD) $(LIBS) +stap-server-connect$(EXEEXT): $(stap_server_connect_OBJECTS) $(stap_server_connect_DEPENDENCIES) + @rm -f stap-server-connect$(EXEEXT) + $(stap_server_connect_LINK) $(stap_server_connect_OBJECTS) $(stap_server_connect_LDADD) $(LIBS) stapio$(EXEEXT): $(stapio_OBJECTS) $(stapio_DEPENDENCIES) @rm -f stapio$(EXEEXT) $(stapio_LINK) $(stapio_OBJECTS) $(stapio_LDADD) $(LIBS) @@ -569,6 +604,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-tapsets.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-translate.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap-util.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap_client_connect-stap-client-connect.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stap_server_connect-stap-server-connect.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stapio-common.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stapio-ctl.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stapio-mainloop.Po@am__quote@ @@ -664,6 +701,34 @@ stap-mdfour.obj: mdfour.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stap_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o stap-mdfour.obj `if test -f 'mdfour.c'; then $(CYGPATH_W) 'mdfour.c'; else $(CYGPATH_W) '$(srcdir)/mdfour.c'; fi` +stap_client_connect-stap-client-connect.o: stap-client-connect.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stap_client_connect_CFLAGS) $(CFLAGS) -MT stap_client_connect-stap-client-connect.o -MD -MP -MF $(DEPDIR)/stap_client_connect-stap-client-connect.Tpo -c -o stap_client_connect-stap-client-connect.o `test -f 'stap-client-connect.c' || echo '$(srcdir)/'`stap-client-connect.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/stap_client_connect-stap-client-connect.Tpo $(DEPDIR)/stap_client_connect-stap-client-connect.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='stap-client-connect.c' object='stap_client_connect-stap-client-connect.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) $(stap_client_connect_CFLAGS) $(CFLAGS) -c -o stap_client_connect-stap-client-connect.o `test -f 'stap-client-connect.c' || echo '$(srcdir)/'`stap-client-connect.c + +stap_client_connect-stap-client-connect.obj: stap-client-connect.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stap_client_connect_CFLAGS) $(CFLAGS) -MT stap_client_connect-stap-client-connect.obj -MD -MP -MF $(DEPDIR)/stap_client_connect-stap-client-connect.Tpo -c -o stap_client_connect-stap-client-connect.obj `if test -f 'stap-client-connect.c'; then $(CYGPATH_W) 'stap-client-connect.c'; else $(CYGPATH_W) '$(srcdir)/stap-client-connect.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/stap_client_connect-stap-client-connect.Tpo $(DEPDIR)/stap_client_connect-stap-client-connect.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='stap-client-connect.c' object='stap_client_connect-stap-client-connect.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) $(stap_client_connect_CFLAGS) $(CFLAGS) -c -o stap_client_connect-stap-client-connect.obj `if test -f 'stap-client-connect.c'; then $(CYGPATH_W) 'stap-client-connect.c'; else $(CYGPATH_W) '$(srcdir)/stap-client-connect.c'; fi` + +stap_server_connect-stap-server-connect.o: stap-server-connect.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stap_server_connect_CFLAGS) $(CFLAGS) -MT stap_server_connect-stap-server-connect.o -MD -MP -MF $(DEPDIR)/stap_server_connect-stap-server-connect.Tpo -c -o stap_server_connect-stap-server-connect.o `test -f 'stap-server-connect.c' || echo '$(srcdir)/'`stap-server-connect.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/stap_server_connect-stap-server-connect.Tpo $(DEPDIR)/stap_server_connect-stap-server-connect.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='stap-server-connect.c' object='stap_server_connect-stap-server-connect.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) $(stap_server_connect_CFLAGS) $(CFLAGS) -c -o stap_server_connect-stap-server-connect.o `test -f 'stap-server-connect.c' || echo '$(srcdir)/'`stap-server-connect.c + +stap_server_connect-stap-server-connect.obj: stap-server-connect.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(stap_server_connect_CFLAGS) $(CFLAGS) -MT stap_server_connect-stap-server-connect.obj -MD -MP -MF $(DEPDIR)/stap_server_connect-stap-server-connect.Tpo -c -o stap_server_connect-stap-server-connect.obj `if test -f 'stap-server-connect.c'; then $(CYGPATH_W) 'stap-server-connect.c'; else $(CYGPATH_W) '$(srcdir)/stap-server-connect.c'; fi` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/stap_server_connect-stap-server-connect.Tpo $(DEPDIR)/stap_server_connect-stap-server-connect.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='stap-server-connect.c' object='stap_server_connect-stap-server-connect.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) $(stap_server_connect_CFLAGS) $(CFLAGS) -c -o stap_server_connect-stap-server-connect.obj `if test -f 'stap-server-connect.c'; then $(CYGPATH_W) 'stap-server-connect.c'; else $(CYGPATH_W) '$(srcdir)/stap-server-connect.c'; fi` + stapio-stapio.o: runtime/staprun/stapio.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(stapio_CPPFLAGS) $(CPPFLAGS) $(stapio_CFLAGS) $(CFLAGS) -MT stapio-stapio.o -MD -MP -MF $(DEPDIR)/stapio-stapio.Tpo -c -o stapio-stapio.o `test -f 'runtime/staprun/stapio.c' || echo '$(srcdir)/'`runtime/staprun/stapio.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/stapio-stapio.Tpo $(DEPDIR)/stapio-stapio.Po @@ -1196,8 +1261,8 @@ ID: $(HEADERS) $(SOURCES) $(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; nonemtpy = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS @@ -1222,8 +1287,8 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) config.in $(TAGS_DEPENDENCIES) \ 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; }; }'`; \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -1233,12 +1298,13 @@ ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ + here=`pwd`; \ list='$(SOURCES) $(HEADERS) config.in $(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; }; }'`; \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique @@ -1421,6 +1487,10 @@ cscope: @BUILD_ELFUTILS_TRUE@ $(INSTALL_PROGRAM) $$file $(DESTDIR)$(pkglibdir); \ @BUILD_ELFUTILS_TRUE@ done @BUILD_ELFUTILS_TRUE@install-exec-local: install-elfutils +stamp-ssl: config.status + $(srcdir)/stap-gen-server-cert ssl + touch $@ +ssl/server/stap-server.cert: stamp-ssl ; install-exec-hook: if [ `id -u` -eq 0 ]; then chmod 04111 "$(DESTDIR)$(bindir)/staprun"; fi @@ -1460,6 +1530,12 @@ install-data-local: i_cmd="$(INSTALL_PROGRAM)"; else \ i_cmd="$(INSTALL_DATA)"; fi; \ $$i_cmd -D $$f $(DESTDIR)$(docdir)/examples/$$f; done) + (cd $(builddir)/ssl/server; for f in pw; \ + do $(INSTALL) -m 600 -D $$f /etc/systemtap/ssl/server/$$f; done) + (cd $(builddir)/ssl/server; for f in *.db; \ + do $(INSTALL) -m 664 -D $$f /etc/systemtap/ssl/server/$$f; done) + (cd $(builddir)/ssl/client; for f in *.db; \ + do $(INSTALL) -m 664 -D $$f /etc/systemtap/ssl/client/$$f; done) gcov: @-$(MAKE) clean CXXFLAGS="-g -fprofile-arcs -ftest-coverage" all check @@ -1497,6 +1573,7 @@ uninstall-local: echo " rm -f '$(SAMPLE_INSTALL_DIR)/$$p'"; \ rm -f "$(SAMPLE_INSTALL_DIR)/$$p"; \ done + rm -rf /etc/systemtap check: SRCDIR=`cd $(srcdir); pwd`; \ @@ -1,7 +1,7 @@ -# generated automatically by aclocal 1.10.1 -*- Autoconf -*- +# generated automatically by aclocal 1.10 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# 2005, 2006 Free Software Foundation, Inc. # This file 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. @@ -11,15 +11,12 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(AC_AUTOCONF_VERSION, [2.61],, -[m4_warning([this file was generated for autoconf 2.61. -You have another version of autoconf. It may work, but is not guaranteed to. -If you have problems, you may need to regenerate the build system entirely. -To do so, use the procedure documented by the package, typically `autoreconf'.])]) +m4_if(m4_PACKAGE_VERSION, [2.61],, +[m4_fatal([this file was generated for autoconf 2.61. +You have another version of autoconf. If you want to use that, +you should regenerate the build system entirely.], [63])]) -# Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc. +# Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -34,7 +31,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.10' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.10.1], [], +m4_if([$1], [1.10], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -50,10 +47,8 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.10.1])dnl -m4_ifndef([AC_AUTOCONF_VERSION], - [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -_AM_AUTOCONF_VERSION(AC_AUTOCONF_VERSION)]) +[AM_AUTOMAKE_VERSION([1.10])dnl +_AM_AUTOCONF_VERSION(m4_PACKAGE_VERSION)]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- @@ -348,7 +343,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue @@ -396,13 +391,13 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005, 2006, 2008 Free Software Foundation, Inc. +# 2005, 2006 Free Software Foundation, Inc. # # This file 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. -# serial 13 +# serial 12 # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. @@ -507,17 +502,16 @@ AC_PROVIDE_IFELSE([AC_PROG_OBJC], # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. -_am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in - $_am_arg | $_am_arg:* ) + $1 | $1:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done -echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) +echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # @@ -878,7 +872,7 @@ AC_SUBST([INSTALL_STRIP_PROGRAM])]) # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- -# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# Prevent Automake from outputing VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) diff --git a/doc/ChangeLog b/doc/ChangeLog index 9cd46fe0..21e92df7 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,8 @@ +2008-12-24 Dave Brolley <brolley@redhat.com> + + * Makefile.in: Regenerated. + * SystemTap_Tapset_Reference/Makefile.in: Regenerated. + 2008-12-21 Will Cohen <wcohen@redhat.com> * Makefile.am: Add generations of tapset reference manual material. diff --git a/doc/Makefile.in b/doc/Makefile.in index e3d8f852..8fbd15d3 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10.1 from Makefile.am. +# Makefile.in generated by automake 1.10 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006 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. @@ -273,8 +273,8 @@ ID: $(HEADERS) $(SOURCES) $(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; nonemtpy = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS @@ -299,8 +299,8 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ 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; }; }'`; \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -310,12 +310,13 @@ ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ + 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; }; }'`; \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/doc/SystemTap_Tapset_Reference/Makefile.in b/doc/SystemTap_Tapset_Reference/Makefile.in index 1f01251d..dfeb5938 100644 --- a/doc/SystemTap_Tapset_Reference/Makefile.in +++ b/doc/SystemTap_Tapset_Reference/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.10.1 from Makefile.am. +# Makefile.in generated by automake 1.10 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006 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. @@ -46,7 +46,7 @@ PROGRAMS = $(noinst_PROGRAMS) docproc_SOURCES = docproc.c docproc_OBJECTS = docproc.$(OBJEXT) docproc_LDADD = $(LDADD) -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -235,8 +235,8 @@ ID: $(HEADERS) $(SOURCES) $(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; nonemtpy = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ mkid -fID $$unique tags: TAGS @@ -248,8 +248,8 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ 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; }; }'`; \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ @@ -259,12 +259,13 @@ ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ + 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; }; }'`; \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique diff --git a/stap-client b/stap-client index 3f530c7e..d700a675 100755 --- a/stap-client +++ b/stap-client @@ -29,11 +29,6 @@ function configuration { tmpdir_prefix_client=stap.client tmpdir_prefix_server=stap.server avahi_service_tag=_stap._tcp - - # We need either netcat or nc. - netcat=`which netcat 2>/dev/null` - test "X$netcat" = "X" && netcat=`which nc 2>/dev/null` - test "X$netcat" = "X" && fatal "ERROR: cannot find required program 'netcat' or 'nc' on PATH" } # function: initialization @@ -44,6 +39,7 @@ function initialization { staprun_running=0 # Default options settings + ssl_db=/etc/systemtap/ssl/client p_phase=5 v_level=0 keep_temps=0 @@ -86,14 +82,28 @@ function parse_options { # It's not a lone dash, so it's an option. # Is it a long option (i.e. --option)? second_char=`expr "$first_token" : '.\(.\).*'` - if test "$second_char" != "-"; then - # It's not a lone dash, or a long option, so it's a short option string. - # Remove the dash. - first_token=`expr "$first_token" : '-\(.*\)'` - dash_seen=1 - first_char=`expr "$first_token" : '\(.\).*'` - cmdline2="$cmdline2 -" + if test "X$second_char" = "X-"; then + long_option=`expr "$first_token" : '--\(.*\)=.*'` + test "X$long_option" != "X" || long_option=`expr "$first_token" : '--\(.*\)'` + case $long_option in + ssl) + process_ssl $first_token + ;; + *) + # An unknown or unimportant option. + # Ignore it, but pass it on to the server. + cmdline2="$cmdline2 $first_token" + ;; + esac + advance_p=$(($advance_p + 1)) + break fi + # It's not a lone dash, or a long option, so it's a short option string. + # Remove the dash. + first_token=`expr "$first_token" : '-\(.*\)'` + dash_seen=1 + first_char=`expr "$first_token" : '\(.\).*'` + cmdline2="$cmdline2 -" fi fi if test $dash_seen = 0; then @@ -236,6 +246,18 @@ function get_arg { advance_p=$(($advance_p + 1)) } +# function: process_ssl ARGUMENT +# +# Process the --ssl option. +function process_ssl { + local db=`expr "$1" : '--ssl=\(.*\)'` + + test "X$db" != "X" || \ + fatal "Missing argument to --ssl" + + ssl_db=$db +} + # function: process_c ARGUMENT # # Process the -c flag. @@ -370,86 +392,44 @@ function client_sysinfo { # Package the client's temp directory into a form suitable for sending to the # server. function package_request { - # Package up the temporary directory into a tar file + # Package up the temporary directory into a zip file cd $tmpdir_env local tmpdir_client_base=`basename $tmpdir_client` - tar_client=$tmpdir_env/`mktemp $tmpdir_client_base.tgz.XXXXXX` || \ - fatal "ERROR: cannot create temporary file " $tar_client - - tar -czhf $tar_client $tmpdir_client_base || \ - fatal "ERROR: tar of request tree, $tmpdir_client, failed" -} - -# function: send_request -# -# Notify the server and then send $tar_client to the server -# The protocol is: -# client -> "request:" -# client -> $tar_client -function send_request { - # Send the request file. - for ((attempt=0; $attempt < 10; ++attempt)) - do - if $netcat -w10 $server $(($port+1)) < $tar_client > /dev/null 2>&1; then - return; - fi - sleep 1 - done - fatal "ERROR: Unable to connect to server while sending request file" -} - -# function: receive_response -# -# Wait for a response from the server indicating the results of our request. -function receive_response { - # Make a place to receive the response file. - tar_server=`mktemp -t $tmpdir_prefix_client.server.tgz.XXXXXX` || \ - fatal "ERROR: cannot create temporary file " $tar_server + zip_client=$tmpdir_env/`mktemp $tmpdir_client_base.zip.XXXXXX` || \ + fatal "ERROR: cannot create temporary file " $zip_client - # Retrieve the file. Wait for up to 5 minutes for a response. - for ((attempt=0; $attempt < 300; ++attempt)) - do - if $netcat $server $(($port+1)) </dev/null > $tar_server 2>/dev/null; then - return; - fi - sleep 1 - done - fatal "ERROR: Unable to connect to server while receiving response file" + (rm $zip_client && zip -r $zip_client $tmpdir_client_base > /dev/null) || \ + fatal "ERROR: zip of request tree, $tmpdir_client, failed" } # function: unpack_response # -# Unpack the tar file received from the server and make the contents available +# Unpack the jar file received from the server and make the contents available # for printing the results and/or running 'staprun'. function unpack_response { tmpdir_server=`mktemp -dt $tmpdir_prefix_client.server.XXXXXX` || \ fatal "ERROR: cannot create temporary file " $tmpdir_server - # Unpack the server output directory - cd $tmpdir_server - tar -xzf $tar_server || \ - fatal "ERROR: Unpacking of server response, $tar_server, failed" - - # Identify the server's response tree. The tar file should have expanded - # into a single directory named to match $tmpdir_prefix_server.?????? - # which should now be the only item in the current directory. - test "`ls | wc -l`" = 1 || \ - fatal "ERROR: Wrong number of files after expansion of server's tar file" - - tmpdir_server=`ls` - tmpdir_server=`expr "$tmpdir_server" : "\\\($tmpdir_prefix_server\\\\.......\\\)"` + # Unpack and verify the digitally signed server output directory + if ! signtool -d $ssl_db -v $jar_server > /dev/null 2>&1; then + # Run the verification again to get the reason + fatal "ERROR: Verification of server response, $jar_server, failed. +"`signtool -d $ssl_db -v $jar_server | grep "reported reason"` + fi - test "X$tmpdir_server" != "X" || \ - fatal "ERROR: server tar file did not expand as expected" + # Unpack the server output directory + unzip -d $tmpdir_server $jar_server > /dev/null || \ + fatal "ERROR: Cannot unpack server response, $jar_server" # Check the contents of the expanded directory. It should contain: # 1) a file called stdout # 2) a file called stderr # 3) a file called rc - # 4) optionally a directory named to match stap?????? + # 4) a directory called META-INF + # 5) optionally a directory named to match stap?????? local num_files=`ls $tmpdir_server | wc -l` - test $num_files = 4 -o $num_files = 3 || \ + test $num_files = 5 -o $num_files = 4 || \ fatal "ERROR: Wrong number of files in server's temp directory" test -f $tmpdir_server/stdout || \ fatal "ERROR: `pwd`/$tmpdir_server/stdout does not exist or is not a regular file" @@ -457,6 +437,8 @@ function unpack_response { fatal "ERROR: `pwd`/$tmpdir_server/stderr does not exist or is not a regular file" test -f $tmpdir_server/rc || \ fatal "ERROR: `pwd`/$tmpdir_server/rc does not exist or is not a regular file" + test -d $tmpdir_server/META-INF || \ + fatal "ERROR: `pwd`/$tmpdir_server/META-INF does not exist or is not a directory" # See if there is a systemtap temp directory tmpdir_stap=`ls $tmpdir_server | grep stap` @@ -480,15 +462,8 @@ function unpack_response { # Make sure we own the systemtap temp directory if we are root. test $EUID = 0 && chown $EUID:$EUID $tmpdir_server/$tmpdir_stap # The temp directory will be moved to here below. - tmpdir_stap=`pwd`/$tmpdir_stap fi fi - - # Move the contents of the server's tmpdir down one level to the - # current directory (our local server tmpdir) - mv $tmpdir_server/* . 2>/dev/null - rm -fr $tmpdir_server - tmpdir_server=`pwd` } # function: find_and_connect_to_server @@ -514,6 +489,22 @@ function choose_server { do num_servers=$(($num_servers + 1)) + # The server must match the dns name on the certificate + # and must be 'localhost' if the server is on the local host. + local server_host_name=`expr "$name" : "\\\([a-zA-Z0-9-]*\\\).*"` + local server_domain_name=`expr "$name" : "$server_host_name\\\(.*\\\)"` + local our_host_name=`expr "$HOSTNAME" : "\\\([a-zA-Z0-9-]*\\\).*"` + local our_domain_name=`expr "$HOSTNAME" : "$our_host_name\\\(.*\\\)"` + + if test "X$server_domain_name" = "X.local"; then + server_domain_name=$our_domain_name + fi + if test "X$server_host_name$server_domain_name" = "X$our_host_name$our_domain_name"; then + server=localhost + else + server=$name + fi + if test "X$server" = "X"; then fatal "ERROR: server ip address not provided" fi @@ -522,7 +513,7 @@ function choose_server { fatal "ERROR: server port not provided" fi - if connect_to_server $server $port; then + if send_receive; then return 0 fi done @@ -534,26 +525,20 @@ function choose_server { fatal "ERROR: unable to connect to a server" } -# function: connect_to_server IP PORT +# function: send_receive # -# Establish connection with the given server -function connect_to_server { - for ((attempt=0; $attempt < 10; ++attempt)) - do - if echo "request:" | $netcat -w10 $1 $2 >/dev/null 2>&1; then - return 0 - fi - sleep 1 - done +# Connect to the server, send the request and receive the response +function send_receive { + # Make a place to receive the response file. + jar_server=`mktemp -t $tmpdir_prefix_client.server.jar.XXXXXX` || \ + fatal "ERROR: cannot create temporary file " $jar_server - return 1 -} + # Send the request and receive the response using stap-client-connect + stap-client-connect -i $zip_client -o $jar_server -d $ssl_db -p $port -h $server & + wait '%stap-client-connect' -# function: disconnect_from_server -# -# Disconnect from the server. -function disconnect_from_server { - : + test $? = 0 && return 0 + return 1 } # function: process_response @@ -561,6 +546,7 @@ function disconnect_from_server { # Write the stdout and stderr from the server to stdout and stderr respectively. function process_response { # Pick up the results of running stap on the server. + cd $tmpdir_server rc=`cat rc` # Copy the module to the current directory, if -m was specified @@ -686,7 +672,6 @@ function staprun_PATH { # Prints its arguments to stderr and exits function fatal { echo "$0:" "$@" >&2 - disconnect_from_server cleanup exit 1 } @@ -699,8 +684,8 @@ function cleanup { cd $tmpdir_env if test $keep_temps != 1; then rm -fr $tmpdir_client - rm -f $tar_client - rm -f $tar_server + rm -f $zip_client + rm -f $jar_server rm -fr $tmpdir_server fi } @@ -716,6 +701,9 @@ function terminate { # Kill any running staprun job kill -s SIGTERM '%?staprun' 2>/dev/null + # Kill any stap-client-connect job + kill -s SIGTERM '%stap-client-connect' + exit 1 } @@ -729,6 +717,9 @@ function interrupt { return fi + # Kill any stap-client-connect job + kill -s SIGINT '%stap-client-connect' + # If staprun was not running, then exit. cleanup exit 1 @@ -750,9 +741,6 @@ parse_options "$@" create_request package_request find_and_connect_to_server -send_request -receive_response -disconnect_from_server unpack_response process_response maybe_call_staprun diff --git a/stap-client-connect.c b/stap-client-connect.c new file mode 100644 index 00000000..29a8e18d --- /dev/null +++ b/stap-client-connect.c @@ -0,0 +1,449 @@ +/* + SSL client program that sets up a connection to a SSL server, transmits + the given input file and then writes the reply to the given output file. + + Copyright (C) 2008 Red Hat Inc. + + This file is part of systemtap, and is free software. You can + redistribute it and/or modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include <stdio.h> + +#include <ssl.h> +#include <nspr.h> +#include <plgetopt.h> +#include <nss.h> + +#define READ_BUFFER_SIZE (60 * 1024) + +static char *hostName = NULL; +static unsigned short port = 0; +static const char *infileName = NULL; +static const char *outfileName = NULL; + +static void +Usage(const char *progName) +{ + fprintf(stderr, "Usage: %s -h hostname -p port -d dbdir -i infile -o outfile\n", + progName); + exit(1); +} + +static void +errWarn(char *function) +{ + PRErrorCode errorNumber = PR_GetError(); + + printf("Error in function %s: %d\n\n", function, errorNumber); +} + +static void +exitErr(char *function) +{ + errWarn(function); + /* Exit gracefully. */ + /* ignoring return value of NSS_Shutdown as code exits with 1*/ + (void) NSS_Shutdown(); + PR_Cleanup(); + exit(1); +} + +static PRFileDesc * +setupSSLSocket(void) +{ + PRFileDesc *tcpSocket; + PRFileDesc *sslSocket; + PRSocketOptionData socketOption; + PRStatus prStatus; + SECStatus secStatus; + + tcpSocket = PR_NewTCPSocket(); + if (tcpSocket == NULL) + { + errWarn("PR_NewTCPSocket"); + } + + /* Make the socket blocking. */ + socketOption.option = PR_SockOpt_Nonblocking; + socketOption.value.non_blocking = PR_FALSE; + + prStatus = PR_SetSocketOption(tcpSocket, &socketOption); + if (prStatus != PR_SUCCESS) + { + errWarn("PR_SetSocketOption"); + goto loser; + } + + /* Import the socket into the SSL layer. */ + sslSocket = SSL_ImportFD(NULL, tcpSocket); + if (!sslSocket) + { + errWarn("SSL_ImportFD"); + goto loser; + } + + /* Set configuration options. */ + secStatus = SSL_OptionSet(sslSocket, SSL_SECURITY, PR_TRUE); + if (secStatus != SECSuccess) + { + errWarn("SSL_OptionSet:SSL_SECURITY"); + goto loser; + } + + secStatus = SSL_OptionSet(sslSocket, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); + if (secStatus != SECSuccess) + { + errWarn("SSL_OptionSet:SSL_HANDSHAKE_AS_CLIENT"); + goto loser; + } + + /* Set SSL callback routines. */ +#if 0 /* no client authentication */ + secStatus = SSL_GetClientAuthDataHook(sslSocket, + (SSLGetClientAuthData)myGetClientAuthData, + (void *)certNickname); + if (secStatus != SECSuccess) + { + errWarn("SSL_GetClientAuthDataHook"); + goto loser; + } +#endif +#if 0 /* Use the default */ + secStatus = SSL_AuthCertificateHook(sslSocket, + (SSLAuthCertificate)myAuthCertificate, + (void *)CERT_GetDefaultCertDB()); + if (secStatus != SECSuccess) + { + errWarn("SSL_AuthCertificateHook"); + goto loser; + } +#endif +#if 0 /* Use the default */ + secStatus = SSL_BadCertHook(sslSocket, + (SSLBadCertHandler)myBadCertHandler, NULL); + if (secStatus != SECSuccess) + { + errWarn("SSL_BadCertHook"); + goto loser; + } +#endif +#if 0 /* No handshake callback */ + secStatus = SSL_HandshakeCallback(sslSocket, myHandshakeCallback, NULL); + if (secStatus != SECSuccess) + { + errWarn("SSL_HandshakeCallback"); + goto loser; + } +#endif + + return sslSocket; + + loser: + PR_Close(tcpSocket); + return NULL; +} + + +static SECStatus +handle_connection(PRFileDesc *sslSocket) +{ +#if DEBUG + int countRead = 0; +#endif + PRInt32 numBytes; + char *readBuffer; + PRFileInfo info; + PRFileDesc *local_file_fd; + PRStatus prStatus; + + /* read and send the data. */ + /* Try to open the local file named. + * If successful, then write it to the server + */ + prStatus = PR_GetFileInfo(infileName, &info); + if (prStatus != PR_SUCCESS || + info.type != PR_FILE_FILE || + info.size < 0) + { + fprintf (stderr, "could not find input file %s\n", infileName); + return SECFailure; + } + + local_file_fd = PR_Open(infileName, PR_RDONLY, 0); + if (local_file_fd == NULL) + { + fprintf (stderr, "could not open input file %s\n", infileName); + return SECFailure; + } + + /* Send the file size first, so the server knows when it has the entire file. */ + numBytes = PR_Write(sslSocket, & info.size, sizeof (info.size)); + /* Error in transmission? */ + if (numBytes < 0) + { + errWarn("PR_TransmitFile"); + return SECFailure; + } + + /* Transmit the local file across the socket. */ + numBytes = PR_TransmitFile(sslSocket, local_file_fd, + NULL, 0, + PR_TRANSMITFILE_KEEP_OPEN, + PR_INTERVAL_NO_TIMEOUT); + /* Error in transmission? */ + if (numBytes < 0) + { + errWarn("PR_TransmitFile"); + return SECFailure; + } + +#if DEBUG + /* Transmitted bytes successfully. */ + fprintf(stderr, "PR_TransmitFile wrote %d bytes from %s\n", + numBytes, "stdin"); +#endif + + PR_Close(local_file_fd); + + /* read until EOF */ + readBuffer = PORT_Alloc(READ_BUFFER_SIZE); + if (! readBuffer) + exitErr("PORT_Alloc"); + + local_file_fd = PR_Open(outfileName, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, + PR_IRUSR | PR_IWUSR | PR_IRGRP | PR_IWGRP | PR_IROTH); + if (local_file_fd == NULL) + { + fprintf (stderr, "could not open output file %s\n", outfileName); + return SECFailure; + } + while (PR_TRUE) + { + numBytes = PR_Read(sslSocket, readBuffer, READ_BUFFER_SIZE); + if (numBytes == 0) + break; /* EOF */ + + if (numBytes < 0) + { + errWarn("PR_Read"); + break; + } +#if DEBUG + countRead += numBytes; +#endif + /* Write to output file */ + numBytes = PR_Write(local_file_fd, readBuffer, numBytes); + if (numBytes < 0) + { + fprintf (stderr, "could not write to %s\n", outfileName); +#if DEBUG + fprintf(stderr, "***** Connection read %d bytes (%d total).\n", + numBytes, countRead ); + readBuffer[numBytes] = '\0'; + fprintf(stderr, "************\n%s\n************\n", readBuffer); +#endif + } + } + + PR_Free(readBuffer); + PR_Close(local_file_fd); + + /* Caller closes the socket. */ +#if DEBUG + fprintf(stderr, "***** Connection read %d bytes total.\n", countRead); +#endif + + return SECSuccess; +} + +/* make the connection. +*/ +static SECStatus +do_connect(PRNetAddr *addr) +{ + PRFileDesc *sslSocket; + PRHostEnt hostEntry; + char buffer[PR_NETDB_BUF_SIZE]; + PRStatus prStatus; + PRIntn hostenum; + SECStatus secStatus; + + /* Set up SSL secure socket. */ + sslSocket = setupSSLSocket(); + if (sslSocket == NULL) + { + errWarn("setupSSLSocket"); + return SECFailure; + } + +#if 0 /* no client authentication */ + secStatus = SSL_SetPKCS11PinArg(sslSocket, password); + if (secStatus != SECSuccess) + { + errWarn("SSL_SetPKCS11PinArg"); + return secStatus; + } +#endif + + secStatus = SSL_SetURL(sslSocket, hostName); + if (secStatus != SECSuccess) + { + errWarn("SSL_SetURL"); + return secStatus; + } + + /* Prepare and setup network connection. */ + prStatus = PR_GetHostByName(hostName, buffer, sizeof(buffer), &hostEntry); + if (prStatus != PR_SUCCESS) + { + errWarn("PR_GetHostByName"); + return SECFailure; + } + + hostenum = PR_EnumerateHostEnt(0, &hostEntry, port, addr); + if (hostenum == -1) + { + errWarn("PR_EnumerateHostEnt"); + return SECFailure; + } + + prStatus = PR_Connect(sslSocket, addr, PR_INTERVAL_NO_TIMEOUT); + if (prStatus != PR_SUCCESS) + { + errWarn("PR_Connect"); + return SECFailure; + } + + /* Established SSL connection, ready to send data. */ +#if 0 /* Not necessary? */ + secStatus = SSL_ForceHandshake(sslSocket); + if (secStatus != SECSuccess) + { + errWarn("SSL_ForceHandshake"); + return secStatus; + } +#endif + + secStatus = SSL_ResetHandshake(sslSocket, /* asServer */ PR_FALSE); + if (secStatus != SECSuccess) + { + errWarn("SSL_ResetHandshake"); + prStatus = PR_Close(sslSocket); + if (prStatus != PR_SUCCESS) + errWarn("PR_Close"); + return secStatus; + } + + secStatus = handle_connection(sslSocket); + if (secStatus != SECSuccess) + { + errWarn("handle_connection"); + return secStatus; + } + + PR_Close(sslSocket); + return SECSuccess; +} + +static void +client_main(unsigned short port, const char *hostName) +{ + SECStatus secStatus; + PRStatus prStatus; + PRInt32 rv; + PRNetAddr addr; + PRHostEnt hostEntry; + char buffer[PR_NETDB_BUF_SIZE]; + + /* Setup network connection. */ + prStatus = PR_GetHostByName(hostName, buffer, sizeof (buffer), &hostEntry); + if (prStatus != PR_SUCCESS) + exitErr("PR_GetHostByName"); + + rv = PR_EnumerateHostEnt(0, &hostEntry, port, &addr); + if (rv < 0) + exitErr("PR_EnumerateHostEnt"); + + secStatus = do_connect (&addr); + if (secStatus != SECSuccess) + exitErr("do_connect"); +} + +#if 0 /* No client authorization */ +static char * +myPasswd(PK11SlotInfo *info, PRBool retry, void *arg) +{ + char * passwd = NULL; + + if ( (!retry) && arg ) + passwd = PORT_Strdup((char *)arg); + + return passwd; +} +#endif + +int +main(int argc, char **argv) +{ + char * certDir = NULL; + char * progName = NULL; + SECStatus secStatus; + PLOptState *optstate; + PLOptStatus status; + + /* Call the NSPR initialization routines */ + PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); + + progName = PL_strdup(argv[0]); + + hostName = NULL; + optstate = PL_CreateOptState(argc, argv, "d:h:i:o:p:"); + while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) + { + switch(optstate->option) + { + case 'd' : certDir = PL_strdup(optstate->value); break; + case 'h' : hostName = PL_strdup(optstate->value); break; + case 'i' : infileName = PL_strdup(optstate->value); break; + case 'o' : outfileName = PL_strdup(optstate->value); break; + case 'p' : port = PORT_Atoi(optstate->value); break; + case '?' : + default : Usage(progName); + } + } + + if (port == 0 || hostName == NULL || infileName == NULL || outfileName == NULL || certDir == NULL) + Usage(progName); + +#if 0 /* no client authentication */ + /* Set our password function callback. */ + PK11_SetPasswordFunc(myPasswd); +#endif + + /* Initialize the NSS libraries. */ + secStatus = NSS_Init(certDir); + if (secStatus != SECSuccess) + exitErr("NSS_Init"); + + /* All cipher suites except RSA_NULL_MD5 are enabled by Domestic Policy. */ + NSS_SetDomesticPolicy(); + + client_main(port, hostName); + + NSS_Shutdown(); + PR_Cleanup(); + + return 0; +} diff --git a/stap-find-or-start-server b/stap-find-or-start-server index 32a45052..108ac6ed 100755 --- a/stap-find-or-start-server +++ b/stap-find-or-start-server @@ -21,7 +21,7 @@ stap-find-servers >/dev/null 2>&1 && echo 0 && exit 0 # No server available, try to start one. -pid=`stap-start-server` +pid=`stap-start-server "$@"` if test $? = 0; then echo $pid exit 0 diff --git a/stap-gen-server-cert b/stap-gen-server-cert new file mode 100755 index 00000000..8f9629ea --- /dev/null +++ b/stap-gen-server-cert @@ -0,0 +1,74 @@ +#!/bin/bash + +# Generate a certificate for the systemtap server and add it to the +# database of trusted servers for the client. +# +# Copyright (C) 2008 Red Hat Inc. +# +# This file is part of systemtap, and is free software. You can +# redistribute it and/or modify it under the terms of the GNU General +# Public License (GPL); either version 2, or (at your option) any +# later version. + +# Obtain the certificate database directory name. +if test "X$1" = "X"; then + echo "Certificate database directory must be specified" >&2 + exit 1 +fi +rm -fr $1 + +# Create the server's certificate database directory. +serverdb=$1/server +if ! mkdir -p $serverdb; then + echo "Unable to create the server certificate database directory: $serverdb" >&2 + exit 1 +fi + +# Create the certificate database password file. Care must be taken +# that this file is only readable by the owner. +if ! (touch $serverdb/pw && chmod 600 $serverdb/pw); then + echo "Unable to create the server certificate database password file: $serverdb/pw" >&2 + exit 1 +fi + +# Generate a random password. +mkpasswd -l 20 > $serverdb/pw + +# Generate the server certificate database +if ! certutil -N -d $serverdb -f $serverdb/pw > /dev/null; then + echo "Unable to initialize the server certificate database directory: $serverdb" >&2 + exit 1 +fi + +# We need some random noise for generating keys +dd bs=123 count=1 < /dev/urandom > $1/noise 2> /dev/null + +# Generate a request for the server's certificate. +certutil -R -d $serverdb -f $serverdb/pw -s "CN=Systemtap Compile Server, OU=Systemtap, O=Red Hat, C=US" -o $1/stap-server.req -z $1/noise 2> /dev/null +rm -fr $1/noise + +# Now generate the actual certificate. +certutil -C -i $1/stap-server.req -o $serverdb/stap-server.cert -x -d $serverdb -f $serverdb/pw -5 -8 "$HOSTNAME,localhost" >/dev/null <<-EOF +1 +3 +7 +8 +y +EOF +rm -fr $1/stap-server.req + +# Add the certificate to the server's certificate/key database as a trusted peer, ssl server and object signer +certutil -A -n stap-server -t "PCu,,PCu" -i $serverdb/stap-server.cert -d $serverdb -f $serverdb/pw + +# Now create a directory for the client's certificate database +clientdb=$1/client +if ! mkdir -p $clientdb; then + echo "Unable to create the client certificate database directory: $clientdb" >&2 + exit 1 +fi + +# Now add the server's certificate to the client's database, making it a trusted peer. +if ! certutil -A -n stap-server -d $clientdb -i $serverdb/stap-server.cert -t "P,P,P" > /dev/null; then + echo "Unable to add $serverdb/x509.cacert to the client certificate database: $clientdb" >&2 + exit 1 +fi diff --git a/stap-server b/stap-server index 0a7d5977..0a63d98e 100755 --- a/stap-server +++ b/stap-server @@ -24,13 +24,6 @@ function configuration { # Configuration tmpdir_prefix_client=stap.client tmpdir_prefix_server=stap.server - port=$1 - test "X$port" = "X" && port=65001 - - # We need either netcat or nc. - netcat=`which netcat 2>/dev/null` - test "X$netcat" = "X" && netcat=`which nc 2>/dev/null` - test "X$netcat" = "X" && fatal "ERROR: cannot find required program 'netcat' or 'nc' on PATH" } # function: initialization @@ -43,63 +36,53 @@ function initialization { p_phase=5 keep_temps=0 - # Make a temp directory to work in. - tmpdir_server=`mktemp -dt $tmpdir_prefix_server.XXXXXX` || \ - fatal "ERROR: cannot create temporary directory " $tmpdir_server - tmpdir_env=`dirname $tmpdir_server` -} - -# function: receive_request -# -# Receive a tar file representing the request from the client: -function receive_request { - # Create a place to receive the client's tar file - tar_client=`mktemp -t $tmpdir_prefix_server.client.tgz.XXXXXX` || \ - fatal "ERROR: cannot create temporary tar file " $tar_client + # Request file name. + zip_client=$1 + test -f $zip_client || \ + fatal "ERROR: Unable to find request file $zip_client" - # Receive the file. - $netcat -l $port < /dev/null > $tar_client 2>/dev/null & + # Temp directory we will be working in + tmpdir_server=$2 + test -d $tmpdir_server || \ + fatal "ERROR: Cannot find temporary directory $tmpdir_server" + tmpdir_env=`dirname $tmpdir_server` - # Wait for 10 seconds before timing out - for ((t=0; $t < 10; ++t)) - do - if jobs '%$netcat -l' >/dev/null 2>&1; then - sleep 1 - else - return - fi - done + # Signed reponse file name. + jar_server=$3 - # We have timed out. fatal will kill the job. - fatal "Timed out waiting for client request file" + # Where is the ssl certificate/key database? + ssl_db=$4 + test "X$ssl_db" = "X" && ssl_db=/etc/systemtap/ssl/server + nss_pw=$ssl_db/pw + nss_cert=stap-server } # function: unpack_request # -# Unpack the tar file received from the client and make the contents +# Unpack the zip file received from the client and make the contents # available for use when running 'stap' function unpack_request { cd $tmpdir_server - # Unpack the tar file. - tar -xzf $tar_client || \ - fatal "ERROR: cannot unpack tar archive $tar_client" + # Unpack the zip file. + unzip $zip_client > /dev/null || \ + fatal "ERROR: cannot unpack zip archive $zip_client" - # Identify the client's request tree. The tar file should have expanded + # Identify the client's request tree. The zip file should have expanded # into a single directory named to match $tmpdir_prefix_client.?????? # which should now be the only item in the current directory. test "`ls | wc -l`" = 1 || \ - fatal "ERROR: Wrong number of files after expansion of client's tar file" + fatal "ERROR: Wrong number of files after expansion of client's zip file" tmpdir_client=`ls` tmpdir_client=`expr "$tmpdir_client" : "\\\($tmpdir_prefix_client\\\\.......\\\)"` test "X$tmpdir_client" != "X" || \ - fatal "ERROR: client tar file did not expand as expected" + fatal "ERROR: client zip file did not expand as expected" # Move the client's temp directory to a local temp location local local_tmpdir_client=`mktemp -dt $tmpdir_prefix_server.client.XXXXXX` || \ - fatal "ERROR: cannot create temporary tar file " $local_tmpdir_client + fatal "ERROR: cannot create temporary zip file " $local_tmpdir_client mv $tmpdir_client/* $local_tmpdir_client rm -fr $tmpdir_client tmpdir_client=$local_tmpdir_client @@ -373,36 +356,18 @@ function create_response { # client. function package_response { cd $tmpdir_env - # Create a place to generate our tar file of our temporary directory - local tmpdir_server_base=`basename $tmpdir_server` - tar_server=$tmpdir_env/`mktemp $tmpdir_server_base.tgz.XXXXXX` || \ - fatal "ERROR: cannot create temporary tar file " $tar_server - chmod +r $tar_server - - # Generate the tar file - tar -czhf $tar_server `basename $tmpdir_server` || \ - fatal "ERROR: tar of $tmpdir_server failed" -} - -# function: send_response -# -# Wait for the client to take the response file. -function send_response { - # Now send it. - $netcat -l $port < $tar_server > /dev/null 2>&1 & - # Wait for 10 seconds before timing out - for ((t=0; $t < 10; ++t)) - do - if jobs '%$netcat -l' >/dev/null 2>&1; then - sleep 1 - else - return - fi - done - - # We have timed out. fatal will kill the job. - fatal "Timed out waiting to send response file" + # We will be digitally signing the server's temporary directory. This + # will sign the entire directory and compress it into a .jar + # archive. + # + # Make sure the specified .jar file exists. + test -f $jar_server || \ + fatal "ERROR: Could not find .jar archive file $jar_server" + #chmod +r $jar_server + + # Generate the jar file + signtool -d $ssl_db -k $nss_cert -p `cat $nss_pw` -Z $jar_server $tmpdir_server } # function: fatal [ MESSAGE ] @@ -428,15 +393,10 @@ function cleanup { # Clean up. cd $tmpdir_env if test $keep_temps != 1; then - rm -fr $tar_client - rm -fr $tmpdir_client - rm -fr $tar_server rm -fr $tmpdir_server + rm -fr $tmpdir_client rm -fr $tmpdir_stap fi - - # Kill any $netcat job that may be running - kill -s SIGTERM '%$netcat' 2> /dev/null } # function: terminate @@ -451,16 +411,14 @@ function terminate { #----------------------------------------------------------------------------- # Beginning of main line execution. #----------------------------------------------------------------------------- -configuration "$@" -initialization -receive_request +configuration +initialization "$@" unpack_request check_request eval parse_options "$cmdline" call_stap create_response package_response -send_response cleanup exit 0 diff --git a/stap-server-connect.c b/stap-server-connect.c new file mode 100644 index 00000000..388c5d96 --- /dev/null +++ b/stap-server-connect.c @@ -0,0 +1,756 @@ +/* + SSL server program listens on a port, accepts client connection, reads + the data into a temporary file, calls the systemtap server script and + then transmits the resulting fileback to the client. + + Copyright (C) 2008 Red Hat Inc. + + This file is part of systemtap, and is free software. You can + redistribute it and/or modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include <ssl.h> +#include <nspr.h> +#include <plgetopt.h> +#include <nss.h> +#include <pk11func.h> + +#define READ_BUFFER_SIZE (60 * 1024) + +/* Global variables */ +static char *password = NULL; +static CERTCertificate *cert = NULL; +static SECKEYPrivateKey *privKey = NULL; +static char *dbdir = NULL; +static char requestFileName[] = "/tmp/stap.server.client.zip.XXXXXX"; +static char responseDirName[] = "/tmp/stap.server.XXXXXX"; +static char responseJarName[] = "/tmp/stap.server.XXXXXX.jar.XXXXXX"; + +static void +Usage(const char *progName) +{ + fprintf(stderr, + "Usage: %s -p port -d dbdir -n rsa_nickname -w passwordFile\n", + progName); + exit(1); +} + +static void +errWarn(char *function) +{ + PRErrorCode errorNumber = PR_GetError(); + + printf("Error in function %s: %d\n\n", function, errorNumber); +} + +static void +exitErr(char *function) +{ + errWarn(function); + /* Exit gracefully. */ + /* ignoring return value of NSS_Shutdown as code exits with 1*/ + (void) NSS_Shutdown(); + PR_Cleanup(); + exit(1); +} + +/* Function: readDataFromSocket() + * + * Purpose: Read data from the socket into a temporary file. + * + */ +static SECStatus +readDataFromSocket(PRFileDesc *sslSocket) +{ + PRFileDesc *local_file_fd; + PRFileInfo info; + PRInt32 numBytesRead; + PRInt32 numBytesWritten; + PRInt32 totalBytes; + char buffer[READ_BUFFER_SIZE]; + + /* Open the output file. */ + local_file_fd = PR_Open(requestFileName, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, + PR_IRUSR | PR_IWUSR | PR_IRGRP | PR_IWGRP | PR_IROTH); + if (local_file_fd == NULL) + { + fprintf (stderr, "could not open output file %s\n", requestFileName); + return SECFailure; + } + + /* Read the number fo bytes to be received. */ + numBytesRead = PR_Read(sslSocket, & info.size, sizeof (info.size)); + if (numBytesRead == 0) /* EOF */ + { + fprintf (stderr, "Error reading size of request file\n"); + return SECFailure; + } + if (numBytesRead < 0) + { + errWarn("PR_Read"); + return SECFailure; + } + + /* Read until EOF or until the expected number of bytes has been read. */ + for (totalBytes = 0; totalBytes < info.size; totalBytes += numBytesRead) + { + numBytesRead = PR_Read(sslSocket, buffer, READ_BUFFER_SIZE); + if (numBytesRead == 0) + break; /* EOF */ + if (numBytesRead < 0) + { + errWarn("PR_Read"); + break; + } + + /* Write to stdout */ + numBytesWritten = PR_Write(local_file_fd, buffer, numBytesRead); + if (numBytesWritten < 0) + fprintf (stderr, "could not write to output file %s\n", requestFileName); + if (numBytesWritten != numBytesRead) + fprintf (stderr, "could not write to output file %s\n", requestFileName); +#if DEBUG + fprintf(stderr, "***** Connection read %d bytes.\n", numBytesRead); +#if 0 + buffer[numBytesRead] = '\0'; + fprintf(stderr, "************\n%s\n************\n", buffer); +#endif +#endif + } + + if (totalBytes != info.size) + { + fprintf (stderr, "Expected %d bytes, got %d\n", info.size, totalBytes); + return SECFailure; + } + + PR_Close(local_file_fd); + + return SECSuccess; +} + +/* Function: setupSSLSocket() + * + * Purpose: Configure a socket for SSL. + * + * + */ +static PRFileDesc * +setupSSLSocket(PRFileDesc *tcpSocket) +{ + PRFileDesc *sslSocket; + SSLKEAType certKEA; +#if 0 + int certErr = 0; +#endif + SECStatus secStatus; + + /* Inport the socket into SSL. */ + sslSocket = SSL_ImportFD(NULL, tcpSocket); + if (sslSocket == NULL) + { + errWarn("SSL_ImportFD"); + goto loser; + } + + /* Set the appropriate flags. */ + secStatus = SSL_OptionSet(sslSocket, SSL_SECURITY, PR_TRUE); + if (secStatus != SECSuccess) + { + errWarn("SSL_OptionSet SSL_SECURITY"); + goto loser; + } + + secStatus = SSL_OptionSet(sslSocket, SSL_HANDSHAKE_AS_SERVER, PR_TRUE); + if (secStatus != SECSuccess) + { + errWarn("SSL_OptionSet:SSL_HANDSHAKE_AS_SERVER"); + goto loser; + } + + secStatus = SSL_OptionSet(sslSocket, SSL_REQUEST_CERTIFICATE, PR_FALSE); + if (secStatus != SECSuccess) + { + errWarn("SSL_OptionSet:SSL_REQUEST_CERTIFICATE"); + goto loser; + } + + secStatus = SSL_OptionSet(sslSocket, SSL_REQUIRE_CERTIFICATE, PR_FALSE); + if (secStatus != SECSuccess) + { + errWarn("SSL_OptionSet:SSL_REQUIRE_CERTIFICATE"); + goto loser; + } + + /* Set the appropriate callback routines. */ +#if 0 /* use the default */ + secStatus = SSL_AuthCertificateHook(sslSocket, myAuthCertificate, + CERT_GetDefaultCertDB()); + if (secStatus != SECSuccess) + { + errWarn("SSL_AuthCertificateHook"); + goto loser; + } +#endif +#if 0 /* Use the default */ + secStatus = SSL_BadCertHook(sslSocket, + (SSLBadCertHandler)myBadCertHandler, &certErr); + if (secStatus != SECSuccess) + { + errWarn("SSL_BadCertHook"); + goto loser; + } +#endif +#if 0 /* no handshake callback */ + secStatus = SSL_HandshakeCallback(sslSocket, + myHandshakeCallback, + NULL); + if (secStatus != SECSuccess) + { + errWarn("SSL_HandshakeCallback"); + goto loser; + } +#endif + secStatus = SSL_SetPKCS11PinArg(sslSocket, password); + if (secStatus != SECSuccess) + { + errWarn("SSL_HandshakeCallback"); + goto loser; + } + + certKEA = NSS_FindCertKEAType(cert); + + secStatus = SSL_ConfigSecureServer(sslSocket, cert, privKey, certKEA); + if (secStatus != SECSuccess) + { + errWarn("SSL_ConfigSecureServer"); + goto loser; + } + + return sslSocket; + +loser: + PR_Close(tcpSocket); + return NULL; +} + +#if 0 /* No client authentication and not authenticating after each transaction. */ +/* Function: authenticateSocket() + * + * Purpose: Perform client authentication on the socket. + * + */ +static SECStatus +authenticateSocket(PRFileDesc *sslSocket, PRBool requireCert) +{ + CERTCertificate *cert; + SECStatus secStatus; + + /* Returns NULL if client authentication is not enabled or if the + * client had no certificate. */ + cert = SSL_PeerCertificate(sslSocket); + if (cert) + { + /* Client had a certificate, so authentication is through. */ + CERT_DestroyCertificate(cert); + return SECSuccess; + } + + /* Request client to authenticate itself. */ + secStatus = SSL_OptionSet(sslSocket, SSL_REQUEST_CERTIFICATE, PR_TRUE); + if (secStatus != SECSuccess) + { + errWarn("SSL_OptionSet:SSL_REQUEST_CERTIFICATE"); + return SECFailure; + } + + /* If desired, require client to authenticate itself. Note + * SSL_REQUEST_CERTIFICATE must also be on, as above. */ + secStatus = SSL_OptionSet(sslSocket, SSL_REQUIRE_CERTIFICATE, requireCert); + if (secStatus != SECSuccess) + { + errWarn("SSL_OptionSet:SSL_REQUIRE_CERTIFICATE"); + return SECFailure; + } + + /* Having changed socket configuration parameters, redo handshake. */ + secStatus = SSL_ReHandshake(sslSocket, PR_TRUE); + if (secStatus != SECSuccess) + { + errWarn("SSL_ReHandshake"); + return SECFailure; + } + + /* Force the handshake to complete before moving on. */ + secStatus = SSL_ForceHandshake(sslSocket); + if (secStatus != SECSuccess) + { + errWarn("SSL_ForceHandshake"); + return SECFailure; + } + + return SECSuccess; +} +#endif /* No client authentication and not authenticating after each transaction. */ + +/* Function: writeDataToSocket + * + * Purpose: Write the server's response back to the socket. + * + */ +static SECStatus +writeDataToSocket(PRFileDesc *sslSocket) +{ + int numBytes; + PRFileDesc *local_file_fd; + PRFileInfo info; + PRStatus prStatus; + + /* Try to open the local file named. + * If successful, then write it to the client. + */ + prStatus = PR_GetFileInfo(responseJarName, &info); + if (prStatus != PR_SUCCESS || info.type != PR_FILE_FILE || info.size < 0) + { + fprintf (stderr, "Input file %s not found\n", responseJarName); + return SECFailure; + } + + local_file_fd = PR_Open(responseJarName, PR_RDONLY, 0); + if (local_file_fd == NULL) + { + fprintf (stderr, "Could not open input file %s\n", responseJarName); + return SECFailure; + } + + /* Transmit the local file across the socket. + */ + numBytes = PR_TransmitFile(sslSocket, local_file_fd, + NULL, 0, + PR_TRANSMITFILE_KEEP_OPEN, + PR_INTERVAL_NO_TIMEOUT); + + /* Error in transmission. */ + if (numBytes < 0) + { + errWarn("PR_TransmitFile"); + return SECFailure; + } +#if DEBUG + /* Transmitted bytes successfully. */ + fprintf(stderr, "PR_TransmitFile wrote %d bytes from %s\n", + numBytes, responseJarName); +#endif + + PR_Close(local_file_fd); + + return SECSuccess; +} + +/* Function: int handle_connection() + * + * Purpose: Handle a connection to a socket. + * + */ +static SECStatus +handle_connection(PRFileDesc *tcpSocket) +{ + PRFileDesc * sslSocket = NULL; + SECStatus secStatus = SECFailure; + PRStatus prStatus; + PRSocketOptionData socketOption; + PRFileInfo info; + char *cmdline; + int rc; + char *rc1; + + /* Make sure the socket is blocking. */ + socketOption.option = PR_SockOpt_Nonblocking; + socketOption.value.non_blocking = PR_FALSE; + PR_SetSocketOption(tcpSocket, &socketOption); + + sslSocket = setupSSLSocket(tcpSocket); + if (sslSocket == NULL) + { + errWarn("setupSSLSocket"); + goto cleanup; + } + + secStatus = SSL_ResetHandshake(sslSocket, /* asServer */ PR_TRUE); + if (secStatus != SECSuccess) + { + errWarn("SSL_ResetHandshake"); + goto cleanup; + } + + /* Create a temporary files and directories. */ + memcpy (requestFileName + sizeof (requestFileName) - 1 - 6, "XXXXXX", 6); + rc = mkstemp(requestFileName); + if (rc == -1) + { + fprintf (stderr, "Could not create temporary file %s\n", requestFileName); + perror (""); + secStatus = SECFailure; + goto cleanup; + } + + memcpy (responseDirName + sizeof (responseDirName) - 1 - 6, "XXXXXX", 6); + rc1 = mkdtemp(responseDirName); + if (! rc1) + { + fprintf (stderr, "Could not create temporary directory %s\n", responseDirName); + perror (""); + secStatus = SECFailure; + goto cleanup; + } + + memcpy (responseJarName, responseDirName, sizeof (responseDirName) - 1); + memcpy (responseJarName + sizeof (responseJarName) - 1 - 6, "XXXXXX", 6); + rc = mkstemp(responseJarName); + if (rc == -1) + { + fprintf (stderr, "Could not create temporary file %s\n", responseJarName); + perror (""); + secStatus = SECFailure; + goto cleanup; + } + + /* Read data from the socket. + * If the user is requesting/requiring authentication, authenticate + * the socket. */ +#if DEBUG + fprintf(stdout, "\nReading data from socket...\n\n"); +#endif + secStatus = readDataFromSocket(sslSocket); + if (secStatus != SECSuccess) + goto cleanup; + +#if 0 /* Don't authenticate after each transaction */ + if (REQUEST_CERT_ALL) + { + fprintf(stdout, "\nAuthentication requested.\n\n"); + secStatus = authenticateSocket(sslSocket); + if (secStatus != SECSuccess) + goto cleanup; + } +#endif + + /* Call the stap-server script. */ + cmdline = PORT_Alloc(sizeof ("stap-server") + + sizeof (requestFileName) + + sizeof (responseDirName) + + sizeof (responseJarName) + + strlen (dbdir) + 1); + if (! cmdline) { + errWarn ("PORT_Alloc"); + secStatus = SECFailure; + goto cleanup; + } + + sprintf (cmdline, "stap-server %s %s %s %s", + requestFileName, responseDirName, responseJarName, dbdir); + rc = system (cmdline); + + PR_Free (cmdline); + +#if DEBUG + fprintf(stdout, "\nWriting data to socket...\n\n"); +#endif + secStatus = writeDataToSocket(sslSocket); + +cleanup: + + /* Close down the socket. */ + prStatus = PR_Close(tcpSocket); + if (prStatus != PR_SUCCESS) + errWarn("PR_Close"); + + /* Attempt to remove temporary files, unless the temporary directory was + not deleted by the server script. */ + prStatus = PR_GetFileInfo(responseDirName, &info); + if (prStatus != PR_SUCCESS) + { + prStatus = PR_Delete (requestFileName); + if (prStatus != PR_SUCCESS) + errWarn ("PR_Delete"); + prStatus = PR_Delete (responseJarName); + if (prStatus != PR_SUCCESS) + errWarn ("PR_Delete"); + } + + return secStatus; +} + +/* Function: int accept_connection() + * + * Purpose: Accept a connection to the socket. + * + */ +static SECStatus +accept_connection(PRFileDesc *listenSocket) +{ + PRNetAddr addr; + PRStatus prStatus; + PRFileDesc *tcpSocket; + SECStatus result; + + while (PR_TRUE) + { +#if DEBUG + fprintf(stderr, "\n\n\nAbout to call accept.\n"); +#endif + + /* Accept a connection to the socket. */ + tcpSocket = PR_Accept(listenSocket, &addr, PR_INTERVAL_NO_TIMEOUT); + if (tcpSocket == NULL) + { + errWarn("PR_Accept"); + break; + } + + /* Accepted the connection, now handle it. */ + result = handle_connection (tcpSocket); + + if (result != SECSuccess) + { + prStatus = PR_Close(tcpSocket); + if (prStatus != PR_SUCCESS) + exitErr("PR_Close"); + break; + } + } + +#if DEBUG + fprintf(stderr, "Closing listen socket.\n"); +#endif + prStatus = PR_Close(listenSocket); + if (prStatus != PR_SUCCESS) + exitErr("PR_Close"); + + return SECSuccess; +} + +/* Function: void server_main() + * + * Purpose: This is the server's main function. It configures a socket + * and listens to it. + * + */ +static void +server_main(unsigned short port, SECKEYPrivateKey *privKey, CERTCertificate *cert) +{ + SECStatus secStatus; + PRStatus prStatus; + PRFileDesc * listenSocket; + PRNetAddr addr; + PRSocketOptionData socketOption; + + /* Create a new socket. */ + listenSocket = PR_NewTCPSocket(); + if (listenSocket == NULL) + exitErr("PR_NewTCPSocket"); + + /* Set socket to be blocking - + * on some platforms the default is nonblocking. + */ + socketOption.option = PR_SockOpt_Nonblocking; + socketOption.value.non_blocking = PR_FALSE; + + prStatus = PR_SetSocketOption(listenSocket, &socketOption); + if (prStatus != PR_SUCCESS) + exitErr("PR_SetSocketOption"); + +#if 0 + /* This cipher is not on by default. The Acceptance test + * would like it to be. Turn this cipher on. + */ + secStatus = SSL_CipherPrefSetDefault(SSL_RSA_WITH_NULL_MD5, PR_TRUE); + if (secStatus != SECSuccess) + exitErr("SSL_CipherPrefSetDefault:SSL_RSA_WITH_NULL_MD5"); +#endif + + /* Configure the network connection. */ + addr.inet.family = PR_AF_INET; + addr.inet.ip = PR_INADDR_ANY; + addr.inet.port = PR_htons(port); + + /* Bind the address to the listener socket. */ + prStatus = PR_Bind(listenSocket, &addr); + if (prStatus != PR_SUCCESS) + exitErr("PR_Bind"); + + /* Listen for connection on the socket. The second argument is + * the maximum size of the queue for pending connections. + */ + prStatus = PR_Listen(listenSocket, 5); + if (prStatus != PR_SUCCESS) + exitErr("PR_Listen"); + + /* Handle connections to the socket. */ + secStatus = accept_connection (listenSocket); + if (secStatus != SECSuccess) + PR_Close(listenSocket); +} + +/* Function: char * myPasswd() + * + * Purpose: This function is our custom password handler that is called by + * SSL when retreiving private certs and keys from the database. Returns a + * pointer to a string that with a password for the database. Password pointer + * should point to dynamically allocated memory that will be freed later. + */ +static char * +myPasswd(PK11SlotInfo *info, PRBool retry, void *arg) +{ + char * passwd = NULL; + + if (! retry && arg) + passwd = PORT_Strdup((char *)arg); + + return passwd; +} + +/* Obtain the certificate and key database password from the given file. */ +static char * +getPassword(char *fileName) +{ + PRFileDesc *local_file_fd; + PRFileInfo fileInfo; + PRInt32 numBytesRead; + PRStatus prStatus; + char *password; + PRInt32 i; + + prStatus = PR_GetFileInfo(fileName, &fileInfo); + if (prStatus != PR_SUCCESS || fileInfo.type != PR_FILE_FILE || fileInfo.size < 0) + { + fprintf (stderr, "Password file %s not found\n", fileName); + return NULL; + } + + local_file_fd = PR_Open(fileName, PR_RDONLY, 0); + if (local_file_fd == NULL) + { + fprintf (stderr, "Could not open password file %s\n", fileName); + return NULL; + } + + password = PORT_Alloc(fileInfo.size + 1); + if (! password) { + errWarn ("PORT_Alloc"); + return NULL; + } + + numBytesRead = PR_Read(local_file_fd, password, fileInfo.size); + if (numBytesRead <= 0) + { + fprintf (stderr, "Error reading password file\n"); + exitErr ("PR_Read"); + } + + PR_Close(local_file_fd); + + /* Keep only the first line of data. */ + for (i = 0; i < numBytesRead; ++i) + { + if (password[i] == '\n' || password[i] == '\r' || + password[i] == '\0') + break; + } + password[i] = '\0'; + + return password; +} + +/* Function: int main() + * + * Purpose: Parses command arguments and configures SSL server. + * + */ +int +main(int argc, char **argv) +{ + char * progName = NULL; + char * nickName = NULL; + char * passwordFile = NULL; + unsigned short port = 0; + SECStatus secStatus; + PLOptState * optstate; + PLOptStatus status; + + progName = PL_strdup(argv[0]); + + optstate = PL_CreateOptState(argc, argv, "d:p:n:w:"); + while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) + { + switch(optstate->option) + { + case 'd': dbdir = PL_strdup(optstate->value); break; + case 'n': nickName = PL_strdup(optstate->value); break; + case 'p': port = PORT_Atoi(optstate->value); break; + case 'w': passwordFile = PL_strdup(optstate->value); break; + default: + case '?': Usage(progName); + } + } + + if (nickName == NULL || port == 0 || dbdir == NULL || passwordFile == NULL) + Usage(progName); + + password = getPassword (passwordFile); + + /* Call the NSPR initialization routines. */ + PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); + + /* Set the cert database password callback. */ + PK11_SetPasswordFunc(myPasswd); + + /* Initialize NSS. */ + secStatus = NSS_Init(dbdir); + if (secStatus != SECSuccess) + exitErr("NSS_Init"); + + /* Set the policy for this server (REQUIRED - no default). */ + secStatus = NSS_SetDomesticPolicy(); + if (secStatus != SECSuccess) + exitErr("NSS_SetDomesticPolicy"); + + /* Get own certificate and private key. */ + cert = PK11_FindCertFromNickname(nickName, password); + if (cert == NULL) + exitErr("PK11_FindCertFromNickname"); + + privKey = PK11_FindKeyByAnyCert(cert, password); + if (privKey == NULL) + exitErr("PK11_FindKeyByAnyCert"); + + /* Configure the server's cache for a multi-process application + * using default timeout values (24 hrs) and directory location (/tmp). + */ + SSL_ConfigMPServerSIDCache(256, 0, 0, NULL); + + /* Launch server. */ + server_main(port, privKey, cert); + + /* Shutdown NSS and exit NSPR gracefully. */ + NSS_Shutdown(); + PR_Cleanup(); + + return 0; +} diff --git a/stap-serverd b/stap-serverd index d4d6a773..094f4ca4 100755 --- a/stap-serverd +++ b/stap-serverd @@ -24,20 +24,20 @@ function initialization { # Default settings. avahi_type=_stap._tcp - # We need either netcat or nc. - netcat=`which netcat 2>/dev/null` - test "X$netcat" = "X" && netcat=`which nc 2>/dev/null` - test "X$netcat" = "X" && fatal "ERROR: cannot find required program 'netcat' or 'nc' on PATH" - - # See if the given port, or the default port is busy. If so, select another. + # What port will we listen on? port=$1 test "X$port" = "X" && port=65000 - port2=$(($port + 1)) - while netstat -atn | awk '{print $4}' | cut -f2 -d: | egrep -q "^($port|$port2)\$"; do + while netstat -atn | awk '{print $4}' | cut -f2 -d: | egrep -q "^$port\$"; + do # Whoops, the port is busy; try another one. port=$((1024+($port + $RANDOM)%64000)) - port2=$(($port + 1)) done + + # Where is the ssl certificate/key database? + ssl_db=$2 + test "X$ssl_db" = "X" && ssl_db=/etc/systemtap/ssl/server + nss_pw=$ssl_db/pw + nss_cert=stap-server } # function: advertise_presence @@ -60,41 +60,10 @@ function advertise_presence { # # Listen for and handle requests to the server. function listen { - # Loop forever accepting requests - while true - do - for ((attempt=0; $attempt < 5; ++attempt)) - do - $netcat -l $port < /dev/null 2>/dev/null | process_request & - wait '%$netcat -l' - rc=$? - if test $rc = 0 -o $rc = 127; then - break; # port was read ok - fi - done - if test $attempt = 5; then - fatal "ERROR: cannot listen on port $port. rc==$rc" - fi - done -} - -# function: process_request -# -# Process an incoming request on stdin -function process_request { - read - case $REPLY in - request:) - stap-server $port2 >/dev/null 2>&1 & - wait '%stap-server' - rc=$? - test $rc = 127 && rc=0 - ;; - *) - rc=1 - esac - - exit $rc + # The stap-server-connect program will listen forever + # accepting requests. + stap-server-connect -p $port -n $nss_cert -d $ssl_db -w $nss_pw > /dev/null 2>&1 & + wait '%stap-server-connect' >/dev/null 2>&1 } # function: fatal [ MESSAGE ] @@ -117,13 +86,9 @@ function terminate { kill -s SIGTERM %avahi-publish-service 2> /dev/null wait '%avahi-publish-service' >/dev/null 2>&1 - # Kill any running 'stap-server' job. - kill -s SIGTERM "%stap-server" 2> /dev/null - wait '%stap-server' >/dev/null 2>&1 - - # Kill any running '$netcat -l' job. - kill -s SIGTERM '%$netcat -l' 2>/dev/null - wait '%$netcat -l' >/dev/null 2>&1 + # Kill any running 'stap-server-connect' job. + kill -s SIGTERM "%stap-server-connect" 2> /dev/null + wait "%stap-server-connect" >/dev/null 2>&1 exit } diff --git a/stap-start-server b/stap-start-server index aa2850b5..5bc97c22 100755 --- a/stap-start-server +++ b/stap-start-server @@ -13,7 +13,7 @@ # process id, if successful. # start the server -stap-serverd </dev/null >/dev/null 2>&1 & +stap-serverd "$@" </dev/null >/dev/null 2>&1 & server_pid=$! # Make sure the server is started diff --git a/systemtap.spec b/systemtap.spec index 9fa0e68d..4ba1895d 100644 --- a/systemtap.spec +++ b/systemtap.spec @@ -82,7 +82,7 @@ Group: Development/System License: GPLv2+ URL: http://sourceware.org/systemtap/ Requires: systemtap-runtime = %{version}-%{release} -Requires: avahi avahi-tools nc mktemp +Requires: avahi avahi-tools nss nss-tools mktemp %description client SystemTap client is the client component of an instrumentation @@ -95,7 +95,7 @@ Group: Development/System License: GPLv2+ URL: http://sourceware.org/systemtap/ Requires: systemtap -Requires: avahi avahi-tools nc net-tools mktemp +Requires: avahi avahi-tools nss nss-tools mktemp %description server SystemTap server is the server component of an instrumentation @@ -251,6 +251,7 @@ exit 0 %{_bindir}/stap-serverd %{_bindir}/stap-start-server %{_bindir}/stap-stop-server +%{_bindir}/stap-gen-server-cert %{_mandir}/man8/stap-server.8* %changelog diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog index b18ccf61..7180bb56 100644 --- a/testsuite/ChangeLog +++ b/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2008-12-24 Dave Brolley <brolley@redhat.com> + + * lib/systemtap.exp: Rename client_path to net_path. + (setup_systemtap_environment): Set ssl_server_path and + ssl_client_path. Pass ssl_server_path to stap-find-or-start-server. + 2008-12-21 Stan Cox <scox@redhat.com> * systemtap.base/static_uprobes.exp: Parms now called $argN diff --git a/testsuite/lib/systemtap.exp b/testsuite/lib/systemtap.exp index 28129f0a..9219e977 100644 --- a/testsuite/lib/systemtap.exp +++ b/testsuite/lib/systemtap.exp @@ -37,7 +37,7 @@ proc print_systemtap_version {} { proc setup_systemtap_environment {} { - global srcdir prefix env server_pid client_path + global srcdir prefix env server_pid net_path # need an absolute SRCDIR for the top-level src/ tree # XXX: or, we could change nearby uses of ${SRCDIR}/testsuite to ${SRCDIR} @@ -55,14 +55,24 @@ proc setup_systemtap_environment {} { if {[use_server_p]} then { print "Testing using a systemtap server" - # Server management scripts are installed if this is an install test, otherwise - # in the source directory. Make sure they are on the $PATH. + # A place for some temporary files and scripts. + set net_path [exec pwd]/net + exec /bin/mkdir -p $net_path + + # Server management scripts and data are installed if this is an + # install test, otherwise there is some setup to do. if {! [installtest_p]} then { + # Make sure the server management scripts are on the $PATH. set env(PATH) "$srcdir/..:$env(PATH)" + set ssl_server_path [exec pwd]/../ssl/server + set ssl_client_path [exec pwd]/../ssl/client + } else { + set ssl_server_path "" + set ssl_client_path "" } # Try to find or start the server. - set server_pid [exec stap-find-or-start-server] + set server_pid [exec stap-find-or-start-server 65000 $ssl_server_path] if { $server_pid == -1 } then { print "Cannot find or start a systemtap server" set server_pid 0 @@ -76,14 +86,15 @@ proc setup_systemtap_environment {} { # Make a copy of 'stap-client' as 'stap' and make sure it's at the # beginning of the $PATH. Do this after starting the server so that # The server does not call this instance of 'stap' - set client_path [exec pwd]/net - exec /bin/mkdir -p $client_path if {[installtest_p]} then { - exec /bin/cp -p [exec which stap-client] $client_path/stap + exec /bin/cp -p [exec which stap-client] $net_path/stap } else { - exec /bin/cp -p $srcdir/../stap-client $client_path/stap + exec /bin/cp -p $srcdir/../stap-client $net_path/stap + # Make sure the client picks up the proper certificates for + # server verification. + exec sed -i s,/etc/systemtap/ssl/client,$ssl_client_path, $net_path/stap } - set env(PATH) "$client_path:$env(PATH)" + set env(PATH) "$net_path:$env(PATH)" } # PATH, SYSTEMTAP_TAPSET, SYSTEMTAP_RUNTIME, LD_LIBRARY_PATH are already set. @@ -121,7 +132,7 @@ proc systemtap_init {args} {} proc systemtap_version {} {} proc systemtap_exit {} { - global server_pid client_path + global server_pid net_path # Stop the stap server, if we started it. if {[use_server_p]} then { @@ -131,7 +142,7 @@ proc systemtap_exit {} { } # Remove the temporary stap script - exec /bin/rm -fr $client_path + exec /bin/rm -fr $net_path } } |