wlan_mlme/
auth.rs

1// Copyright 2019 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use anyhow::{bail, ensure, Error};
6use fidl_fuchsia_wlan_ieee80211 as fidl_ieee80211;
7use wlan_common::mac;
8
9pub fn make_open_client_req() -> mac::AuthHdr {
10    mac::AuthHdr {
11        auth_alg_num: mac::AuthAlgorithmNumber::OPEN,
12        auth_txn_seq_num: 1,
13        status_code: fidl_ieee80211::StatusCode::Success.into(),
14    }
15}
16
17#[derive(Debug)]
18pub enum ValidFrame {
19    Open,
20    SaeCommit,
21    SaeConfirm,
22}
23
24/// Validates whether a given authentication header is a valid response to an authentication
25/// request.
26pub fn validate_ap_resp(auth: &mac::AuthHdr) -> Result<ValidFrame, Error> {
27    ensure!(
28        { auth.status_code } == fidl_ieee80211::StatusCode::Success.into(),
29        "invalid status_code: {}",
30        { auth.status_code }.0
31    );
32    match auth.auth_alg_num {
33        mac::AuthAlgorithmNumber::OPEN => {
34            ensure!(auth.auth_txn_seq_num == 2, "invalid auth_txn_seq_num: {}", {
35                auth.auth_txn_seq_num
36            });
37            Ok(ValidFrame::Open)
38        }
39        mac::AuthAlgorithmNumber::SAE => match auth.auth_txn_seq_num {
40            1 => Ok(ValidFrame::SaeCommit),
41            2 => Ok(ValidFrame::SaeConfirm),
42            _ => bail!("invalid auth_txn_seq_num: {}", { auth.auth_txn_seq_num }),
43        },
44        _ => bail!("invalid auth_alg_num: {}", { auth.auth_alg_num }.0),
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51    use wlan_common::assert_variant;
52
53    fn make_valid_auth_resp(frame_type: ValidFrame) -> mac::AuthHdr {
54        mac::AuthHdr {
55            auth_alg_num: match frame_type {
56                ValidFrame::Open => mac::AuthAlgorithmNumber::OPEN,
57                ValidFrame::SaeCommit | ValidFrame::SaeConfirm => mac::AuthAlgorithmNumber::SAE,
58            },
59            auth_txn_seq_num: match frame_type {
60                ValidFrame::SaeCommit => 1,
61                ValidFrame::Open | ValidFrame::SaeConfirm => 2,
62            },
63            status_code: fidl_ieee80211::StatusCode::Success.into(),
64        }
65    }
66
67    #[test]
68    fn valid_auth_resp() {
69        assert_variant!(
70            validate_ap_resp(&make_valid_auth_resp(ValidFrame::Open)),
71            Ok(ValidFrame::Open)
72        );
73        assert_variant!(
74            validate_ap_resp(&make_valid_auth_resp(ValidFrame::SaeCommit)),
75            Ok(ValidFrame::SaeCommit)
76        );
77        assert_variant!(
78            validate_ap_resp(&make_valid_auth_resp(ValidFrame::SaeConfirm)),
79            Ok(ValidFrame::SaeConfirm)
80        );
81    }
82
83    #[test]
84    fn invalid_auth_resp() {
85        let mut auth_hdr = make_valid_auth_resp(ValidFrame::Open);
86        auth_hdr.auth_alg_num = mac::AuthAlgorithmNumber::FAST_BSS_TRANSITION;
87        assert_variant!(validate_ap_resp(&auth_hdr), Err(_));
88
89        let mut auth_hdr = make_valid_auth_resp(ValidFrame::Open);
90        auth_hdr.auth_txn_seq_num = 1;
91        assert_variant!(validate_ap_resp(&auth_hdr), Err(_));
92
93        let mut auth_hdr = make_valid_auth_resp(ValidFrame::Open);
94        auth_hdr.status_code = fidl_ieee80211::StatusCode::RefusedReasonUnspecified.into();
95        assert_variant!(validate_ap_resp(&auth_hdr), Err(_));
96
97        let mut auth_hdr = make_valid_auth_resp(ValidFrame::SaeCommit);
98        auth_hdr.auth_txn_seq_num = 4;
99        assert_variant!(validate_ap_resp(&auth_hdr), Err(_));
100
101        let mut auth_hdr = make_valid_auth_resp(ValidFrame::SaeCommit);
102        auth_hdr.status_code = fidl_ieee80211::StatusCode::RefusedReasonUnspecified.into();
103        assert_variant!(validate_ap_resp(&auth_hdr), Err(_));
104    }
105}