예제 #1
0
QString OscapScannerLocal::getOscapProgramAndAdaptArgs(QStringList& args)
{
    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
    return program;
}
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);
}