use serde::{Deserialize, Serialize};
use crate::{OracleClass, ProbeDefinition, ResponseSurface};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RequestAuthState {
Absent,
Present,
}
impl RequestAuthState {
#[must_use]
pub fn from_request(req: &ProbeDefinition) -> Self {
if req.headers.contains_key(http::header::AUTHORIZATION) {
Self::Present
} else {
Self::Absent
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Applicability {
Strong,
Weak,
Missing,
}
impl Applicability {
#[must_use]
pub fn confidence(self) -> f64 {
match self {
Self::Strong => 1.0,
Self::Weak => 0.3,
Self::Missing => 0.0,
}
}
}
#[must_use]
pub fn always_applicable(_baseline: &ResponseSurface, _probe: &ResponseSurface) -> Applicability {
Applicability::Strong
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub enum SignalSurface {
Status,
Body,
Headers,
Timing,
Composite,
}
#[derive(Debug, Clone, Copy)]
pub struct Technique {
pub id: &'static str,
pub name: &'static str,
pub oracle_class: OracleClass,
pub vector: Vector,
pub strength: NormativeStrength,
pub normalization_weight: Option<f32>,
pub inverted_signal_weight: Option<f32>,
pub method_relevant: bool,
pub parser_relevant: bool,
pub applicability: fn(&ResponseSurface, &ResponseSurface) -> Applicability,
pub contradiction_surface: SignalSurface,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub enum Vector {
StatusCodeDiff,
CacheProbing,
ErrorMessageGranularity,
RedirectDiff,
}
#[cfg(test)]
#[path = "technique_tests.rs"]
mod tests;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub enum NormativeStrength {
Must,
MustNot,
Should,
May,
}
impl std::fmt::Display for Vector {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::StatusCodeDiff => write!(f, "StatusCodeDiff"),
Self::CacheProbing => write!(f, "CacheProbing"),
Self::ErrorMessageGranularity => write!(f, "ErrorMessageGranularity"),
Self::RedirectDiff => write!(f, "RedirectDiff"),
}
}
}
impl std::fmt::Display for NormativeStrength {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Must => write!(f, "Must"),
Self::MustNot => write!(f, "MustNot"),
Self::Should => write!(f, "Should"),
Self::May => write!(f, "May"),
}
}
}