# HG changeset patch # User Jacob Varughese # Date 1359569786 28800 # Node ID 226e8d9d2ff0798874eb9706a458a7d6009fb496 # Parent 7f8ef38770aab571d21ca5116b514b314d3df119 16186528 Implement SMF probe to support the OVAL schema for solaris diff -r 7f8ef38770aa -r 226e8d9d2ff0 components/openscap/Makefile --- a/components/openscap/Makefile Mon Jan 28 21:25:50 2013 -0800 +++ b/components/openscap/Makefile Wed Jan 30 10:16:26 2013 -0800 @@ -19,7 +19,7 @@ # CDDL HEADER END # -# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. # include ../../make-rules/shared-macros.mk @@ -34,28 +34,31 @@ COMPONENT_BUGDB= utility/openscap COMPILER= gcc -CFLAGS+= -std=c99 -DNDEBUG +CFLAGS+= -std=c99 +CFLAGS+= -DNDEBUG include $(WS_TOP)/make-rules/prep.mk include $(WS_TOP)/make-rules/configure.mk include $(WS_TOP)/make-rules/ips.mk -CPPFLAGS += "-I/usr/include/openldap" +CPPFLAGS += -I/usr/include/openldap # Perl related patch needs configure script recreation. COMPONENT_PREP_ACTION +=(cd $(@D); autoreconf); # Needed to make "gmake test" work. -CPPFLAGS += "-I$(SOURCE_DIR)/src/OVAL" -CPPFLAGS += "-I$(SOURCE_DIR)/src/OVAL/probes" -CPPFLAGS += "-I/usr/include/pcre" +CPPFLAGS += -I$(SOURCE_DIR)/src/OVAL +CPPFLAGS += -I$(SOURCE_DIR)/src/OVAL/probes +CPPFLAGS += -I/usr/include/pcre +CONFIGURE_OPTIONS += CFLAGS="$(CFLAGS)" CONFIGURE_OPTIONS += CPPFLAGS="$(CPPFLAGS)" CONFIGURE_OPTIONS += --enable-debug=no +CONFIGURE_OPTIONS += --enable-sce=yes CONFIGURE_OPTIONS += --libexecdir=$(CONFIGURE_LIBDIR.$(BITS)) CONFIGURE_OPTIONS += am_cv_python_pythondir=$(PYTHON_VENDOR_PACKAGES) CONFIGURE_OPTIONS += am_cv_python_pyexecdir=$(PYTHON_VENDOR_PACKAGES) -CONFIGURE_OPTIONS += LIBS="-lsocket -lnsl -lldap_r" +CONFIGURE_OPTIONS += LIBS="-lsocket -lnsl -lldap_r -lscf" # common targets build: $(BUILD_32) diff -r 7f8ef38770aa -r 226e8d9d2ff0 components/openscap/patches/debug.c.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/openscap/patches/debug.c.patch Wed Jan 30 10:16:26 2013 -0800 @@ -0,0 +1,52 @@ +--- openscap-0.8.1/src/common/debug.c.orig 2012-11-19 10:04:47.622821073 -0800 ++++ openscap-0.8.1/src/common/debug.c 2012-11-19 09:58:03.173819234 -0800 +@@ -150,7 +150,11 @@ + else + f = file; + ++#if defined(__SVR4) && defined (__sun) ++ if (lockf(fileno(__debuglog_fp), F_LOCK, 0L) == -1) { ++#else + if (flock(fileno(__debuglog_fp), LOCK_EX) == -1) { ++#endif + __UNLOCK_FP; + return; + } +@@ -178,7 +182,11 @@ + #endif + vfprintf(__debuglog_fp, fmt, ap); + ++#if defined(__SVR4) && defined (__sun) ++ if (lockf(fileno(__debuglog_fp), F_ULOCK, 0L) == -1) { ++#else + if (flock(fileno(__debuglog_fp), LOCK_UN) == -1) { ++#endif + /* __UNLOCK_FP; */ + abort(); + } +@@ -232,8 +240,11 @@ + fprintf (__debuglog_fp, "=============== LOG: %.24s ===============\n", st); + atexit(&__oscap_debuglog_close); + } +- ++#if defined(__SVR4) && defined (__sun) ++ if (lockf (fileno (__debuglog_fp), F_LOCK, 0L) == -1) { ++#else + if (flock (fileno (__debuglog_fp), LOCK_EX | LOCK_NB) == -1) { ++#endif + __UNLOCK_FP; + return; + } +@@ -251,8 +262,11 @@ + } + + fprintf(__debuglog_fp, "\n-----------\n"); +- ++#if defined(__SVR4) && defined (__sun) ++ if (lockf (fileno (__debuglog_fp), F_ULOCK, 0L) == -1) { ++#else + if (flock (fileno (__debuglog_fp), LOCK_UN | LOCK_NB) == -1) { ++#endif + /* __UNLOCK_FP; */ + abort (); + } diff -r 7f8ef38770aa -r 226e8d9d2ff0 components/openscap/patches/oval_probe.c.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/openscap/patches/oval_probe.c.patch Wed Jan 30 10:16:26 2013 -0800 @@ -0,0 +1,12 @@ +--- openscap-0.8.1/src/OVAL/oval_probe.c.orig 2012-11-19 10:04:14.596320954 -0800 ++++ openscap-0.8.1/src/OVAL/oval_probe.c 2012-11-19 09:56:27.562728645 -0800 +@@ -84,7 +84,8 @@ + OVAL_PROBE_EXTERNAL(OVAL_UNIX_PROCESS58, "process58"), + OVAL_PROBE_EXTERNAL(OVAL_UNIX_FILEEXTENDEDATTRIBUTE, "fileextendedattribute"), + OVAL_PROBE_EXTERNAL(OVAL_UNIX_GCONF, "gconf"), +- OVAL_PROBE_EXTERNAL(OVAL_UNIX_ROUTINGTABLE, "routingtable") ++ OVAL_PROBE_EXTERNAL(OVAL_UNIX_ROUTINGTABLE, "routingtable"), ++ OVAL_PROBE_EXTERNAL(OVAL_SOLARIS_SMF, "smf") + }; + + #define __PROBE_META_COUNT (sizeof OSCAP_GSYM(__probe_meta)/sizeof OSCAP_GSYM(__probe_meta)[0]) diff -r 7f8ef38770aa -r 226e8d9d2ff0 components/openscap/patches/smf.c.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/components/openscap/patches/smf.c.patch Wed Jan 30 10:16:26 2013 -0800 @@ -0,0 +1,243 @@ +--- openscap-0.8.1/src/OVAL/probes/unix/solaris/smf.c.~1~ 2011-09-21 04:46:46.000000000 -0700 ++++ openscap-0.8.1/src/OVAL/probes/unix/solaris/smf.c 2013-01-28 15:39:59.601258629 -0800 +@@ -28,10 +28,238 @@ + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + ++/* ++ * smf probe: ++ * ++ * fmri ++ * service_name ++ * service_state ++ * protocol ++ * server_executable ++ * server_arguements ++ * exec_as_user ++ */ ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "seap.h" + #include "probe-api.h" ++#include "probe/entcmp.h" ++#include "alloc.h" ++#include "common/debug_priv.h" ++ ++#ifndef SCF_PG_START ++#define SCF_PG_START "start" ++#endif ++ ++/* Convenience structure for the results being reported */ ++struct result_info { ++ const char *fmri; ++ char *service_name; ++ char *service_state; ++ char *protocol; ++ char *server_executable; ++ char *server_arguments; ++ char *exec_as_user; ++}; + + +-int probe_main(probe_ctx *ctx, void *probe_arg) ++static void ++toUpperCase(char *str) ++{ ++ int i = 0; ++ ++ if (str != NULL) { ++ while (str[i] != '\0') { ++ str[i] = toupper(str[i]); ++ i++; ++ } ++ } ++} ++ ++static char * ++strdup_check(char *p) + { +- return(PROBE_EOPNOTSUPP); ++ char *ret; ++ ++ if ((ret = strdup(p)) == NULL) { ++ oscap_dlprintf(DBG_E, "Error: Out of Memory error.\n"); ++ exit(PROBE_ENOMEM); ++ } ++ return (ret); ++} ++ ++static int ++get_smf_prop(scf_handle_t *h, const char *fmri, ++ const char *prop_grp_name, const char *prop_name, char **val) ++{ ++ scf_simple_prop_t *prop; ++ char *state; ++ *val = NULL; ++ ++ if ((prop = scf_simple_prop_get(h, fmri, prop_grp_name, ++ prop_name)) == NULL) { ++ if (scf_error() == SCF_ERROR_NOT_FOUND) ++ oscap_dlprintf(DBG_E, "Error: Specified service " ++ " %s has no %s/%s property.\n", ++ fmri, prop_grp_name, prop_name); ++ if (scf_error() == SCF_ERROR_INVALID_ARGUMENT) { ++ oscap_dlprintf(DBG_E, "Error: %s is not a valid " ++ "service.\n", fmri); ++ (void) scf_handle_unbind(h); ++ scf_handle_destroy(h); ++ return (PROBE_EINVAL); ++ } ++ } else { ++ if ((state = ++ scf_simple_prop_next_astring(prop)) == NULL) { ++ oscap_dlprintf(DBG_E, ++ "Error: Could not read " ++ " %s/%s property of %s.\n", ++ prop_grp_name, ++ prop_name, ++ fmri); ++ } else if (state[0] != '\0') { ++ *val = strdup_check(state); ++ } ++ scf_simple_prop_free(prop); ++ } ++ return (0); ++} ++ ++static int ++find_smf(struct result_info *res) ++{ ++ scf_handle_t *scf_hdl; ++ int i; ++ ++ oscap_dlprintf(DBG_I, "In find_smf\n"); ++ if ((scf_hdl = scf_handle_create(SCF_VERSION)) == NULL) { ++ oscap_dlprintf(DBG_E, "Unexpected libscf error: %s. Exiting.\n", ++ scf_strerror(scf_error())); ++ return (PROBE_EFATAL); ++ } ++ if (scf_handle_bind(scf_hdl) == -1) { ++ oscap_dlprintf(DBG_E, "Error: Could not bind to" ++ " svc.configd.\n"); ++ scf_handle_destroy(scf_hdl); ++ return (PROBE_EFATAL); ++ } ++ if ((i = get_smf_prop(scf_hdl, res->fmri, SCF_PG_RESTARTER, ++ SCF_PROPERTY_STATE, &(res->service_state))) != 0) { ++ return (i); ++ } else { ++ toUpperCase(res->service_state); ++ } ++ if ((i = get_smf_prop(scf_hdl, res->fmri, SCF_PG_START, ++ SCF_PROPERTY_EXEC, &(res->server_executable))) != 0) ++ return (i); ++ if ((i = get_smf_prop(scf_hdl, res->fmri, SCF_PG_START, ++ SCF_PROPERTY_USER, &(res->exec_as_user))) != 0) ++ return (i); ++ (void) scf_handle_unbind(scf_hdl); ++ scf_handle_destroy(scf_hdl); ++ return (0); ++} ++ ++static void ++report_finding(struct result_info *res, probe_ctx *ctx) ++{ ++ SEXP_t *item; ++ ++ oscap_dlprintf(DBG_I, "In report_finding.\n"); ++ item = probe_item_create(OVAL_SOLARIS_SMF, NULL, ++ "fmri", OVAL_DATATYPE_STRING, res->fmri, ++ "service_name", OVAL_DATATYPE_STRING, res->service_name, ++ "service_state", OVAL_DATATYPE_STRING, res->service_state, ++ "protocol", OVAL_DATATYPE_STRING, res->protocol, ++ "server_executable", OVAL_DATATYPE_STRING, ++ res->server_executable, ++ "server_arguments", OVAL_DATATYPE_STRING, ++ res->server_arguments, ++ "exec_as_user", OVAL_DATATYPE_STRING, res->exec_as_user, ++ NULL); ++ probe_item_collect(ctx, item); ++} ++ ++static int ++collect_smf_info(char *fmri, probe_ctx *ctx) ++{ ++ struct result_info r; ++ int i, rc, type; ++ const char *service, *instance, *scope, *propgrp, *prop; ++ char *tmp; ++ ++ oscap_dlprintf(DBG_I, "In collect_smf_info.\n"); ++ memset(&r, 0, sizeof (r)); ++ r.service_name = strdup_check(fmri); ++ tmp = r.service_name; ++ scf_parse_fmri(r.service_name, &type, &scope, &service, ++ &instance, &propgrp, &prop); ++ if (scf_error() == SCF_ERROR_INVALID_ARGUMENT) { ++ oscap_dlprintf(DBG_E, "Error: Not a valid fmri:%s.\n", ++ fmri); ++ free(r.service_name); ++ return (PROBE_EINVAL); ++ } ++ if (instance == NULL) ++ r.service_name = strdup(service); ++ else /* service name is service:instance */ ++ asprintf(&r.service_name, "%s:%s", service, instance); ++ if (r.service_name == NULL) ++ exit(PROBE_ENOMEM); ++ free(tmp); ++ r.fmri = fmri; ++ if ((rc = find_smf(&r)) > 0) { ++ free(r.service_name); ++ return (rc); ++ } ++ oscap_dlprintf(DBG_I, "service params %s, %s, %s, %s, %s, %s, %s\n", ++ r.fmri, r.service_name, r.service_state, r.protocol, ++ r.server_executable, r.server_arguments, r.exec_as_user); ++ report_finding(&r, ctx); ++ free(r.protocol); ++ free(r.service_name); ++ free(r.service_state); ++ free(r.server_executable); ++ free(r.server_arguments); ++ free(r.exec_as_user); ++ return (0); ++} ++ ++int ++probe_main(probe_ctx *ctx, void *arg) ++{ ++ SEXP_t *fmri, *fmri_val, *probe_in; ++ char *fmri_str; ++ int rc; ++ ++ probe_in = probe_ctx_getobject(ctx); ++ if (probe_in == NULL) { ++ oscap_dlprintf(DBG_E, "No object in context.\n"); ++ return (PROBE_ENOVAL); ++ } ++ fmri = probe_obj_getent(probe_in, "fmri", 1); ++ if (fmri == NULL) { ++ oscap_dlprintf(DBG_E, "No fmri in context.\n"); ++ return (PROBE_ENOVAL); ++ } ++ fmri_val = probe_ent_getval(fmri); ++ fmri_str = SEXP_string_cstr(fmri_val); ++ oscap_dlprintf(DBG_I, "fmri in context: %s.\n", fmri_str); ++ rc = collect_smf_info(fmri_str, ctx); ++ free(fmri_str); ++ SEXP_free(fmri_val); ++ SEXP_free(fmri); ++ return (rc); + }