16186528 Implement SMF probe to support the OVAL schema for solaris
authorJacob Varughese <jacob.varughese@oracle.com>
Wed, 30 Jan 2013 10:16:26 -0800
changeset 1136 226e8d9d2ff0
parent 1135 7f8ef38770aa
child 1137 5f35de46aa92
16186528 Implement SMF probe to support the OVAL schema for solaris
components/openscap/Makefile
components/openscap/patches/debug.c.patch
components/openscap/patches/oval_probe.c.patch
components/openscap/patches/smf.c.patch
--- 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)
--- /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 ();
+         }
--- /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])
--- /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 <stdlib.h>
++#include <string.h>
++#include <stdio.h>
++#include <errno.h>
++#include <sys/stat.h>
++#include <ctype.h>
++#include <sys/types.h>
++#include <limits.h>
++#include <unistd.h>
++#include <libscf.h>
++#include <libscf_priv.h>
++#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);
+ }