1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
//! Gssapi is the standard way of using Kerberos to build and use //! Kerberized services on unix. It has other uses, but Kerberos is by //! far the most common (and making Kerberos work well is the focus of //! this library). //! //! ## Contexts //! //! Gssapi is used through contexts which are connected to each other //! in a mechanism specific way. In the case of Kerberos once you have //! a context set up you can use to to send and receive encrypted //! messages that only the other side can read. Other mechanisms may //! or may not provide this feature. //! //! * Initiate a new connection with a [`ClientCtx`](context/struct.ClientCtx.html) //! * Accept a client connection with a [`ServerCtx`](context/struct.ServerCtx.html) //! * Both types implement [`SecurityContext`](context/trait.SecurityContext.html) //! //! Unlike SSL Gssapi is completely independent of the transport. It //! will give you tokens to send to the other side, and tell you when //! the context is established, it's up to you to decide how the data //! gets there. //! //! ``` //! use std::env::args; //! use libgssapi::{ //! name::Name, //! credential::{Cred, CredUsage}, //! error::Error, //! context::{CtxFlags, ClientCtx, ServerCtx, SecurityContext}, //! util::Buf, //! oid::{OidSet, GSS_NT_HOSTBASED_SERVICE, GSS_MECH_KRB5}, //! }; //! //! fn setup_server_ctx( //! service_name: &[u8], //! desired_mechs: &OidSet //! ) -> Result<(ServerCtx, Name), Error> { //! let name = Name::new(service_name, Some(&GSS_NT_HOSTBASED_SERVICE))?; //! let cname = name.canonicalize(Some(&GSS_MECH_KRB5))?; //! let server_cred = Cred::acquire( //! Some(&cname), None, CredUsage::Accept, Some(desired_mechs) //! )?; //! Ok((ServerCtx::new(server_cred), cname)) //! } //! //! fn setup_client_ctx( //! service_name: Name, //! desired_mechs: &OidSet //! ) -> Result<ClientCtx, Error> { //! let client_cred = Cred::acquire( //! None, None, CredUsage::Initiate, Some(&desired_mechs) //! )?; //! Ok(ClientCtx::new( //! client_cred, service_name, CtxFlags::GSS_C_MUTUAL_FLAG, Some(&GSS_MECH_KRB5) //! )) //! } //! //! fn run(service_name: &[u8]) -> Result<(), Error> { //! let desired_mechs = { //! let mut s = OidSet::new()?; //! s.add(&GSS_MECH_KRB5)?; //! s //! }; //! let (server_ctx, cname) = setup_server_ctx(service_name, &desired_mechs)?; //! let client_ctx = setup_client_ctx(cname, &desired_mechs)?; //! let mut server_tok: Option<Buf> = None; //! loop { //! match client_ctx.step(server_tok.as_ref().map(|b| &**b))? { //! None => break, //! Some(client_tok) => match server_ctx.step(&*client_tok)? { //! None => break, //! Some(tok) => { server_tok = Some(tok); } //! } //! } //! } //! let secret_msg = client_ctx.wrap(true, b"super secret message")?; //! let decoded_msg = server_ctx.unwrap(&*secret_msg)?; //! println!("the decrypted message is: '{}'", String::from_utf8_lossy(&*decoded_msg)); //! Ok(()) //! } //! ``` #[macro_use] extern crate bitflags; #[macro_use] extern crate lazy_static; pub mod oid; pub mod error; pub mod util; pub mod name; pub mod credential; pub mod context;