use binrw::binrw;
use crate::arch;
#[binrw]
#[derive(Debug, Clone)]
#[brw(big, magic = 50_u8)]
pub struct Request<'b> {
pub username: arch::Utf8<'b>,
pub service_name: arch::Ascii<'b>,
#[bw(calc = method.as_ascii())]
auth_method: arch::Ascii<'b>,
#[br(args(auth_method))]
pub method: Method<'b>,
}
#[binrw]
#[derive(Debug, Clone)]
#[br(import(method: arch::Ascii<'_>))]
pub enum Method<'b> {
#[br(pre_assert(method == Method::NONE))]
None,
#[br(pre_assert(method == Method::PUBLICKEY))]
Publickey {
#[bw(calc = arch::Bool::from(signature.is_some()))]
signed: arch::Bool,
algorithm: arch::Bytes<'b>,
blob: arch::Bytes<'b>,
#[br(if(*signed))]
signature: Option<arch::Bytes<'b>>,
},
#[br(pre_assert(method == Method::PASSWORD))]
Password {
#[bw(calc = arch::Bool::from(new.is_some()))]
change: arch::Bool,
password: arch::Utf8<'b>,
#[br(if(*change))]
new: Option<arch::Utf8<'b>>,
},
#[br(pre_assert(method == Method::HOSTBASED))]
Hostbased {
algorithm: arch::Bytes<'b>,
host_key: arch::Bytes<'b>,
client_fqdn: arch::Ascii<'b>,
username: arch::Utf8<'b>,
signature: arch::Bytes<'b>,
},
#[br(pre_assert(method == Method::KEYBOARD_INTERACTIVE))]
KeyboardInteractive {
language: arch::Ascii<'b>,
submethods: arch::Utf8<'b>,
},
}
impl Method<'_> {
pub const NONE: arch::Ascii<'static> = arch::ascii!("none");
pub const PUBLICKEY: arch::Ascii<'static> = arch::ascii!("publickey");
pub const PASSWORD: arch::Ascii<'static> = arch::ascii!("password");
pub const HOSTBASED: arch::Ascii<'static> = arch::ascii!("hostbased");
pub const KEYBOARD_INTERACTIVE: arch::Ascii<'static> = arch::ascii!("keyboard-interactive");
pub fn as_ascii(&self) -> arch::Ascii<'static> {
match self {
Self::None { .. } => Self::NONE,
Self::Publickey { .. } => Self::PUBLICKEY,
Self::Password { .. } => Self::PASSWORD,
Self::Hostbased { .. } => Self::HOSTBASED,
Self::KeyboardInteractive { .. } => Self::KEYBOARD_INTERACTIVE,
}
}
}
#[binrw]
#[derive(Debug, Clone)]
#[brw(big, magic = 60_u8)]
pub struct PkOk<'b> {
pub algorithm: arch::Bytes<'b>,
pub blob: arch::Bytes<'b>,
}
#[binrw]
#[derive(Debug, Default, Clone)]
#[brw(big, magic = 60_u8)]
pub struct PasswdChangereq<'b> {
pub prompt: arch::Utf8<'b>,
pub language: arch::Ascii<'b>,
}
#[binrw]
#[derive(Debug, Clone)]
#[brw(big, magic = 60_u8)]
pub struct InfoRequest<'b> {
pub name: arch::Utf8<'b>,
pub instruction: arch::Utf8<'b>,
pub language: arch::Ascii<'b>,
#[bw(calc = prompts.len() as u32)]
num_prompts: u32,
#[br(count = num_prompts)]
pub prompts: Vec<InfoRequestPrompt<'static>>,
}
#[binrw]
#[derive(Debug, Clone)]
#[brw(big)]
pub struct InfoRequestPrompt<'b> {
pub prompt: arch::Utf8<'b>,
pub echo: arch::Bool,
}
#[binrw]
#[derive(Debug, Clone)]
#[brw(big, magic = 61_u8)]
pub struct InfoResponse {
#[bw(calc = responses.len() as u32)]
num_responses: u32,
#[br(count = num_responses)]
pub responses: Vec<arch::Utf8<'static>>,
}
#[binrw]
#[derive(Debug, Default, Clone)]
#[brw(big, magic = 51_u8)]
pub struct Failure<'b> {
pub continue_with: arch::NameList<'b>,
pub partial_success: arch::Bool,
}
#[binrw]
#[derive(Debug, Default, Clone)]
#[brw(big, magic = 52_u8)]
pub struct Success;
#[binrw]
#[derive(Debug, Default, Clone)]
#[brw(big, magic = 53_u8)]
pub struct Banner<'b> {
pub message: arch::Utf8<'b>,
pub language: arch::Ascii<'b>,
}