Sunday, October 30, 2011

Compiling OVALDI for CentOS 6

Note: Take a look at the newer version of this post. Things are simpler now.

I described in one earlier post the purpose of OVAL and the benefits it gives to a user. Here I'm going to describe how to setup OVAL interpreter on CentOS 6. The problem is that there is no prepackaged Oval interpreter for CentOS 6. Actually, there is but it's only for 32 bit version of CentOS 4 and 5, an it is an older version, not the latest one. So, here I'm going to describe how to build it from source. The build process consists of building XML processor Xalan, then XSLT processor Xerces and finally in building interpreter itself. There are certain prerequisites you need to have in order for Oval to build, I'll mention those also.

I'll assume that you created working directory for this purpose and that you run all the following commands within that directory. When necessary, I'll reference that directory as $WORKDIR and when you see that string replace it with full path of your working directory. Also, I'm going to install oval interpreter into directory /opt/oval. The reason I'm not placing it into some of the "system" directories like /usr/bin, /usr/lib and similar is to avoid clash with versions of xalan and xerces shipped with distribution itself.

In case you trust me enough, here is archive of final content of directory /opt/oval, so you can unpack it and skip to the Running ovaldi section.

Installing prerequisites

Download version 2.8.0, or whatever is the latest version of Xalan 2. Don't use Xalan 3 because API was changed with respect to version 2 and OVAL won't work with it! In the following text, I'll reference version 2.8.0 and if there is a newer one replace version numbers as necessary.

After downloading some package it is a good practice to check MD5 sum (or SHA1). In this case md5 sum will give the following output:
$ md5sum xerces-c-src_2_8_0.tar.gz
5daf514b73f3e0de9e3fce704387c0d2  xerces-c-src_2_8_0.tar.gz
which matches the one given on the dowload page.

Now, unpack the archive using the following command:
$ tar xzf xerces-c-src_2_8_0.tar.gz
and you'll get directory xerces-c-src_2_8_0/. Go into that directory and then into src/xercesc subdirectory. Before configuring distribution set the environment variable XERCESCROOT to the top level directory of the unpacked archive, i.e.
export XERCESCROOT=$WORKDIR/xerces-c-src_2_8_0
now, start configuration process:
./runConfigure -p linux -c gcc -x c++ -b 64 -P /opt/oval
In that command option p specifies platform on which you are performing build process, option c specifies compiler to use, x specifies c++ compiler, option b determines bit width of the platform (32 or 64 bit) and option P specifies installation directory. All the other options have appropriate default values. Note that you must specify c++ instead of g++! If you specify g++, then while building Xalan, you'll get the following errors:
$XERCESCROOT/lib/ undefined reference to `stricmp(char const*, char const*)'
$XERCESCROOT/lib/ undefined reference to `strnicmp(char const*, char const*, unsigned int)'
The problem is that the configuration process misidentified that GNU's compiler is used that doesn't have stricmp and strnicmp functions and it didn't include replacement functions!

If everything went without an error, start build process by issuing make command:
and finally, install xerces (you should switch to root user to run the following command):
make install

Go to the download page and take most recent version of Xalan. I was using 1.10 which was the latest one at the time this post was written. So, after download it, and checking signature(!), unpack it with the following command:
tar xzf Xalan-C_1_10_0-src.tar.gz
This will create new directory, xml-xalan/. Before building Xalan, you should apply a patch to it. The problem is that gcc developers made some changes to header files (removed unnecessary includes) in recent version available on CentOS and that means that some prerequisite includes have to be explicitly specified. The problem is manifested with the following error messages:
home/zavod/sgros/work/xml-xalan/c/src/xalanc/XalanDOM/XalanDOMString.cpp: In member function ‘xalanc_1_10::XalanDOMString& xalanc_1_10::XalanDOMString::assign(const xalanc_1_10::XalanDOMString&, xalanc_1_10::XalanDOMString::size_type, xalanc_1_10::XalanDOMString::size_type)’:
/home/zavod/sgros/work/xml-xalan/c/src/xalanc/XalanDOM/XalanDOMString.cpp:251: error: ‘memmove’ was not declared in this scope
/home/zavod/sgros/work/xml-xalan/c/src/xalanc/XalanDOM/XalanDOMString.cpp: In static member function ‘static xalanc_1_10::XalanDOMString::size_type xalanc_1_10::XalanDOMString::length(const char*)’:
/home/zavod/sgros/work/xml-xalan/c/src/xalanc/XalanDOM/XalanDOMString.cpp:780: error: ‘strlen’ was not declared in this scope
So, download the patch and enter into xml-xalan directory. Then, run the following command:
$ patch -p1 < ../xml-xalan.gcc-4.4.patch
patching file c/src/xalanc/TestXPath/TestXPath.cpp
patching file c/src/xalanc/XalanDOM/XalanDOMString.cpp
patching file c/src/xalanc/XalanExe/XalanExe.cpp
patching file c/src/xalanc/XMLSupport/FormatterToHTML.cpp
patching file c/src/xalanc/XSLT/ElemNumber.cpp
this assumes that you've downloaded patch into the same place where you downloaded Xalan itself (i.e. $WORKDIR).

Now, enter into subdirectory named c/. Before configuring the build process, define the variable XALANCROOT. You should set it to $WORKDIR/xml-xalan/c with the following command:
export XALANCROOT=$WORKDIR/xml-xalan/c
Also, note that Xalan depends on Xerces and to be able for Xalan to find Xerces you need to set the environment variable XERCESROOT, or Xerces has to be in some system directory that is searched by default (e.g. /usr/include and similar directories).  If you followed this post withouth interruption, you probably have it defined already. Now, initiate configure process using runConfigure command:
./runConfigure -p linux -c gcc -x c++ -b 64 -P /opt/oval
the options used are same as for Xerces. Initiate build process using make, and after build finishes, install it using 'make install' command switching before to root user.

Necessary development packages
As a final prerequisite you should check that the following development packages are installed. The simplest way to do that is to initiate install process and yum will react appropriately: pcre-devel, libgcrypt-devel, rpm-devel, openldap-devel, libblkid-devel, and libselinux-devel.

Building and installing Ovaldi
Go now to the download page of Ovaldi and download the latest version. Version is the latest one at the time of writing this post. So download it and upack it. This will create directory ovaldi- Also, download the following patch. Note that this patch is made so that ovaldi can be compiled on CentOS 6 and it is not applicable for other distributions, neither it will allow ovaldi to be compiled on other platforms (though, very unlikely it might :)).

Now, enter ovaldi- directory and apply patch:
patch -p1 < ../ovaldi-
Three changes are in the patch file. The first one is addition of /opt/oval/include and /opt/oval/lib directories in main Makefile. The second are some changes to RPM part of the code since API has changed in recent versions of RPM. More specifically, I introduced compatibility switch (-D_RPM_4_4_COMPAT) and also replaced int_32 with int32_t types.

Third change resolves the following error message already reported on some forums:
Error running rpm query in child process: blah: -q: unknown option
There is also additional patch that isn't always necessary, and that's why I separated it. Namely, I placed ovaldi in /opt/oval directory, while ovaldi expects by default its shared files to be within /usr/share/oval. So, this patch changes this:
patch -p1 < ../ovaldi-
Since for some unknown reason (I didn't have will/time to investigate further) linker can not find library, even though it has appropriate path in -L option, define LD_LIBRARY_PATH using the following command prior to comilation:
export LD_LIBRARY_PATH=/opt/oval/lib/
Finally, enter project/linux subdirectory and initiate build process:
When the build process is over, copy ovaldi binary (you'll find it in project/linux/Release subdirectory) to /opt/oval/bin directory. Also, create directory /opt/oval/share/ovaldi and move there directory xml (you'll find it directly beneath ovaldi- directory).

Running ovaldi
Finally, we are ready to run ovaldi interpreter. Before running ovaldi you should define LD_LIBRARY_PATH and optinally PATH variable. In other words, before running ovaldi execute once these commands:
export LD_LIBRARY_PATH=/opt/oval/lib
export PATH=/opt/oval/bin:$PATH
Then, try to run ovaldi, you should get help message.

This concludes this post. In the next one I'm going to try to run ovaldi using RedHat's provided files. Until I do this note that the patches I provided may turn to have errors that would prevent ovaldi from correctly functioning.


David Wagenheim said...


I tried to download the patch but got the following error:

The requested URL /~sgros/files/ovaldi-5.10.1-centos6.patch was not found on this server.

Can you provide a link or file via an attachment?


Stjepan Groš (sgros) said...

Well, it turns out that I somehow deleted those files and also that I don't have a backup copy!? Sorry for that! Anyway, I decided to update this post for the latest version of Ovaldi (, so in a due course I'll recreate missing patches. Hope I manage all this to be done this weekend...

Stjepan Groš (sgros) said...

Ok, I updated this post and the other post (the one about detecting OpenSSL vulnerability). For some strange reason I managed to delete all the files. I saw that some of them are available in Google Cache but I decided to recreate all of them again on a new version of ovaldi. If there are any problems please let me know...

Tomas Vobruba said...

Very nice guide. thank you for this. this saves time for me a lot.

PASSION said...

Your blog is so useful for me to try ovaldi on SL6, thank you very much :)

About Me

scientist, consultant, security specialist, networking guy, system administrator, philosopher ;)

Blog Archive