//
// $Id: FilePermissionData.cpp,v 1.1 2004/06/01 17:05:19 bakerj Exp $
//
//************************** Property of the MITRE Corporation ***************************//
//
// Copyright (c) 2003 - The MITRE Corporation
//
// This file is part of the Query-based Network Assessment project.
//
// The Query-based Network Assessment is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 of the License.
//
// The Query-based Network Assessment is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with the
// Query-based Network Assessment; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//****************************************************************************************//
//
//  file:	FilePermissionData.cpp
//  author: Jon Baker	
//  date:   13 Februauy 2004
//
//	This class will store all data for a Linux files permissions. 
//	The class is a child class of ProbeData and implments the Write() and ParseNode() function 
//****************************************************************************************//

#include "FilePermissionData.h"

//****************************************************************************************//
//								FilePermissionData Class								  //	
//****************************************************************************************//
FilePermissionData::FilePermissionData(DOMNode *test)
{
  // -----------------------------------------------------------------------
  //	Abstract
  //
  //	Initialize a new FilePermissionData and populate with the node's data
  // -----------------------------------------------------------------------

  string testName;

  //	Validate the test node
  if(test->getNodeType() != DOMNode::ELEMENT_NODE )
    {
      throw ProbeDataException("Error: FilePermissionData() Invalid test node specified. Only ELEMENT_NODE's are allowed.");
    }else
      {
	testName = DOMCommon::ToString(test->getNodeName());
	if(testName.compare("permission_test") != 0)
	  throw ProbeDataException("Error: FilePermissionData() Invalid test node specified. Received: " + testName);
      }

  //	Init the data members
  testId	= "";
  path	= new TypedData(LITTERAL_TYPE, "");
  gexec	= "";
  gread	= "";
  gwrite	= "";
  oexec	= "";
  oread	= "";
  owrite	= "";
  sgid	= "";
  sticky	= "";
  suid	= "";
  uexec	= "";
  uread	= "";
  uwrite	= "";
  msg		= "";

  //	Call the parse node function
  ParseNode(test);
}

FilePermissionData::FilePermissionData()
{
  // -----------------------------------------------------------------------
  //	Abstract
  //
  //	Initialize a new FilePermissionData as an empty object.
  // -----------------------------------------------------------------------

  testId	= "";
  path	= new TypedData(LITTERAL_TYPE, "");
  gexec	= "";
  gread	= "";
  gwrite	= "";
  oexec	= "";
  oread	= "";
  owrite	= "";
  sgid	= "";
  sticky	= "";
  suid	= "";
  uexec	= "";
  uread	= "";
  uwrite	= "";
  msg		= "";
}

FilePermissionData::~FilePermissionData()
{
  // -----------------------------------------------------------------------
  //	Abstract
  //
  //	Do nothing for now
  // -----------------------------------------------------------------------

}

// ***************************************************************************************	//
//								Public members												//
// ***************************************************************************************	//
void FilePermissionData::Write(XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument *dataDocument)
{
  // -----------------------------------------------------------------------
  //	Abstract
  //
  //	Create a new permission_test node and add it to the dataDocument.
  //	
  // -----------------------------------------------------------------------

  //	Create a new test node
  DOMElement *permission_test = CreateNewTestNode(dataDocument, "permission_test");

  //	Add the path element - as a string
  AddChildNode(dataDocument, permission_test, "path", path->data);

  //    Only write permission bits if the path is found
  if (path->data.compare("") != 0)
    {
    
      //	Add the gexec element - as an integer
      AddChildNode(dataDocument, permission_test, "gexec", gexec, INTEGER_DATATYPE);
  
      //	Add the gread element - as an integer
      AddChildNode(dataDocument, permission_test, "gread", gread, INTEGER_DATATYPE);

      //	Add the gwrite element - as an integer
      AddChildNode(dataDocument, permission_test, "gwrite", gwrite, INTEGER_DATATYPE);

      //	Add the oexec element - as an integer
      AddChildNode(dataDocument, permission_test, "oexec", oexec, INTEGER_DATATYPE);

      //	Add the oread element - as an integer
      AddChildNode(dataDocument, permission_test, "oread", oread, INTEGER_DATATYPE);

      //	Add the owrite element - as an integer
      AddChildNode(dataDocument, permission_test, "owrite", owrite, INTEGER_DATATYPE);

      //	Add the sgid element - as an integer
      AddChildNode(dataDocument, permission_test, "sgid", sgid, INTEGER_DATATYPE);

      //	Add the sticky element - as an integer
      AddChildNode(dataDocument, permission_test, "sticky", sticky, INTEGER_DATATYPE);

      //	Add the suid element - as an integer
      AddChildNode(dataDocument, permission_test, "suid", suid, INTEGER_DATATYPE);

      //	Add the uexec element - as an integer
      AddChildNode(dataDocument, permission_test, "uexec", uexec, INTEGER_DATATYPE);

      //	Add the uread element - as an integer
      AddChildNode(dataDocument, permission_test, "uread", uread, INTEGER_DATATYPE);

      //	Add the uwrite element - as an integer
      AddChildNode(dataDocument, permission_test, "uwrite", uwrite, INTEGER_DATATYPE);
    }

  //	Add the uwrite element - as a string
  AddChildNode(dataDocument, permission_test, "message", msg);
}

// ***************************************************************************************	//
//								Private members												//
// ***************************************************************************************	//
void FilePermissionData::ParseNode(DOMNode *test)
{
  // -----------------------------------------------------------------------
  //	Abstract
  //
  //	Parse the node gathering all data to popular this FilePermissionData
  //	Really just need to gather the Test id.
  // -----------------------------------------------------------------------

  ///////////////////////////////////////////////////////////////////////////
  //	Get the test id
  ///////////////////////////////////////////////////////////////////////////
  testId = DOMCommon::GetAttributeByName(test, "id");
  if(testId.compare("") == 0)
    throw ProbeDataException("Error: Unable to find the 'id' attribute for a Red Hat permission test.");	


  ///////////////////////////////////////////////////////////////////////////
  //	Gather the data needed to call the probe
  ///////////////////////////////////////////////////////////////////////////
  string childName	= "";
  string childOp		= "";
	
  DOMNode *processChild;
  DOMNodeList *processChildList;

  //	get a list of the child nodes and their values
  processChildList = test->getChildNodes();
  unsigned int index = 0;
  while(index < processChildList->getLength())
    {
      processChild = processChildList->item(index);

      //	only concerned with ELEMENT_NODEs
      if (processChild->getNodeType() == DOMNode::ELEMENT_NODE)
	{
	  //	get the name of the child
	  childName = DOMCommon::ToString(processChild->getNodeName());

	  //	Get the child's operator
	  childOp = DOMCommon::GetAttributeByName(processChild, "operator");
			
	  //	Get the path value	
	  if(strncmp(childName.c_str(), "path", 7)==0)
	    {
	      if(childOp.compare("pattern match") == 0)
		path->type = PATTERN_MATCH_TYPE;
	      else
		path->type = LITTERAL_TYPE;

	      path->data = DOMCommon::GetDataNodeValue(processChild);
	    }
	}
      index ++;
    }
}

