diff --git a/man/man8/twprint.8 b/man/man8/twprint.8 index 9a460fd..c7277d6 100644 --- a/man/man8/twprint.8 +++ b/man/man8/twprint.8 @@ -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 diff --git a/src/tw/textreportviewer.cpp b/src/tw/textreportviewer.cpp index f2cced4..2d24b5b 100644 --- a/src/tw/textreportviewer.cpp +++ b/src/tw/textreportviewer.cpp @@ -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 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()); + // if we're updating, save a list of FCO names + if (mfUpdate && pFCONameList) + pFCONameList->insert(fco->GetName()); + } } (*mpOut) << endl; } @@ -1528,11 +1533,15 @@ void cTextReportViewer::OutputRemovedSummary(const cFCOReportSpecIter& ri, FCOLi const cIterProxy 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()); + // if we're updating, save a list of FCO names + if (mfUpdate && pFCONameList) + 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()); + // if we're updating, save a list of FCO names + if (mfUpdate && pFCONameList) + pFCONameList->insert(fco->GetName()); + } } (*mpOut) << endl; @@ -1570,14 +1583,18 @@ void cTextReportViewer::OutputAddedDetails(const cFCOReportSpecIter& ri) ASSERT(pSetIterAdded != 0); for (pSetIterAdded->SeekBegin(); !pSetIterAdded->Done(); pSetIterAdded->Next()) { - (*mpOut) << TSS_GetString(cTW, tw::STR_ADDED_FILE_NAME) << _T(" ") - << mpCurNT->ToStringDisplay(pSetIterAdded->FCO()->GetName()).c_str() << endl; - - if (FULL_REPORT == mReportingLevel) + const iFCO* fco = pSetIterAdded->FCO(); + if (!IgnoreThisFCO(fco)) { - (*mpOut) << endl; - DisplayChangedProps(NULL, pSetIterAdded->FCO(), NULL); - (*mpOut) << endl << endl; + (*mpOut) << TSS_GetString(cTW, tw::STR_ADDED_FILE_NAME) << _T(" ") + << mpCurNT->ToStringDisplay(fco->GetName()).c_str() << 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); for (pSetIterRemoved->SeekBegin(); !pSetIterRemoved->Done(); pSetIterRemoved->Next()) { - (*mpOut) << TSS_GetString(cTW, tw::STR_REMOVED_FILE_NAME) << _T(" ") - << mpCurNT->ToStringDisplay(pSetIterRemoved->FCO()->GetName()).c_str() << endl; - - if (FULL_REPORT == mReportingLevel) + const iFCO* fco = pSetIterRemoved->FCO(); + if (!IgnoreThisFCO(fco)) { - (*mpOut) << endl; - DisplayChangedProps(pSetIterRemoved->FCO(), NULL, NULL); - (*mpOut) << endl << endl; + (*mpOut) << TSS_GetString(cTW, tw::STR_REMOVED_FILE_NAME) << _T(" ") + << mpCurNT->ToStringDisplay(fco->GetName()).c_str() << endl; + + if (FULL_REPORT == mReportingLevel) + { + (*mpOut) << endl; + DisplayChangedProps(fco, NULL, NULL); + (*mpOut) << endl << endl; + } } } (*mpOut) << endl; @@ -1620,42 +1641,70 @@ void cTextReportViewer::OutputChangedDetails(const cFCOReportSpecIter& ri) cFCOReportChangeIter changedIter(ri); for (changedIter.SeekBegin(); !changedIter.Done(); changedIter.Next()) { - (*mpOut) << TSS_GetString(cTW, tw::STR_CHANGED_FILE_NAME) << _T(" ") - << mpCurNT->ToStringDisplay(changedIter.GetOld()->GetName()).c_str() << endl - << endl; - DisplayChangedProps(changedIter.GetOld(), changedIter.GetNew(), &changedIter.GetChangeVector()); - (*mpOut) << endl << endl; + const iFCO* fco = changedIter.GetOld(); + if (!IgnoreThisFCO(fco)) + { + (*mpOut) << TSS_GetString(cTW, tw::STR_CHANGED_FILE_NAME) << _T(" ") + << mpCurNT->ToStringDisplay(fco->GetName()).c_str() << endl + << endl; + DisplayChangedProps(fco, changedIter.GetNew(), &changedIter.GetChangeVector()); + (*mpOut) << endl << endl; + } } (*mpOut) << endl; } } +void cTextReportViewer::SetObjects(const std::set& 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,28 +1940,37 @@ 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 pSetIterAdded = ri.GetAddedSet()->GetIter(); for (pSetIterAdded->SeekBegin(); !pSetIterAdded->Done(); pSetIterAdded->Next()) { - (*mpOut) << TSS_GetString(cTW, tw::STR_ADDED) << _T(":\t"); - (*mpOut) << mpCurNT->ToStringDisplay(pSetIterAdded->FCO()->GetName(), true) << endl; + 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 pSetIterRemoved = ri.GetRemovedSet()->GetIter(); for (pSetIterRemoved->SeekBegin(); !pSetIterRemoved->Done(); pSetIterRemoved->Next()) { - (*mpOut) << TSS_GetString(cTW, tw::STR_REMOVED) << _T(":\t"); - (*mpOut) << mpCurNT->ToStringDisplay(pSetIterRemoved->FCO()->GetName(), true) << endl; + 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()) { - (*mpOut) << TSS_GetString(cTW, tw::STR_CHANGED) << _T(":\t"); - (*mpOut) << mpCurNT->ToStringDisplay(changedIter.GetNew()->GetName(), true) << endl; + if (!IgnoreThisFCO(changedIter.GetNew())) + { + (*mpOut) << TSS_GetString(cTW, tw::STR_CHANGED) << _T(":\t"); + (*mpOut) << mpCurNT->ToStringDisplay(changedIter.GetNew()->GetName(), true) << endl; + } } } } diff --git a/src/tw/textreportviewer.h b/src/tw/textreportviewer.h index 0387751..5c94614 100644 --- a/src/tw/textreportviewer.h +++ b/src/tw/textreportviewer.h @@ -120,6 +120,8 @@ public: int GetMaxSeverityViolated(); int GetNumberViolations(); + void SetObjects(const std::set& 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 mObjects; }; diff --git a/src/twprint/twprintcmdline.cpp b/src/twprint/twprintcmdline.cpp index 62f6b0f..50762fc 100644 --- a/src/twprint/twprintcmdline.cpp +++ b/src/twprint/twprintcmdline.cpp @@ -314,7 +314,8 @@ static void FillOutCmdLineInfo(cTWPrintModeCommon* pModeInfo, const cCmdLinePars class cTWPrintReportMode_i : public cTWPrintModeCommon { public: - TSTRING mReportFile; + TSTRING mReportFile; + std::set 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) { } }; diff --git a/src/twprint/twprintstrings.cpp b/src/twprint/twprintstrings.cpp index 097c9c7..05d0a73 100644 --- a/src/twprint/twprintstrings.cpp +++ b/src/twprint/twprintstrings.cpp @@ -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")),