1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
//! User Interaction (UI)

use crate::{
    error::{Error, ErrorKind},
    v3::Metric,
};
use std::{fmt, str::FromStr};

/// User Interaction (UI) - CVSS v3.1 Base Metric Group
///
/// Described in CVSS v3.1 Specification: Section 2.1.4:
/// <https://www.first.org/cvss/specification-document#t6>
///
/// > This metric captures the requirement for a human user, other than the
/// > attacker, to participate in the successful compromise of the vulnerable
/// > component. This metric determines whether the vulnerability can be
/// > exploited solely at the will of the attacker, or whether a separate user
/// > (or user-initiated process) must participate in some manner.
/// > The Base Score is greatest when no user interaction is required.
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub enum UserInteraction {
    /// Required (R)
    ///
    /// > Successful exploitation of this vulnerability requires a user to
    /// > take some action before the vulnerability can be exploited. For
    /// > example, a successful exploit may only be possible during the
    /// > installation of an application by a system administrator.
    Required,

    /// None (N)
    ///
    /// > The vulnerable system can be exploited without interaction from any user.
    None,
}

impl Metric for UserInteraction {
    const NAME: &'static str = "UI";

    fn score(self) -> f64 {
        match self {
            UserInteraction::Required => 0.62,
            UserInteraction::None => 0.85,
        }
    }

    fn as_str(self) -> &'static str {
        match self {
            UserInteraction::Required => "R",
            UserInteraction::None => "N",
        }
    }
}

impl fmt::Display for UserInteraction {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}:{}", Self::NAME, self.as_str())
    }
}

impl FromStr for UserInteraction {
    type Err = Error;

    fn from_str(s: &str) -> Result<Self, Error> {
        match s {
            "R" => Ok(UserInteraction::Required),
            "N" => Ok(UserInteraction::None),
            other => fail!(ErrorKind::Parse, "invalid UI (Base): {}", other),
        }
    }
}