use async_trait::async_trait;
use tracing::trace;
use super::super::tokens::Tokens;
use super::common::TokenParser;
use crate::io::token_stream::ParserContext;
use crate::token::fed_auth_info::SspiToken;
use crate::{core::TdsResult, io::packet_reader::TdsPacketReader};
#[derive(Default)]
pub(crate) struct SspiTokenParser;
#[async_trait]
impl<T> TokenParser<T> for SspiTokenParser
where
T: TdsPacketReader + Send + Sync,
{
async fn parse(&self, reader: &mut T, _context: &ParserContext) -> TdsResult<Tokens> {
let length = reader.read_uint16().await?;
trace!("Parsing SSPI token with length: {}", length);
let data = if length > 0 {
let mut buffer = vec![0u8; length as usize];
reader.read_bytes(&mut buffer).await?;
buffer
} else {
Vec::new()
};
trace!("SSPI token data length: {} bytes", data.len());
Ok(Tokens::Sspi(SspiToken { data }))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::token::parsers::common::test_utils::MockReader;
#[tokio::test]
async fn test_parse_sspi_token_empty() {
let data = vec![0x00, 0x00]; let mut reader = MockReader::new(data);
let parser = SspiTokenParser;
let result = parser.parse(&mut reader, &ParserContext::default()).await;
assert!(result.is_ok());
if let Tokens::Sspi(token) = result.unwrap() {
assert!(token.data.is_empty());
} else {
panic!("Expected SSPI token");
}
}
#[tokio::test]
async fn test_parse_sspi_token_with_data() {
let mut data = vec![0x04, 0x00]; data.extend_from_slice(&[0xDE, 0xAD, 0xBE, 0xEF]);
let mut reader = MockReader::new(data);
let parser = SspiTokenParser;
let result = parser.parse(&mut reader, &ParserContext::default()).await;
assert!(result.is_ok());
if let Tokens::Sspi(token) = result.unwrap() {
assert_eq!(token.data, vec![0xDE, 0xAD, 0xBE, 0xEF]);
} else {
panic!("Expected SSPI token");
}
}
#[tokio::test]
async fn test_parse_sspi_token_ntlm_challenge_size() {
let length: u16 = 172;
let mut data = length.to_le_bytes().to_vec();
data.extend(std::iter::repeat_n(0xAA, length as usize));
let mut reader = MockReader::new(data);
let parser = SspiTokenParser;
let result = parser.parse(&mut reader, &ParserContext::default()).await;
assert!(result.is_ok());
if let Tokens::Sspi(token) = result.unwrap() {
assert_eq!(token.data.len(), 172);
} else {
panic!("Expected SSPI token");
}
}
#[tokio::test]
async fn test_parse_sspi_token_kerberos_size() {
let length: u16 = 2048;
let mut data = length.to_le_bytes().to_vec();
data.extend(std::iter::repeat_n(0xBB, length as usize));
let mut reader = MockReader::new(data);
let parser = SspiTokenParser;
let result = parser.parse(&mut reader, &ParserContext::default()).await;
assert!(result.is_ok());
if let Tokens::Sspi(token) = result.unwrap() {
assert_eq!(token.data.len(), 2048);
} else {
panic!("Expected SSPI token");
}
}
}