cli/command/
session.rs

1// SPDX-License-Identifier: GPL-3-0-or-later
2// Copyright (c) 2025 Opinsys Oy
3
4use crate::{cli::SubCommand, command::CommandError, context::ContextCache, device::Device};
5use argh::FromArgs;
6use std::{cell::RefCell, rc::Rc};
7use strum::{Display, EnumString};
8use tabled::Tabled;
9use tpm2_protocol::data::TpmSe;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Display, EnumString)]
12#[strum(serialize_all = "kebab-case")]
13pub enum SessionType {
14    Hmac,
15    Policy,
16    Trial,
17}
18
19impl From<TpmSe> for SessionType {
20    fn from(val: TpmSe) -> Self {
21        match val {
22            TpmSe::Hmac => Self::Hmac,
23            TpmSe::Policy => Self::Policy,
24            TpmSe::Trial => Self::Trial,
25        }
26    }
27}
28
29#[derive(Tabled)]
30struct SessionRow {
31    #[tabled(rename = "HANDLE")]
32    handle: String,
33    #[tabled(rename = "DETAILS")]
34    details: String,
35}
36
37/// Lists cached authorization sessions.
38#[derive(FromArgs, Debug)]
39#[argh(
40    subcommand,
41    name = "session",
42    note = "Lists cached authorization sessions."
43)]
44pub struct Session {
45    /// filter by session type
46    #[argh(option, long = "type")]
47    pub type_filter: Option<SessionType>,
48}
49
50impl SubCommand for Session {
51    fn run(
52        &self,
53        _device: Option<Rc<RefCell<Device>>>,
54        context: &mut ContextCache,
55        plain: bool,
56    ) -> Result<(), CommandError> {
57        let mut results: Vec<(u32, SessionType)> = Vec::new();
58
59        for (_, session) in &context.session_map {
60            let handle = session.context.saved_handle.0;
61            results.push((handle, session.session_type.into()));
62        }
63
64        if let Some(filter_type) = self.type_filter {
65            results.retain(|(_, session_type)| *session_type == filter_type);
66        }
67
68        results.sort_unstable();
69
70        let rows: Vec<SessionRow> = results
71            .into_iter()
72            .map(|(handle, session_type)| SessionRow {
73                handle: format!("session://{handle:08x}"),
74                details: session_type.to_string(),
75            })
76            .collect();
77
78        super::print_table(&mut context.writer, rows, plain)?;
79
80        Ok(())
81    }
82}