mirror of
https://github.com/cubixle/radius-rs.git
synced 2026-04-24 23:04:43 +01:00
Add test cases
This commit is contained in:
192
src/packet.rs
192
src/packet.rs
@@ -1,6 +1,7 @@
|
|||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
|
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::attributes::Attributes;
|
use crate::attributes::Attributes;
|
||||||
use crate::avp::{AVPType, AVP};
|
use crate::avp::{AVPType, AVP};
|
||||||
@@ -9,9 +10,7 @@ use crate::code::Code;
|
|||||||
const MAX_PACKET_LENGTH: usize = 4096;
|
const MAX_PACKET_LENGTH: usize = 4096;
|
||||||
const RADIUS_PACKET_HEADER_LENGTH: usize = 20; // i.e. minimum packet length
|
const RADIUS_PACKET_HEADER_LENGTH: usize = 20; // i.e. minimum packet length
|
||||||
|
|
||||||
use thiserror::Error;
|
#[derive(Error, Debug, PartialEq)]
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
|
||||||
pub enum PacketError {
|
pub enum PacketError {
|
||||||
#[error("radius packet doesn't have enough length of bytes; it has to be at least {0} bytes")]
|
#[error("radius packet doesn't have enough length of bytes; it has to be at least {0} bytes")]
|
||||||
InsufficientPacketLengthError(usize),
|
InsufficientPacketLengthError(usize),
|
||||||
@@ -49,6 +48,10 @@ impl Packet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_code(&self) -> Code {
|
||||||
|
self.code
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_identifier(&self) -> u8 {
|
pub fn get_identifier(&self) -> u8 {
|
||||||
self.identifier
|
self.identifier
|
||||||
}
|
}
|
||||||
@@ -243,10 +246,12 @@ impl Packet {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::net::Ipv4Addr;
|
||||||
|
|
||||||
|
use crate::avp::AVP;
|
||||||
use crate::code::Code;
|
use crate::code::Code;
|
||||||
use crate::packet::{Packet, PacketError};
|
use crate::packet::{Packet, PacketError};
|
||||||
use crate::rfc2865;
|
use crate::rfc2865;
|
||||||
use std::net::Ipv4Addr;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_for_rfc2865_7_1() -> Result<(), PacketError> {
|
fn test_for_rfc2865_7_1() -> Result<(), PacketError> {
|
||||||
@@ -303,4 +308,183 @@ mod tests {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_for_rfc2865_7_2() -> Result<(), PacketError> {
|
||||||
|
let secret: Vec<u8> = "xyzzy5461".as_bytes().to_vec();
|
||||||
|
let request: Vec<u8> = vec![
|
||||||
|
0x01, 0x01, 0x00, 0x47, 0x2a, 0xee, 0x86, 0xf0, 0x8d, 0x0d, 0x55, 0x96, 0x9c, 0xa5,
|
||||||
|
0x97, 0x8e, 0x0d, 0x33, 0x67, 0xa2, 0x01, 0x08, 0x66, 0x6c, 0x6f, 0x70, 0x73, 0x79,
|
||||||
|
0x03, 0x13, 0x16, 0xe9, 0x75, 0x57, 0xc3, 0x16, 0x18, 0x58, 0x95, 0xf2, 0x93, 0xff,
|
||||||
|
0x63, 0x44, 0x07, 0x72, 0x75, 0x04, 0x06, 0xc0, 0xa8, 0x01, 0x10, 0x05, 0x06, 0x00,
|
||||||
|
0x00, 0x00, 0x14, 0x06, 0x06, 0x00, 0x00, 0x00, 0x02, 0x07, 0x06, 0x00, 0x00, 0x00,
|
||||||
|
0x01,
|
||||||
|
];
|
||||||
|
|
||||||
|
let request_packet = Packet::decode(&request, &secret)?;
|
||||||
|
assert_eq!(request_packet.get_code(), Code::AccessRequest);
|
||||||
|
assert_eq!(request_packet.identifier, 1);
|
||||||
|
assert_eq!(
|
||||||
|
rfc2865::lookup_user_name(&request_packet).unwrap().unwrap(),
|
||||||
|
"flopsy"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
rfc2865::lookup_nas_ip_address(&request_packet)
|
||||||
|
.unwrap()
|
||||||
|
.unwrap(),
|
||||||
|
Ipv4Addr::from([192, 168, 1, 16]),
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
rfc2865::lookup_nas_port(&request_packet).unwrap().unwrap(),
|
||||||
|
20
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
rfc2865::lookup_service_type(&request_packet)
|
||||||
|
.unwrap()
|
||||||
|
.unwrap(),
|
||||||
|
rfc2865::SERVICE_TYPE_FRAMED_USER,
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
rfc2865::lookup_framed_protocol(&request_packet)
|
||||||
|
.unwrap()
|
||||||
|
.unwrap(),
|
||||||
|
rfc2865::FRAMED_PROTOCOL_PPP,
|
||||||
|
);
|
||||||
|
|
||||||
|
let response: Vec<u8> = vec![
|
||||||
|
0x02, 0x01, 0x00, 0x38, 0x15, 0xef, 0xbc, 0x7d, 0xab, 0x26, 0xcf, 0xa3, 0xdc, 0x34,
|
||||||
|
0xd9, 0xc0, 0x3c, 0x86, 0x01, 0xa4, 0x06, 0x06, 0x00, 0x00, 0x00, 0x02, 0x07, 0x06,
|
||||||
|
0x00, 0x00, 0x00, 0x01, 0x08, 0x06, 0xff, 0xff, 0xff, 0xfe, 0x0a, 0x06, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x0d, 0x06, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x06, 0x00, 0x00, 0x05,
|
||||||
|
// ^ incorrectly a 2 in the document
|
||||||
|
0xdc,
|
||||||
|
];
|
||||||
|
let response_packet = Packet::decode(&response, &secret).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(response_packet.get_code(), Code::AccessAccept);
|
||||||
|
assert_eq!(response_packet.get_identifier(), 1);
|
||||||
|
assert_eq!(
|
||||||
|
rfc2865::lookup_service_type(&response_packet)
|
||||||
|
.unwrap()
|
||||||
|
.unwrap(),
|
||||||
|
rfc2865::SERVICE_TYPE_FRAMED_USER
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
rfc2865::lookup_framed_protocol(&response_packet)
|
||||||
|
.unwrap()
|
||||||
|
.unwrap(),
|
||||||
|
rfc2865::FRAMED_PROTOCOL_PPP,
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
rfc2865::lookup_framed_ip_address(&response_packet)
|
||||||
|
.unwrap()
|
||||||
|
.unwrap(),
|
||||||
|
Ipv4Addr::from([255, 255, 255, 254]),
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
rfc2865::lookup_framed_routing(&response_packet)
|
||||||
|
.unwrap()
|
||||||
|
.unwrap(),
|
||||||
|
rfc2865::FRAMED_ROUTING_NONE,
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
rfc2865::lookup_framed_compression(&response_packet)
|
||||||
|
.unwrap()
|
||||||
|
.unwrap(),
|
||||||
|
rfc2865::FRAMED_COMPRESSION_VAN_JACOBSON_TCP_IP,
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
rfc2865::lookup_framed_mtu(&response_packet)
|
||||||
|
.unwrap()
|
||||||
|
.unwrap(),
|
||||||
|
1500,
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_passwords() {
|
||||||
|
let passwords = vec![
|
||||||
|
b"".to_vec(),
|
||||||
|
b"qwerty".to_vec(),
|
||||||
|
b"helloworld1231231231231233489hegufudhsgdsfygdf8g".to_vec(),
|
||||||
|
];
|
||||||
|
|
||||||
|
let secret = b"xyzzy5461";
|
||||||
|
|
||||||
|
for password in passwords {
|
||||||
|
let mut request_packet = Packet::new(Code::AccessRequest, secret);
|
||||||
|
rfc2865::add_user_password(&mut request_packet, &password).unwrap();
|
||||||
|
|
||||||
|
let encoded = request_packet.encode().unwrap();
|
||||||
|
|
||||||
|
let decoded = Packet::decode(&encoded, secret).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
rfc2865::lookup_user_password(&decoded).unwrap().unwrap(),
|
||||||
|
password
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_parse_invalid() {
|
||||||
|
struct TestCase<'a> {
|
||||||
|
plain_text: &'a str,
|
||||||
|
expected_error: PacketError,
|
||||||
|
};
|
||||||
|
|
||||||
|
let test_cases = &[
|
||||||
|
TestCase {
|
||||||
|
plain_text: "\x01",
|
||||||
|
expected_error: PacketError::InsufficientPacketLengthError(20),
|
||||||
|
},
|
||||||
|
TestCase {
|
||||||
|
plain_text: "\x01\x7f\x00\x00\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01",
|
||||||
|
expected_error: PacketError::InvalidPacketLengthError(0),
|
||||||
|
},
|
||||||
|
TestCase {
|
||||||
|
plain_text: "\x01\x7f\x7f\x7f\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01",
|
||||||
|
expected_error: PacketError::InvalidPacketLengthError(32639),
|
||||||
|
},
|
||||||
|
TestCase {
|
||||||
|
plain_text: "\x00\x7f\x00\x16\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00",
|
||||||
|
expected_error: PacketError::InvalidPacketLengthError(22),
|
||||||
|
},
|
||||||
|
TestCase {
|
||||||
|
plain_text: "\x01\x01\x00\x16\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00",
|
||||||
|
expected_error: PacketError::DecodingError("invalid attribute length".to_owned()),
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
let secret = b"12345";
|
||||||
|
for test_case in test_cases {
|
||||||
|
let result = Packet::decode(test_case.plain_text.as_bytes(), secret);
|
||||||
|
assert_eq!(result.is_err(), true);
|
||||||
|
assert_eq!(result.err().unwrap(), test_case.expected_error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_packet_attribute_length_boundary() {
|
||||||
|
let mut packet = Packet::new(Code::AccessRequest, b"12345");
|
||||||
|
packet.add(AVP {
|
||||||
|
typ: 1,
|
||||||
|
value: vec![1; 253],
|
||||||
|
});
|
||||||
|
let encoded = packet.encode();
|
||||||
|
assert_eq!(encoded.is_err(), false);
|
||||||
|
|
||||||
|
let mut packet = Packet::new(Code::AccessRequest, b"12345");
|
||||||
|
packet.add(AVP {
|
||||||
|
typ: 1,
|
||||||
|
value: vec![1; 254],
|
||||||
|
});
|
||||||
|
let encoded = packet.encode();
|
||||||
|
assert_eq!(encoded.is_err(), true);
|
||||||
|
assert_eq!(
|
||||||
|
encoded.err().unwrap(),
|
||||||
|
PacketError::EncodingError("attribute is too large".to_owned()),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user