#[repr(i32)]
#[non_exhaustive]
pub enum ItemType {
Service = 1,
User = 2,
Tty = 3,
RHost = 4,
Conv = 5,
AuthTok = 6,
OldAuthTok = 7,
RUser = 8,
UserPrompt = 9,
FailDelay = 10,
XDisplay = 11,
XAuthData = 12,
AuthTokType = 13,
}
pub trait Item<'a> {
type Raw;
fn type_id() -> ItemType;
unsafe fn from_raw(raw: *const Self::Raw) -> Self;
fn into_raw(self) -> *const Self::Raw;
}
macro_rules! cstr_item {
($name:ident) => {
#[derive(Debug)]
pub struct $name<'s>(pub &'s std::ffi::CStr);
impl<'s> std::ops::Deref for $name<'s> {
type Target = &'s std::ffi::CStr;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<'s> Item<'s> for $name<'s> {
type Raw = libc::c_char;
fn type_id() -> ItemType {
ItemType::$name
}
unsafe fn from_raw(raw: *const Self::Raw) -> Self {
unsafe { Self(std::ffi::CStr::from_ptr(raw)) }
}
fn into_raw(self) -> *const Self::Raw {
self.0.as_ptr()
}
}
};
}
cstr_item!(Service);
cstr_item!(User);
cstr_item!(Tty);
cstr_item!(RHost);
cstr_item!(RUser);
cstr_item!(UserPrompt);
macro_rules! secret_cstr_item {
($name:ident, $doc:expr) => {
#[doc = $doc]
pub struct $name<'s>(&'s std::ffi::CStr);
impl<'s> $name<'s> {
#[must_use]
#[allow(clippy::missing_const_for_fn)]
pub fn as_bytes(&self) -> &[u8] {
self.0.to_bytes()
}
#[must_use]
pub fn to_owned_secret(&self) -> $crate::secret::SecretBytes {
$crate::secret::SecretBytes::new(self.0.to_bytes().to_vec())
}
}
impl std::fmt::Debug for $name<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple(stringify!($name))
.field(&"[redacted]")
.finish()
}
}
impl<'s> Item<'s> for $name<'s> {
type Raw = libc::c_char;
fn type_id() -> ItemType {
ItemType::$name
}
unsafe fn from_raw(raw: *const Self::Raw) -> Self {
unsafe { Self(std::ffi::CStr::from_ptr(raw)) }
}
fn into_raw(self) -> *const Self::Raw {
self.0.as_ptr()
}
}
};
}
secret_cstr_item!(AuthTok, "The user's current authentication token.");
secret_cstr_item!(OldAuthTok, "The user's previous authentication token.");