1 //! Availability Impact (A)
2 
3 use crate::{
4     error::{Error, ErrorKind},
5     v3::Metric,
6 };
7 use std::{fmt, str::FromStr};
8 
9 /// Availability Impact (A) - CVSS v3.1 Base Metric Group
10 ///
11 /// Described in CVSS v3.1 Specification: Section 2.3.3:
12 /// <https://www.first.org/cvss/specification-document#t6>
13 ///
14 /// > This metric measures the impact to the availability of the impacted
15 /// > component resulting from a successfully exploited vulnerability.
16 /// > While the Confidentiality and Integrity impact metrics apply to the
17 /// > loss of confidentiality or integrity of data (e.g., information,
18 /// > files) used by the impacted component, this metric refers to the loss
19 /// > of availability of the impacted component itself, such as a networked
20 /// > service (e.g., web, database, email). Since availability refers to the
21 /// > accessibility of information resources, attacks that consume network
22 /// > bandwidth, processor cycles, or disk space all impact the availability
23 /// > of an impacted component. The Base Score is greatest when the
24 /// > consequence to the impacted component is highest.
25 #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
26 pub enum Availability {
27     /// None (N)
28     ///
29     /// > There is no impact to availability within the impacted component.
30     None,
31 
32     /// Low (L)
33     ///
34     /// > Performance is reduced or there are interruptions in resource
35     /// > availability. Even if repeated exploitation of the vulnerability
36     /// > is possible, the attacker does not have the ability to completely
37     /// > deny service to legitimate users. The resources in the impacted
38     /// > component are either partially available all of the time, or fully
39     /// > available only some of the time, but overall there is no direct,
40     /// > serious consequence to the impacted component.
41     Low,
42 
43     /// High (H)
44     ///
45     /// > There is a total loss of availability, resulting in the attacker
46     /// > being able to fully deny access to resources in the impacted
47     /// > component; this loss is either sustained (while the attacker
48     /// > continues to deliver the attack) or persistent (the condition
49     /// > persists even after the attack has completed). Alternatively,
50     /// > the attacker has the ability to deny some availability, but
51     /// > the loss of availability presents a direct, serious consequence
52     /// > to the impacted component (e.g., the attacker cannot disrupt
53     /// > existing connections, but can prevent new connections; the
54     /// > attacker can repeatedly exploit a vulnerability that, in each
55     /// > instance of a successful attack, leaks a only small amount of
56     /// > memory, but after repeated exploitation causes a service to become
57     /// > completely unavailable).
58     High,
59 }
60 
61 impl Metric for Availability {
62     const NAME: &'static str = "A";
63 
score(self) -> f6464     fn score(self) -> f64 {
65         match self {
66             Availability::None => 0.0,
67             Availability::Low => 0.22,
68             Availability::High => 0.56,
69         }
70     }
71 
as_str(self) -> &'static str72     fn as_str(self) -> &'static str {
73         match self {
74             Availability::None => "N",
75             Availability::Low => "L",
76             Availability::High => "H",
77         }
78     }
79 }
80 
81 impl fmt::Display for Availability {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result82     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83         write!(f, "{}:{}", Self::NAME, self.as_str())
84     }
85 }
86 
87 impl FromStr for Availability {
88     type Err = Error;
89 
from_str(s: &str) -> Result<Self, Error>90     fn from_str(s: &str) -> Result<Self, Error> {
91         match s {
92             "N" => Ok(Availability::None),
93             "L" => Ok(Availability::Low),
94             "H" => Ok(Availability::High),
95             other => fail!(ErrorKind::Parse, "invalid A (Base): {}", other),
96         }
97     }
98 }
99