Add ability to print report by object list, like we already do w/ print-db mode

This commit is contained in:
Brian Cox 2018-03-29 23:40:34 -07:00
parent 4d3c188cac
commit 6d82f3b6b1
5 changed files with 133 additions and 41 deletions

View File

@ -10,6 +10,9 @@ twprint \- Tripwire database and report printer
.B twprint
.RB "{ " "-m r" " | " "--print-report" " } "
.RI "[ " options... " ]"
.if n .br
.if n .ti +.5i
.RI " [ " "object1" " [ " "object2..." " ]]"
.br
.B twprint
.RB "{ " "-m d" " | " "--print-dbfile" " } "
@ -59,6 +62,7 @@ lbw(1.2i) lb.
-L \fIlocalkey\fP --local-keyfile \fIlocalkey\fP
-t \fR{ 0|1|2|3|4 }\fP --report-level \fR{ 0|1|2|3|4 }\fP
.TE
.RI "[ " "object1" " [ " "object2..." " ]]"
.RE
.TP
.BR "\(hym r" ", " --print-report
@ -87,6 +91,11 @@ with reports which are signed.
Specifies the detail level of the printed report, overriding the
\f(CWREPORTLEVEL\fP variable in the configuration
file. \fIlevel\fR must be a number from 0\ to\ 4.
.TP
.RI "[ " "object1" " [ " "object2..." " ]]"
List of filesystem objects in the report to print. If no
objects are specified, every object in the report will
be printed.
.\" *****************************************
.SS Database printing mode:
.RS 0.4i

View File

@ -157,6 +157,7 @@ int cTextReportViewer::Init(const cFCOReportHeader& h, cFCOReport& r)
mfGotNumbers = false;
mCurrentChar[0] = '\0';
mCurrentCharSize = 0;
mFilterFCOs = false;
return 0;
}
@ -1508,11 +1509,15 @@ void cTextReportViewer::OutputAddedSummary(const cFCOReportSpecIter& ri, FCOList
const cIterProxy<iFCOIter> pSetIterAdded = ri.GetAddedSet()->GetIter();
for (pSetIterAdded->SeekBegin(); !pSetIterAdded->Done(); pSetIterAdded->Next())
{
PrintBallotLine(*pSetIterAdded->FCO());
const iFCO* fco = pSetIterAdded->FCO();
if (!IgnoreThisFCO(fco))
{
PrintBallotLine(*fco);
// if we're updating, save a list of FCO names
if (mfUpdate && pFCONameList)
pFCONameList->insert(pSetIterAdded->FCO()->GetName());
pFCONameList->insert(fco->GetName());
}
}
(*mpOut) << endl;
}
@ -1528,11 +1533,15 @@ void cTextReportViewer::OutputRemovedSummary(const cFCOReportSpecIter& ri, FCOLi
const cIterProxy<iFCOIter> pSetIterRemoved = ri.GetRemovedSet()->GetIter();
for (pSetIterRemoved->SeekBegin(); !pSetIterRemoved->Done(); pSetIterRemoved->Next())
{
PrintBallotLine(*pSetIterRemoved->FCO());
const iFCO* fco = pSetIterRemoved->FCO();
if (!IgnoreThisFCO(fco))
{
PrintBallotLine(*fco);
// if we're updating, save a list of FCO names
if (mfUpdate && pFCONameList)
pFCONameList->insert(pSetIterRemoved->FCO()->GetName());
pFCONameList->insert(fco->GetName());
}
}
(*mpOut) << endl;
}
@ -1548,11 +1557,15 @@ void cTextReportViewer::OutputChangedSummary(const cFCOReportSpecIter& ri, FCOLi
cFCOReportChangeIter changedIter(ri);
for (changedIter.SeekBegin(); !changedIter.Done(); changedIter.Next())
{
PrintBallotLine(*changedIter.GetNew());
const iFCO* fco = changedIter.GetNew();
if (!IgnoreThisFCO(fco))
{
PrintBallotLine(*fco);
// if we're updating, save a list of FCO names
if (mfUpdate && pFCONameList)
pFCONameList->insert(changedIter.GetNew()->GetName());
pFCONameList->insert(fco->GetName());
}
}
(*mpOut) << endl;
@ -1569,17 +1582,21 @@ void cTextReportViewer::OutputAddedDetails(const cFCOReportSpecIter& ri)
const cIterProxy<iFCOIter> pSetIterAdded = ri.GetAddedSet()->GetIter();
ASSERT(pSetIterAdded != 0);
for (pSetIterAdded->SeekBegin(); !pSetIterAdded->Done(); pSetIterAdded->Next())
{
const iFCO* fco = pSetIterAdded->FCO();
if (!IgnoreThisFCO(fco))
{
(*mpOut) << TSS_GetString(cTW, tw::STR_ADDED_FILE_NAME) << _T(" ")
<< mpCurNT->ToStringDisplay(pSetIterAdded->FCO()->GetName()).c_str() << endl;
<< mpCurNT->ToStringDisplay(fco->GetName()).c_str() << endl;
if (FULL_REPORT == mReportingLevel)
{
(*mpOut) << endl;
DisplayChangedProps(NULL, pSetIterAdded->FCO(), NULL);
DisplayChangedProps(NULL, fco, NULL);
(*mpOut) << endl << endl;
}
}
}
(*mpOut) << endl;
}
@ -1595,17 +1612,21 @@ void cTextReportViewer::OutputRemovedDetails(const cFCOReportSpecIter& ri)
const cIterProxy<iFCOIter> pSetIterRemoved = ri.GetRemovedSet()->GetIter();
ASSERT(pSetIterRemoved != 0);
for (pSetIterRemoved->SeekBegin(); !pSetIterRemoved->Done(); pSetIterRemoved->Next())
{
const iFCO* fco = pSetIterRemoved->FCO();
if (!IgnoreThisFCO(fco))
{
(*mpOut) << TSS_GetString(cTW, tw::STR_REMOVED_FILE_NAME) << _T(" ")
<< mpCurNT->ToStringDisplay(pSetIterRemoved->FCO()->GetName()).c_str() << endl;
<< mpCurNT->ToStringDisplay(fco->GetName()).c_str() << endl;
if (FULL_REPORT == mReportingLevel)
{
(*mpOut) << endl;
DisplayChangedProps(pSetIterRemoved->FCO(), NULL, NULL);
DisplayChangedProps(fco, NULL, NULL);
(*mpOut) << endl << endl;
}
}
}
(*mpOut) << endl;
}
}
@ -1619,43 +1640,71 @@ void cTextReportViewer::OutputChangedDetails(const cFCOReportSpecIter& ri)
// iterate over all changed fcos
cFCOReportChangeIter changedIter(ri);
for (changedIter.SeekBegin(); !changedIter.Done(); changedIter.Next())
{
const iFCO* fco = changedIter.GetOld();
if (!IgnoreThisFCO(fco))
{
(*mpOut) << TSS_GetString(cTW, tw::STR_CHANGED_FILE_NAME) << _T(" ")
<< mpCurNT->ToStringDisplay(changedIter.GetOld()->GetName()).c_str() << endl
<< mpCurNT->ToStringDisplay(fco->GetName()).c_str() << endl
<< endl;
DisplayChangedProps(changedIter.GetOld(), changedIter.GetNew(), &changedIter.GetChangeVector());
DisplayChangedProps(fco, changedIter.GetNew(), &changedIter.GetChangeVector());
(*mpOut) << endl << endl;
}
}
(*mpOut) << endl;
}
}
void cTextReportViewer::SetObjects(const std::set<std::string>& objects)
{
if (!objects.empty())
{
mObjects = objects;
mFilterFCOs = true;
}
}
// overridables:
// These function allows derived classes to tailor reports
bool cTextReportViewer::IgnoreThisSpec(const cFCOSpecAttr* attr)
{
return false;
}
bool cTextReportViewer::IgnoreThisFCO(const iFCO* fco)
{
if (!mFilterFCOs)
{
return false;
}
return (mObjects.find(fco->GetName().AsString()) == mObjects.end());
}
bool cTextReportViewer::WantOutputReportHeader()
{
return true;
}
bool cTextReportViewer::WantOutputRulesSummary()
{
return true;
}
bool cTextReportViewer::WantOutputSpecHeader()
{
return true;
}
bool cTextReportViewer::WantOutputObjectSummary()
{
return true;
}
bool cTextReportViewer::WantOutputObjectDetails()
{
return true;
}
bool cTextReportViewer::CanUpdate()
{
return true;
@ -1891,25 +1940,33 @@ void cTextReportViewer::OutputParseableReport()
cFCOReportSpecIter ri(genreIter);
for (ri.SeekBegin(); !ri.Done(); ri.Next())
{
// iterate over all removed fcos
// iterate over all added fcos
const cIterProxy<iFCOIter> pSetIterAdded = ri.GetAddedSet()->GetIter();
for (pSetIterAdded->SeekBegin(); !pSetIterAdded->Done(); pSetIterAdded->Next())
{
if (!IgnoreThisFCO(pSetIterAdded->FCO()))
{
(*mpOut) << TSS_GetString(cTW, tw::STR_ADDED) << _T(":\t");
(*mpOut) << mpCurNT->ToStringDisplay(pSetIterAdded->FCO()->GetName(), true) << endl;
}
}
// iterate over all removed fcos
const cIterProxy<iFCOIter> pSetIterRemoved = ri.GetRemovedSet()->GetIter();
for (pSetIterRemoved->SeekBegin(); !pSetIterRemoved->Done(); pSetIterRemoved->Next())
{
if (!IgnoreThisFCO(pSetIterRemoved->FCO()))
{
(*mpOut) << TSS_GetString(cTW, tw::STR_REMOVED) << _T(":\t");
(*mpOut) << mpCurNT->ToStringDisplay(pSetIterRemoved->FCO()->GetName(), true) << endl;
}
}
// iterate over all changed fcos
cFCOReportChangeIter changedIter(ri);
for (changedIter.SeekBegin(); !changedIter.Done(); changedIter.Next())
{
if (!IgnoreThisFCO(changedIter.GetNew()))
{
(*mpOut) << TSS_GetString(cTW, tw::STR_CHANGED) << _T(":\t");
(*mpOut) << mpCurNT->ToStringDisplay(changedIter.GetNew()->GetName(), true) << endl;
@ -1917,6 +1974,7 @@ void cTextReportViewer::OutputParseableReport()
}
}
}
}
char cTextReportViewer::PeekChar()
{

View File

@ -120,6 +120,8 @@ public:
int GetMaxSeverityViolated();
int GetNumberViolations();
void SetObjects(const std::set<std::string>& objects);
protected:
//
// don't let C++ create these functions
@ -246,6 +248,7 @@ protected:
//
virtual bool IgnoreThisSpec(const cFCOSpecAttr* attr);
virtual bool IgnoreThisFCO(const iFCO* fco);
virtual bool WantOutputReportHeader();
virtual bool WantOutputRulesSummary();
virtual bool WantOutputSpecHeader();
@ -274,6 +277,8 @@ protected:
bool mfGotNumbers;
char mCurrentChar[6];
size_t mCurrentCharSize;
bool mFilterFCOs;
std::set<std::string> mObjects;
};

View File

@ -315,6 +315,7 @@ class cTWPrintReportMode_i : public cTWPrintModeCommon
{
public:
TSTRING mReportFile;
std::set<TSTRING> mFilesToCheck;
// ctor can set up some default values
cTWPrintReportMode_i() : cTWPrintModeCommon()
@ -398,6 +399,9 @@ void cTWPrintReportMode::InitCmdLineParser(cCmdLineParser& parser)
// multiple levels of reporting
parser.AddArg(
cTWPrintCmdLine::REPORTLEVEL, TSTRING(_T("t")), TSTRING(_T("report-level")), cCmdLineParser::PARAM_ONE);
// For the variable object list.
parser.AddArg(cTWPrintCmdLine::PARAMS, TSTRING(_T("")), TSTRING(_T("")), cCmdLineParser::PARAM_MANY);
}
///////////////////////////////////////////////////////////////////////////////
@ -446,6 +450,16 @@ bool cTWPrintReportMode::Init(const cConfigFile& cf, const cCmdLineParser& cmdLi
errStr += iter.ParamAt(0);
throw eTWPrintInvalidReportLevel(errStr);
}
break;
}
case cTWPrintCmdLine::PARAMS:
{
// pack all of these onto the files to check list...
mpData->mFilesToCheck.clear();
for (int i = 0; i < iter.NumParams(); i++)
{
mpData->mFilesToCheck.insert(iter.ParamAt(i));
}
}
//done with report-level stuff.
break;
@ -515,6 +529,11 @@ int cTWPrintReportMode::Execute(cErrorQueue* pQueue)
// print it
cTextReportViewer trv(reportHeader, report);
if (!mpData->mFilesToCheck.empty())
{
trv.SetObjects(mpData->mFilesToCheck);
}
trv.PrintTextReport(_T("-"), mpData->mReportLevel);
}
catch (eError& e)
@ -545,7 +564,7 @@ public:
cTextDBViewer::DbVerbosity mDbVerbosity;
// ctor can set up some default values
cTWPrintDBMode_i() : cTWPrintModeCommon(), mVerbosity(cTextDBViewer::VERBOSE)
cTWPrintDBMode_i() : cTWPrintModeCommon(), mDbVerbosity(cTextDBViewer::VERBOSE)
{
}
};

View File

@ -51,7 +51,7 @@ TSS_BeginStringtable(cTWPrint)
_T("Usage:\n")
_T("\n")
_T("Print Database: twprint [-m d|--print-dbfile] [options] [object1 [object2...]]\n")
_T("Print Report: twprint [-m r|--print-report] [options]\n")
_T("Print Report: twprint [-m r|--print-report] [options] [object1 [object2...]]\n")
_T("Type 'twprint [mode] --help' OR\n")
_T("'twprint --help mode [mode...]' OR\n")
_T("'twprint --help all' for extended help\n")
@ -82,6 +82,7 @@ TSS_BeginStringtable(cTWPrint)
_T(" -r report --twrfile report\n")
_T(" -L localkey --local-keyfile localkey\n")
_T(" -t { 0|1|2|3|4 } --report-level { 0|1|2|3|4 }\n")
_T("[object1 [object2 ...]]\n")
_T("\n")
_T("The -v and -s options are mutually exclusive.\n")
_T("\n")),