//
// $Id: DataCollector.cpp,v 1.18 2005/08/30 19:02:59 abuttner Exp $
//
//****************************************************************************************//
// Copyright (c) 2005, The MITRE Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice, this list
//       of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright notice, this 
//       list of conditions and the following disclaimer in the documentation and/or other
//       materials provided with the distribution.
//     * Neither the name of The MITRE Corporation nor the names of its contributors may be
//       used to endorse or promote products derived from this software without specific 
//       prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
// SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
// TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//****************************************************************************************//


#include "DataCollector.h"

//****************************************************************************************//
//								DataCollector Class								  //	
//****************************************************************************************//

DataCollector::DataCollector(XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *oval, 
							XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *data) 
							: OvalDataCollector(oval, data, "windows")
{
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Init the DataCollector object. Pass the two documents
	//	to the base class. Hardcode the family parameter to windows for the base
	//	class.
	//	oval	- the DOMDocument that represents the oval.xml
	//	data	- the DOMDocument that will contain the data model.
	// -----------------------------------------------------------------------
	
	// Add the system_info element
	Probe *p = SystemInfoProbe::Instance();
	WriteSystemInfo(p);
	delete p;
}

DataCollector::~DataCollector()
{
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Nothing for now
	// -----------------------------------------------------------------------
}

// ***************************************************************************************	//
//								Public members												//
// ***************************************************************************************	//

void DataCollector::Run()
{
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Find the tests node and loop through all of its children.
	//	If a test belongs to the family that is being tested run that test.
	//	
	//	To run a test call OvalDataCollector::RunTest()
	// -----------------------------------------------------------------------

	DOMElement *testsNode;
	DOMNodeList *ovalTestsChildren;

	//////////////////////////////////////////////////////
	////////////////  Process OVAL Tests  ////////////////
	//////////////////////////////////////////////////////
	//	get a ptr to the tests node in the oval document.
	testsNode = XmlCommon::FindNodeNS(ovalDoc, "tests");
	//	get a list of the child nodes
	ovalTestsChildren = testsNode->getChildNodes();

	//	Loop through all the nodes in ovalTestList
	unsigned int index = 0;
	while(index < ovalTestsChildren->getLength())
	{
		DOMNode *tmpNode = ovalTestsChildren->item(index);

		//	Handle exceptions on a test by test basis
		try
		{
			//	only concerned with ELEMENT_NODEs
			if (tmpNode->getNodeType() == DOMNode::ELEMENT_NODE) {
	
				// Cast the test to a DOMElement
				DOMElement *test = (DOMElement*)tmpNode;
		
			//	DEBUG code
			//	string testId = XmlCommon::GetAttributeByName(test, "id");
			//	cout << "Test Id: " << testId << endl; 

				//	get the name of the test
				string name = XmlCommon::GetElementName(test);
				if(name.compare("compound_test") != 0 && name.compare("unknown_test") != 0) {

					//	only handle supported tests
					if(name.compare("activedirectory_test") == 0) {
						//	Run the test
						RunTest(ActiveDirectoryProbe::Instance(), new ActiveDirectoryData(test));

					} else if(name.compare("file_test") == 0) {
						//	Run the test
						RunTest(FileProbe::Instance(), new FileData(test));

/*	This code has been romoved because late in the release of the oval schema for 
	version 4 an error in the schem was discovered that makes this test meaningless.
	A future version of the oval schem will correct this error.

					} else if(name.compare("fileeffectiverights_test") == 0) {
						//	Run the test
						RunTest(FileProbe::Instance(), new FileData(test));
*/

					} else if(name.compare("metabase_test") == 0) {
						//	Run the test
						RunTest(MetabaseKeyProbe::Instance(), new MetabaseKeyData(test));

					} else if(name.compare("registry_test") == 0) {
						//	Run the test
						RunTest(RegistryProbe::Instance(), new RegistryData(test));

					} else if(name.compare("xmlfilecontent_test") == 0) {
						//	Run the test
						RunTest(XmlFileContentProbe::Instance(), new XmlFileContentData(test));
							
/*	This code has been romoved because late in the release of the oval schema for 
	version 4 an error in the schem was discovered that makes this test meaningless.
	A future version of the oval schem will correct this error.

					} else if(name.compare("regkeyeffectiverights_test") == 0) {
						//	Run the test
						RunTest(RegistryEffectiveRightsProbe::Instance(), new RegistryEffectiveRightsData(test));
*/
					} else if(name.compare("wmi_test") == 0) {
						//	Run the test
						RunTest(WMIProbe::Instance(), new WMIData(test));

					} else {

						//	This is not really an error, we just don't handle this test yet
						throw OvalDataCollectorException("Message: Not a supported test: " + name + " id= " + XmlCommon::GetAttributeByName(test, "id") + "\n");
					}
				}
			}

		} catch(Exception ex) {

			if(Log::verboseMode) {
				Log::WriteLog(ex.GetErrorMessage() + "\n");
				cout << ex.GetErrorMessage() << endl;		
			}
		} catch(...) {

			string errMsg = "Fatal error: An unknown exception occured in 'DataCollector::Run()'\n";
			Log::WriteLog(errMsg + "\n");
			cout << errMsg << endl;
		}

		index ++;
	}
}



