Mercurial > crates > nonstick
comparison src/handle.rs @ 143:ebb71a412b58
Turn everything into OsString and Just Walk Out! for strings with nul.
To reduce the hazard surface of the API, this replaces most uses of &str
with &OsStr (and likewise with String/OsString).
Also, I've decided that instead of dealing with callers putting `\0`
in their parameters, I'm going to follow the example of std::env and
Just Walk Out! (i.e., panic!()).
This makes things a lot less annoying for both me and (hopefully) users.
| author | Paul Fisher <paul@pfish.zone> |
|---|---|
| date | Sat, 05 Jul 2025 22:12:46 -0400 |
| parents | a508a69c068a |
| children | 56b559b7ecea |
comparison
equal
deleted
inserted
replaced
| 142:5c1e315c18ff | 143:ebb71a412b58 |
|---|---|
| 3 use crate::constants::{Flags, Result}; | 3 use crate::constants::{Flags, Result}; |
| 4 use crate::conv::Conversation; | 4 use crate::conv::Conversation; |
| 5 use crate::environ::{EnvironMap, EnvironMapMut}; | 5 use crate::environ::{EnvironMap, EnvironMapMut}; |
| 6 use crate::logging::{Level, Location}; | 6 use crate::logging::{Level, Location}; |
| 7 use crate::{guide, linklist, man7, manbsd, stdlinks}; | 7 use crate::{guide, linklist, man7, manbsd, stdlinks}; |
| 8 use std::ffi::{OsStr, OsString}; | |
| 8 | 9 |
| 9 macro_rules! trait_item { | 10 macro_rules! trait_item { |
| 10 ($(#[$md:meta])* get = $getter:ident, item = $item:literal $(, see = $see:path)?) => { | 11 ($(#[$md:meta])* get = $getter:ident, item = $item:literal $(, see = $see:path)?) => { |
| 11 $(#[$md])* | 12 $(#[$md])* |
| 12 #[doc = ""] | 13 #[doc = ""] |
| 24 #[doc = linklist!(pam_get_item: mwg, adg, _std)] | 25 #[doc = linklist!(pam_get_item: mwg, adg, _std)] |
| 25 /// | 26 /// |
| 26 #[doc = guide!(adg: "adg-interface-by-app-expected.html#adg-pam_get_item")] | 27 #[doc = guide!(adg: "adg-interface-by-app-expected.html#adg-pam_get_item")] |
| 27 #[doc = guide!(mwg: "mwg-expected-by-module-item.html#mwg-pam_get_item")] | 28 #[doc = guide!(mwg: "mwg-expected-by-module-item.html#mwg-pam_get_item")] |
| 28 #[doc = stdlinks!(3 pam_get_item)] | 29 #[doc = stdlinks!(3 pam_get_item)] |
| 29 fn $getter(&self) -> Result<Option<String>>; | 30 fn $getter(&self) -> Result<Option<OsString>>; |
| 30 }; | 31 }; |
| 31 ($(#[$md:meta])* set = $setter:ident, item = $item:literal $(, see = $see:path)?) => { | 32 ($(#[$md:meta])* set = $setter:ident, item = $item:literal $(, see = $see:path)?) => { |
| 32 $(#[$md])* | 33 $(#[$md])* |
| 33 #[doc = ""] | 34 #[doc = ""] |
| 34 #[doc = concat!("Sets the `", $item, "` from the PAM handle.")] | 35 #[doc = concat!("Sets the `", $item, "` from the PAM handle.")] |
| 35 $( | 36 $( |
| 36 #[doc = concat!("See [`", stringify!($see), "`].")] | 37 #[doc = concat!("See [`", stringify!($see), "`].")] |
| 37 )? | 38 )? |
| 38 /// | 39 /// |
| 39 /// Sets the item's value. PAM copies the string's contents. | 40 /// Sets the item's value. PAM copies the string's contents. |
| 40 /// If the string contains a null byte, this will return | 41 /// |
| 41 /// a `ConversationError`. | 42 /// # Panics |
| 43 /// | |
| 44 /// If the string contains a nul byte, this will panic. | |
| 42 /// | 45 /// |
| 43 /// # References | 46 /// # References |
| 44 /// | 47 /// |
| 45 #[doc = linklist!(pam_set_item: mwg, adg, _std)] | 48 #[doc = linklist!(pam_set_item: mwg, adg, _std)] |
| 46 /// | 49 /// |
| 47 #[doc = guide!(adg: "adg-interface-by-app-expected.html#adg-pam_set_item")] | 50 #[doc = guide!(adg: "adg-interface-by-app-expected.html#adg-pam_set_item")] |
| 48 #[doc = guide!(mwg: "mwg-expected-by-module-item.html#mwg-pam_set_item")] | 51 #[doc = guide!(mwg: "mwg-expected-by-module-item.html#mwg-pam_set_item")] |
| 49 #[doc = stdlinks!(3 pam_set_item)] | 52 #[doc = stdlinks!(3 pam_set_item)] |
| 50 fn $setter(&mut self, value: Option<&str>) -> Result<()>; | 53 fn $setter(&mut self, value: Option<&OsStr>) -> Result<()>; |
| 51 }; | 54 }; |
| 52 } | 55 } |
| 53 | 56 |
| 54 /// Functionality for both PAM applications and PAM modules. | 57 /// Functionality for both PAM applications and PAM modules. |
| 55 /// | 58 /// |
| 114 /// // Get the username using the default prompt. | 117 /// // Get the username using the default prompt. |
| 115 /// let user = handle.username(None)?; | 118 /// let user = handle.username(None)?; |
| 116 /// // Get the username using a custom prompt. | 119 /// // Get the username using a custom prompt. |
| 117 /// // If this were actually called right after the above, | 120 /// // If this were actually called right after the above, |
| 118 /// // both user and user_2 would have the same value. | 121 /// // both user and user_2 would have the same value. |
| 119 /// let user_2 = handle.username(Some("who ARE you even???"))?; | 122 /// let user_2 = handle.username(Some("who ARE you even???".as_ref()))?; |
| 120 /// # Ok(()) | 123 /// # Ok(()) |
| 121 /// # } | 124 /// # } |
| 122 /// ``` | 125 /// ``` |
| 123 #[doc = stdlinks!(3 pam_get_user)] | 126 #[doc = stdlinks!(3 pam_get_user)] |
| 124 #[doc = guide!(mwg: "mwg-expected-by-module-item.html#mwg-pam_get_user")] | 127 #[doc = guide!(mwg: "mwg-expected-by-module-item.html#mwg-pam_get_user")] |
| 125 fn username(&mut self, prompt: Option<&str>) -> Result<String>; | 128 fn username(&mut self, prompt: Option<&OsStr>) -> Result<OsString>; |
| 126 | 129 |
| 127 /// The contents of the environment to set, read-only. | 130 /// The contents of the environment to set, read-only. |
| 128 fn environ(&self) -> impl EnvironMap; | 131 fn environ(&self) -> impl EnvironMap; |
| 129 | 132 |
| 130 /// A writable version of the environment. | 133 /// A writable version of the environment. |
| 329 /// # use nonstick::handle::PamHandleModule; | 332 /// # use nonstick::handle::PamHandleModule; |
| 330 /// # fn _doc(handle: &mut impl PamHandleModule) -> Result<(), Box<dyn std::error::Error>> { | 333 /// # fn _doc(handle: &mut impl PamHandleModule) -> Result<(), Box<dyn std::error::Error>> { |
| 331 /// // Get the user's password using the default prompt. | 334 /// // Get the user's password using the default prompt. |
| 332 /// let pass = handle.authtok(None)?; | 335 /// let pass = handle.authtok(None)?; |
| 333 /// // Get the user's password using a custom prompt. | 336 /// // Get the user's password using a custom prompt. |
| 334 /// let pass = handle.authtok(Some("Reveal your secrets!"))?; | 337 /// let pass = handle.authtok(Some("Reveal your secrets!".as_ref()))?; |
| 335 /// Ok(()) | 338 /// Ok(()) |
| 336 /// # } | 339 /// # } |
| 337 /// ``` | 340 /// ``` |
| 338 #[doc = man7!(3 pam_get_authtok)] | 341 #[doc = man7!(3 pam_get_authtok)] |
| 339 #[doc = manbsd!(3 pam_get_authtok)] | 342 #[doc = manbsd!(3 pam_get_authtok)] |
| 340 fn authtok(&mut self, prompt: Option<&str>) -> Result<String>; | 343 fn authtok(&mut self, prompt: Option<&OsStr>) -> Result<OsString>; |
| 341 | 344 |
| 342 /// Retrieves the user's old authentication token when changing passwords. | 345 /// Retrieves the user's old authentication token when changing passwords. |
| 343 /// | 346 /// |
| 344 /// | 347 /// |
| 345 fn old_authtok(&mut self, prompt: Option<&str>) -> Result<String>; | 348 fn old_authtok(&mut self, prompt: Option<&OsStr>) -> Result<OsString>; |
| 346 | 349 |
| 347 trait_item!( | 350 trait_item!( |
| 348 /// Gets the user's authentication token (e.g., password). | 351 /// Gets the user's authentication token (e.g., password). |
| 349 /// | 352 /// |
| 350 /// This is normally set automatically by PAM when calling | 353 /// This is normally set automatically by PAM when calling |
