void OscapScannerLocal::evaluate() { if (mDryRun) { signalCompletion(mCancelRequested); return; } emit infoMessage(QObject::tr("Querying capabilities...")); try { fillInCapabilities(); } catch (std::exception& e) { emit errorMessage(e.what()); return; } if (!checkPrerequisites()) { mCancelRequested = true; signalCompletion(mCancelRequested); return; } // TODO: Error handling! // This is mainly for check-engine-results and oval-results, to ensure // we get a full report, including info from these files. openscap's XSLT // uses info in the check engine results if it can find them. QProcess process(this); emit infoMessage(QObject::tr("Creating temporary files...")); // This is mainly for check-engine-results and oval-results, to ensure // we get a full report, including info from these files. openscap's XSLT // uses info in the check engine results if it can find them. TemporaryDir workingDir; process.setWorkingDirectory(workingDir.getPath()); QStringList args; QTemporaryFile inputARFFile; QTemporaryFile arfFile; arfFile.setAutoRemove(true); setFilenameToTempFile(arfFile); QTemporaryFile reportFile; reportFile.setAutoRemove(true); setFilenameToTempFile(reportFile); QTemporaryFile resultFile; resultFile.setAutoRemove(true); setFilenameToTempFile(resultFile); if (mScannerMode == SM_OFFLINE_REMEDIATION) { inputARFFile.open(); inputARFFile.write(getARFForRemediation()); inputARFFile.close(); args = buildOfflineRemediationArgs(inputARFFile.fileName(), resultFile.fileName(), reportFile.fileName(), arfFile.fileName()); } else { args = buildEvaluationArgs(mSession->getOpenedFilePath(), mSession->hasTailoring() ? mSession->getTailoringFilePath() : QString(), resultFile.fileName(), reportFile.fileName(), arfFile.fileName(), mScannerMode == SM_SCAN_ONLINE_REMEDIATION); } QString program = getOscapProgramAndAdaptArgs(args); emit infoMessage(QObject::tr("Starting the oscap process...")); process.start(program, args); process.waitForStarted(); if (process.state() != QProcess::Running) { emit errorMessage(QObject::tr("Failed to start local scanning process '%1'. Perhaps the executable was not found?").arg(program)); mCancelRequested = true; } unsigned int pollInterval = 100; emit infoMessage(QObject::tr("Processing...")); while (!process.waitForFinished(pollInterval)) { // read everything new readStdOut(process); watchStdErr(process); // pump the event queue, mainly because the user might want to cancel QAbstractEventDispatcher::instance(mScanThread)->processEvents(QEventLoop::AllEvents); if (mCancelRequested) { pollInterval = 1000; emit infoMessage(QObject::tr("Cancellation was requested! Terminating scanning...")); process.kill(); } } if (!mCancelRequested) { if (process.exitCode() == 1) // error happened { watchStdErr(process); // TODO: pass the diagnostics over emit errorMessage(QObject::tr("There was an error during evaluation! Exit code of the 'oscap' process was 1.")); // mark this run as canceled mCancelRequested = true; } else { // read everything left over readStdOut(process); watchStdErr(process); emit infoMessage(QObject::tr("The oscap tool has finished. Reading results...")); resultFile.open(); mResults = resultFile.readAll(); resultFile.close(); reportFile.open(); mReport = reportFile.readAll(); reportFile.close(); arfFile.open(); mARF = arfFile.readAll(); arfFile.close(); emit infoMessage(QObject::tr("Processing has been finished!")); } } else { emit infoMessage(QObject::tr("Scanning cancelled!")); } signalCompletion(mCancelRequested); }
void OscapScannerLocal::evaluate() { if (mDryRun) { signalCompletion(mCancelRequested); return; } emit infoMessage(QObject::tr("Querying capabilities...")); { SyncProcess proc(this); proc.setCommand(SCAP_WORKBENCH_LOCAL_OSCAP_PATH); proc.setArguments(QStringList("--v")); proc.run(); if (proc.getExitCode() != 0) { emit errorMessage( QObject::tr("Failed to query capabilities of oscap on local machine.\n" "Diagnostic info:\n%1").arg(proc.getDiagnosticInfo()) ); mCancelRequested = true; signalCompletion(mCancelRequested); return; } mCapabilities.parse(proc.getStdOutContents()); } if (!checkPrerequisites()) { mCancelRequested = true; signalCompletion(mCancelRequested); return; } // TODO: Error handling! emit infoMessage(QObject::tr("Creating temporary files...")); QTemporaryFile resultFile; resultFile.setAutoRemove(true); // the following forces Qt to give us the filename resultFile.open(); resultFile.close(); QTemporaryFile reportFile; reportFile.setAutoRemove(true); reportFile.open(); reportFile.close(); QTemporaryFile arfFile; arfFile.setAutoRemove(true); arfFile.open(); arfFile.close(); // This is mainly for check-engine-results and oval-results, to ensure // we get a full report, including info from these files. openscap's XSLT // uses info in the check engine results if it can find them. TemporaryDir workingDir; emit infoMessage(QObject::tr("Starting the oscap process...")); QProcess process(this); process.setWorkingDirectory(workingDir.getPath()); QStringList args; QTemporaryFile inputARFFile; inputARFFile.setAutoRemove(true); if (mScannerMode == SM_OFFLINE_REMEDIATION) { inputARFFile.open(); inputARFFile.write(getARFForRemediation()); inputARFFile.close(); args = buildOfflineRemediationArgs(inputARFFile.fileName(), resultFile.fileName(), reportFile.fileName(), arfFile.fileName()); } else { args = buildEvaluationArgs(mSession->getOpenedFilePath(), mSession->hasTailoring() ? mSession->getTailoringFilePath() : QString(), resultFile.fileName(), reportFile.fileName(), arfFile.fileName(), mScannerMode == SM_SCAN_ONLINE_REMEDIATION); } QString program = ""; #ifdef SCAP_WORKBENCH_LOCAL_NICE_FOUND args.prepend(getPkexecOscapPath()); args.prepend(QString::number(SCAP_WORKBENCH_LOCAL_OSCAP_NICENESS)); args.prepend("-n"); program = SCAP_WORKBENCH_LOCAL_NICE_PATH; #else program = getPkexecOscapPath(); #endif process.start(program, args); process.waitForStarted(); if (process.state() != QProcess::Running) { emit errorMessage(QObject::tr("Failed to start local scanning process '%1'. Perhaps the executable was not found?").arg(program)); mCancelRequested = true; } const unsigned int pollInterval = 100; emit infoMessage(QObject::tr("Processing...")); while (!process.waitForFinished(pollInterval)) { // read everything new readStdOut(process); watchStdErr(process); // pump the event queue, mainly because the user might want to cancel QAbstractEventDispatcher::instance(mScanThread)->processEvents(QEventLoop::AllEvents); if (mCancelRequested) { emit infoMessage(QObject::tr("Cancellation was requested! Terminating scanning...")); process.kill(); process.waitForFinished(1000); break; } } if (!mCancelRequested) { if (process.exitCode() == 1) // error happened { watchStdErr(process); // TODO: pass the diagnostics over emit errorMessage(QObject::tr("There was an error during evaluation! Exit code of the 'oscap' process was 1.")); // mark this run as canceled mCancelRequested = true; } else { // read everything left over readStdOut(process); watchStdErr(process); emit infoMessage(QObject::tr("The oscap tool has finished. Reading results...")); resultFile.open(); mResults = resultFile.readAll(); resultFile.close(); reportFile.open(); mReport = reportFile.readAll(); reportFile.close(); arfFile.open(); mARF = arfFile.readAll(); arfFile.close(); emit infoMessage(QObject::tr("Processing has been finished!")); } } signalCompletion(mCancelRequested); }