tripwire-open-source/src/twtest/textreportviewer_t.cpp

485 lines
17 KiB
C++

//
// The developer of the original code and/or files is Tripwire, Inc.
// Portions created by Tripwire, Inc. are copyright (C) 2000-2021 Tripwire,
// Inc. Tripwire is a registered trademark of Tripwire, Inc. All rights
// reserved.
//
// This program is free software. The contents of this file are subject
// to the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version. You may redistribute it and/or modify it
// only in compliance with the GNU General Public License.
//
// This program is distributed in the hope that it will be useful.
// However, this program is distributed AS-IS WITHOUT ANY
// WARRANTY; INCLUDING THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS
// FOR A PARTICULAR PURPOSE. Please see the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
//
// Nothing in the GNU General Public License or any other license to use
// the code or files shall permit you to use Tripwire's trademarks,
// service marks, or other intellectual property without Tripwire's
// prior written consent.
//
// If you have any questions, please contact Tripwire, Inc. at either
// info@tripwire.org or www.tripwire.org.
//
///////////////////////////////////////////////////////////////////////////////
// textreportviewer_t.cpp -- tests textreportviewer
//
#include "tw/stdtw.h"
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#include "tw/fcoreport.h"
#include "fco/fcospecimpl.h"
#include "fco/fcosetimpl.h"
#include "fs/fsobject.h"
#include "core/serializerimpl.h"
#include "core/archive.h"
#include "twtest/test.h"
#include "core/errorbucketimpl.h"
#include "tw/textreportviewer.h"
#include "fs/fspropset.h"
#include "fs/fspropcalc.h"
#include "core/fsservices.h"
#include <iostream>
#include <fstream>
#include "fco/fcospechelper.h"
#include "fco/fcospecattr.h"
#include "tw/fcoreportutil.h"
#include "tw/headerinfo.h"
//#ifdef FIXED_TRV_TEST_SUITE
void MakeFile(TSTRING& fcoNameMakeMe);
void MakeDir(const TCHAR* const lpszDirName);
#if 0 // Not used untill this test is fixed
// we use this instead of TraceContents() so we can test the report iterators.
static void TraceReport(const cFCOReport& r, cDebug& d)
{
d.TraceDebug("Global Error Queue:\n");
r.GetErrorQueue()->TraceContents();
cFCOReportGenreIter genreIter(r);
int genreCount = 0;
for (genreIter.SeekBegin(); !genreIter.Done(); genreIter.Next())
{
d.TraceDebug("> Genre [%d]:\n", genreCount);
cFCOReportSpecIter specIter(genreIter);
int ct = 0;
for (specIter.SeekBegin(); !specIter.Done(); specIter.Next(), ct++)
{
d.TraceDebug(">>> Spec [%d]:\n", ct);
TEST(specIter.GetSpec());
specIter.GetSpec()->TraceContents();
specIter.GetErrorQueue()->TraceContents();
d.TraceDebug(">>> Added Files:\n");
specIter.GetAddedSet()->TraceContents();
d.TraceDebug(">>> Removed Files:\n");
specIter.GetRemovedSet()->TraceContents();
// trace out changed files
cFCOReportChangeIter changeIter(specIter);
int changeCtr = 0;
for (changeIter.SeekBegin(); !changeIter.Done(); changeIter.Next(), changeCtr++)
{
d.TraceDebug(">>>>> Changed fco [%d]\n", changeCtr);
d.TraceDebug(">>>>> Old FCO:\n");
changeIter.GetOld()->TraceContents();
d.TraceDebug(">>>>> New FCO:\n");
changeIter.GetNew()->TraceContents();
changeIter.GetChangeVector().TraceContents();
}
}
}
}
#endif
/*
//
// basic functionality
//
void DisplayReportAndHaveUserUpdateIt( const TSTRING& edName, ReportingLevel level = FULL_REPORT ); //throw (eFSServices, eTextReportViewer, eInternal);
// outputs the given report to a temp file, opens an editor, has
// the user view changes to the database, and, by selecting FCO entries,
// chooses which changes to write to the database. Unchecked entries
// are removed from the report
// edName is the name of the editor to use to update the report
virtual void PrintTextReport( const TSTRING& strFilename, ReportingLevel level = FULL_REPORT ); //throw (eTextReportViewer);
// if strFilename is "-", will print to TCOUT
virtual void PrintTextReport( TOSTREAM& ostr, ReportingLevel level = FULL_REPORT ); //throw (eTextReportViewer);
// prints the report to the specified ostream
*/
void TestTextReportViewer()
{
skip("TestTextReportViewer needs to be cleaned up & fixed, currently disabled");
#if 0
cFCOReport report;
cFCOReportGenreIter genreIter(report);
cFCOReportSpecIter specIter(genreIter);
cDebug d("TestFCOReport");
cFCOName fcoNameSpec1;
cFCOName fcoNameSpec2;
TSTRING fcoNameTempFile;
try
{
iFSServices* pFSServices = iFSServices::GetInstance();
TEST( pFSServices );
TSTRING fcoNameTempDir;
pFSServices->GetTempDirName( fcoNameTempDir );
fcoNameSpec1 = fcoNameTempDir += _T("SPEC1/");
fcoNameSpec2 = fcoNameTempDir += _T("SPEC2/");
tw_mkdir( fcoNameTempDir.c_str(), 0777 );
tw_mkdir( fcoNameSpec1.AsString().c_str(), 0777 );
tw_mkdir( fcoNameSpec2.AsString().c_str(), 0777 );
fcoNameTempFile = fcoNameTempDir += _T("twtempXXXXXX");
pFSServices->MakeTempFilename( fcoNameTempFile );
}
catch(const eFSServices& /* e */)
{
// TODO: properly handle error
TEST( false );
}
// need two prop calcs because.....
// if cFSPropCalc::VisitFSObject succeeds, cFSPropCalc stores the FCO in
// an internal set (why, I don't know), and the cFCOSet TESTs that the same
// FCO isn't inserted more than once. But since we visit changed FCOs twice
// in this test routine, we need two calcs. Make sense? Oh, well.
cFSPropCalc* pPropCalc = new cFSPropCalc;
cFSPropCalc* pPropCalc2 = new cFSPropCalc;
cFCOSpecStopPointSet *pStopPts = new cFCOSpecStopPointSet;
cFCOSpecImpl* pSpec = new cFCOSpecImpl( fcoNameSpec1.AsString(), NULL, pStopPts);
cFCOSpecAttr* pAttr = new cFCOSpecAttr;
cFCOPropVector v;
for( int i = 0; i < 32; i++ )
v.AddItem( i );
pPropCalc->SetPropVector(v);
pPropCalc2->SetPropVector(v);
TSTRING fcoNameMakeMe;
fcoNameMakeMe = fcoNameSpec1.AsString() + _T("/added_fileXXXXXX");
MakeFile( fcoNameMakeMe );
cFSObject* addedFCO = new cFSObject( cFCOName(fcoNameMakeMe));
pPropCalc->VisitFSObject( *addedFCO );
// MakeTempFile can't handle strings with escaped quotes, so we'll have to do this ourselves
fcoNameMakeMe = fcoNameSpec1.AsString() + _T("/\"quoted\\_and_backslashed_file1\"");
//TOFSTREAM file1( fcoNameMakeMe.c_str() );
//TEST( file1 );
//file1.close();
cFSObject* addedFCO2 = new cFSObject( cFCOName(fcoNameMakeMe) );
//pPropCalc->VisitFSObject( *addedFCO2 );
// MakeTempFile can't handle strings with escaped quotes, so we'll have to do this ourselves
fcoNameMakeMe = fcoNameSpec1.AsString() + _T("/quoted_file\"2\"XXXXXX");
//TOFSTREAM file2( fcoNameMakeMe.c_str() );
//TEST( file2 );
//file2.close();
cFSObject* addedFCO3 = new cFSObject( cFCOName(fcoNameMakeMe) );
//pPropCalc->VisitFSObject( *addedFCO3 );
fcoNameMakeMe = fcoNameSpec1.AsString() + _T("/removed_fileXXXXXX");
MakeFile( fcoNameMakeMe );
cFSObject* removedFCO = new cFSObject( cFCOName(fcoNameMakeMe) );
pPropCalc->VisitFSObject( *removedFCO );
fcoNameMakeMe = fcoNameSpec1.AsString() + _T("/removed_fileXXXXXX");
MakeFile( fcoNameMakeMe );
cFSObject* removedFCO2 = new cFSObject( cFCOName(fcoNameMakeMe) );
pPropCalc->VisitFSObject( *removedFCO2 );
pSpec->SetStartPoint( fcoNameSpec1 );
pAttr->SetName( fcoNameSpec1.AsString() );
pAttr->SetSeverity(53);
pStopPts->Add( cFCOName( fcoNameSpec1.AsString() + _T("/End1")) );
report.AddSpec(0x00020001, pSpec, pAttr, &specIter); // TODO:bam - use cFS::Genre
pAttr->Release();
TEST(specIter.GetAddedSet());
TEST(specIter.GetRemovedSet());
specIter.GetAddedSet()->Insert(addedFCO);
specIter.GetAddedSet()->Insert(addedFCO2);
specIter.GetAddedSet()->Insert(addedFCO3);
specIter.GetRemovedSet()->Insert(removedFCO);
specIter.GetRemovedSet()->Insert(removedFCO2);
// make changed FCO1
cFCOPropVector changedPropVector1;
fcoNameMakeMe = fcoNameSpec1.AsString() + _T("/changed_fileXXXXXX");
MakeFile( fcoNameMakeMe );
cFSObject* oldChangedFCO = new cFSObject( cFCOName(fcoNameMakeMe) );
pPropCalc->VisitFSObject( *oldChangedFCO );
(static_cast<cFSPropSet*> (oldChangedFCO->GetPropSet()))->SetSize(123);
//(static_cast<cFSPropSet*> (oldChangedFCO->GetPropSet()))->SetUID(_T("old"));
cFSObject* newChangedFCO = new cFSObject( cFCOName(fcoNameMakeMe) );
pPropCalc2->VisitFSObject( *newChangedFCO );
(static_cast<cFSPropSet*> (newChangedFCO->GetPropSet()))->SetSize(666);
//(static_cast<cFSPropSet*> (newChangedFCO->GetPropSet()))->SetUID(_T("new"));
changedPropVector1.AddItem(cFSPropSet::PROP_SIZE);
changedPropVector1.AddItem(cFSPropSet::PROP_UID);
report.AddChangedFCO(specIter, oldChangedFCO, newChangedFCO, changedPropVector1);
// make changed FCO2
cFCOPropVector changedPropVector2;
fcoNameMakeMe = fcoNameSpec1.AsString() + _T("/changed_fileXXXXXX");
MakeFile( fcoNameMakeMe );
cFSObject* oldChangedFCO2 = new cFSObject( cFCOName(fcoNameMakeMe) );
pPropCalc->VisitFSObject( *oldChangedFCO2 );
//(static_cast<cFSPropSet*> (oldChangedFCO2->GetPropSet()))->SetGSID( _T("S-1-1-0") );
cFSObject* newChangedFCO2 = new cFSObject( cFCOName(fcoNameMakeMe) );
pPropCalc2->VisitFSObject( *newChangedFCO2 );
//(static_cast<cFSPropSet*> (newChangedFCO2->GetPropSet()))->SetGSID( _T("S-1-1-1") );
//changedPropVector2.AddItem(cFSPropSet::PROP_GSID);
report.AddChangedFCO(specIter, oldChangedFCO2, newChangedFCO2, changedPropVector2);
// add some errors
// report.GetErrorQueue()->AddError(eError(_T("this is a general error")));
// report.GetErrorQueue()->AddError(eError(_T("this too is a general error")));
cFCOSpecStopPointSet *pStopPts2 = new cFCOSpecStopPointSet;
cFCOSpecImpl* pSpec2 = new cFCOSpecImpl( fcoNameSpec2.AsString(), NULL, pStopPts2);
cFCOSpecAttr* pAttr2 = new cFCOSpecAttr;
fcoNameMakeMe = fcoNameSpec2.AsString() + _T("/added_fileXXXXXX");
MakeFile( fcoNameMakeMe );
cFSObject* addedFCO5 = new cFSObject( cFCOName(fcoNameMakeMe) );
pPropCalc->VisitFSObject( *addedFCO5 );
fcoNameMakeMe = fcoNameSpec2.AsString() + _T("/removed_fileXXXXXX");
MakeFile( fcoNameMakeMe );
cFSObject* removedFCO5 = new cFSObject( cFCOName(fcoNameMakeMe) );
pPropCalc->VisitFSObject( *removedFCO5 );
pSpec2->SetStartPoint( fcoNameSpec2 );
pAttr2->SetName( fcoNameSpec2.AsString() );
pAttr2->SetSeverity(64);
pStopPts2->Add( cFCOName( fcoNameSpec2.AsString() + _T("/End2") ) );
report.AddSpec(0x00020001, pSpec2, pAttr2, &specIter); // TODO:bam -- use cFS::Genre
pAttr2->Release();
specIter.GetAddedSet()->Insert(addedFCO5);
specIter.GetRemovedSet()->Insert(removedFCO5);
// make changed FCO3
cFCOPropVector changedPropVector3;
fcoNameMakeMe = fcoNameSpec2.AsString() + _T("/changed_fileXXXXXX");
MakeFile( fcoNameMakeMe );
cFSObject* oldChangedFCO3 = new cFSObject( cFCOName(fcoNameMakeMe) );
pPropCalc->VisitFSObject( *oldChangedFCO3 );
(static_cast<cFSPropSet*> (oldChangedFCO3->GetPropSet()))->SetBlockSize(313222);
cFSObject* newChangedFCO3 = new cFSObject( cFCOName(fcoNameMakeMe) );
pPropCalc2->VisitFSObject( *newChangedFCO3 );
(static_cast<cFSPropSet*> (newChangedFCO3->GetPropSet()))->SetBlockSize(22213145);
changedPropVector3.AddItem(cFSPropSet::PROP_BLOCK_SIZE);
report.AddChangedFCO(specIter, oldChangedFCO3, newChangedFCO3, changedPropVector3);
// make changed FCO4
cFCOPropVector changedPropVector4;
fcoNameMakeMe = fcoNameSpec2.AsString() + _T("/changed_fileXXXXXX");
MakeFile( fcoNameMakeMe );
cFSObject* oldChangedFCO4 = new cFSObject( cFCOName(fcoNameMakeMe) );
pPropCalc->VisitFSObject( *oldChangedFCO4 );
(static_cast<cFSPropSet*> (oldChangedFCO4->GetPropSet()))->SetSize(9104498);
(static_cast<cFSPropSet*> (oldChangedFCO4->GetPropSet()))->SetMode( S_IREAD | S_IWRITE );
cFSObject* newChangedFCO4 = new cFSObject( cFCOName(fcoNameMakeMe) );
pPropCalc2->VisitFSObject( *newChangedFCO4 );
(static_cast<cFSPropSet*> (newChangedFCO4->GetPropSet()))->SetSize(66);
(static_cast<cFSPropSet*> (newChangedFCO4->GetPropSet()))->SetMode( S_IREAD | S_IWRITE | S_IEXEC );
changedPropVector4.AddItem(cFSPropSet::PROP_SIZE);
changedPropVector4.AddItem(cFSPropSet::PROP_MODE);
report.AddChangedFCO(specIter, oldChangedFCO4, newChangedFCO4, changedPropVector4);
specIter.SeekBegin();
specIter.Next();
//specIter.GetErrorQueue()->AddError(2, "this is an \"/etc2\" spec error",NULL);
d.TraceDebug(_T("\n======================================================\nStart PrintTextReport...\n======================================================\n\n\n"));
TSTRING tstrEmpty( _T("") );
cFCOReportHeader rhi;
cFCOReportUtil::FinalizeReport( report );
cTextReportViewer trv(rhi, report);
trv.DisplayReportAndHaveUserUpdateIt( _T("") );
// test writing of USID
cFileArchive outFile;
outFile.OpenReadWrite(_T("tmp.twr"));
cSerializerImpl outSer(outFile, cSerializerImpl::S_WRITE);
//TraceReport(report, d);
outSer.Init();
outSer.WriteObject(&report);
outSer.Finit();
outFile.Close();
cFileArchive inFile;
inFile.OpenRead(_T("tmp.twr"));
cSerializerImpl inSer(inFile, cSerializerImpl::S_READ);
cFCOReport inReport;
inSer.Init();
inSer.ReadObject(&inReport);
inSer.Finit();
d.TraceDebug("Read in serialized report:\n");
//TraceReport(inReport, d);
trv.PrintTextReport(TSTRING( TwTestPath("test2.txt" ) ) );
//TODO: this does not work any more
//trv.LaunchEditorOnFile( TSTRING( TEMP_DIR _T("/test2.txt") ), _T("") );
// look at results
trv.PrintTextReport(fcoNameTempFile );
//TODO: this does not work any more
//cTextReportViewer::LaunchEditorOnFile( fcoNameTempFile, _T("") );
iFSServices* pFSServices = iFSServices::GetInstance();
TEST( pFSServices );
pFSServices->FileDelete( addedFCO->GetName().AsString() );
pFSServices->FileDelete( addedFCO2->GetName().AsString() );
pFSServices->FileDelete( addedFCO3->GetName().AsString() );
pFSServices->FileDelete( addedFCO5->GetName().AsString() );
pFSServices->FileDelete( removedFCO->GetName().AsString() );
pFSServices->FileDelete( removedFCO2->GetName().AsString() );
pFSServices->FileDelete( removedFCO5->GetName().AsString() );
pFSServices->FileDelete( newChangedFCO->GetName().AsString() );
pFSServices->FileDelete( newChangedFCO2->GetName().AsString() );
pFSServices->FileDelete( newChangedFCO3->GetName().AsString() );
pFSServices->FileDelete( newChangedFCO4->GetName().AsString() );
pFSServices->FileDelete( fcoNameTempFile );
// don't remove TEMP_DIR since other people may be using it
rmdir( fcoNameSpec1.AsString().c_str() );
rmdir( fcoNameSpec2.AsString().c_str() );
pSpec->Release();
pSpec2->Release();
addedFCO->Release();
addedFCO2->Release();
addedFCO3->Release();
addedFCO5->Release();
removedFCO->Release();
removedFCO2->Release();
removedFCO5->Release();
delete pPropCalc;
delete pPropCalc2;
oldChangedFCO->Release();
newChangedFCO->Release();
oldChangedFCO2->Release();
newChangedFCO2->Release();
oldChangedFCO3->Release();
newChangedFCO3->Release();
oldChangedFCO4->Release();
newChangedFCO4->Release();
#endif
return;
}
void MakeFile(TSTRING& strNameMakeMe)
{
try
{
iFSServices* pFSServices = iFSServices::GetInstance();
TEST(pFSServices);
pFSServices->MakeTempFilename(strNameMakeMe);
std::string strA;
for (TSTRING::iterator i = strNameMakeMe.begin(); i != strNameMakeMe.end(); ++i)
{
char ach[6];
TEST(MB_CUR_MAX <= 6);
int n = wctomb(ach, *i);
TEST(n != -1);
for (int j = 0; j < n; j++)
strA += ach[j];
}
TOFSTREAM file(strA.c_str());
TEST(file);
file.close();
}
catch (const eFSServices& e)
{
TEST(false);
}
catch (...)
{
TEST(false);
}
}
void MakeDir(const TCHAR* const lpszDirName)
{
TEST(0 == tw_mkdir(lpszDirName, 0777))
}
//#endif //FIXED_TRV_TEST_SUITE
void RegisterSuite_TextReportViewer()
{
RegisterTest("TextReportViewer", "Basic", TestTextReportViewer);
}