auth/
auth.rs

1use bytes::Bytes;
2use cross_krb5::{AcceptFlags, ClientCtx, InitiateFlags, K5Ctx, Step, ServerCtx};
3use std::{env::args, process::exit, sync::mpsc, thread};
4
5enum Msg {
6    Token(Bytes),
7    Msg(Bytes),
8}
9
10fn server(spn: String, input: mpsc::Receiver<Msg>, output: mpsc::Sender<Msg>) {
11    let mut server = ServerCtx::new(AcceptFlags::empty(), Some(&spn)).expect("new");
12    let mut server = loop {
13        let token = match input.recv().expect("expected data") {
14            Msg::Msg(_) => panic!("server not finished initializing"),
15            Msg::Token(t) => t,
16        };
17        match server.step(&*token).expect("step") {
18            Step::Finished((ctx, token)) => {
19                if let Some(token) = token {
20                    output.send(Msg::Token(Bytes::copy_from_slice(&*token))).expect("send");
21                }
22                break ctx
23            },
24            Step::Continue((ctx, token)) => {
25                output.send(Msg::Token(Bytes::copy_from_slice(&*token))).expect("send");
26                server = ctx;
27            }
28        }
29    };
30    match input.recv().expect("expected data msg") {
31        Msg::Token(_) => panic!("unexpected extra token"),
32        Msg::Msg(secret_msg) => println!(
33            "{}",
34            String::from_utf8_lossy(&server.unwrap(&*secret_msg).expect("unwrap"))
35        ),
36    }
37}
38
39fn client(spn: &str, input: mpsc::Receiver<Msg>, output: mpsc::Sender<Msg>) {
40    let (mut client, token) =
41        ClientCtx::new(InitiateFlags::empty(), None, spn, None).expect("new");
42    output.send(Msg::Token(Bytes::copy_from_slice(&*token))).expect("send");
43    let mut client = loop {
44        let token = match input.recv().expect("expected data") {
45            Msg::Msg(_) => panic!("client not finished initializing"),
46            Msg::Token(t) => t,
47        };
48        match client.step(&*token).expect("step") {
49            Step::Finished((ctx, token)) => {
50                if let Some(token) = token {
51                    output.send(Msg::Token(Bytes::copy_from_slice(&*token))).expect("send");
52                }
53                break ctx
54            },
55            Step::Continue((ctx, token)) => {
56                output.send(Msg::Token(Bytes::copy_from_slice(&*token))).expect("send");
57                client = ctx;
58            }
59        }
60    };
61    let msg = client.wrap(true, b"super secret message").expect("wrap");
62    output.send(Msg::Msg(Bytes::copy_from_slice(&*msg))).expect("send");
63}
64
65fn main() {
66    let args = args().collect::<Vec<_>>();
67    if args.len() != 2 {
68        println!("usage: {}: <service/host@REALM>", args[0]);
69        exit(1);
70    }
71    let spn = String::from(&args[1]);
72    let (server_snd, server_recv) = mpsc::channel();
73    let (client_snd, client_recv) = mpsc::channel();
74    thread::spawn(move || server(spn, server_recv, client_snd));
75    client(&args[1], client_recv, server_snd);
76}