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
71
72
73
74
75
76
//! Get auditing options which have been configured on the device.
//!
//! <https://developers.yubico.com/YubiHSM2/Commands/Get_Option.html>

use super::{Command, Response};
use audit::*;
use serializers::deserialize;
use session::{Session, SessionError, SessionErrorKind::ProtocolError};
use {Adapter, CommandType};

/// Get the audit policy setting for a particular command
pub fn get_command_audit_option<A: Adapter>(
    session: &mut Session<A>,
    command: CommandType,
) -> Result<AuditOption, SessionError> {
    let command_audit_options = get_all_command_audit_options(session)?;
    Ok(command_audit_options
        .iter()
        .find(|opt| opt.command_type() == command)
        .map(|opt| opt.audit_option())
        .unwrap_or(AuditOption::Off))
}

/// Get the audit policy settings for all commands
pub fn get_all_command_audit_options<A>(
    session: &mut Session<A>,
) -> Result<Vec<AuditCommand>, SessionError>
where
    A: Adapter,
{
    let response = session.send_command(GetOptionCommand {
        tag: AuditTag::Command,
    })?;

    Ok(deserialize(&response.0)?)
}

/// Get the forced auditing global option: when enabled, the device will
/// refuse operations if the [log store] becomes full.
///
/// [log store]: https://developers.yubico.com/YubiHSM2/Concepts/Logs.html
pub fn get_force_audit_option<A: Adapter>(
    session: &mut Session<A>,
) -> Result<AuditOption, SessionError> {
    let response = session.send_command(GetOptionCommand {
        tag: AuditTag::Force,
    })?;

    ensure!(
        response.0.len() == 1,
        ProtocolError,
        "expected 1-byte response, got {}",
        response.0.len()
    );

    AuditOption::from_u8(response.0[0]).map_err(|e| err!(ProtocolError, e))
}

/// Request parameters for `commands::get_option`
#[derive(Serialize, Deserialize, Debug)]
pub(crate) struct GetOptionCommand {
    /// Tag byte for `Force` vs `Command` options
    pub tag: AuditTag,
}

impl Command for GetOptionCommand {
    type ResponseType = GetOptionResponse;
}

/// Response from `commands::get_option`
#[derive(Serialize, Deserialize, Debug)]
pub(crate) struct GetOptionResponse(pub(crate) Vec<u8>);

impl Response for GetOptionResponse {
    const COMMAND_TYPE: CommandType = CommandType::GetOption;
}