rust_rcs_core/security/authentication/
authentication_info.rs

1// Copyright 2023 宋昊文
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::{internet::HeaderField, util::raw_string::StrEq};
16
17use super::auth_param::AuthParamParser;
18
19pub struct ResponseAuth<'a> {
20    pub qop: &'a [u8],
21    pub cnonce: &'a [u8],
22    pub nc: &'a [u8],
23    pub auth: &'a [u8],
24}
25
26pub struct AuthenticationInfo<'a> {
27    pub next_nonce: Option<&'a [u8]>,
28    pub response_auth: Option<ResponseAuth<'a>>,
29}
30
31pub trait AsAuthenticationInfo<'a> {
32    type Target;
33    fn as_authentication_info(&'a self) -> Self::Target;
34}
35
36impl<'a> AsAuthenticationInfo<'a> for [u8] {
37    type Target = AuthenticationInfo<'a>;
38    fn as_authentication_info(&'a self) -> Self::Target {
39        let mut authentication_info = AuthenticationInfo {
40            next_nonce: None,
41            response_auth: None,
42        };
43        let mut qop = None;
44        let mut cnonce = None;
45        let mut nc = None;
46        let mut response_auth = None;
47        let mut p = 0;
48        while let Some((param, advance)) = self[p..].try_auth_param() {
49            if param.name.equals_bytes(b"next_nonce", true) {
50                authentication_info.next_nonce = Some(param.value);
51            } else if param.name.equals_bytes(b"qop", true) {
52                qop = Some(param.value);
53            } else if param.name.equals_bytes(b"cnonce", true) {
54                cnonce = Some(param.value);
55            } else if param.name.equals_bytes(b"nc", true) {
56                nc = Some(param.value);
57            } else if param.name.equals_bytes(b"rspauth", true) {
58                response_auth = Some(param.value);
59            }
60            p += advance;
61        }
62        if let (Some(qop), Some(cnonce), Some(nc), Some(response_auth)) =
63            (qop, cnonce, nc, response_auth)
64        {
65            authentication_info.response_auth = Some(ResponseAuth {
66                qop,
67                cnonce,
68                nc,
69                auth: response_auth,
70            });
71        }
72        authentication_info
73    }
74}