/*
* Copyright 2010--2014 Red Hat Inc., Durham, North Carolina.
* All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Authors:
* Peter Vrabec <pvrabec@redhat.com>
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
/* Standard header files */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
#include <assert.h>
#include <math.h>
#include <cve_nvd.h>
#include <oscap_source.h>
#include <xccdf_session.h>
#include "oscap-tool.h"
static bool getopt_cve(int argc, char **argv, struct oscap_action *action);
static int app_cve_validate(const struct oscap_action *action);
static int app_cve_find(const struct oscap_action *action);
#define CVE_SUBMODULES_NUM 3 /* See actual CVE_SUBMODULES array
initialization below. */
static struct oscap_module* CVE_SUBMODULES[CVE_SUBMODULES_NUM];
struct oscap_module OSCAP_CVE_MODULE = {
.name = "cve",
.parent = &OSCAP_ROOT_MODULE,
.summary = "Common Vulnerabilities and Exposures",
.submodules = CVE_SUBMODULES
};
static struct oscap_module CVE_VALIDATE_MODULE = {
.name = "validate",
.parent = &OSCAP_CVE_MODULE,
.summary = "Validate CVE NVD feed",
.usage = "nvd-feed.xml",
.help = "Validate CVE NVD feed.",
.opt_parser = getopt_cve,
.func = app_cve_validate
};
static struct oscap_module CVE_FIND_MODULE = {
.name = "find",
.parent = &OSCAP_CVE_MODULE,
.summary = "Find particular CVE in CVE NVD feed",
.usage = "CVE nvd-feed.xml",
.help = "Find particular CVE in CVE NVD feed.",
.opt_parser = getopt_cve,
.func = app_cve_find
};
static struct oscap_module* CVE_SUBMODULES[CVE_SUBMODULES_NUM] = {
&CVE_VALIDATE_MODULE,
&CVE_FIND_MODULE,
NULL
};
static int app_cve_validate(const struct oscap_action *action)
{
int ret;
int result;
struct oscap_source *source = oscap_source_new_from_file(action->cve_action->file);
ret = oscap_source_validate(source, reporter, (void *) action);
oscap_source_free(source);
if (ret==-1) {
result=OSCAP_ERROR;
goto cleanup;
}
else if (ret==1) {
result=OSCAP_FAIL;
}
else
result=OSCAP_OK;
cleanup:
if (oscap_err())
fprintf(stderr, "%s %s\n", OSCAP_ERR_MSG, oscap_err_desc());
free(action->cve_action);
return result;
}
static int app_cve_find(const struct oscap_action *action)
{
struct cve_model *model = NULL;
struct cve_entry *entry = NULL;
struct cve_entry_iterator *entry_it;
const struct cvss_impact *cvss;
struct cvss_metrics *metrics;
float base_score;
char * vector;
int result;
struct cve_product_iterator *prod_it;
struct cve_product *product;
model = cve_model_import(action->cve_action->file);
if(!model) {
result=OSCAP_ERROR;
goto cleanup;
}
entry_it = cve_model_get_entries(model);
while (cve_entry_iterator_has_more(entry_it)) {
entry = cve_entry_iterator_next(entry_it);
if (!strcmp(cve_entry_get_id(entry), action->cve_action->cve))
break;
entry = NULL;
}
cve_entry_iterator_free(entry_it);
if (!entry) {
result=OSCAP_FAIL;
goto cleanup;
}
printf("ID: %s\n", cve_entry_get_id(entry));
/* cvss content */
cvss = cve_entry_get_cvss(entry);
if (cvss) {
metrics = cvss_impact_get_base_metrics(cvss);
base_score = cvss_metrics_get_score(metrics);
vector = cvss_impact_to_vector(cvss);
printf("Base Score: %.1f\n", base_score);
printf("Vector String:\n\t%s\n", vector);
free(vector);
}
/* vulnerable-software-list */
printf("Vulnerable Software:\n");
prod_it=cve_entry_get_products(entry);
while(cve_product_iterator_has_more(prod_it)) {
product = cve_product_iterator_next(prod_it);
printf("\t%s\n", cve_product_get_value(product));
}
cve_product_iterator_free(prod_it);
result=OSCAP_OK;
cleanup:
if (oscap_err())
fprintf(stderr, "%s %s\n", OSCAP_ERR_MSG, oscap_err_desc());
if (model)
cve_model_free(model);
free(action->cve_action);
return result;
}
bool getopt_cve(int argc, char **argv, struct oscap_action *action)
{
if( (action->module == &CVE_VALIDATE_MODULE)) {
if( argc != 4 ) {
oscap_module_usage(action->module, stderr, "Wrong number of parameters.\n");
return false;
}
action->doctype = OSCAP_DOCUMENT_CVE_FEED;
action->cve_action = malloc(sizeof(struct cve_action));
action->cve_action->file=argv[3];
}
else if (action->module == &CVE_FIND_MODULE) {
if( argc != 5 ) {
oscap_module_usage(action->module, stderr, "Wrong number of parameters.\n");
return false;
}
action->doctype = OSCAP_DOCUMENT_CVE_FEED;
action->cve_action = malloc(sizeof(struct cve_action));
action->cve_action->cve=argv[3];
action->cve_action->file=argv[4];
}
return true;
}