mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-10-30 01:10:50 +08:00
190 lines
6.9 KiB
Rust
190 lines
6.9 KiB
Rust
#[cfg(test)]
|
|
mod alert_test;
|
|
|
|
use std::fmt;
|
|
use std::io::{Read, Write};
|
|
|
|
use byteorder::{ReadBytesExt, WriteBytesExt};
|
|
|
|
use super::content::*;
|
|
use crate::error::Result;
|
|
|
|
#[derive(Copy, Clone, PartialEq, Debug)]
|
|
pub(crate) enum AlertLevel {
|
|
Warning = 1,
|
|
Fatal = 2,
|
|
Invalid,
|
|
}
|
|
|
|
impl fmt::Display for AlertLevel {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
match *self {
|
|
AlertLevel::Warning => write!(f, "LevelWarning"),
|
|
AlertLevel::Fatal => write!(f, "LevelFatal"),
|
|
_ => write!(f, "Invalid alert level"),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<u8> for AlertLevel {
|
|
fn from(val: u8) -> Self {
|
|
match val {
|
|
1 => AlertLevel::Warning,
|
|
2 => AlertLevel::Fatal,
|
|
_ => AlertLevel::Invalid,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Copy, Clone, PartialEq, Debug)]
|
|
pub(crate) enum AlertDescription {
|
|
CloseNotify = 0,
|
|
UnexpectedMessage = 10,
|
|
BadRecordMac = 20,
|
|
DecryptionFailed = 21,
|
|
RecordOverflow = 22,
|
|
DecompressionFailure = 30,
|
|
HandshakeFailure = 40,
|
|
NoCertificate = 41,
|
|
BadCertificate = 42,
|
|
UnsupportedCertificate = 43,
|
|
CertificateRevoked = 44,
|
|
CertificateExpired = 45,
|
|
CertificateUnknown = 46,
|
|
IllegalParameter = 47,
|
|
UnknownCa = 48,
|
|
AccessDenied = 49,
|
|
DecodeError = 50,
|
|
DecryptError = 51,
|
|
ExportRestriction = 60,
|
|
ProtocolVersion = 70,
|
|
InsufficientSecurity = 71,
|
|
InternalError = 80,
|
|
UserCanceled = 90,
|
|
NoRenegotiation = 100,
|
|
UnsupportedExtension = 110,
|
|
UnknownPskIdentity = 115,
|
|
Invalid,
|
|
}
|
|
|
|
impl fmt::Display for AlertDescription {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
match *self {
|
|
AlertDescription::CloseNotify => write!(f, "CloseNotify"),
|
|
AlertDescription::UnexpectedMessage => write!(f, "UnexpectedMessage"),
|
|
AlertDescription::BadRecordMac => write!(f, "BadRecordMac"),
|
|
AlertDescription::DecryptionFailed => write!(f, "DecryptionFailed"),
|
|
AlertDescription::RecordOverflow => write!(f, "RecordOverflow"),
|
|
AlertDescription::DecompressionFailure => write!(f, "DecompressionFailure"),
|
|
AlertDescription::HandshakeFailure => write!(f, "HandshakeFailure"),
|
|
AlertDescription::NoCertificate => write!(f, "NoCertificate"),
|
|
AlertDescription::BadCertificate => write!(f, "BadCertificate"),
|
|
AlertDescription::UnsupportedCertificate => write!(f, "UnsupportedCertificate"),
|
|
AlertDescription::CertificateRevoked => write!(f, "CertificateRevoked"),
|
|
AlertDescription::CertificateExpired => write!(f, "CertificateExpired"),
|
|
AlertDescription::CertificateUnknown => write!(f, "CertificateUnknown"),
|
|
AlertDescription::IllegalParameter => write!(f, "IllegalParameter"),
|
|
AlertDescription::UnknownCa => write!(f, "UnknownCA"),
|
|
AlertDescription::AccessDenied => write!(f, "AccessDenied"),
|
|
AlertDescription::DecodeError => write!(f, "DecodeError"),
|
|
AlertDescription::DecryptError => write!(f, "DecryptError"),
|
|
AlertDescription::ExportRestriction => write!(f, "ExportRestriction"),
|
|
AlertDescription::ProtocolVersion => write!(f, "ProtocolVersion"),
|
|
AlertDescription::InsufficientSecurity => write!(f, "InsufficientSecurity"),
|
|
AlertDescription::InternalError => write!(f, "InternalError"),
|
|
AlertDescription::UserCanceled => write!(f, "UserCanceled"),
|
|
AlertDescription::NoRenegotiation => write!(f, "NoRenegotiation"),
|
|
AlertDescription::UnsupportedExtension => write!(f, "UnsupportedExtension"),
|
|
AlertDescription::UnknownPskIdentity => write!(f, "UnknownPskIdentity"),
|
|
_ => write!(f, "Invalid alert description"),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<u8> for AlertDescription {
|
|
fn from(val: u8) -> Self {
|
|
match val {
|
|
0 => AlertDescription::CloseNotify,
|
|
10 => AlertDescription::UnexpectedMessage,
|
|
20 => AlertDescription::BadRecordMac,
|
|
21 => AlertDescription::DecryptionFailed,
|
|
22 => AlertDescription::RecordOverflow,
|
|
30 => AlertDescription::DecompressionFailure,
|
|
40 => AlertDescription::HandshakeFailure,
|
|
41 => AlertDescription::NoCertificate,
|
|
42 => AlertDescription::BadCertificate,
|
|
43 => AlertDescription::UnsupportedCertificate,
|
|
44 => AlertDescription::CertificateRevoked,
|
|
45 => AlertDescription::CertificateExpired,
|
|
46 => AlertDescription::CertificateUnknown,
|
|
47 => AlertDescription::IllegalParameter,
|
|
48 => AlertDescription::UnknownCa,
|
|
49 => AlertDescription::AccessDenied,
|
|
50 => AlertDescription::DecodeError,
|
|
51 => AlertDescription::DecryptError,
|
|
60 => AlertDescription::ExportRestriction,
|
|
70 => AlertDescription::ProtocolVersion,
|
|
71 => AlertDescription::InsufficientSecurity,
|
|
80 => AlertDescription::InternalError,
|
|
90 => AlertDescription::UserCanceled,
|
|
100 => AlertDescription::NoRenegotiation,
|
|
110 => AlertDescription::UnsupportedExtension,
|
|
115 => AlertDescription::UnknownPskIdentity,
|
|
_ => AlertDescription::Invalid,
|
|
}
|
|
}
|
|
}
|
|
|
|
// One of the content types supported by the TLS record layer is the
|
|
// alert type. Alert messages convey the severity of the message
|
|
// (warning or fatal) and a description of the alert. Alert messages
|
|
// with a level of fatal result in the immediate termination of the
|
|
// connection. In this case, other connections corresponding to the
|
|
// session may continue, but the session identifier MUST be invalidated,
|
|
// preventing the failed session from being used to establish new
|
|
// connections. Like other messages, alert messages are encrypted and
|
|
// compressed, as specified by the current connection state.
|
|
/// ## Specifications
|
|
///
|
|
/// * [RFC 5246 §7.2]
|
|
///
|
|
/// [RFC 5246 §7.2]: https://tools.ietf.org/html/rfc5246#section-7.2
|
|
#[derive(Copy, Clone, PartialEq, Debug)]
|
|
pub struct Alert {
|
|
pub(crate) alert_level: AlertLevel,
|
|
pub(crate) alert_description: AlertDescription,
|
|
}
|
|
|
|
impl fmt::Display for Alert {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "Alert {}: {}", self.alert_level, self.alert_description)
|
|
}
|
|
}
|
|
|
|
impl Alert {
|
|
pub fn content_type(&self) -> ContentType {
|
|
ContentType::Alert
|
|
}
|
|
|
|
pub fn size(&self) -> usize {
|
|
2
|
|
}
|
|
|
|
pub fn marshal<W: Write>(&self, writer: &mut W) -> Result<()> {
|
|
writer.write_u8(self.alert_level as u8)?;
|
|
writer.write_u8(self.alert_description as u8)?;
|
|
|
|
Ok(writer.flush()?)
|
|
}
|
|
|
|
pub fn unmarshal<R: Read>(reader: &mut R) -> Result<Self> {
|
|
let alert_level = reader.read_u8()?.into();
|
|
let alert_description = reader.read_u8()?.into();
|
|
|
|
Ok(Alert {
|
|
alert_level,
|
|
alert_description,
|
|
})
|
|
}
|
|
}
|