Unity3D’s Vector2 and Vector3 NUnit asserts

It could be just me missing something but I couldn’t find any usable Assert methods for Unity’s Vector2 and Vector3 equality. The following simple code implements the old school NUnit asserts for them using the new constraint based assert method.

The code works by calculating distance between 2 vectors and asserting that it’s smaller than delta. Comparing squared distance to squared delta would be faster but would make the code less readable. Keep in mind that even 0.001f is quite an aggressive tolerance in these cases and could easily fail for close vectors that are too far from the origin point.

Commented is code that compares all components pairwise. This may work better when you have vectors that often have NaN or Infinite components but other than that I don’t recommend using it.

/*
 * Copyright (c) 2014 Martin Preisler
 * Licensed under http://opensource.org/licenses/MIT
 */

using UnityEngine;
using NUnit.Framework;
using System;

class TestUtils
{
	#region Vector2
	public static void AreEqual(Vector2 expected, Vector2 actual, float delta, string message)
	{
		if (delta <= 0)
			delta = 0.001f;

		float distance = Vector2.Distance(expected, actual);

		if (string.IsNullOrEmpty(message))
			message = String.Format("Expected: Vector2({0}, {1})\nBut was:  Vector2({2}, {3})\nDistance: {4} is greated than allowed delta {5}",
			                        expected.x, expected.y, actual.x, actual.y,
			                        distance, delta);

		Assert.That(distance, Is.LessThanOrEqualTo(delta), message);

		/*
		if (float.IsNaN(expected.x) || float.IsInfinity(expected.x))
			Assert.That(actual.x, Is.EqualTo(expected.x), message);
		else
			Assert.That(actual.x, Is.EqualTo(expected.x).Within(delta), message);

		if (float.IsNaN(expected.y) || float.IsInfinity(expected.y))
			Assert.That(actual.y, Is.EqualTo(expected.y), message);
		else
			Assert.That(actual.y, Is.EqualTo(expected.y).Within(delta), message);
		*/
	}

	public static void AreEqual(Vector2 expected, Vector2 actual, float delta)
	{
		AreEqual(expected, actual, delta, null);
	}

	public static void AreEqual(Vector2 expected, Vector2 actual, string message)
	{
		AreEqual(expected, actual, 0, message);
	}

	public static void AreEqual(Vector2 expected, Vector2 actual)
	{
		AreEqual(expected, actual, 0, null);
	}
	#endregion

	#region Vector3
	public static void AreEqual(Vector3 expected, Vector3 actual, float delta, string message)
	{
		if (delta <= 0)
			delta = 0.001f;

		float distance = Vector3.Distance(expected, actual);

		if (string.IsNullOrEmpty(message))
			message = String.Format("Expected: Vector3({0}, {1}, {2})\nBut was:  Vector3({3}, {4}, {5})\nDistance: {6} is greated than allowed delta {7}",
			                        expected.x, expected.y, expected.z,
			                        actual.x, actual.y, actual.z,
			                        distance, delta);

		Assert.That(distance, Is.LessThanOrEqualTo(delta), message);

		/*
		if (float.IsNaN(expected.x) || float.IsInfinity(expected.x))
			Assert.That(actual.x, Is.EqualTo(expected.x), message);
		else
			Assert.That(actual.x, Is.EqualTo(expected.x).Within(delta), message);

		if (float.IsNaN(expected.y) || float.IsInfinity(expected.y))
			Assert.That(actual.y, Is.EqualTo(expected.y), message);
		else
			Assert.That(actual.y, Is.EqualTo(expected.y).Within(delta), message);

		if (float.IsNaN(expected.z) || float.IsInfinity(expected.z))
			Assert.That(actual.z, Is.EqualTo(expected.z), message);
		else
			Assert.That(actual.z, Is.EqualTo(expected.z).Within(delta), message);
		*/
	}

	public static void AreEqual(Vector3 expected, Vector3 actual, float delta)
	{
		AreEqual(expected, actual, delta, null);
	}

	public static void AreEqual(Vector3 expected, Vector3 actual, string message)
	{
		AreEqual(expected, actual, 0, message);
	}

	public static void AreEqual(Vector3 expected, Vector3 actual)
	{
		AreEqual(expected, actual, 0, null);
	}
	#endregion
}

XCCDF tailoring

I would like to informally introduce the concept of XCCDF tailoring because it is not used as much as I would like and I believe the reason is that it is mostly undocumented. We have to go through some basics first.

XCCDF Profile

Profiles are an XCCDF feature that can select / deselect rules and change values that are inputs of the rules (e.g.: password length, various delays, etc… different profiles can have different values without creating multiple rules for the same thing). Even though profiles can change values that act as input to rules we will only deal with selection in this document for simplicity.
Profiles are part of the XCCDF file, the element that specifies them is called <xccdf:profile>.

Example:

<Profile id="xccdf_org.open-scap_profile_unselecting">
  <title>Unselecting</title>
  <select idref="xccdf_moc.elpmaxe.www_rule_1" selected="false"/>
</Profile>
This profile unselects rule number 1 that is (presumably) selected by default.

Profile inheritance

Every profile can act as an ancestor to another profile. The attribute that is used for this is called @extends.

Example:

<Profile id="xccdf_org.open-scap_profile_anti_unselecting" extends="xccdf_org.open-scap_profile_unselecting">
  <title>Not Really Unselecting</title>
  <select idref="xccdf_moc.elpmaxe.www_rule_1" selected="true"/>
</Profile>

Tailoring is a process that affects profiles in an XCCDF without changing the XCCDF file itself. So if it is signed, sha1-ed or otherwise officially “frozen”, you can select/deselect a rule without making any of the signatures invalid.

Other situation where tailoring is suitable is when you have a company-wide policy but one rule of it does not make sense for one particular machine, or perhaps you want to enforce stricter rules on public facing servers? In general you want to make slight temporary (revertible) tweaks to the profile you are using for whatever reason.

Result of tailoring is a tailoring file which is supposed to be used with the XCCDF file for evaluations.

Example:

<?xml version="1.0" encoding="UTF-8"?>
<Tailoring xmlns="http://checklists.nist.gov/xccdf/1.2" id="xccdf_org.open-scap_tailoring_example">
  <status>incomplete</status>
  <version time="2013-01-15T16:00:00.000+02:00">1.0</version>
  <Profile id="xccdf_org.open-scap_profile_anti_unselecting" extends="xccdf_org.open-scap_profile_unselecting">
    <title>Not Really Unselecting</title>
    <select idref="xccdf_moc.elpmaxe.www_rule_1" selected="true"/>
  </Profile>
</Tailoring>

using oscap with tailoring:

oscap xccdf eval --tailoring-file some-xccdf-tailoring.xml some-xccdf.xml

Inheritance and tailoring:

XCCDF Tailoring file can contain profiles created from scratch that do not extend any profile in the XCCDF but this situation is fairly rare. The most usual use case is to inherit some profile and select or deselect a couple of rules. This is a very convenient way to make minor adjustments to tailor the profile to your specific needs. The tailoring in the example above inherits a profile in XCCDF and selects a deselected rule.

scap-workbench and tailoring

Tailoring is the only way to change profiles in the new scap-workbench, for simplicity it is called profile customization in the application to make it more accessible to people not well versed in the SCAP nomenclature.
Creating tailoring files by hand is fairly tedious and error prone. Fortunately, you can now do it conveniently in scap-workbench!
First we open the content that we want to use for scanning, in this example case it is scap-security-guide.
The right profile has to be selected (this is the profile that will be tailored). In the screenshot above the ‘Example Server Profile’ that we wanted tailored is already selected.
After clicking the Customize button a new window pops up. Notice how the profile is called Example Server Profile [TAILORED] now. Workbench automatically changes the name to make it obvious that this profile is the tailored profile.
Users can navigate this window to see all the rules, the checkboxes next to rules allow them to select or deselect any given Rule. Addition of  elements happens under the hood automatically.
After tailoring is finished click Finish tailoring.
We can now perform evaluation, tailor again or save the tailoring to a file that can be used later (even outside scap-workbench!). Click Save Tailoring.

Aldous Huxley – Brave New World (1932) EPUB + MOBI

I was looking for the aforementioned book on the internet for my Kindle and even though it’s been in public domain for a long time, there are no properly formatted versions around! The only versions I found didn’t have any TOC or chapter breaks.

The following files are my attempt to remedy the situation. They have proper chapter breaks and TOC. Feel free to submit / share this anywhere, I don’t claim any credit for reformatting the book – the files are public domain as is the book.

Reuploaded zip file: Brave_New_World.zip

Google has since disabled public sharing on the original files because it allegedly violates their guidelines. It’s public domain but Google robots can’t be reasoned with.

Brave New World – Aldous Huxley.epub
Brave New World – Aldous Huxley.mobi (this file will work on your Kindle)

SCAP Workbench redesign

What is SCAP Workbench?

A GUI tool that allows user to perform scans and limited XCCDF editing. Its role is to flatten the learning curve and make entry into the SCAP world easier for newcomers.
I do not believe that it is the only essential tool in the quiver of an SCAP auditor. The main use case is scanning single machines and refining the policy. After everything is set up I expect auditors and admins to scan periodically via the command line oscap tool or a system management tool (e.g. Spacewalk) instead. So workbench should in my opinion avoid feature creep and avoid becoming an all-in-one essential tool.
The old workbench scanning a local machine

Why the rewrite? The workbench is perfect!

No, it really isn’t. The codebase is very large, on the brink of not being maintainable and big portions of it are completely unused. The scanning code is more or less a port of oscap tool code from C to Python. And while the oscap tool from the openscap project is gradually improved, workbench scanning stays the same.
Generally I think we have come to a point when it’s worth it to take learned lessons from the past and rewrite from scratch. Also, openscap is now featuring a high level API that can do most of the heavy lifting for us. Thus the new version can have a very lean codebase.

Working prototype

So far I have created a prototype to prove that the new major features can be done. It is residing (most likely just temporarily) in a github repository at https://github.com/mpreisler/scap-workbench.

Requirements

  • cmake
  • Qt4
  • QtWebKit
  • openscap from git

Notable changes

Using the oscap tool for all scanning

Previously, we used the openscap library’s API to perform the scan. That is done using the oscap scanner in the new version. There are several reasons why this is a good idea. For one we can have just one heavily tested code that does evaluation and rely on it for both tools. Also if the oscap scanner gets certified the workbench ends up using a certified scanner which may be valuable for users. [5]

High level API from openscap

This is done for the workbench to be less likely to break with openscap API changes. The old workbench used to suffer very frequently from this.

Remote scanning

Old workbench can only scan the machine it was running on. The new workbench allows users to scan any remote machine with accessible ssh. It will ssh into a remote machine and run oscap there. oscap scanner must be installed on that machine in order to do that.

Results are fetched back to the machine with workbench for analysis.

Datastream support

SCAP Workbench used to only support XCCDF. The prototype allows you to open a source datastream and select any checklist inside. Going forward, datastreams are the preferred way of exchanging SCAP content so it is essential that workbench supports them.

Remediation

Workbench did not enable users to fix a system so that a rule passes. Since support for remediation has been added to openscap recently, we can simply use the oscap tool to perform it.

So far only online remediation is implemented for both local and remote scans.

The new workflow

I am trying to emphasize straight forward usage for the most common use case. Any special use cases should be hidden behind menus.

When opened, the application immediately pops a file open window and will close itself if user cancels. A file has to be opened at all times in the new workbench. Majority of the work is done in the main window of the application.

Datastream opened in the new workbench

 

New workbench scanning

Results are shown in a separate modal dialog, as is the option to save them in one of the 3 formats.

SCAP Workbench and its result viewer (uses WebKit)

Future plans

Proper tailoring

Currently, SCAP Workbench doesn’t follow the specification when it comes to XCCDF profile tailoring. It changes profiles directly instead of tailoring them even though the feature is called Tailoring in the tool. The new workbench will work with tailoring files and will correctly inherit the profile to tailor it.
This has been enabled by improvements in openscap that allows profile inheritance and name shadowing.

Offline remediation

Online remediation is not applicable to all use cases. Very often users want additional control over what to remedy. In the future I plan to implement selective remediation that can be applied after scan finishes. User will be able to select or deselect failed rules that should be remedied.

I need some help

At this point I only have a very crude GUI prototype. I am looking at polishing and improving the workflow. As I am not experienced in developing GUI applications I appreciate any help regarding that. Feedback and ideas are very welcome.

References, further reading

Introduction to SCAP datastreams with openscap

What are datastreams?

Datastream can be thought of as an archive of interlinked SCAP content (XCCDF, OVAL, CPE, …). It was introduced in SCAP 1.2 standard. In its purpose it is similar to SCAP bundle known from previous SCAP version and datastreams are expected to replace SCAP bundles. The whole concept is fairly simple but is made confusing because of unfortunate choice of nomenclature. Lets disambiguate the terms first.

There are two types of datastreams: source datastreams (SDS) and result datastreams (ARF). The idea is that the scanner takes a source datastream, evaluates it and gives results in the result datastream format back. What makes things confusing is that each source datastream has a root element called “data-stream-collection” that contains 1 or more elements called “data-stream” inside it! So the datastream is actually a collection of datastreams…[1] The way I think about this is that each source datastream has 1 or more modes in which it can be evaluated. Most datastreams will only have one.

Support in openscap

Datastreams have been supported since 0.8.5 but the code has been continuously improved since then. This guide assumes that you are using the latest openscap, namely version 0.9.3.

Having an up to date libxml2 is also important, libxml2-2.7 or newer is recommended because of various XSD validation bugs in older versions.

Why should I care?

Despite looking like fancy wrapping around SCAP content, datastreams do have extra features that may be valuable to your use case. People creating content might be interested in signing it (uses public key cryptography). [1] [2] [3] Content consumers might like the ease of use and added flexibility.

Another reason is that SCAP datastreams are slowly becoming the recommended way to distribute all SCAP content. I would not be surprised if separate XCCDF and OVAL files are only used for content creation in the coming years.

Evaluating the datastream

Evaluation of datastream means evaluation of either one of the XCCDFs or OVALs in it. The whole process is a bit more involved because of various links and references in the datastream but openscap kindly hides this complexity for us.

Confirming content type

A recommended first step is to make sure the content is what is expected. The oscap tool has a convenient command for this called oscap info.

This will print information about the content, including referenced XCCDF and OVAL components. 

$ oscap info datastream.xml
Document type: Source Data Stream
Imported: 2012-12-18T13:46:13

Stream: scap_org.open-scap_example_datastream
Generated: (null)
Version: 1.2
Checklists:
        Ref-Id: scap_org.open-scap_cref_xccdf.xml
                Profile: xccdf_cdf_profile_Default
Checks:
        Ref-Id: scap_org.open-scap_cref_oval.xml
No dictionaries.

XCCDF inside SDS evaluation

$ oscap xccdf eval datastream.xml

OVAL inside SDS evaluation

$ oscap oval eval datastream.xml
openscap automatically detects that given file is a datastream and acts accordingly, splitting it into separate files before evaluation. You can also split it manually and evaluate it in the conventional way, see the next section.
In cases where the datastream contains more OVAL components or more XCCDFs, the user can choose which one to evaluate. 

XCCDF with given ID inside SDS evaluation

$ oscap xccdf eval --xccdf-id COMPONENT_ID datastream.xml

It is encouraged to use oscap info as seen in one of the previous sections to print out component-ref IDs and use these for the command-line options.

Similarly with OVAL. Please review the oscap man page for more details about component ref selection (–xccdf-id, –oval-id and –datastream-id).

More options

You can use all the other options you are accustomed to when evaluating a single XCCDF file: selecting profiles in the XCCDF, creating results and guides, … See the XCCDF section of the oscap man page for more details.

Result datastream

If you are evaluating a source datastream it is very likely that you want a result datastream back. There is a special command-line switch to achieve that called –results-arf, it behaves similarly to –results but writes out the file in ARF format instead of the XCCDF results format. ARF stands for Asset Reporting Format and is the standard for result datastreams. [1]

$ oscap xccdf eval --results-arf result.xml datastream.xml

Splitting the stream manually

In some cases it is more suitable to split the datastream into multiple files and work with these. Especially if you already have an established workflow around these files. openscap allows you to do this via its oscap command line tool.
$ oscap ds sds-split datastream.xml target_folder/

If the content inside the datastream requires it, subfolders will be created in the target folder. As was the case previously, you might want to specify –datastream-id and/or –xccdf-id if there are more XCCDFs in the datastream you are splitting. Otherwise, the first suitable XCCDF is used.

Creating a datastream from separate files

openscap also allows you to create a datastream from separate files. The implementation only allows this for the most common case of one XCCDF with one or more OVAL files referenced. The referenced OVAL files are automatically detected and packed in.

$ oscap ds sds-compose some-xccdf.xml target-datastream.xml

References, further reading