//
// $Id: RegistryKeyData.cpp,v 1.1 2004/06/01 17:05:21 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:	RegistryKeyData.cpp
//  author: Jon Baker	
//  date:   30 January 2004
//
//	This class will store all data for a windows registry key. 
//	The class is a child class of ProbeData and implments the Write() function.
//****************************************************************************************//

#include "RegistryKeyData.h"

//****************************************************************************************//
//								RegistryKeyData Class								  //	
//****************************************************************************************//
RegistryKeyData::RegistryKeyData(string regKeyStrIn)
{
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Initialize a new RegistryKeyData based on the string provided
	// -----------------------------------------------------------------------


	//	Init the data members 
	testId = "";
	hive = new TypedData(LITTERAL_TYPE, "");
	key = new TypedData(LITTERAL_TYPE, "");
	name = new TypedData(LITTERAL_TYPE, "");
	type = "";
	value = "";
	msg = "";

	//	Call the parse node function
	Parse(regKeyStrIn);

}

RegistryKeyData::RegistryKeyData()
{
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Initialize a new RegistryKeyData as an empty object.
	// -----------------------------------------------------------------------
	testId = "";
	hive = new TypedData(LITTERAL_TYPE, "");
	key = new TypedData(LITTERAL_TYPE, "");
	name = new TypedData(LITTERAL_TYPE, "");
	type = "";
	value = "";
	msg = "";
}

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

}

// ***************************************************************************************	//
//								Public members												//
// ***************************************************************************************	//
void RegistryKeyData::Write(DBInterface *db)
{
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Write a windows registry key data objerct to the database.
	//
	// -----------------------------------------------------------------------

	string sqlStmt = "";
	sqlStmt.append("INSERT INTO ");
	sqlStmt.append("Windows_RegistryKeys");
	sqlStmt.append(" VALUES ('");
	//	Key
	sqlStmt.append(Common::FixQuotes(this->hive->data + "\\" + this->key->data));
	sqlStmt.append("','");
	//	Name
	sqlStmt.append(Common::FixQuotes(this->name->data));
	// Type
	sqlStmt.append("','" + this->type + "','");
	//	Value
	sqlStmt.append(Common::FixQuotes(this->value));
	sqlStmt.append("')");


	// Update the database.
	if(this->key->data.compare("") != 0 && this->value.compare("") != 0 && this->type.compare("") != 0)
		db->ExecSQL(sqlStmt);


	//	Display any messages if running in verbose mode
	if(Log::verboseMode && this->msg.compare("") != 0)
	{
		string displayMsg = "\nMessage from the Windows Registry Key probe:\n";
		displayMsg.append("--------------------------------------------\n");
		displayMsg.append(this->msg);
		displayMsg.append("\n");
		
		cout << displayMsg << endl;;

		Log::WriteLog(displayMsg + "\n");

	}
}

// ***************************************************************************************	//
//								Private members												//
// ***************************************************************************************	//
void RegistryKeyData::Parse(string regKeyStrIn)
{
	// -----------------------------------------------------------------------
	//	Abstract
	//
	//	Parse the parse the input string getting the hive, key, and name to
	//	populate this RegistryKeyData object. Expected input is as follows:
	//
	//	LIT/PAT|hiveValue:LIT/PAT|keyValue:LIT/PAT|nameValue
	//	
	//	If one of the items is missing it is assumed to be equivalent to .*
	//
	// -----------------------------------------------------------------------
	string element			= "";
	string type				= "";
	unsigned int delim		= string::npos;
	unsigned int prevDelim	= string::npos;

	//	Get the hive and its type
	delim = regKeyStrIn.find(":");
	
	//	Was a hive found?
	if(delim == 0)
	{
		hive->type = PATTERN_MATCH_TYPE;
		hive->data = ".*";

		regKeyStrIn = regKeyStrIn.substr(1, regKeyStrIn.length()-1);

	}else
	{
		element = regKeyStrIn.substr(0, delim);
		type = element.substr(0, 3);
		if(type.compare("PAT") == 0)
			hive->type = PATTERN_MATCH_TYPE;

		hive->data = element.substr(4, element.length()-4);

		regKeyStrIn = regKeyStrIn.substr(delim+1, regKeyStrIn.length());
	}

	//	Reset vars
	delim = string::npos;
	type = "";
	element = "";

	//	Get the key and its type
	delim = regKeyStrIn.find(":");

	//	Was a key found?
	if(delim == 0)
	{
		key->type = PATTERN_MATCH_TYPE;
		key->data = ".*";

		regKeyStrIn = regKeyStrIn.substr(0, regKeyStrIn.length()-2);

	}else
	{
		element = regKeyStrIn.substr(0, delim);
		type = element.substr(0, 3);
		if(type.compare("PAT") == 0)
			key->type = PATTERN_MATCH_TYPE;

		key->data = element.substr(4, element.length()-4);

		regKeyStrIn = regKeyStrIn.substr(delim+1, regKeyStrIn.length());
	}

	//	Reset vars
	prevDelim = delim;
	type = "";
	element = "";

	//	Get the name and its type
	delim = regKeyStrIn.find(":", delim+1);

	//	Was a name found?
	if(delim == prevDelim + 1)
	{
		name->type = PATTERN_MATCH_TYPE;
		name->data = ".*";

	}else
	{
		element = regKeyStrIn.substr(0, delim);
		type = element.substr(0, 3);
		if(type.compare("PAT") == 0)
			name->type = PATTERN_MATCH_TYPE;

		name->data = element.substr(4, element.length()-4);
	}
}
	