diff --git a/code-generator/src/main.rs b/code-generator/src/main.rs index 25e3a69..2df3257 100644 --- a/code-generator/src/main.rs +++ b/code-generator/src/main.rs @@ -556,7 +556,7 @@ fn generate_fixed_length_octets_attribute_code( let code = format!( "pub fn add_{method_identifier}(packet: &mut Packet, value: &[u8]) -> Result<(), AVPError> {{ if value.len() != {fixed_octets_length} {{ - return Err(AVPError::InvalidAttributeLengthError({fixed_octets_length})); + return Err(AVPError::InvalidAttributeLengthError(\"{fixed_octets_length} bytes\".to_owned(), value.len())); }} packet.add(AVP::from_bytes({type_identifier}, value)); Ok(()) diff --git a/radius-client/src/client.rs b/radius-client/src/client.rs index 12d4ed1..eb597ca 100644 --- a/radius-client/src/client.rs +++ b/radius-client/src/client.rs @@ -7,27 +7,39 @@ use tokio::time::timeout; use radius::packet::Packet; -use crate::client::ClientError::{ - FailedConnection, FailedParsingUDPResponse, FailedRadiusPacketEncoding, - FailedReceivingResponse, FailedSendingPacket, FailedUdpSocketBinding, -}; - #[derive(Error, Debug)] pub enum ClientError { - #[error("failed to bind a UDP socket => `{0}`")] - FailedUdpSocketBinding(String), - #[error("failed to connect to `{0}` => `{1}`")] - FailedConnection(String, String), - #[error("failed to encode a RADIUS request => `{0}`")] - FailedRadiusPacketEncoding(String), - #[error("failed to send a UDP datagram to `{0}` => `{1}`")] - FailedSendingPacket(String, String), - #[error("failed to receive the UDP response from `{0}` => `{1}`")] - FailedReceivingResponse(String, String), - #[error("failed to parse a UDP response into a RADIUS packet => `{0}`")] - FailedParsingUDPResponse(String), + /// This error is occurred when UDP socket binding has been failed. + #[error("failed to bind a UDP socket; {0}")] + FailedUdpSocketBindingError(String), + + /// This error is raised when it failed to establish the connection. + #[error("failed to establish a UDP connection to {0}; {1}")] + FailedEstablishingUdpConnectionError(String, String), + + /// This error is raised when encoding RADIUS packet has been failed. + #[error("failed to encode a RADIUS request; {0}")] + FailedRadiusPacketEncodingError(String), + + /// This error is raised when it fails to send a RADIUS packet. + #[error("failed to send a UDP datagram to {0}; {1}")] + FailedSendingRadiusPacketError(String, String), + + /// This error is raised when it fails to receive a RADIUS response. + #[error("failed to receive the UDP response from {0}; {1}")] + FailedReceivingResponseError(String, String), + + /// This error is raised when it fails to decode a RADIUS response packet. + #[error("failed to decode a RADIUS response packet; {0}")] + FailedDecodingRadiusResponseError(String), + + /// This error is raised when it exceeds the connection timeout duration. + /// Connection timeout means it fails to establish a connection in time. #[error("connection timeout")] ConnectionTimeoutError(), + + /// This error is raised when it exceeds the socket timeout duration. + /// Socket timeout means it fails to receive a response from the request target in time. #[error("socket timeout")] SocketTimeoutError(), } @@ -74,7 +86,7 @@ impl Client { let conn = match UdpSocket::bind(local_addr).await { Ok(conn) => conn, - Err(e) => return Err(FailedUdpSocketBinding(e.to_string())), + Err(e) => return Err(ClientError::FailedUdpSocketBindingError(e.to_string())), }; match self.connection_timeout { @@ -89,7 +101,12 @@ impl Client { let request_data = match request_packet.encode() { Ok(encoded) => encoded, - Err(e) => return Err(FailedRadiusPacketEncoding(format!("{:?}", e))), + Err(e) => { + return Err(ClientError::FailedRadiusPacketEncodingError(format!( + "{:?}", + e + ))) + } }; let response = match self.socket_timeout { @@ -109,14 +126,20 @@ impl Client { match Packet::decode(&response.to_vec(), request_packet.get_secret()) { Ok(response_packet) => Ok(response_packet), - Err(e) => Err(FailedParsingUDPResponse(format!("{:?}", e))), + Err(e) => Err(ClientError::FailedDecodingRadiusResponseError(format!( + "{:?}", + e + ))), } } async fn connect(&self, conn: &UdpSocket, remote_addr: &SocketAddr) -> Result<(), ClientError> { match conn.connect(remote_addr).await { Ok(_) => Ok(()), - Err(e) => Err(FailedConnection(remote_addr.to_string(), e.to_string())), + Err(e) => Err(ClientError::FailedEstablishingUdpConnectionError( + remote_addr.to_string(), + e.to_string(), + )), } } @@ -128,13 +151,18 @@ impl Client { ) -> Result, ClientError> { match conn.send(request_data).await { Ok(_) => {} - Err(e) => return Err(FailedSendingPacket(remote_addr.to_string(), e.to_string())), + Err(e) => { + return Err(ClientError::FailedSendingRadiusPacketError( + remote_addr.to_string(), + e.to_string(), + )) + } }; let mut buf = vec![0; Self::MAX_DATAGRAM_SIZE]; match conn.recv(&mut buf).await { Ok(len) => Ok(buf[..len].to_vec()), - Err(e) => Err(FailedReceivingResponse( + Err(e) => Err(ClientError::FailedReceivingResponseError( remote_addr.to_string(), e.to_string(), )), diff --git a/radius-server/src/secret_provider.rs b/radius-server/src/secret_provider.rs index c292b6c..d01c59d 100644 --- a/radius-server/src/secret_provider.rs +++ b/radius-server/src/secret_provider.rs @@ -4,8 +4,12 @@ use thiserror::Error; #[derive(Error, Debug)] pub enum SecretProviderError { - #[error("failed to fetch a secret value => `{0}`")] - FailedFetching(String), + /// An error that represents a failure to fetch a secret value from the provider. + #[error("failed to fetch a secret value: {0}")] + FailedFetchingError(String), + /// An error that represents a generic (i.e. unclassified) error that occurs on the secret value provider. + #[error("unexpected error: {0}")] + GenericError(String), } /// SecretProvider is a provider for secret value. diff --git a/radius/src/avp.rs b/radius/src/avp.rs index 67db50e..5f7be9e 100644 --- a/radius/src/avp.rs +++ b/radius/src/avp.rs @@ -9,23 +9,39 @@ use crate::tag::{Tag, UNUSED_TAG_VALUE}; #[derive(Error, PartialEq, Debug)] pub enum AVPError { - #[error( - "the maximum length of the plain text is 128, but the given value is longer than that" - )] - PlainTextMaximumLengthExceededError(), - #[error("secret hasn't be empty, but the given value is empty")] - SecretMissingError(), - #[error("request authenticator has to have 16-bytes payload, but the given value doesn't")] + /// This error is raised on the length of given plain text for user-password exceeds the maximum limit. + #[error("the maximum length of the plain text for user-password is 128, but the given value has {0} bytes")] + UserPasswordPlainTextMaximumLengthExceededError(usize), + + /// This error is raised when the given secret value for a password is empty. + #[error("secret for password mustn't be empty, but the given value is empty")] + PasswordSecretMissingError(), + + /// This error is raised when the given request-authenticator for the password doesn't have 16 bytes length exactly. + #[error("request authenticator for password has to have 16-bytes payload, but the given value doesn't")] InvalidRequestAuthenticatorLength(), - #[error("invalid attribute length: {0}")] - InvalidAttributeLengthError(usize), - // ^ TODO: more meaningful error message - #[error("unexpected decoding error: {0}")] - UnexpectedDecodingError(String), + + /// This error is raised when attribute length is conflicted with the expected. + #[error("invalid attribute length: expected={0}, actual={1} bytes")] + InvalidAttributeLengthError(String, usize), + + /// This error is raised when the tagged-value doesn't have a tag byte. + #[error("tag value is missing")] + TagMissingError(), + + /// This error represents AVP decoding error. + #[error("decoding error: {0}")] + DecodingError(String), + + /// This error is raised when the MSB of salt is invalid. #[error("invalid salt. the MSB has to be 1, but given value isn't: {0}")] InvalidSaltMSBError(u8), + + /// This error is raised when a tag is invalid for the tagged-staring value. #[error("invalid tag for string value. this must not be zero")] InvalidTagForStringValueError(), + + /// This error is raised when a tag is invalid for the tagged-integer value. #[error("invalid tag for integer value. this must be less than or equal 0x1f")] InvalidTagForIntegerValueError(), } @@ -115,7 +131,10 @@ impl AVP { pub fn from_ipv4_prefix(typ: AVPType, prefix: &[u8]) -> Result { let prefix_len = prefix.len(); if prefix_len != 4 { - return Err(AVPError::InvalidAttributeLengthError(prefix_len)); + return Err(AVPError::InvalidAttributeLengthError( + "4 bytes".to_owned(), + prefix_len, + )); } Ok(AVP { @@ -136,7 +155,10 @@ impl AVP { pub fn from_ipv6_prefix(typ: AVPType, prefix: &[u8]) -> Result { let prefix_len = prefix.len(); if prefix_len > 16 { - return Err(AVPError::InvalidAttributeLengthError(prefix_len)); + return Err(AVPError::InvalidAttributeLengthError( + "16 bytes".to_owned(), + prefix_len, + )); } Ok(AVP { @@ -169,11 +191,13 @@ impl AVP { // ref: https://tools.ietf.org/html/rfc2865#section-5.2 if plain_text.len() > 128 { - return Err(AVPError::PlainTextMaximumLengthExceededError()); + return Err(AVPError::UserPasswordPlainTextMaximumLengthExceededError( + plain_text.len(), + )); } if secret.is_empty() { - return Err(AVPError::SecretMissingError()); + return Err(AVPError::PasswordSecretMissingError()); } if request_authenticator.len() != 16 { @@ -251,6 +275,7 @@ impl AVP { if request_authenticator.len() > 240 { return Err(AVPError::InvalidAttributeLengthError( + "240 bytes".to_owned(), request_authenticator.len(), )); } @@ -259,7 +284,7 @@ impl AVP { let salt: [u8; 2] = [rng.gen::() | 0x80, rng.gen::()]; if secret.is_empty() { - return Err(AVPError::SecretMissingError()); + return Err(AVPError::PasswordSecretMissingError()); } if request_authenticator.len() != 16 { @@ -313,13 +338,16 @@ impl AVP { pub fn encode_u32(&self) -> Result { const U32_SIZE: usize = std::mem::size_of::(); if self.value.len() != U32_SIZE { - return Err(AVPError::InvalidAttributeLengthError(self.value.len())); + return Err(AVPError::InvalidAttributeLengthError( + format!("{} bytes", U32_SIZE), + self.value.len(), + )); } let (int_bytes, _) = self.value.split_at(U32_SIZE); match int_bytes.try_into() { Ok(boxed_array) => Ok(u32::from_be_bytes(boxed_array)), - Err(e) => Err(AVPError::UnexpectedDecodingError(e.to_string())), + Err(e) => Err(AVPError::DecodingError(e.to_string())), } } @@ -327,20 +355,23 @@ impl AVP { pub fn encode_u16(&self) -> Result { const U16_SIZE: usize = std::mem::size_of::(); if self.value.len() != U16_SIZE { - return Err(AVPError::InvalidAttributeLengthError(self.value.len())); + return Err(AVPError::InvalidAttributeLengthError( + format!("{} bytes", U16_SIZE), + self.value.len(), + )); } let (int_bytes, _) = self.value.split_at(U16_SIZE); match int_bytes.try_into() { Ok(boxed_array) => Ok(u16::from_be_bytes(boxed_array)), - Err(e) => Err(AVPError::UnexpectedDecodingError(e.to_string())), + Err(e) => Err(AVPError::DecodingError(e.to_string())), } } /// (This method is for dictionary developers) encode an AVP into a tag and u32 value. pub fn encode_tagged_u32(&self) -> Result<(u32, Tag), AVPError> { if self.value.is_empty() { - return Err(AVPError::InvalidAttributeLengthError(self.value.len())); + return Err(AVPError::TagMissingError()); } let tag = Tag { @@ -356,12 +387,15 @@ impl AVP { const U32_SIZE: usize = std::mem::size_of::(); if self.value[1..].len() != U32_SIZE { - return Err(AVPError::InvalidAttributeLengthError(self.value.len())); + return Err(AVPError::InvalidAttributeLengthError( + format!("{} bytes", U32_SIZE + 1), + self.value.len(), + )); } let (int_bytes, _) = self.value[1..].split_at(U32_SIZE); match int_bytes.try_into() { Ok(boxed_array) => Ok((u32::from_be_bytes(boxed_array), tag)), - Err(e) => Err(AVPError::UnexpectedDecodingError(e.to_string())), + Err(e) => Err(AVPError::DecodingError(e.to_string())), } } @@ -369,7 +403,7 @@ impl AVP { pub fn encode_string(&self) -> Result { match String::from_utf8(self.value.to_vec()) { Ok(str) => Ok(str), - Err(e) => Err(AVPError::UnexpectedDecodingError(e.to_string())), + Err(e) => Err(AVPError::DecodingError(e.to_string())), } } @@ -377,7 +411,7 @@ impl AVP { pub fn encode_tagged_string(&self) -> Result<(String, Option), AVPError> { let string_vec = self.value.to_vec(); if string_vec.is_empty() { - return Err(AVPError::InvalidAttributeLengthError(string_vec.len())); + return Err(AVPError::TagMissingError()); } let tag = Tag { @@ -392,7 +426,7 @@ impl AVP { if tag.is_valid_value() { return match String::from_utf8(string_vec[1..].to_vec()) { Ok(str) => Ok((str, Some(tag))), - Err(e) => Err(AVPError::UnexpectedDecodingError(e.to_string())), + Err(e) => Err(AVPError::DecodingError(e.to_string())), }; } @@ -405,7 +439,7 @@ impl AVP { // interpreted as the first byte of the following String field. match String::from_utf8(self.value.to_vec()) { Ok(str) => Ok((str, None)), - Err(e) => Err(AVPError::UnexpectedDecodingError(e.to_string())), + Err(e) => Err(AVPError::DecodingError(e.to_string())), } } @@ -418,13 +452,16 @@ impl AVP { pub fn encode_ipv4(&self) -> Result { const IPV4_SIZE: usize = std::mem::size_of::(); if self.value.len() != IPV4_SIZE { - return Err(AVPError::InvalidAttributeLengthError(self.value.len())); + return Err(AVPError::InvalidAttributeLengthError( + format!("{} bytes", IPV4_SIZE), + self.value.len(), + )); } let (int_bytes, _) = self.value.split_at(IPV4_SIZE); match int_bytes.try_into() { Ok::<[u8; IPV4_SIZE], _>(boxed_array) => Ok(Ipv4Addr::from(boxed_array)), - Err(e) => Err(AVPError::UnexpectedDecodingError(e.to_string())), + Err(e) => Err(AVPError::DecodingError(e.to_string())), } } @@ -432,7 +469,10 @@ impl AVP { pub fn encode_ipv4_prefix(&self) -> Result, AVPError> { match self.value.len() == 6 { true => Ok(self.value[2..].to_owned()), - false => Err(AVPError::InvalidAttributeLengthError(self.value.len())), + false => Err(AVPError::InvalidAttributeLengthError( + "6 bytes".to_owned(), + self.value.len(), + )), } } @@ -440,13 +480,16 @@ impl AVP { pub fn encode_ipv6(&self) -> Result { const IPV6_SIZE: usize = std::mem::size_of::(); if self.value.len() != IPV6_SIZE { - return Err(AVPError::InvalidAttributeLengthError(self.value.len())); + return Err(AVPError::InvalidAttributeLengthError( + format!("{} bytes", IPV6_SIZE), + self.value.len(), + )); } let (int_bytes, _) = self.value.split_at(IPV6_SIZE); match int_bytes.try_into() { Ok::<[u8; IPV6_SIZE], _>(boxed_array) => Ok(Ipv6Addr::from(boxed_array)), - Err(e) => Err(AVPError::UnexpectedDecodingError(e.to_string())), + Err(e) => Err(AVPError::DecodingError(e.to_string())), } } @@ -454,7 +497,10 @@ impl AVP { pub fn encode_ipv6_prefix(&self) -> Result, AVPError> { match self.value.len() >= 2 { true => Ok(self.value[2..].to_owned()), - false => Err(AVPError::InvalidAttributeLengthError(self.value.len())), + false => Err(AVPError::InvalidAttributeLengthError( + "2+ bytes".to_owned(), + self.value.len(), + )), } } @@ -465,11 +511,14 @@ impl AVP { request_authenticator: &[u8], ) -> Result, AVPError> { if self.value.len() < 16 || self.value.len() > 128 { - return Err(AVPError::InvalidAttributeLengthError(self.value.len())); + return Err(AVPError::InvalidAttributeLengthError( + "16 >= bytes && 128 <= bytes".to_owned(), + self.value.len(), + )); } if secret.is_empty() { - return Err(AVPError::SecretMissingError()); + return Err(AVPError::PasswordSecretMissingError()); } if request_authenticator.len() != 16 { @@ -506,7 +555,10 @@ impl AVP { pub fn encode_date(&self) -> Result, AVPError> { const U32_SIZE: usize = std::mem::size_of::(); if self.value.len() != U32_SIZE { - return Err(AVPError::InvalidAttributeLengthError(self.value.len())); + return Err(AVPError::InvalidAttributeLengthError( + format!("{}", U32_SIZE), + self.value.len(), + )); } let (int_bytes, _) = self.value.split_at(U32_SIZE); @@ -515,7 +567,7 @@ impl AVP { let timestamp = u32::from_be_bytes(boxed_array); Ok(Utc.timestamp(timestamp as i64, 0)) } - Err(e) => Err(AVPError::UnexpectedDecodingError(e.to_string())), + Err(e) => Err(AVPError::DecodingError(e.to_string())), } } @@ -525,11 +577,11 @@ impl AVP { secret: &[u8], request_authenticator: &[u8], ) -> Result<(Vec, Tag), AVPError> { - if self.value.len() - 3 < 16 - || self.value.len() - 3 > 240 - || (self.value.len() - 3) % 16 != 0 - { - return Err(AVPError::InvalidAttributeLengthError(self.value.len())); + if self.value.len() < 19 || self.value.len() > 243 || (self.value.len() - 3) % 16 != 0 { + return Err(AVPError::InvalidAttributeLengthError( + "19 <= bytes && bytes <= 242 && (bytes - 3) % 16 == 0".to_owned(), + self.value.len(), + )); } if self.value[1] & 0x80 != 0x80 { @@ -538,7 +590,7 @@ impl AVP { } if secret.is_empty() { - return Err(AVPError::SecretMissingError()); + return Err(AVPError::PasswordSecretMissingError()); } if request_authenticator.len() != 16 { @@ -804,10 +856,16 @@ mod tests { #[test] fn should_convert_ipv4_prefix_fail_because_of_invalid_prefix_length() { let avp = AVP::from_ipv4_prefix(1, &[0x01, 0x02, 0x03]); - assert_eq!(avp.unwrap_err(), AVPError::InvalidAttributeLengthError(3)); + assert_eq!( + avp.unwrap_err(), + AVPError::InvalidAttributeLengthError("4 bytes".to_owned(), 3) + ); let avp = AVP::from_ipv4_prefix(1, &[0x01, 0x02, 0x03, 0x04, 0x05]); - assert_eq!(avp.unwrap_err(), AVPError::InvalidAttributeLengthError(5)); + assert_eq!( + avp.unwrap_err(), + AVPError::InvalidAttributeLengthError("4 bytes".to_owned(), 5) + ); assert_eq!( AVP { @@ -816,7 +874,7 @@ mod tests { } .encode_ipv4_prefix() .unwrap_err(), - AVPError::InvalidAttributeLengthError(0) + AVPError::InvalidAttributeLengthError("6 bytes".to_owned(), 0) ); } @@ -849,6 +907,9 @@ mod tests { 0x0e, 0x0f, 0x10, ], ); - assert_eq!(avp.unwrap_err(), AVPError::InvalidAttributeLengthError(17)); + assert_eq!( + avp.unwrap_err(), + AVPError::InvalidAttributeLengthError("16 bytes".to_owned(), 17) + ); } } diff --git a/radius/src/packet.rs b/radius/src/packet.rs index 34c7470..0192314 100644 --- a/radius/src/packet.rs +++ b/radius/src/packet.rs @@ -12,17 +12,28 @@ const RADIUS_PACKET_HEADER_LENGTH: usize = 20; // i.e. minimum packet length #[derive(Error, Debug, PartialEq)] pub enum PacketError { - #[error("radius packet doesn't have enough length of bytes; it has to be at least {0} bytes")] - InsufficientPacketLengthError(usize), - #[error("invalid radius packet length: {0}")] - InvalidPacketLengthError(usize), - #[error("unexpected decoding error: {0}")] - UnexpectedDecodingError(String), + /// An error indicates the entire length of the given packet has insufficient length. + #[error("RADIUS packet doesn't have enough length of bytes; it has to be at least {0} bytes, but actual length was {1}")] + InsufficientPacketPayloadLengthError(usize, usize), + + /// An error indicates the length that is instructed by a header is insufficient. + #[error("RADIUS packet header indicates the length as {0} bytes, but this is insufficient; this must have {1} bytes at least")] + InsufficientHeaderDefinedPacketLengthError(usize, usize), + + /// An error indicates the length that is instructed by a header exceeds the maximum length of the RADIUS packet. + #[error("RADIUS packet header indicates the length as {0} bytes, but this exceeds the maximum length {1} bytes")] + HeaderDefinedPacketLengthExceedsMaximumLimitError(usize, usize), + + /// An error that is raised when an error has been occurred on decoding bytes for a packet. #[error("failed to decode the packet: {0}")] DecodingError(String), + + /// An error that is raised when an error has been occurred on encoding a packet into bytes. #[error("failed to encode the packet: {0}")] EncodingError(String), - #[error("Unknown radius packet code: {0}")] + + /// An error that is raised when it received unknown packet type code of RADIUS. + #[error("Unknown RADIUS packet type code: {0}")] UnknownCodeError(String), } @@ -69,17 +80,35 @@ impl Packet { /// This decodes bytes into a Packet. pub fn decode(bs: &[u8], secret: &[u8]) -> Result { if bs.len() < RADIUS_PACKET_HEADER_LENGTH { - return Err(PacketError::InsufficientPacketLengthError( + return Err(PacketError::InsufficientPacketPayloadLengthError( RADIUS_PACKET_HEADER_LENGTH, + bs.len(), )); } let len = match bs[2..4].try_into() { Ok(v) => u16::from_be_bytes(v), - Err(e) => return Err(PacketError::UnexpectedDecodingError(e.to_string())), + Err(e) => return Err(PacketError::DecodingError(e.to_string())), } as usize; - if len < RADIUS_PACKET_HEADER_LENGTH || len > MAX_PACKET_LENGTH || bs.len() < len { - return Err(PacketError::InvalidPacketLengthError(len)); + if len < RADIUS_PACKET_HEADER_LENGTH { + return Err(PacketError::InsufficientHeaderDefinedPacketLengthError( + len, + RADIUS_PACKET_HEADER_LENGTH, + )); + } + if len > MAX_PACKET_LENGTH { + return Err( + PacketError::HeaderDefinedPacketLengthExceedsMaximumLimitError( + len, + MAX_PACKET_LENGTH, + ), + ); + } + if bs.len() < len { + return Err(PacketError::InsufficientPacketPayloadLengthError( + len, + bs.len(), + )); } let attributes = match Attributes::decode(&bs[RADIUS_PACKET_HEADER_LENGTH..len].to_vec()) { @@ -266,7 +295,7 @@ mod tests { use crate::avp::AVP; use crate::code::Code; - use crate::packet::{Packet, PacketError}; + use crate::packet::{Packet, PacketError, MAX_PACKET_LENGTH, RADIUS_PACKET_HEADER_LENGTH}; use crate::rfc2865; #[test] @@ -468,19 +497,19 @@ mod tests { let test_cases = &[ TestCase { plain_text: "\x01", - expected_error: PacketError::InsufficientPacketLengthError(20), + expected_error: PacketError::InsufficientPacketPayloadLengthError(RADIUS_PACKET_HEADER_LENGTH, 1), }, 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), + expected_error: PacketError::InsufficientHeaderDefinedPacketLengthError(0, RADIUS_PACKET_HEADER_LENGTH), }, 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), + expected_error: PacketError::HeaderDefinedPacketLengthExceedsMaximumLimitError(32639, MAX_PACKET_LENGTH), }, 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), + expected_error: PacketError::InsufficientPacketPayloadLengthError(22, 21), }, 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", diff --git a/radius/src/rfc2869.rs b/radius/src/rfc2869.rs index 65d00df..1fd9e2a 100644 --- a/radius/src/rfc2869.rs +++ b/radius/src/rfc2869.rs @@ -69,7 +69,10 @@ pub fn delete_arap_password(packet: &mut Packet) { } pub fn add_arap_password(packet: &mut Packet, value: &[u8]) -> Result<(), AVPError> { if value.len() != 16 { - return Err(AVPError::InvalidAttributeLengthError(16)); + return Err(AVPError::InvalidAttributeLengthError( + "16 bytes".to_owned(), + value.len(), + )); } packet.add(AVP::from_bytes(ARAP_PASSWORD_TYPE, value)); Ok(()) @@ -91,7 +94,10 @@ pub fn delete_arap_features(packet: &mut Packet) { } pub fn add_arap_features(packet: &mut Packet, value: &[u8]) -> Result<(), AVPError> { if value.len() != 14 { - return Err(AVPError::InvalidAttributeLengthError(14)); + return Err(AVPError::InvalidAttributeLengthError( + "14 bytes".to_owned(), + value.len(), + )); } packet.add(AVP::from_bytes(ARAP_FEATURES_TYPE, value)); Ok(()) @@ -290,7 +296,10 @@ pub fn delete_arap_challenge_response(packet: &mut Packet) { } pub fn add_arap_challenge_response(packet: &mut Packet, value: &[u8]) -> Result<(), AVPError> { if value.len() != 8 { - return Err(AVPError::InvalidAttributeLengthError(8)); + return Err(AVPError::InvalidAttributeLengthError( + "8 bytes".to_owned(), + value.len(), + )); } packet.add(AVP::from_bytes(ARAP_CHALLENGE_RESPONSE_TYPE, value)); Ok(()) diff --git a/radius/src/rfc3162.rs b/radius/src/rfc3162.rs index d561d34..abedfb3 100644 --- a/radius/src/rfc3162.rs +++ b/radius/src/rfc3162.rs @@ -31,7 +31,10 @@ pub fn delete_framed_interface_id(packet: &mut Packet) { } pub fn add_framed_interface_id(packet: &mut Packet, value: &[u8]) -> Result<(), AVPError> { if value.len() != 8 { - return Err(AVPError::InvalidAttributeLengthError(8)); + return Err(AVPError::InvalidAttributeLengthError( + "8 bytes".to_owned(), + value.len(), + )); } packet.add(AVP::from_bytes(FRAMED_INTERFACE_ID_TYPE, value)); Ok(()) diff --git a/radius/src/rfc6572.rs b/radius/src/rfc6572.rs index db8cc14..957927c 100644 --- a/radius/src/rfc6572.rs +++ b/radius/src/rfc6572.rs @@ -181,7 +181,10 @@ pub fn delete_pmip6_home_interface_id(packet: &mut Packet) { } pub fn add_pmip6_home_interface_id(packet: &mut Packet, value: &[u8]) -> Result<(), AVPError> { if value.len() != 8 { - return Err(AVPError::InvalidAttributeLengthError(8)); + return Err(AVPError::InvalidAttributeLengthError( + "8 bytes".to_owned(), + value.len(), + )); } packet.add(AVP::from_bytes(PMIP6_HOME_INTERFACE_ID_TYPE, value)); Ok(()) @@ -205,7 +208,10 @@ pub fn delete_pmip6_visited_interface_id(packet: &mut Packet) { } pub fn add_pmip6_visited_interface_id(packet: &mut Packet, value: &[u8]) -> Result<(), AVPError> { if value.len() != 8 { - return Err(AVPError::InvalidAttributeLengthError(8)); + return Err(AVPError::InvalidAttributeLengthError( + "8 bytes".to_owned(), + value.len(), + )); } packet.add(AVP::from_bytes(PMIP6_VISITED_INTERFACE_ID_TYPE, value)); Ok(()) diff --git a/radius/src/rfc7155.rs b/radius/src/rfc7155.rs index bc9f10c..d1fb91b 100644 --- a/radius/src/rfc7155.rs +++ b/radius/src/rfc7155.rs @@ -9,7 +9,10 @@ pub fn delete_originating_line_info(packet: &mut Packet) { } pub fn add_originating_line_info(packet: &mut Packet, value: &[u8]) -> Result<(), AVPError> { if value.len() != 2 { - return Err(AVPError::InvalidAttributeLengthError(2)); + return Err(AVPError::InvalidAttributeLengthError( + "2 bytes".to_owned(), + value.len(), + )); } packet.add(AVP::from_bytes(ORIGINATING_LINE_INFO_TYPE, value)); Ok(())