1use std::net::SocketAddr;
2
3use sha2::Sha256;
4
5use hmac::Hmac;
6use hmac::Mac;
7
8use bincode::Decode;
9use bincode::Encode;
10
11use crate::node_get_cookie;
12
13type HmacSha256 = Hmac<Sha256>;
15
16#[derive(Debug, Encode, Decode)]
18pub struct Hello {
19 pub name: String,
20 pub broadcast_address: SocketAddr,
21 pub challenge: Vec<u8>,
22}
23
24impl Hello {
25 pub fn new(name: String, broadcast_address: SocketAddr) -> Self {
27 let mut challenge = {
28 let cookie = node_get_cookie();
29 let cookie = cookie
30 .as_ref()
31 .map(|cookie| cookie.as_bytes())
32 .unwrap_or(&[0]);
33
34 HmacSha256::new_from_slice(cookie).unwrap()
35 };
36
37 challenge.update(name.as_bytes());
38 challenge.update(broadcast_address.to_string().as_bytes());
39
40 Self {
41 name,
42 broadcast_address,
43 challenge: challenge.finalize().into_bytes().to_vec(),
44 }
45 }
46
47 pub fn validate(&mut self) -> bool {
49 let mut challenge = {
50 let cookie = node_get_cookie();
51 let cookie = cookie
52 .as_ref()
53 .map(|cookie| cookie.as_bytes())
54 .unwrap_or(&[0]);
55
56 HmacSha256::new_from_slice(cookie).unwrap()
57 };
58
59 challenge.update(self.name.as_bytes());
60 challenge.update(self.broadcast_address.to_string().as_bytes());
61
62 let wanted = challenge.finalize().into_bytes();
63
64 let challenge = std::mem::take(&mut self.challenge);
65
66 wanted.as_slice() == challenge
67 }
68}