### Kerberos Client-Server Example Source: https://docs.rs/cross-krb5 Demonstrates a basic client-server interaction using Kerberos authentication. This example requires a service principal name (SPN) as a command-line argument. It sets up channels for communication and spawns a server thread, then initiates the client-side Kerberos context. ```rust use bytes::Bytes; use cross_krb5::{AcceptFlags, ClientCtx, InitiateFlags, K5Ctx, Step, ServerCtx}; use std::{env::args, process::exit, sync::mpsc, thread}; enum Msg { Token(Bytes), Msg(Bytes), } fn server(spn: String, input: mpsc::Receiver, output: mpsc::Sender) { let mut server = ServerCtx::new(AcceptFlags::empty(), Some(&spn)).expect("new"); let mut server = loop { let token = match input.recv().expect("expected data") { Msg::Msg(_) => panic!("server not finished initializing"), Msg::Token(t) => t, }; match server.step(&*token).expect("step") { Step::Finished((ctx, token)) => { if let Some(token) = token { output.send(Msg::Token(Bytes::copy_from_slice(&*token))).expect("send"); } break ctx }, Step::Continue((ctx, token)) => { output.send(Msg::Token(Bytes::copy_from_slice(&*token))).expect("send"); server = ctx; } } }; match input.recv().expect("expected data msg") { Msg::Token(_) => panic!("unexpected extra token"), Msg::Msg(secret_msg) => println!( "{}", String::from_utf8_lossy(&server.unwrap(&*secret_msg).expect("unwrap")) ), } } fn client(spn: &str, input: mpsc::Receiver, output: mpsc::Sender) { let (mut client, token) = ClientCtx::new(InitiateFlags::empty(), None, spn, None).expect("new"); output.send(Msg::Token(Bytes::copy_from_slice(&*token))).expect("send"); let mut client = loop { let token = match input.recv().expect("expected data") { Msg::Msg(_) => panic!("client not finished initializing"), Msg::Token(t) => t, }; match client.step(&*token).expect("step") { Step::Finished((ctx, token)) => { if let Some(token) = token { output.send(Msg::Token(Bytes::copy_from_slice(&*token))).expect("send"); } break ctx }, Step::Continue((ctx, token)) => { output.send(Msg::Token(Bytes::copy_from_slice(&*token))).expect("send"); client = ctx; } } }; let msg = client.wrap(true, b"super secret message").expect("wrap"); output.send(Msg::Msg(Bytes::copy_from_slice(&*msg))).expect("send"); } fn main() { let args = args().collect::>(); if args.len() != 2 { println!("usage: {}: ", args[0]); exit(1); } let spn = String::from(&args[1]); let (server_snd, server_recv) = mpsc::channel(); let (client_snd, client_recv) = mpsc::channel(); thread::spawn(move || server(spn, server_recv, client_snd)); client(&args[1], client_recv, server_snd); } ``` -------------------------------- ### Kerberos Client-Server Example Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/index.html Demonstrates a basic client-server interaction using cross-krb5 for secure communication. Requires a service principal name (SPN) as a command-line argument. ```rust use bytes::Bytes; use cross_krb5::{AcceptFlags, ClientCtx, InitiateFlags, K5Ctx, Step, ServerCtx}; use std::{env::args, process::exit, sync::mpsc, thread}; enum Msg { Token(Bytes), Msg(Bytes), } fn server(spn: String, input: mpsc::Receiver, output: mpsc::Sender) { let mut server = ServerCtx::new(AcceptFlags::empty(), Some(&spn)).expect("new"); let mut server = loop { let token = match input.recv().expect("expected data") { Msg::Msg(_) => panic!("server not finished initializing"), Msg::Token(t) => t, }; match server.step(&*token).expect("step") { Step::Finished((ctx, token)) => { if let Some(token) = token { output.send(Msg::Token(Bytes::copy_from_slice(&*token))).expect("send"); } break ctx }, Step::Continue((ctx, token)) => { output.send(Msg::Token(Bytes::copy_from_slice(&*token))).expect("send"); server = ctx; } } }; match input.recv().expect("expected data msg") { Msg::Token(_) => panic!("unexpected extra token"), Msg::Msg(secret_msg) => println!( "{}", String::from_utf8_lossy(&server.unwrap(&*secret_msg).expect("unwrap")) ), } } fn client(spn: &str, input: mpsc::Receiver, output: mpsc::Sender) { let (mut client, token) = ClientCtx::new(InitiateFlags::empty(), None, spn, None).expect("new"); output.send(Msg::Token(Bytes::copy_from_slice(&*token))).expect("send"); let mut client = loop { let token = match input.recv().expect("expected data") { Msg::Msg(_) => panic!("client not finished initializing"), Msg::Token(t) => t, }; match client.step(&*token).expect("step") { Step::Finished((ctx, token)) => { if let Some(token) = token { output.send(Msg::Token(Bytes::copy_from_slice(&*token))).expect("send"); } break ctx }, Step::Continue((ctx, token)) => { output.send(Msg::Token(Bytes::copy_from_slice(&*token))).expect("send"); client = ctx; } } }; let msg = client.wrap(true, b"super secret message").expect("wrap"); output.send(Msg::Msg(Bytes::copy_from_slice(&*msg))).expect("send"); } fn main() { let args = args().collect::>(); if args.len() != 2 { println!("usage: {}: ", args[0]); exit(1); } let spn = String::from(&args[1]); let (server_snd, server_recv) = mpsc::channel(); let (client_snd, client_recv) = mpsc::channel(); thread::spawn(move || server(spn, server_recv, client_snd)); client(&args[1], client_recv, server_snd); } ``` -------------------------------- ### Server Initialization and Step Processing Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.PendingServerCtx.html This example demonstrates how to initialize a server context and process incoming tokens using the `step` method. It handles both `Step::Finished` and `Step::Continue` outcomes, sending tokens to the output and updating the server context as needed. ```rust 10fn server(spn: String, input: mpsc::Receiver, output: mpsc::Sender) { let mut server = ServerCtx::new(AcceptFlags::empty(), Some(&spn)).expect("new"); let mut server = loop { let token = match input.recv().expect("expected data") { Msg::Msg(_) => panic!("server not finished initializing"), Msg::Token(t) => t, }; match server.step(&*token).expect("step") { Step::Finished((ctx, token)) => { if let Some(token) = token { output.send(Msg::Token(Bytes::copy_from_slice(&*token))).expect("send"); } break ctx }, Step::Continue((ctx, token)) => { output.send(Msg::Token(Bytes::copy_from_slice(&*token))).expect("send"); server = ctx; } } }; match input.recv().expect("expected data msg") { Msg::Token(_) => panic!("unexpected extra token"), Msg::Msg(secret_msg) => println!( "{}", String::from_utf8_lossy(&server.unwrap(&*secret_msg).expect("unwrap")) ), } } ``` -------------------------------- ### Initialize Client Context Step Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.PendingClientCtx.html This example demonstrates how to use the `step` method of a client context to process tokens during initialization. It handles both successful completion and continuation of the initialization process. ```rust fn client(spn: &str, input: mpsc::Receiver, output: mpsc::Sender) { let (mut client, token) = ClientCtx::new(InitiateFlags::empty(), None, spn, None).expect("new"); output.send(Msg::Token(Bytes::copy_from_slice(&*token))).expect("send"); let mut client = loop { let token = match input.recv().expect("expected data") { Msg::Msg(_) => panic!("client not finished initializing"), Msg::Token(t) => t, }; match client.step(&*token).expect("step") { Step::Finished((ctx, token)) => { if let Some(token) = token { output.send(Msg::Token(Bytes::copy_from_slice(&*token))).expect("send"); } break ctx }, Step::Continue((ctx, token)) => { output.send(Msg::Token(Bytes::copy_from_slice(&*token))).expect("send"); client = ctx; } } }; let msg = client.wrap(true, b"super secret message").expect("wrap"); output.send(Msg::Msg(Bytes::copy_from_slice(&*msg))).expect("send"); } ``` -------------------------------- ### InitiateFlags::empty Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html Get a flags value with all bits unset. This is useful for starting with no flags enabled. ```APIDOC ## InitiateFlags::empty ### Description Get a flags value with all bits unset. ### Method `const fn empty() -> Self` ### Example ```rust use cross_krb5::InitiateFlags; let flags = InitiateFlags::empty(); assert!(flags.is_empty()); ``` ``` -------------------------------- ### InitiateFlags::all Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html Get a flags value with all known bits set. This is useful for enabling all available flags. ```APIDOC ## InitiateFlags::all ### Description Get a flags value with all known bits set. ### Method `const fn all() -> Self` ### Example ```rust use cross_krb5::InitiateFlags; let flags = InitiateFlags::all(); assert!(flags.is_all()); ``` ``` -------------------------------- ### Create an empty InitiateFlags Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html Use `InitiateFlags::empty()` to get a flags value with all bits unset. This is useful for starting with default or no specific flags enabled. ```rust let (mut client, token) = ClientCtx::new(InitiateFlags::empty(), None, spn, None).expect("new"); ``` -------------------------------- ### AcceptFlags::empty() - Initialize Flags Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.AcceptFlags.html Creates a new AcceptFlags value with all bits unset. This is useful for starting with a default, no-option configuration. ```rust let mut server = ServerCtx::new(AcceptFlags::empty(), Some(&spn)).expect("new"); ``` -------------------------------- ### ttl Method - Get Remaining Session Time Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/trait.K5Ctx.html Retrieves the remaining time-to-live for the current Kerberos session. This is useful for managing session expiry. ```rust fn ttl(&mut self) -> Result ``` -------------------------------- ### type_id Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html Gets the `TypeId` of the InitiateFlags value. ```APIDOC ## type_id ### Description Gets the `TypeId` of `self`. ### Method `type_id` ### Returns - `TypeId` - The `TypeId` of the InitiateFlags value. ``` -------------------------------- ### InitiateFlags::bits Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html Get the underlying bits value of the flags. This returns the raw `u32` representation of the set bits. ```APIDOC ## InitiateFlags::bits ### Description Get the underlying bits value. ### Method `const fn bits(&self) -> u32` ### Example ```rust use cross_krb5::InitiateFlags; let flags = InitiateFlags::empty(); assert_eq!(flags.bits(), 0); let all_flags = InitiateFlags::all(); // The exact value depends on the number of defined flags // assert_ne!(all_flags.bits(), 0); ``` ``` -------------------------------- ### InitiateFlags::from_name Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html Get a flags value with the bits of a flag with the given name set. Returns `None` if the name is empty or doesn't correspond to any named flag. ```APIDOC ## InitiateFlags::from_name ### Description Get a flags value with the bits of a flag with the given name set. ### Method `pub fn from_name(name: &str) -> Option` ### Example ```rust use cross_krb5::InitiateFlags; // Assuming 'negotiate_token' is a valid flag name // let flags = InitiateFlags::from_name("negotiate_token"); // assert!(flags.is_some()); let unknown_flags = InitiateFlags::from_name("non_existent_flag"); assert!(unknown_flags.is_none()); ``` ``` -------------------------------- ### K5ServerCtx Trait Definition Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/trait.K5ServerCtx.html Defines the K5ServerCtx trait, which requires implementations to provide a `client` method. This method is used to get the principal name of the client associated with the server context. ```rust pub trait K5ServerCtx: K5Ctx { // Required method fn client(&mut self) -> Result; } ``` -------------------------------- ### AcceptFlags::from_name() - Get Flags by Name Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.AcceptFlags.html Retrieves an AcceptFlags value corresponding to a named flag. Returns `None` if the provided name is empty or does not match any known flag. ```rust pub fn from_name(name: &str) -> Option ``` -------------------------------- ### InitiateFlags Methods Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html This section details the public methods available on the InitiateFlags struct, including flag iteration and manipulation. ```APIDOC ## pub const fn iter_names(&self) -> IterNames ### Description Yield a set of contained named flags values. This method is like `iter`, except only yields bits in contained named flags. Any unknown bits, or bits not corresponding to a contained flag will not be yielded. ### Method `iter_names` ``` ```APIDOC ## impl Flags for InitiateFlags ### Description Provides methods for manipulating and querying flag values. ### Methods - `const FLAGS: &'static [Flag]`: The set of defined flags. - `type Bits = u32`: The underlying bits type. - `fn bits(&self) -> u32`: Get the underlying bits value. - `fn from_bits_retain(bits: u32) -> InitiateFlags`: Convert from a bits value exactly. - `fn empty() -> Self`: Get a flags value with all bits unset. - `fn all() -> Self`: Get a flags value with all known bits set. - `fn contains_unknown_bits(&self) -> bool`: Returns `true` if any unknown bits are set. - `fn from_bits(bits: Self::Bits) -> Option`: Convert from a bits value. - `fn from_bits_truncate(bits: Self::Bits) -> Self`: Convert from a bits value, unsetting any unknown bits. - `fn from_name(name: &str) -> Option`: Get a flags value with the bits of a flag with the given name set. - `fn iter(&self) -> Iter`: Yield a set of contained flags values. - `fn iter_names(&self) -> IterNames`: Yield a set of contained named flags values. - `fn is_empty(&self) -> bool`: Whether all bits in this flags value are unset. - `fn is_all(&self) -> bool`: Whether all known bits in this flags value are set. - `fn intersects(&self, other: Self) -> bool`: Whether any set bits in a source flags value are also set in a target flags value. - `fn contains(&self, other: Self) -> bool`: Whether all set bits in a source flags value are also set in a target flags value. - `fn truncate(&mut self)`: Remove any unknown bits from the flags. - `fn insert(&mut self, other: Self)`: The bitwise or (`|`) of the bits in two flags values. - `fn remove(&mut self, other: Self)`: The intersection of a source flags value with the complement of a target flags value (`&!`). - `fn toggle(&mut self, other: Self)`: The bitwise exclusive-or (`^`) of the bits in two flags values. - `fn set(&mut self, other: Self, value: bool)`: Call `Flags::insert` when `value` is `true` or `Flags::remove` when `value` is `false`. - `fn clear(&mut self)`: Unsets all bits in the flags. - `fn intersection(self, other: Self) -> Self`: The bitwise and (`&`) of the bits in two flags values. - `fn union(self, other: Self) -> Self`: The bitwise or (`|`) of the bits in two flags values. - `fn difference(self, other: Self) -> Self`: The intersection of a source flags value with the complement of a target flags value (`&!`). ``` -------------------------------- ### PendingClientCtx::step Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.PendingClientCtx.html Feeds a server-provided token to the client context, performing one step of the initialization. It returns either the established context if initialization is complete, or the pending context to continue the process. ```APIDOC ## PendingClientCtx::step ### Description Feed the server provided token to the client context, performing one step of the initialization. If the initialization is complete then return the established context and optionally a final token that must be sent to the server, otherwise return the pending context and another token to pass to the server. ### Method `pub fn step( self, token: &[u8], ) -> Result>), (PendingClientCtx, impl Deref)>>` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust // Example usage within a client function // (See repository for full context) match client.step(&*token).expect("step") { Step::Finished((ctx, token)) => { // Handle finished context }, Step::Continue((ctx, token)) => { // Handle continuation client = ctx; } } ``` ### Response #### Success Response - `Step::Finished((ClientCtx, Option<&[u8]>))` if initialization is complete. - `Step::Continue((PendingClientCtx, &[u8]))` if initialization is ongoing. #### Response Example ```rust // Example of a successful continuation step Step::Continue((pending_ctx, server_token)) // Example of a finished step Step::Finished((established_ctx, final_server_token)) ``` ``` -------------------------------- ### ServerCtx::new_with_cred Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.ServerCtx.html Creates a new server context using provided credentials. ```APIDOC ## `ServerCtx::new_with_cred` ### Description Create a new server context using provided credentials. ### Parameters #### Path Parameters - None #### Query Parameters - None #### Request Body - None ### Method Signature `pub fn new_with_cred(cred: Cred) -> Result` ``` -------------------------------- ### from Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html Creates an InitiateFlags value from another value of the same type. ```APIDOC ## from ### Description Returns the argument unchanged. ### Method `from` ### Parameters - `t` (T) - The value to convert from. ### Returns - `T` - The converted value. ``` -------------------------------- ### AcceptFlags::bits() - Get Underlying Bits Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.AcceptFlags.html Retrieves the raw `u32` representation of the flags. This is useful for debugging or when interacting with systems that expect raw bitmasks. ```rust pub const fn bits(&self) -> u32 ``` -------------------------------- ### AcceptFlags NEGOTIATE_TOKEN Constant Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.AcceptFlags.html Windows-only constant to use the SSPI Negotiate package instead of Kerberos. Use this if the client is on Windows and sends Negotiate tokens. ```rust pub const NEGOTIATE_TOKEN: Self ``` -------------------------------- ### fmt (Octal) Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html Formats the InitiateFlags value as an octal string. ```APIDOC ## fmt (Octal) ### Description Formats the value using the given formatter. ### Method `fmt` ### Parameters - `f` (&mut Formatter<'_>) - The formatter to use. ### Returns - `Result` - Ok if formatting was successful, Err otherwise. ``` -------------------------------- ### fmt (UpperHex) Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html Formats the InitiateFlags value as an uppercase hexadecimal string. ```APIDOC ## fmt (UpperHex) ### Description Formats the value using the given formatter. ### Method `fmt` ### Parameters - `f` (&mut Formatter<'_>) - The formatter to use. ### Returns - `Result` - Ok if formatting was successful, Err otherwise. ``` -------------------------------- ### Create New Server Context Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.ServerCtx.html Creates a new server context for a given service principal name. The context must be initialized by exchanging tokens with the client. If the principal is None, it defaults to the current process user. ```rust fn server(spn: String, input: mpsc::Receiver, output: mpsc::Sender) { let mut server = ServerCtx::new(AcceptFlags::empty(), Some(&spn)).expect("new"); let mut server = loop { let token = match input.recv().expect("expected data") { Msg::Msg(_) => panic!("server not finished initializing"), Msg::Token(t) => t, }; match server.step(&*token).expect("step") { Step::Finished((ctx, token)) => { if let Some(token) = token { output.send(Msg::Token(Bytes::copy_from_slice(&*token))).expect("send"); } break ctx }, Step::Continue((ctx, token)) => { output.send(Msg::Token(Bytes::copy_from_slice(&*token))).expect("send"); server = ctx; } } }; match input.recv().expect("expected data msg") { Msg::Token(_) => panic!("unexpected extra token"), Msg::Msg(secret_msg) => println!( "{}", String::from_utf8_lossy(&server.unwrap(&*secret_msg).expect("unwrap")) ), } } ``` -------------------------------- ### into Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html Converts an InitiateFlags value into another type. ```APIDOC ## into ### Description Calls `U::from(self)`. That is, this conversion is whatever the implementation of `From for U` chooses to do. ### Method `into` ### Returns - `U` - The converted value. ``` -------------------------------- ### try_from Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html Attempts to convert a value into InitiateFlags. ```APIDOC ## try_from ### Description Performs the conversion. ### Method `try_from` ### Parameters - `value` (U) - The value to convert. ### Returns - `Result>::Error>` - Ok if the conversion is successful, Err otherwise. ``` -------------------------------- ### ClientCtx::new_with_cred Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.ClientCtx.html Creates a new client context using provided credentials. ```APIDOC ## ClientCtx::new_with_cred ### Description Creates a new client context using provided credentials. ### Method Signature ```rust pub fn new_with_cred( cred: Cred, target_principal: &str, channel_bindings: Option<&[u8]>, ) -> Result<(PendingClientCtx, impl Deref) ``` ### Parameters * **cred** (`Cred`): The credentials to use for the client context. * **target_principal** (`&str`): The service principal name (SPN) of the target service. * **channel_bindings** (`Option<&[u8]>`): Optional channel binding token. ### Returns A `Result` containing a tuple of `PendingClientCtx` and a token (`impl Deref`) on success, or an error on failure. ``` -------------------------------- ### ClientCtx::new Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.ClientCtx.html Creates a new Kerberos client context for speaking to a target principal. If the principal is None, the current process's credentials are used. The target principal must be a service principal name (SPN). ```APIDOC ## ClientCtx::new ### Description Creates a new client context for speaking to `target_principal`. If `principal` is `None` then the credentials of the user running current process will be used. `target_principal` must be the service principal name of the service you intend to communicate with. This should be an spn as described by GSSAPI, e.g. `service/host@REALM`. If present, `channel_bindings` is a service-specific channel binding token which will be part of the initial communication with the server. On success a `PendingClientCtx` and a token to be sent to the server will be returned. The server and client may generate multiple additional tokens, which must be passed to the their respective `step` methods until the initialization is complete. ### Method Signature ```rust pub fn new( flags: InitiateFlags, principal: Option<&str>, target_principal: &str, channel_bindings: Option<&[u8]>, ) -> Result<(PendingClientCtx, impl Deref) ``` ### Parameters * **flags** (`InitiateFlags`): Flags to control the initiation of the client context. * **principal** (`Option<&str>`): The principal name to use. If `None`, the current process's credentials are used. * **target_principal** (`&str`): The service principal name (SPN) of the target service. * **channel_bindings** (`Option<&[u8]>`): Optional channel binding token. ### Returns A `Result` containing a tuple of `PendingClientCtx` and a token (`impl Deref`) on success, or an error on failure. ### Example ```rust // Assuming InitiateFlags, PendingClientCtx, and Msg are defined elsewhere // let (mut client, token) = ClientCtx::new(InitiateFlags::empty(), None, "service/host@REALM", None).expect("new"); ``` ``` -------------------------------- ### Formatting Implementations Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.AcceptFlags.html Provides methods for formatting AcceptFlags values in different bases. ```APIDOC ## fmt(&self, f: &mut Formatter<'_>) -> Result ### Description Formats the AcceptFlags value using the given formatter (for LowerHex, Octal, UpperHex). ### Method fmt ### Parameters - **self**: &AcceptFlags - A reference to the flags value. - **f**: &mut Formatter<'_> - The formatter to use. ### Response - **Result**: The result of the formatting operation. ``` -------------------------------- ### fmt (LowerHex) Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html Formats the InitiateFlags value as a lowercase hexadecimal string. ```APIDOC ## fmt (LowerHex) ### Description Formats the value using the given formatter. ### Method `fmt` ### Parameters - `f` (&mut Formatter<'_>) - The formatter to use. ### Returns - `Result` - Ok if formatting was successful, Err otherwise. ``` -------------------------------- ### borrow Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html Immutably borrows the InitiateFlags value. ```APIDOC ## borrow ### Description Immutably borrows from an owned value. ### Method `borrow` ### Returns - `&T` - An immutable reference to the borrowed value. ``` -------------------------------- ### complement Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html Computes the bitwise negation of an InitiateFlags value. ```APIDOC ## complement ### Description The bitwise negation (`!`) of the bits in a flags value, truncating the result. ### Method `complement` ### Returns - `Self` - A new InitiateFlags value representing the bitwise negation. ``` -------------------------------- ### wrap Method - Encrypt and Protect Message Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/trait.K5Ctx.html Use this method to encrypt and protect the integrity of a message for transmission. When `encrypt` is false, only integrity is protected. ```rust fn wrap(&mut self, encrypt: bool, msg: &[u8]) -> Result ``` -------------------------------- ### from_iter Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html Creates an InitiateFlags value by performing a bitwise OR on an iterator of InitiateFlags. ```APIDOC ## from_iter ### Description The bitwise or (`|`) of the bits in each flags value. ### Method `from_iter` ### Parameters - `iterator` (T: IntoIterator) - An iterator yielding InitiateFlags values. ### Returns - `Self` - A new InitiateFlags value representing the bitwise OR of all elements in the iterator. ``` -------------------------------- ### ServerCtx::new Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.ServerCtx.html Creates a new server context for a given principal. The principal should be the service principal name. If None, it defaults to the current process user. The returned context must be initialized by exchanging tokens. ```APIDOC ## `ServerCtx::new` ### Description Create a new server context for `principal`, which should be the service principal name assigned to the service the client will be requesting. If it is left as `None` it will use the user running the current process. The returned pending context must be initiaized by exchanging one or more tokens with the client before it can be used. ### Parameters #### Path Parameters - None #### Query Parameters - None #### Request Body - None ### Method Signature `pub fn new(flags: AcceptFlags, principal: Option<&str>) -> Result` ### Example ```rust let mut server = ServerCtx::new(AcceptFlags::empty(), Some(&spn)).expect("new"); ``` ``` -------------------------------- ### InitiateFlags::from_bits Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html Convert from a bits value. Returns `None` if any unknown bits are set. ```APIDOC ## InitiateFlags::from_bits ### Description Convert from a bits value. ### Method `const fn from_bits(bits: u32) -> Option` ### Example ```rust use cross_krb5::InitiateFlags; let flags = InitiateFlags::from_bits(0); assert!(flags.is_some()); assert!(flags.unwrap().is_empty()); // Assuming a hypothetical flag with value 1 exists // let flags_with_unknown = InitiateFlags::from_bits(1 | 0x80000000); // 0x80000000 is an unknown bit // assert!(flags_with_unknown.is_none()); ``` ``` -------------------------------- ### InitiateFlags::is_all Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html Check if all known bits in this flags value are set. Returns `true` if all defined flags are enabled. ```APIDOC ## InitiateFlags::is_all ### Description Whether all known bits in this flags value are set. ### Method `const fn is_all(&self) -> bool` ### Example ```rust use cross_krb5::InitiateFlags; let flags = InitiateFlags::all(); assert!(flags.is_all()); let flags_with_some_unset = InitiateFlags::from_bits_truncate(InitiateFlags::all().bits() & !1); assert!(!flags_with_some_unset.is_all()); ``` ``` -------------------------------- ### Bitwise Operations Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html This section details the bitwise operations supported by the InitiateFlags struct. ```APIDOC ## impl BitAnd for InitiateFlags ### Description Provides the bitwise AND operation. ### Methods - `fn bitand(self, other: Self) -> Self`: The bitwise and (`&`) of the bits in two flags values. - `type Output = InitiateFlags`: The resulting type after applying the `&` operator. ## impl BitAndAssign for InitiateFlags ### Description Provides the bitwise AND assignment operation. ### Methods - `fn bitand_assign(&mut self, other: Self)`: The bitwise and (`&`) of the bits in two flags values. ## impl BitOr for InitiateFlags ### Description Provides the bitwise OR operation. ### Methods - `fn bitor(self, other: InitiateFlags) -> Self`: The bitwise or (`|`) of the bits in two flags values. - `type Output = InitiateFlags`: The resulting type after applying the `|` operator. ## impl BitOrAssign for InitiateFlags ### Description Provides the bitwise OR assignment operation. ### Methods - `fn bitor_assign(&mut self, other: Self)`: The bitwise or (`|`) of the bits in two flags values. ## impl BitXor for InitiateFlags ### Description Provides the bitwise XOR operation. ### Methods - `fn bitxor(self, other: Self) -> Self`: The bitwise exclusive-or (`^`) of the bits in two flags values. - `type Output = InitiateFlags`: The resulting type after applying the `^` operator. ## impl BitXorAssign for InitiateFlags ### Description Provides the bitwise XOR assignment operation. ### Methods - `fn bitxor_assign(&mut self, other: Self)`: The bitwise exclusive-or (`^`) of the bits in two flags values. ``` -------------------------------- ### into_iter Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html Creates an iterator from an InitiateFlags value. ```APIDOC ## into_iter ### Description Creates an iterator from a value. ### Method `into_iter` ### Returns - `Self::IntoIter` - An iterator over the elements of the InitiateFlags value. ``` -------------------------------- ### K5Cred Trait: Server Acquire Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.Cred.html Acquires credentials for a server using the K5Cred trait. Requires AcceptFlags and an optional principal name. ```rust fn server_acquire(flags: AcceptFlags, principal: Option<&str>) -> Result ``` -------------------------------- ### try_into Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html Attempts to convert an InitiateFlags value into another type. ```APIDOC ## try_into ### Description Performs the conversion. ### Method `try_into` ### Returns - `Result>::Error>` - Ok if the conversion is successful, Err otherwise. ``` -------------------------------- ### AcceptFlags::NEGOTIATE_TOKEN Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.AcceptFlags.html A constant flag for Windows-specific negotiation using the SSPI negotiate package instead of the Kerberos package. Use this only if the client is known to be on Windows and sending negotiate tokens. ```APIDOC ## AcceptFlags::NEGOTIATE_TOKEN ### Description Windows only, use the sspi negotiate package instead of the Kerberos package. Some Windows clients generate these tokens instead of normal gssapi compatible tokens. This likely won’t be able to parse gssapi tokens, so only use this if you know the client will be on windows sending negotiate tokens. ### Constant `pub const NEGOTIATE_TOKEN: Self` ``` -------------------------------- ### K5Ctx trait implementations for ClientCtx Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.ClientCtx.html Provides methods for message wrapping, unwrapping, and session time-to-live (TTL) management for Kerberos contexts. ```APIDOC ## K5Ctx Trait Implementations for ClientCtx ### wrap #### Description Wrap the specified message for sending to the other side. If `encrypt` is true then the contents will be encrypted. Even if `encrypt` is false the integrity of the contents are protected; if the message is altered in transit the other side will know. #### Method Signature ```rust fn wrap(&mut self, encrypt: bool, msg: &[u8]) -> Result ``` ### wrap_iov #### Description Wrap data in place using the underlying wrap_iov facility. If `encrypt` is true then the contents of `data` will be encrypted in place. The returned buffer is NOT contiguous, and as such you must use some kind of `writev` implementation to properly send it. You can use tokio’s `write_buf` directly, or you can extract the iovecs for a direct call to `writev` using `bytes::Buf::chunks_vectored`. #### Method Signature ```rust fn wrap_iov(&mut self, encrypt: bool, msg: BytesMut) -> Result ``` ### unwrap #### Description Unwrap the specified message returning its decrypted and verified contents. #### Method Signature ```rust fn unwrap(&mut self, msg: &[u8]) -> Result ``` ### unwrap_iov #### Description Unwrap in place the message at the beginning of the specified `BytesMut` and then split it off and return it. This won’t copy or allocate, it just looks that way because the bytes crate is awesome. #### Method Signature ```rust fn unwrap_iov(&mut self, len: usize, msg: &mut BytesMut) -> Result ``` ### ttl #### Description Return the remaining time this session has to live. #### Method Signature ```rust fn ttl(&mut self) -> Result ``` ``` -------------------------------- ### PendingServerCtx::step Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.PendingServerCtx.html Processes a token as part of the server-side authentication handshake. It can either complete the authentication, returning a finished ServerCtx and an optional token, or continue the handshake, returning an updated PendingServerCtx and a token. ```APIDOC ## PendingServerCtx::step ### Description Processes a token as part of the server-side authentication handshake. It can either complete the authentication, returning a finished ServerCtx and an optional token, or continue the handshake, returning an updated PendingServerCtx and a token. ### Method `step` ### Signature `pub fn step(self, token: &[u8]) -> Result>), (PendingServerCtx, impl Deref)>>` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **token** (`&[u8]`) - Required - The token to process. ### Request Example ```rust // Example usage within a server loop: // let mut server = loop { // let token = match input.recv().expect("expected data") { // Msg::Msg(_) => panic!("server not finished initializing"), // Msg::Token(t) => t, // }; // match server.step(&*token).expect("step") { // Step::Finished((ctx, token)) => { // if let Some(token) = token { // output.send(Msg::Token(Bytes::copy_from_slice(&*token))).expect("send"); // } // break ctx // }, // Step::Continue((ctx, token)) => { // output.send(Msg::Token(Bytes::copy_from_slice(&*token))).expect("send"); // server = ctx; // } // } // }; ``` ### Response #### Success Response - **Step::Finished((ServerCtx, Option<&[u8]>))**: Indicates the authentication is complete. Returns the final `ServerCtx` and an optional token. - **Step::Continue((PendingServerCtx, &[u8]))**: Indicates the handshake should continue. Returns the updated `PendingServerCtx` and the token to be sent back to the client. #### Response Example ```rust // For Step::Finished: // (ServerCtx, Option) // For Step::Continue: // (PendingServerCtx, Bytes) ``` ``` -------------------------------- ### Extend Operations Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html This section details the extend operations for the InitiateFlags struct. ```APIDOC ## impl Extend for InitiateFlags ### Description Provides methods for extending the flags with other flag values. ### Methods - `fn extend>(&mut self, iterator: T)`: The bitwise or (`|`) of the bits in each flags value. - `fn extend_one(&mut self, item: A)`: Extends a collection with exactly one element. (Nightly-only experimental API) - `fn extend_reserve(&mut self, additional: usize)`: Reserves capacity in a collection for the given number of additional elements. (Nightly-only experimental API) ``` -------------------------------- ### not Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html Computes the bitwise negation of an InitiateFlags value. ```APIDOC ## not ### Description The bitwise negation (`!`) of the bits in a flags value, truncating the result. ### Method `not` ### Returns - `Self` - A new InitiateFlags value representing the bitwise negation. ``` -------------------------------- ### Wrap Message In-Place (IOV) Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.ClientCtx.html Wraps data in-place using the underlying `wrap_iov` facility. If `encrypt` is true, the data is encrypted in place. The returned buffer is not contiguous and requires a `writev` implementation. ```rust fn wrap_iov(&mut self, encrypt: bool, msg: BytesMut) -> Result ``` -------------------------------- ### K5Ctx trait implementations for ServerCtx Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.ServerCtx.html Provides methods for wrapping and unwrapping messages, and checking session time-to-live. ```APIDOC ## `K5Ctx` Trait Implementations for `ServerCtx` ### Description These methods are part of the `K5Ctx` trait, providing functionalities for secure message handling and session management within the Kerberos context. ### Methods #### `wrap` - **Description**: Wrap the specified message for sending to the other side. If `encrypt` is true then the contents will be encrypted. Even if `encrypt` is false the integrity of the contents are protected. - **Signature**: `fn wrap(&mut self, encrypt: bool, msg: &[u8]) -> Result` #### `wrap_iov` - **Description**: Wrap data in place using the underlying `wrap_iov` facility. If `encrypt` is true then the contents of `data` will be encrypted in place. The returned buffer is NOT contiguous. - **Signature**: `fn wrap_iov(&mut self, encrypt: bool, msg: BytesMut) -> Result` #### `unwrap` - **Description**: Unwrap the specified message returning its decrypted and verified contents. - **Signature**: `fn unwrap(&mut self, msg: &[u8]) -> Result` #### `unwrap_iov` - **Description**: Unwrap in place the message at the beginning of the specified `BytesMut` and then split it off and return it. - **Signature**: `fn unwrap_iov(&mut self, len: usize, msg: &mut BytesMut) -> Result` #### `ttl` - **Description**: Return the remaining time this session has to live. - **Signature**: `fn ttl(&mut self) -> Result` ``` -------------------------------- ### borrow_mut Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html Mutably borrows the InitiateFlags value. ```APIDOC ## borrow_mut ### Description Mutably borrows from an owned value. ### Method `borrow_mut` ### Returns - `&mut T` - A mutable reference to the borrowed value. ``` -------------------------------- ### InitiateFlags::set Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.InitiateFlags.html Set or unset bits based on a boolean value. If `value` is `true`, bits are inserted; if `false`, they are removed. ```APIDOC ## InitiateFlags::set ### Description Call `insert` when `value` is `true` or `remove` when `value` is `false`. ### Method `pub fn set(&mut self, other: Self>, value: bool)` ### Example ```rust use cross_krb5::InitiateFlags; let mut flags = InitiateFlags::empty(); let flag_to_set = InitiateFlags::from_bits_truncate(1); flags.set(flag_to_set, true); assert_eq!(flags.bits(), 1); flags.set(flag_to_set, false); assert_eq!(flags.bits(), 0); ``` ``` -------------------------------- ### K5Cred Trait: Client Acquire Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.Cred.html Acquires credentials for a client using the K5Cred trait. Requires InitiateFlags and an optional principal name. ```rust fn client_acquire(flags: InitiateFlags, principal: Option<&str>) -> Result ``` -------------------------------- ### wrap_iov Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/trait.K5Ctx.html Wraps data in place using the underlying `wrap_iov` facility. If `encrypt` is true, the contents of `data` are encrypted in place. The returned buffer is not contiguous, requiring a `writev` implementation for proper sending. This method can offer significant performance gains (2x-3x) over `wrap`/`unwrap` on supported operating systems when the `iov` feature is enabled. ```APIDOC ## wrap_iov ### Description Wrap data in place using the underlying wrap_iov facility. If `encrypt` is true then the contents of `data` will be encrypted in place. The returned buffer is NOT contiguous, and as such you must use some kind of `writev` implementation to properly send it. You can use tokio’s `write_buf` directly, or you can extract the iovecs for a direct call to `writev` using `bytes::Buf::chunks_vectored`. If feature `iov` isn’t enabled (it’s in the default set) then the underlying functionaly will be emulated, and there will be no performance gain. `iov` is currently not available on Mac OS, and compilation will fail if you try to enable it. On OSes where it is supported using wrap_iov/unwrap_iov is generally in the neighborhood of 2x to 3x faster than wrap/unwrap. ### Method `wrap_iov` ### Parameters - `encrypt` (bool) - Whether to encrypt the message. - `msg` (BytesMut) - The mutable byte buffer containing the message to wrap. ### Returns - `Result` - The wrapped message buffer, potentially non-contiguous. ``` -------------------------------- ### TryFrom for T Source: https://docs.rs/cross-krb5/0.4.2/cross_krb5/struct.ServerCtx.html Provides functionality to attempt conversion from one type to another, with a defined error type. ```APIDOC ## impl TryFrom for T ### Description This implementation allows for attempting a conversion from type `U` into type `T`. ### Type Alias #### Error - **type Error = Infallible** The type returned in the event of a conversion error. In this case, `Infallible` indicates that the conversion will always succeed if the `Into` trait is implemented for `U`. ### Method #### try_from - **fn try_from(value: U) -> Result>::Error>** Performs the conversion from `value` of type `U` into type `T`. Returns a `Result` which is `Ok(T)` on success or `Err(Error)` on failure. ```