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 |