2012/12/18 <scm-com...@wald.intevation.org>: > Author: jan > Date: 2012-12-18 22:31:13 +0100 (Tue, 18 Dec 2012) > New Revision: 14885 > > Modified: > trunk/openvas-libraries/COPYING > trunk/openvas-libraries/ChangeLog > trunk/openvas-libraries/base/cvss.c > trunk/openvas-libraries/base/cvss.h > Log: > * COPYING: Added cvss module. > * base/cvss.c (cvss_as_str): New. > * base/cvss.h: Added proto accordingly.
Hello, I have some concerns regarding this new cvss.c file. - It doesn't match the style and coding standards of the codebase. - It doesn't leverage the glib functions. - The final free(token) seems broken. Unless I miss something we have the following pattern: while (token != NULL) { ... } free(token); <-- ?? - Readability is not optimal. I tried to improve it a bit. Please find a patch attached. If people prefer this version I can polish the documentation and commit it. I've added a standalone version (cvss_prog.c) to ease testing. That's exactly the same file, with a main version to take a cvss base vector as argv[1] and print out the corresponding score. Regards -- Henri
cvss_cleanup.diff
Description: Binary data
/* openvas-libraries/base * $Id$ * Description: CVSS utility functions * * Authors: * Preeti Subramanian * * Copyright: * Copyright (C) 2012 Greenbone Networks GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * or, at your option, any later version as published by the Free * Software Foundation * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ /** * @file cvss.c * @brief CVSS utility functions * * This file contains utitlity functions for handlung CVSS. * Namels a calculator for the CVSS base score from a CVSS base * vector. * * The base equation is the foundation of CVSS scoring. The base equation is: * BaseScore6 = round_to_1_decimal(((0.6*Impact)+(0.4*Exploitability)–1.5)*f(Impact)) * Impact = 10.41*(1-(1-ConfImpact)*(1-IntegImpact)*(1-AvailImpact)) * Exploitability = 20* AccessVector*AccessComplexity*Authentication * * f(impact)= 0 if Impact=0, 1.176 otherwise * AccessVector = case AccessVector of * requires local access: 0.395 * adjacent network accessible: 0.646 * network accessible: 1.0 * AccessComplexity = case AccessComplexity of * high: 0.35 * medium: 0.61 * low: 0.71 * Authentication = case Authentication of * requires multiple instances of authentication: 0.45 * requires single instance of authentication: 0.56 * requires no authentication: 0.704 * ConfImpact = case ConfidentialityImpact of * none: 0.0 * partial: 0.275 * complete: 0.660 * IntegImpact = case IntegrityImpact of * none: 0.0 * partial: 0.275 * complete: 0.660 * AvailImpact = case AvailabilityImpact of * none: 0.0 * partial: 0.275 * complete: 0.660 */ #include <string.h> #include <stdio.h> #include <stdlib.h> #include <glib.h> /* AccessVector (AV) Constants */ #define AV_NETWORK 1.0 #define AV_ADJACENT_NETWORK 0.646 #define AV_LOCAL 0.395 /* AccessComplexity (AC) Constants */ #define AC_LOW 0.71 #define AC_MEDIUM 0.61 #define AC_HIGH 0.35 /* Authentication (Au) Constants */ #define Au_MULTIPLE_INSTANCES 0.45 #define Au_SINGLE_INSTANCE 0.56 #define Au_NONE 0.704 /* ConfidentialityImpact (C) Constants */ #define C_NONE 0.0 #define C_PARTIAL 0.275 #define C_COMPLETE 0.660 /* IntegrityImpact (I) Constants */ #define I_NONE 0.0 #define I_PARTIAL 0.275 #define I_COMPLETE 0.660 /* AvailabilityImpact (A) Constants */ #define A_NONE 0.0 #define A_PARTIAL 0.275 #define A_COMPLETE 0.660 enum base_metrics { A, I, C, Au, AC, AV }; struct impact_item { const char *name; double nvalue; }; static const struct impact_item impact_map[][3] = { [A] = { {"N", A_NONE}, {"P", A_PARTIAL}, {"C", A_COMPLETE}, }, [I] = { {"N", I_NONE}, {"P", I_PARTIAL}, {"C", I_COMPLETE}, }, [C] = { {"N", C_NONE}, {"P", C_PARTIAL}, {"C", C_COMPLETE}, }, [Au] = { {"N", Au_NONE}, {"M", Au_MULTIPLE_INSTANCES}, {"C", Au_SINGLE_INSTANCE}, }, [AV] = { {"N", AV_NETWORK}, {"A", AV_ADJACENT_NETWORK}, {"L", AV_LOCAL}, }, [AC] = { {"L", AC_LOW}, {"M", AC_MEDIUM}, {"H", AC_HIGH}, }, }; struct cvss { double conf_impact; double integ_impact; double avail_impact; double access_vector; double access_complexity; double authentication; }; /** * @brief Determin base metric enumeration from a string. * * @param str Base metric in string form, for example "A". * * @return The respective base_metric enumeration for the * string. -1 in case parsing the string failed. */ static enum base_metrics metricname2enum (char * str) { if (g_strcmp0(str, "A") == 0) return A; else if (g_strcmp0(str, "I") == 0) return I; else if (g_strcmp0(str, "C") == 0) return C; else if (g_strcmp0(str, "Au") == 0) return Au; else if (g_strcmp0(str, "AV") == 0) return AV; else if (g_strcmp0(str, "AC") == 0) return AC; return -1; } /** * @brief Calculate Impact Sub Score. * * @return The resulting sub score. */ static double get_impact_subscore (const struct cvss *cvss) { return (10.41 * (1 - (1 - cvss->conf_impact) * (1 - cvss->integ_impact) * (1 - cvss->avail_impact))); } /** * @brief Calculate Exploitability Sub Score. * * @return The resulting sub score. */ static double get_exploitability_subscore (const struct cvss *cvss) { return (20 * cvss->access_vector * cvss->access_complexity * cvss->authentication); } static inline int get_impact_from_str (const char *value, enum base_metrics metric, struct cvss *cvss) { int i; for (i = 0; i < 3; i++) { const struct impact_item *impact; impact = &impact_map[metric][i]; if (g_strcmp0 (impact->name, value) == 0) { switch (metric) { case A: cvss->avail_impact = impact->nvalue; break; case I: cvss->integ_impact = impact->nvalue; break; case C: cvss->conf_impact = impact->nvalue; break; case Au: cvss->authentication = impact->nvalue; break; case AV: cvss->access_vector = impact->nvalue; break; case AC: cvss->access_complexity = impact->nvalue; break; default: return -1; } return 0; } } return -1; } static double __get_cvss_score (struct cvss *cvss) { double impact = 1.176; double impact_sub; double exploitability_sub; impact_sub = get_impact_subscore (cvss); exploitability_sub = get_exploitability_subscore (cvss); if (impact_sub < 0.1) impact = 0.0; return (((0.6 * impact_sub) + (0.4 * exploitability_sub) - 1.5) * impact); } /** * @brief Calculate CVSS Score. * * @param base_metrics Base vector string from which to compute score. * * @return The resulting score. -1 upon error during parsing. */ double get_cvss_score_from_base_metrics (char *base_metrics) { struct cvss cvss; char *token, *base_str; memset(&cvss, 0x00, sizeof(struct cvss)); if (base_metrics == NULL) return 0.0; base_str = base_metrics = g_strdup_printf ("%s/", base_metrics); while ((token = strchr (base_metrics, '/')) != NULL) { char *token2 = strtok (base_metrics, ":"); char *metric_name = token2; char *metric_value; *token++ = '\0'; if (metric_name == NULL) return (double)-1; metric_value = strtok (NULL, ":"); if (metric_value == NULL) return (double)-1; if (get_impact_from_str (metric_value, metricname2enum (metric_name), &cvss)) return (double)-1; base_metrics = token; } free(base_str); return __get_cvss_score(&cvss); } int main(int ac, char **av) { if (ac < 2) { fprintf(stderr, "Usage: %s <CVSS base vector>\n", av[0]); return 1; } printf("CVSS for %s => %.03f\n", av[1], get_cvss_score_from_base_metrics(av[1])); return 0; }
_______________________________________________ Openvas-devel mailing list Openvas-devel@wald.intevation.org https://lists.wald.intevation.org/cgi-bin/mailman/listinfo/openvas-devel