components/openscap/patches/smfproperty.patch
author Jacob Varughese <jacob.varughese@oracle.com>
Wed, 24 Feb 2016 14:19:35 -0800
branchs11u3-sru
changeset 5494 4d99913076de
permissions -rw-r--r--
22188277 upgrade openscap to 1.2.6 21051102 Need smfproperty probe to check smfproperty values in OVAL 21928864 oscap is limited to processing 32K records due to memory checks in the code 21636352 Fix the cpe OVAL checks

This patch provides the implementation of the smfproperty probe
on solaris.
This patch has not been contributed upstream but is planned to be contributed
upstream.  Hoping to have it accepted by 2016-Mar-15.
--- openscap-1.2.1/configure.ac.~3~	2015-04-22 16:20:53.433875799 -0700
+++ openscap-1.2.1/configure.ac	2015-04-22 16:25:56.053053597 -0700
@@ -257,6 +257,10 @@
 probe_systemdunitdependency_req_deps_missing=
 probe_systemdunitdependency_opt_deps_ok=yes
 probe_systemdunitdependency_opt_deps_missing=
+probe_smfproperty_req_deps_ok=yes
+probe_smfproperty_req_deps_missing=
+probe_smfproperty_opt_deps_ok=yes
+probe_smfproperty_opt_deps_missing=
 
 #
 # env
@@ -1325,6 +1329,8 @@
 probe_systemdunitproperty_enabled=$probe_systemdunitproperty_req_deps_ok
 AM_CONDITIONAL([probe_systemdunitdependency_enabled], test "$probe_systemdunitdependency_req_deps_ok" = yes)
 probe_systemdunitdependency_enabled=$probe_systemdunitdependency_req_deps_ok
+AM_CONDITIONAL([probe_smfproperty_enabled], test "$probe_smfproperty_req_deps_ok" = yes)
+probe_smfproperty_enabled=$probe_smfproperty_req_deps_ok
 
 AM_CONDITIONAL([WANT_CCE],  test "$cce"  = yes)
 
@@ -1736,6 +1742,12 @@
   probe_systemdunitdependency_table_result="NO (missing: $probe_systemdunitdependency_req_deps_missing)"
 fi
 printf "  %-28s %s\n" "systemdunitdependency:" "$probe_systemdunitdependency_table_result"
+if test "$probe_smfproperty_req_deps_ok" = "yes"; then
+  probe_smfproperty_table_result="yes"
+else
+  probe_smfproperty_table_result="NO (missing: $probe_smfproperty_req_deps_missing)"
+fi
+printf "  %-28s %s\n" "smfproperty:" "$probe_smfproperty_table_result"
 echo
 echo "  === configuration ==="
 echo "  probe directory set to:      $probe_dir"
--- openscap-1.2.1/src/OVAL/oval_enumerations.c.~1~	2015-04-22 16:40:36.569105567 -0700
+++ openscap-1.2.1/src/OVAL/oval_enumerations.c	2015-04-22 16:41:10.935676772 -0700
@@ -512,6 +512,7 @@
 	{OVAL_SOLARIS_SMF, "smf"},
 	{OVAL_SOLARIS_NDD, "ndd"},
 	{OVAL_SOLARIS_PACKAGECHECK, "packagecheck"},
+	{OVAL_SOLARIS_SMFPROPERTY, "smfproperty"},
 	{OVAL_SUBTYPE_UNKNOWN, NULL}
 };
 
--- openscap-1.2.1/src/OVAL/probes/Makefile.am.~1~	2015-04-22 16:43:21.761989228 -0700
+++ openscap-1.2.1/src/OVAL/probes/Makefile.am	2015-04-22 16:44:11.722065041 -0700
@@ -202,6 +202,11 @@
 probe_smf_SOURCES= unix/solaris/smf.c
 endif
 
+if probe_smfproperty_enabled
+pkglibexec_PROGRAMS += probe_smfproperty
+probe_smfproperty_SOURCES= unix/solaris/smfproperty.c
+endif
+
 endif
 
 #
--- openscap-1.2.3/src/OVAL/probes/unix/solaris/smfproperty.c.~1~	2015-06-02 21:28:41.068464123 -0700
+++ openscap-1.2.3/src/OVAL/probes/unix/solaris/smfproperty.c	2015-06-03 09:48:55.973035835 -0700
@@ -0,0 +1,385 @@
+/**
+ * @file smfproperty.c
+ * @brief smfproperty probe
+ * @author "Jacob Varughese" <[email protected]>
+ *
+ * This probe processes retrieves the properties of smf services.
+ */
+
+
+#include "probe-api.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if	defined(__SVR4) && defined(__sun)
+#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/entcmp.h"
+#include "alloc.h"
+#include "common/debug_priv.h"
+
+#ifndef	SCF_PG_START
+#define	SCF_PG_START	"start"
+#endif
+
+#ifndef	SCF_SNAPSHOT_RUNNING
+#define	SCF_SNAPSHOT_RUNNING	"running"
+#endif
+
+#define	MAX_SCF_VALUE_LENGTH	1024
+/* Convenience structure for the results being reported */
+
+/*
+ * smfproperty probe:
+ *
+ *
+ * fmri
+ * service
+ * instance
+ * property
+ * value
+ */
+
+
+/* Convenience structure for the results being reported */
+struct result_info {
+	char *fmri;
+	char *service;
+	char *instance;
+	char *property;
+	char *value;
+};
+
+
+static char *
+strdup_check(char *p)
+{
+	char *ret;
+
+	if ((ret = strdup(p)) == NULL) {
+		dE("Error: Out of Memory error.\n");
+		exit(PROBE_ENOMEM);
+	}
+	return ret;
+}
+
+
+
+static void
+report_smfproperty(struct result_info *res, probe_ctx *ctx)
+{
+	SEXP_t *item;
+
+	item = probe_item_create(OVAL_SOLARIS_SMFPROPERTY, NULL,
+	    "fmri", OVAL_DATATYPE_STRING, res->fmri,
+	    "service", OVAL_DATATYPE_STRING, res->service,
+	    "instance", OVAL_DATATYPE_STRING, res->instance,
+	    "property", OVAL_DATATYPE_STRING, res->property,
+	    "value", OVAL_DATATYPE_STRING,
+	    res->value,
+	    NULL);
+	probe_item_collect(ctx, item);
+}
+
+
+static int
+convert_prop(scf_handle_t *hdl, const scf_property_t *prop,
+    struct result_info *res, probe_ctx *ctx)
+{
+	char propname[256];
+	scf_iter_t *iter = NULL;
+	scf_value_t *value = NULL;
+	ssize_t size = 0, len = 0, i = 0;
+	char *buffer;
+	int cur_size;
+
+	if (prop == NULL)
+		return 0;
+
+	if (scf_property_get_name(prop, propname,
+	    sizeof(propname)) < 0) {
+		dE("Cannot get name of property\n");
+		dE("Error: %s\n", scf_strerror(scf_error()));
+		return 1;
+	}
+	if ((value = scf_value_create(hdl)) == NULL) {
+		dE("Cannot create value from handle for prop:%s\n",
+		    propname);
+		dE("Error: %s\n", scf_strerror(scf_error()));
+		return 1;
+	}
+	if ((iter = scf_iter_create(hdl)) == NULL) {
+		dE("Cannot create value iterator for prop:%s\n",
+		    propname);
+		dE("Error: %s\n", scf_strerror(scf_error()));
+		return 1;
+	}
+	if (scf_iter_property_values(iter, prop) != 0) {
+		dE("Cannot iterate values  for prop:%s\n",
+		    propname);
+		dE("Error: %s\n", scf_strerror(scf_error()));
+		return 1;
+	}
+	buffer = malloc(MAX_SCF_VALUE_LENGTH);
+	if (buffer == NULL) {
+		dE("Out of Memory Error.\n");
+		exit(PROBE_ENOMEM);
+	}
+	buffer[0] = '\0';
+	cur_size = MAX_SCF_VALUE_LENGTH;
+	while ((scf_iter_next_value(iter, value)) > 0) {
+		char *tmp;
+		i++;
+		size = scf_value_get_as_string(value, NULL, 0) + 1;
+		if (size < 0) {
+			dE("Cannot get value for prop:%s size is"
+			    " invalid\n", propname);
+			dE("Error: %s\n", scf_strerror(scf_error()));
+			return 1;
+		}
+		if ((size + len + 2) > cur_size) {
+			cur_size = cur_size * 2 + size;
+			buffer = realloc(buffer, cur_size);
+			if (buffer == NULL) {
+				dE("Out of Memory Error.\n");
+				exit(PROBE_ENOMEM);
+			}
+		}
+		if (i > 1) {
+			buffer[len -1] = ' ';
+			buffer[len] = '\0';
+			tmp = &buffer[len];
+		} else {
+			tmp = &buffer[0];
+		}
+		scf_value_get_as_string(value, tmp, size);
+		len += size;
+	}
+	res->value = buffer;
+	report_smfproperty(res, ctx);
+	dI("fmri=% service=%s instance=%s property=%s value=%s\n",
+	    res->fmri, res->service, res->instance, res->property, res->value);
+	free(buffer);
+	return 0;
+}
+
+static int
+get_smf_prop(scf_handle_t *h, const scf_service_t *service,
+    const scf_instance_t *instance, const char *prop_grp_name,
+    const char *prop_name, struct result_info *res, probe_ctx *ctx)
+{
+	scf_propertygroup_t *pg = scf_pg_create(h);
+	scf_property_t *prop = scf_property_create(h);
+	int rc;
+
+	if (pg == NULL) {
+		dE("Unable to create property group from handle.\n");
+		dE("prop_grp_name=%s prop_name=%s.\n",
+		    prop_grp_name, prop_name);
+		dE("Error: %s.\n", scf_strerror(scf_error()));
+		rc = 1;
+		goto cleanup;
+	}
+	if (prop == NULL) {
+		dE("Unable to create property from handle.\n");
+		dE("prop_grp_name=%s prop_name=%s.\n",
+		    prop_grp_name, prop_name);
+		dE("Error: %s.\n", scf_strerror(scf_error()));
+		rc = 1;
+		goto cleanup;
+	}
+
+	if (instance == NULL) {
+		if (scf_service_get_pg(service, prop_grp_name, pg) == -1 ||
+		    scf_pg_get_property(pg, prop_name, prop) == -1) {
+			dE("Error: Could not read %s/%s from service.\n",
+			    prop_grp_name, prop_name);
+			rc = 1;
+			goto cleanup;
+		}
+	} else {
+		scf_snapshot_t *snap;
+		if ((snap = scf_snapshot_create(h)) == NULL) {
+			dE("Unable to create snapshot from handle.\n");
+			dE("fmri=%s \n", res->fmri);
+			dE("Error: %s.\n", scf_strerror(scf_error()));
+			rc = 1;
+			goto cleanup;
+		}
+		if (scf_instance_get_snapshot(instance, SCF_SNAPSHOT_RUNNING,
+		    snap) == -1) {
+			dE("Unable to get running snapshot.\n");
+			dE("for fmri=%s \n", res->fmri);
+			dE("Error: %s.\n", scf_strerror(scf_error()));
+			rc = 1;
+			goto cleanup;
+		}
+		if (scf_instance_get_pg_composed(instance, snap,
+		    prop_grp_name, pg) == -1) {
+			dE("Error: Could not read "
+			    " %s/%s property from snapshot for %s\n",
+			    prop_grp_name, prop_name, res->fmri);
+			rc = 1;
+			scf_snapshot_destroy(snap);
+			goto cleanup;
+		}
+		scf_snapshot_destroy(snap);
+	}
+	if (scf_pg_get_property(pg, prop_name, prop) == -1) {
+		dE("Error: Could not read %s/%s property %s\n",
+		    prop_grp_name, prop_name, res->fmri);
+		rc = 1;
+		goto cleanup;
+	}
+	rc = convert_prop(h, prop, res, ctx);
+cleanup:
+	scf_property_destroy(prop);
+	scf_pg_destroy(pg);
+	return rc;
+}
+
+static int
+collect_smfprop_info(char *asvc, char *ainst, char *aprop,
+    probe_ctx *ctx)
+{
+	struct result_info r;
+	int rc = 0;
+	char *propgrp = NULL, *prop = NULL;
+	char *tmp = NULL;
+	scf_handle_t *scf_hdl;
+	scf_instance_t *inst = NULL;
+	scf_service_t *svc = NULL;
+	char *p = NULL;
+
+	memset(&r, 0, sizeof(r));
+	r.service = asvc;
+
+	if (ainst == NULL) {
+		r.fmri = strdup_check(asvc);
+	} else { /* service name is service:instance */
+		asprintf(&r.fmri, "%s:%s", asvc, ainst);
+	}
+	if (r.fmri == NULL)
+		_exit(1);
+	if ((scf_hdl = scf_handle_create(SCF_VERSION)) == NULL ||
+	    scf_handle_bind(scf_hdl) != 0 ||
+	    (svc = scf_service_create(scf_hdl)) == NULL ||
+	    (ainst != NULL &&
+	    (inst = scf_instance_create(scf_hdl)) == NULL)) {
+		rc = PROBE_EFATAL;
+		goto cleanup;
+	}
+	if (scf_handle_decode_fmri(scf_hdl, r.fmri, NULL, svc,
+	    (ainst == NULL ? NULL : inst), NULL, NULL,
+	    SCF_DECODE_FMRI_EXACT) != 0 ||
+	    scf_error() == SCF_ERROR_NOT_FOUND) {
+		dE("scf_handle_decode_fmri failed.\n");
+		goto cleanup;
+	}
+
+	tmp = strdup_check(aprop);
+	if ((p = strstr(tmp, SCF_FMRI_PROPERTY_PREFIX)) != NULL) {
+		*p = '\0';
+		p++;
+		prop = p;
+	}
+	propgrp = tmp;
+	dI("r.service_name=%s\n", r.service);
+	dI("service:%s instance:%s propgrp:%s prop:%s\n",
+	    STR(asvc), STR(ainst), STR(propgrp), STR(prop));
+	r.instance = ainst;
+	r.property = aprop;
+	if (get_smf_prop(scf_hdl, svc, inst, propgrp, prop, &r, ctx) > 0) {
+		r.fmri = NULL;
+		dE("get_smf_prop failed.\n");
+	}
+	dI("Service exists:%s\n", r.service);
+cleanup:
+	free(tmp);
+	free(r.fmri);
+	scf_handle_destroy(scf_hdl);
+	scf_handle_unbind(scf_hdl);
+	scf_service_destroy(svc);
+	scf_instance_destroy(inst);
+	return rc;
+}
+
+int
+probe_main(probe_ctx *ctx, void *arg)
+{
+	SEXP_t *probe_in, *service = NULL, *instance = NULL, *property = NULL;
+	SEXP_t *service_val = NULL, *instance_val = NULL, *property_val = NULL;
+	char *service_str = NULL, *instance_str = NULL, *property_str = NULL;
+	int rc;
+
+	probe_in = probe_ctx_getobject(ctx);
+	if (probe_in == NULL) {
+		return PROBE_ENOOBJ;
+	}
+	service = probe_obj_getent(probe_in, "service", 1);
+	if (service == NULL) {
+		dE("No service in context.\n");
+		return PROBE_ENOENT;
+	}
+	instance = probe_obj_getent(probe_in, "instance", 1);
+	property = probe_obj_getent(probe_in, "property", 1);
+	if (property == NULL) {
+		dE("No property in context.\n");
+		rc = PROBE_ENOENT;
+		goto error;
+	}
+	service_val = probe_ent_getval(service);
+	if (service_val == NULL) {
+		dE("Get service value failed.\n");
+		rc = PROBE_ENOVAL;
+		goto error;
+	}
+	service_str = SEXP_string_cstr(service_val);
+	dI("service in context: %s.\n", service_str);
+	if (instance != NULL) {
+		instance_val = probe_ent_getval(instance);
+		instance_str = SEXP_string_cstr(instance_val);
+	}
+	if (instance_str != NULL && strcmp(instance_str, "") == 0)
+		instance_str = NULL;
+	dI("instance in context: %s.\n", instance_str);
+	property_val = probe_ent_getval(property);
+	if (property_val == NULL) {
+		dE("Get property value failed.\n");
+		rc = PROBE_ENOVAL;
+		goto error;
+	}
+	property_str = SEXP_string_cstr(property_val);
+	dI("property in context: %s.\n", property_str);
+	rc = collect_smfprop_info(service_str, instance_str, property_str, ctx);
+error:
+	free(service_str);
+	free(instance_str);
+	free(property_str);
+	SEXP_free(service);
+	SEXP_free(instance);
+	SEXP_free(property);
+	SEXP_free(service_val);
+	SEXP_free(instance_val);
+	SEXP_free(property_val);
+	return rc;
+}
+#else
+
+int
+probe_main(probe_ctx *ctx, void *probe_arg)
+{
+	return PROBE_EOPNOTSUPP;
+}
+#endif
--- openscap-1.2.3/src/OVAL/probes/unix/solaris/smfproperty.c.~2~	2015-11-10 10:00:28.564892744 -0800
+++ openscap-1.2.3/src/OVAL/probes/unix/solaris/smfproperty.c	2015-11-10 10:03:34.496610180 -0800
@@ -38,6 +38,7 @@
 #endif
 
 #define	MAX_SCF_VALUE_LENGTH	1024
+#define	STR(x)	((x == NULL) ? "" : x)
 /* Convenience structure for the results being reported */
 
 /*
--- openscap-1.2.6/src/OVAL/public/oval_types.h.~1~	2016-01-28 10:36:10.169093685 -0800
+++ openscap-1.2.6/src/OVAL/public/oval_types.h	2016-01-28 10:36:55.766025827 -0800
@@ -238,7 +238,8 @@
 	OVAL_SOLARIS_SMF = OVAL_FAMILY_SOLARIS + 4,
 	OVAL_SOLARIS_PATCH54 = OVAL_FAMILY_SOLARIS + 5,
 	OVAL_SOLARIS_NDD = OVAL_FAMILY_SOLARIS + 6,
-	OVAL_SOLARIS_PACKAGECHECK = OVAL_FAMILY_SOLARIS + 7
+	OVAL_SOLARIS_PACKAGECHECK = OVAL_FAMILY_SOLARIS + 7,
+	OVAL_SOLARIS_SMFPROPERTY = OVAL_FAMILY_SOLARIS + 8
 } oval_solaris_subtype_t;
 
 /// Unix subtypes