Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ntp-proto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
//FIXME: Enable #![warn(clippy::doc_markdown)]
#![warn(clippy::elidable_lifetime_names)]
#![warn(clippy::empty_enum)]
//FIXME: Enable #![warn(clippy::enum_glob_use)]
#![warn(clippy::enum_glob_use)]
#![warn(clippy::expl_impl_clone_on_copy)]
#![warn(clippy::explicit_deref_methods)]
//FIXME: Enable #![warn(clippy::explicit_into_iter_loop)]
Expand Down
36 changes: 18 additions & 18 deletions ntp-proto/src/packet/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,32 @@ pub enum ParsingError<T> {

impl<T> ParsingError<T> {
pub(super) fn get_decrypt_error<U>(self) -> Result<T, ParsingError<U>> {
use ParsingError::*;

match self {
InvalidVersion(v) => Err(InvalidVersion(v)),
IncorrectLength => Err(IncorrectLength),
MalformedNtsExtensionFields => Err(MalformedNtsExtensionFields),
MalformedNonce => Err(MalformedNonce),
MalformedCookiePlaceholder => Err(MalformedCookiePlaceholder),
DecryptError(decrypt_error) => Ok(decrypt_error),
V5(e) => Err(V5(e)),
ParsingError::InvalidVersion(v) => Err(ParsingError::InvalidVersion(v)),
ParsingError::IncorrectLength => Err(ParsingError::IncorrectLength),
ParsingError::MalformedNtsExtensionFields => {
Err(ParsingError::MalformedNtsExtensionFields)
}
ParsingError::MalformedNonce => Err(ParsingError::MalformedNonce),
ParsingError::MalformedCookiePlaceholder => {
Err(ParsingError::MalformedCookiePlaceholder)
}
ParsingError::DecryptError(decrypt_error) => Ok(decrypt_error),
ParsingError::V5(e) => Err(ParsingError::V5(e)),
}
}
}

impl ParsingError<std::convert::Infallible> {
pub(super) fn generalize<U>(self) -> ParsingError<U> {
use ParsingError::*;

match self {
InvalidVersion(v) => InvalidVersion(v),
IncorrectLength => IncorrectLength,
MalformedNtsExtensionFields => MalformedNtsExtensionFields,
MalformedNonce => MalformedNonce,
MalformedCookiePlaceholder => MalformedCookiePlaceholder,
DecryptError(decrypt_error) => match decrypt_error {},
V5(e) => V5(e),
ParsingError::InvalidVersion(v) => ParsingError::InvalidVersion(v),
ParsingError::IncorrectLength => ParsingError::IncorrectLength,
ParsingError::MalformedNtsExtensionFields => ParsingError::MalformedNtsExtensionFields,
ParsingError::MalformedNonce => ParsingError::MalformedNonce,
ParsingError::MalformedCookiePlaceholder => ParsingError::MalformedCookiePlaceholder,
ParsingError::DecryptError(decrypt_error) => match decrypt_error {},
ParsingError::V5(e) => ParsingError::V5(e),
}
}
}
Expand Down
68 changes: 39 additions & 29 deletions ntp-proto/src/packet/extension_fields.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,28 +100,34 @@ impl<'a> ExtensionField<'a> {
const HEADER_LENGTH: usize = 4;

pub fn into_owned(self) -> ExtensionField<'static> {
use ExtensionField::*;

match self {
Unknown {
ExtensionField::Unknown {
type_id: typeid,
data,
} => Unknown {
} => ExtensionField::Unknown {
type_id: typeid,
data: Cow::Owned(data.into_owned()),
},
UniqueIdentifier(data) => UniqueIdentifier(Cow::Owned(data.into_owned())),
NtsCookie(data) => NtsCookie(Cow::Owned(data.into_owned())),
NtsCookiePlaceholder {
ExtensionField::UniqueIdentifier(data) => {
ExtensionField::UniqueIdentifier(Cow::Owned(data.into_owned()))
}
ExtensionField::NtsCookie(data) => {
ExtensionField::NtsCookie(Cow::Owned(data.into_owned()))
}
ExtensionField::NtsCookiePlaceholder {
cookie_length: body_length,
} => NtsCookiePlaceholder {
} => ExtensionField::NtsCookiePlaceholder {
cookie_length: body_length,
},
InvalidNtsEncryptedField => InvalidNtsEncryptedField,
DraftIdentification(data) => DraftIdentification(Cow::Owned(data.into_owned())),
Padding(len) => Padding(len),
ReferenceIdRequest(req) => ReferenceIdRequest(req),
ReferenceIdResponse(res) => ReferenceIdResponse(res.into_owned()),
ExtensionField::InvalidNtsEncryptedField => ExtensionField::InvalidNtsEncryptedField,
ExtensionField::DraftIdentification(data) => {
ExtensionField::DraftIdentification(Cow::Owned(data.into_owned()))
}
ExtensionField::Padding(len) => ExtensionField::Padding(len),
ExtensionField::ReferenceIdRequest(req) => ExtensionField::ReferenceIdRequest(req),
ExtensionField::ReferenceIdResponse(res) => {
ExtensionField::ReferenceIdResponse(res.into_owned())
}
}
}

Expand All @@ -131,26 +137,28 @@ impl<'a> ExtensionField<'a> {
minimum_size: u16,
version: ExtensionHeaderVersion,
) -> std::io::Result<()> {
use ExtensionField::*;

match self {
Unknown { type_id, data } => {
ExtensionField::Unknown { type_id, data } => {
Self::encode_unknown(w, *type_id, data, minimum_size, version)
}
UniqueIdentifier(identifier) => {
ExtensionField::UniqueIdentifier(identifier) => {
Self::encode_unique_identifier(w, identifier, minimum_size, version)
}
NtsCookie(cookie) => Self::encode_nts_cookie(w, cookie, minimum_size, version),
NtsCookiePlaceholder {
ExtensionField::NtsCookie(cookie) => {
Self::encode_nts_cookie(w, cookie, minimum_size, version)
}
ExtensionField::NtsCookiePlaceholder {
cookie_length: body_length,
} => Self::encode_nts_cookie_placeholder(w, *body_length, minimum_size, version),
InvalidNtsEncryptedField => Err(std::io::ErrorKind::Other.into()),
DraftIdentification(data) => {
ExtensionField::InvalidNtsEncryptedField => Err(std::io::ErrorKind::Other.into()),
ExtensionField::DraftIdentification(data) => {
Self::encode_draft_identification(w, data, minimum_size, version)
}
Padding(len) => Self::encode_padding_field(w, *len, minimum_size, version),
ReferenceIdRequest(req) => req.serialize(w),
ReferenceIdResponse(res) => res.serialize(w),
ExtensionField::Padding(len) => {
Self::encode_padding_field(w, *len, minimum_size, version)
}
ExtensionField::ReferenceIdRequest(req) => req.serialize(w),
ExtensionField::ReferenceIdResponse(res) => res.serialize(w),
}
}

Expand Down Expand Up @@ -597,8 +605,6 @@ impl<'a> ExtensionFieldData<'a> {
cipher: &(impl CipherProvider + ?Sized),
version: ExtensionHeaderVersion,
) -> Result<DeserializedExtensionField<'a>, ParsingError<InvalidNtsExtensionField<'a>>> {
use ExtensionField::InvalidNtsEncryptedField;

let mut efdata = Self::default();
let mut size = 0;
let mut is_valid_nts = true;
Expand All @@ -621,7 +627,9 @@ impl<'a> ExtensionFieldData<'a> {
.map_err(ParsingError::generalize)?;

let Some(cipher) = cipher.get(&efdata.untrusted) else {
efdata.untrusted.push(InvalidNtsEncryptedField);
efdata
.untrusted
.push(ExtensionField::InvalidNtsEncryptedField);
is_valid_nts = false;
continue;
};
Expand All @@ -636,7 +644,9 @@ impl<'a> ExtensionFieldData<'a> {
// early return if it's anything but a decrypt error
e.get_decrypt_error()?;

efdata.untrusted.push(InvalidNtsEncryptedField);
efdata
.untrusted
.push(ExtensionField::InvalidNtsEncryptedField);
is_valid_nts = false;
continue;
}
Expand Down Expand Up @@ -691,7 +701,7 @@ impl<'a> RawEncryptedField<'a> {
fn from_message_bytes(
message_bytes: &'a [u8],
) -> Result<Self, ParsingError<std::convert::Infallible>> {
use ParsingError::*;
use ParsingError::IncorrectLength;

let [b0, b1, b2, b3, ref rest @ ..] = message_bytes[..] else {
return Err(IncorrectLength);
Expand Down
10 changes: 4 additions & 6 deletions ntp-proto/src/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,15 +267,13 @@ impl NtpSourceSnapshot {
local_ips: &[IpAddr],
system: &SystemSnapshot,
) -> Result<(), AcceptSynchronizationError> {
use AcceptSynchronizationError::*;

if self.stratum >= local_stratum {
debug!(
source_stratum = self.stratum,
own_stratum = local_stratum,
"Source rejected due to invalid stratum. The stratum of a source must be lower than the own stratum",
);
return Err(Stratum);
return Err(AcceptSynchronizationError::Stratum);
}

// Detect whether the remote uses us as their main time reference.
Expand All @@ -289,21 +287,21 @@ impl NtpSourceSnapshot {
.any(|ip| ReferenceId::from_ip(*ip) == self.source_id)
{
debug!("Source rejected because of detected synchronization loop (ref id)");
return Err(Loop);
return Err(AcceptSynchronizationError::Loop);
}

match self.bloom_filter {
Some(filter) if filter.contains_id(&system.server_id) => {
debug!("Source rejected because of detected synchronization loop (bloom filter)");
return Err(Loop);
return Err(AcceptSynchronizationError::Loop);
}
_ => {}
}

// An unreachable error occurs if the server is unreachable.
if !self.reach.is_reachable() {
debug!("Source is unreachable");
return Err(ServerUnreachable);
return Err(AcceptSynchronizationError::ServerUnreachable);
}

Ok(())
Expand Down
Loading