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

View File

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

View File

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

View File

@ -314,7 +314,8 @@ static void FillOutCmdLineInfo(cTWPrintModeCommon* pModeInfo, const cCmdLinePars
class cTWPrintReportMode_i : public cTWPrintModeCommon class cTWPrintReportMode_i : public cTWPrintModeCommon
{ {
public: public:
TSTRING mReportFile; TSTRING mReportFile;
std::set<TSTRING> mFilesToCheck;
// ctor can set up some default values // ctor can set up some default values
cTWPrintReportMode_i() : cTWPrintModeCommon() cTWPrintReportMode_i() : cTWPrintModeCommon()
@ -398,6 +399,9 @@ void cTWPrintReportMode::InitCmdLineParser(cCmdLineParser& parser)
// multiple levels of reporting // multiple levels of reporting
parser.AddArg( parser.AddArg(
cTWPrintCmdLine::REPORTLEVEL, TSTRING(_T("t")), TSTRING(_T("report-level")), cCmdLineParser::PARAM_ONE); 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); errStr += iter.ParamAt(0);
throw eTWPrintInvalidReportLevel(errStr); 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. //done with report-level stuff.
break; break;
@ -515,6 +529,11 @@ int cTWPrintReportMode::Execute(cErrorQueue* pQueue)
// print it // print it
cTextReportViewer trv(reportHeader, report); cTextReportViewer trv(reportHeader, report);
if (!mpData->mFilesToCheck.empty())
{
trv.SetObjects(mpData->mFilesToCheck);
}
trv.PrintTextReport(_T("-"), mpData->mReportLevel); trv.PrintTextReport(_T("-"), mpData->mReportLevel);
} }
catch (eError& e) catch (eError& e)
@ -545,7 +564,7 @@ public:
cTextDBViewer::DbVerbosity mDbVerbosity; cTextDBViewer::DbVerbosity mDbVerbosity;
// ctor can set up some default values // 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("Usage:\n")
_T("\n") _T("\n")
_T("Print Database: twprint [-m d|--print-dbfile] [options] [object1 [object2...]]\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("Type 'twprint [mode] --help' OR\n")
_T("'twprint --help mode [mode...]' OR\n") _T("'twprint --help mode [mode...]' OR\n")
_T("'twprint --help all' for extended help\n") _T("'twprint --help all' for extended help\n")
@ -82,6 +82,7 @@ TSS_BeginStringtable(cTWPrint)
_T(" -r report --twrfile report\n") _T(" -r report --twrfile report\n")
_T(" -L localkey --local-keyfile localkey\n") _T(" -L localkey --local-keyfile localkey\n")
_T(" -t { 0|1|2|3|4 } --report-level { 0|1|2|3|4 }\n") _T(" -t { 0|1|2|3|4 } --report-level { 0|1|2|3|4 }\n")
_T("[object1 [object2 ...]]\n")
_T("\n") _T("\n")
_T("The -v and -s options are mutually exclusive.\n") _T("The -v and -s options are mutually exclusive.\n")
_T("\n")), _T("\n")),